@cartanova/qgrid-cli 2.4.8 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +18 -11
- package/README.md +18 -11
- package/bundle/.env +0 -0
- package/bundle/dist/_virtual/{_@oxc-project_runtime@0.122.0/helpers → _@oxc-project_runtime@0.140.0/helpers/esm}/decorate.js +2 -2
- package/bundle/dist/_virtual/{_@oxc-project_runtime@0.122.0/helpers → _@oxc-project_runtime@0.140.0/helpers/esm}/decorateMetadata.js +2 -2
- package/bundle/dist/_virtual/_rolldown/runtime.js +2 -3
- package/bundle/dist/application/monit/log-buffer.js +3 -2
- package/bundle/dist/application/monit/monit.frame.js +5 -6
- package/bundle/dist/application/monit/monit.types.js +1 -2
- package/bundle/dist/application/qgrid/conv-routing.js +1 -2
- package/bundle/dist/application/qgrid/oauth.js +1 -2
- package/bundle/dist/application/qgrid/qgrid-image-generation.js +1 -2
- package/bundle/dist/application/qgrid/qgrid-response-format.js +1 -2
- package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +76 -47
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +1 -2
- package/bundle/dist/application/qgrid/qgrid.frame.js +73 -97
- package/bundle/dist/application/qgrid/qgrid.types.js +11 -10
- package/bundle/dist/application/qgrid/token-subscriber.js +3 -2
- package/bundle/dist/application/qgrid/token-trigger-setup.js +1 -2
- package/bundle/dist/application/qgrid/tool-emulation.js +1 -2
- package/bundle/dist/application/queries.generated.js +1 -2
- package/bundle/dist/application/request-log/request-log.model.js +116 -47
- package/bundle/dist/application/request-log/request-log.types.js +1 -2
- package/bundle/dist/application/request-log-step/request-log-step.model.js +3 -4
- package/bundle/dist/application/request-log-step/request-log-step.types.js +1 -2
- package/bundle/dist/application/sonamu.generated.js +14 -15
- package/bundle/dist/application/sonamu.generated.sso.js +1 -2
- package/bundle/dist/application/token/token.model.js +3 -4
- package/bundle/dist/application/token/token.types.js +1 -2
- package/bundle/dist/codex-protocol/AbsolutePathBuf.js +0 -1
- package/bundle/dist/codex-protocol/AgentPath.js +0 -1
- package/bundle/dist/codex-protocol/ApplyPatchApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/ApplyPatchApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/AuthMode.js +0 -1
- package/bundle/dist/codex-protocol/ClientInfo.js +0 -1
- package/bundle/dist/codex-protocol/ClientNotification.js +0 -1
- package/bundle/dist/codex-protocol/ClientRequest.js +0 -1
- package/bundle/dist/codex-protocol/CollaborationMode.js +0 -1
- package/bundle/dist/codex-protocol/ContentItem.js +0 -1
- package/bundle/dist/codex-protocol/ConversationGitInfo.js +0 -1
- package/bundle/dist/codex-protocol/ConversationSummary.js +0 -1
- package/bundle/dist/codex-protocol/ExecCommandApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/ExecCommandApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/ExecPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/FileChange.js +0 -1
- package/bundle/dist/codex-protocol/ForcedLoginMethod.js +0 -1
- package/bundle/dist/codex-protocol/FunctionCallOutputBody.js +0 -1
- package/bundle/dist/codex-protocol/FunctionCallOutputContentItem.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchMatchType.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchParams.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchResponse.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchResult.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchSessionCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchSessionUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/GetAuthStatusParams.js +0 -1
- package/bundle/dist/codex-protocol/GetAuthStatusResponse.js +0 -1
- package/bundle/dist/codex-protocol/GetConversationSummaryParams.js +0 -1
- package/bundle/dist/codex-protocol/GetConversationSummaryResponse.js +0 -1
- package/bundle/dist/codex-protocol/GitDiffToRemoteParams.js +0 -1
- package/bundle/dist/codex-protocol/GitDiffToRemoteResponse.js +0 -1
- package/bundle/dist/codex-protocol/GitSha.js +0 -1
- package/bundle/dist/codex-protocol/ImageDetail.js +0 -1
- package/bundle/dist/codex-protocol/InitializeCapabilities.js +0 -1
- package/bundle/dist/codex-protocol/InitializeParams.js +0 -1
- package/bundle/dist/codex-protocol/InitializeResponse.js +0 -1
- package/bundle/dist/codex-protocol/InputModality.js +0 -1
- package/bundle/dist/codex-protocol/InternalSessionSource.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellAction.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellExecAction.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellStatus.js +0 -1
- package/bundle/dist/codex-protocol/MessagePhase.js +0 -1
- package/bundle/dist/codex-protocol/ModeKind.js +0 -1
- package/bundle/dist/codex-protocol/NetworkPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/NetworkPolicyRuleAction.js +0 -1
- package/bundle/dist/codex-protocol/ParsedCommand.js +0 -1
- package/bundle/dist/codex-protocol/Personality.js +0 -1
- package/bundle/dist/codex-protocol/PlanType.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeConversationVersion.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeOutputModality.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeVoice.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeVoicesList.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningEffort.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningItemContent.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningItemReasoningSummary.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningSummary.js +0 -1
- package/bundle/dist/codex-protocol/RequestId.js +0 -1
- package/bundle/dist/codex-protocol/Resource.js +0 -1
- package/bundle/dist/codex-protocol/ResourceContent.js +0 -1
- package/bundle/dist/codex-protocol/ResourceTemplate.js +0 -1
- package/bundle/dist/codex-protocol/ResponseItem.js +0 -1
- package/bundle/dist/codex-protocol/ReviewDecision.js +0 -1
- package/bundle/dist/codex-protocol/ServerNotification.js +0 -1
- package/bundle/dist/codex-protocol/ServerRequest.js +0 -1
- package/bundle/dist/codex-protocol/SessionSource.js +0 -1
- package/bundle/dist/codex-protocol/Settings.js +0 -1
- package/bundle/dist/codex-protocol/SubAgentSource.js +0 -1
- package/bundle/dist/codex-protocol/ThreadId.js +0 -1
- package/bundle/dist/codex-protocol/ThreadMemoryMode.js +0 -1
- package/bundle/dist/codex-protocol/Tool.js +0 -1
- package/bundle/dist/codex-protocol/Verbosity.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchAction.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchContextSize.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchLocation.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchMode.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchToolConfig.js +0 -1
- package/bundle/dist/codex-protocol/index.js +0 -1
- package/bundle/dist/codex-protocol/serde_json/JsonValue.js +0 -1
- package/bundle/dist/codex-protocol/v2/Account.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountLoginCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountRateLimitsUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ActivePermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/ActivePermissionProfileModification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AddCreditsNudgeCreditType.js +0 -1
- package/bundle/dist/codex-protocol/v2/AddCreditsNudgeEmailStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalFileSystemPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalNetworkPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/AgentMessageDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AnalyticsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppBranding.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppListUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppReview.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppScreenshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppToolApproval.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppToolsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/ApprovalsReviewer.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsDefaultConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/AskForApproval.js +0 -1
- package/bundle/dist/codex-protocol/v2/AutoReviewDecisionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ByteRange.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshReason.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CodexErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentState.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentTool.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollaborationModeMask.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecOutputStream.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResizeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResizeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminalSize.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminateResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionApprovalDecision.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/Config.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigBatchWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigEdit.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayer.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayerMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayerSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigRequirementsReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigValueWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfiguredHookHandler.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfiguredHookMatcherGroup.js +0 -1
- package/bundle/dist/codex-protocol/v2/ContextCompactedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CreditsSnapshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/DeprecationNoticeNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallOutputContentItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolSpec.js +0 -1
- package/bundle/dist/codex-protocol/v2/ErrorNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExecPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeature.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureEnablementSetParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureEnablementSetResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureStage.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigDetectParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigDetectResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigMigrationItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigMigrationItemType.js +0 -1
- package/bundle/dist/codex-protocol/v2/FeedbackUploadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FeedbackUploadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeApprovalDecision.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangePatchUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemAccessMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemPath.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemSandboxEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemSpecialPath.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileUpdateChange.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCopyParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCopyResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCreateDirectoryParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCreateDirectoryResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsGetMetadataParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsGetMetadataResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadFileParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadFileResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsRemoveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsRemoveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsUnwatchParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsUnwatchResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWatchParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWatchResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWriteFileParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWriteFileResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountRateLimitsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GitInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/GrantedPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReview.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReviewAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReviewStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianCommandSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianRiskLevel.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianUserAuthorization.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookEventName.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookExecutionMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookHandlerType.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookOutputEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookOutputEntryKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookPromptFragment.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookRunStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookRunSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookTrustStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemGuardianApprovalReviewCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemGuardianApprovalReviewStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ListMcpServerStatusParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ListMcpServerStatusResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/LoginAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/LoginAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/LogoutAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ManagedHooksRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceAddParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceAddResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceLoadErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceRemoveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceRemoveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpAuthStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationArrayType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationBooleanSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationBooleanType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationConstOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationLegacyTitledEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationNumberSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationNumberType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationObjectType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationPrimitiveSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringFormat.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledEnumItems.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledEnumItems.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpResourceReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpResourceReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationRequestParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationRequestResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerRefreshResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStartupState.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatusDetail.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatusUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerToolCallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerToolCallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallError.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallProgressNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallResult.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/MemoryCitation.js +0 -1
- package/bundle/dist/codex-protocol/v2/MemoryCitationEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/MergeStrategy.js +0 -1
- package/bundle/dist/codex-protocol/v2/MigrationDetails.js +0 -1
- package/bundle/dist/codex-protocol/v2/Model.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelAvailabilityNux.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelProviderCapabilitiesReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelProviderCapabilitiesReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelRerouteReason.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelReroutedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelServiceTier.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelUpgradeInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelVerification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelVerificationNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkAccess.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkApprovalContext.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkApprovalProtocol.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkDomainPermission.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkPolicyRuleAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkUnixSocketPermission.js +0 -1
- package/bundle/dist/codex-protocol/v2/NonSteerableTurnKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/OverriddenMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/PatchApplyStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/PatchChangeKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionGrantScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileFileSystemPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileModificationParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileNetworkPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileSelectionParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionsRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionsRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PlanDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginAuthPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginAvailability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginDetail.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginHookSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListMarketplaceKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginMarketplaceEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareContext.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDeleteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDeleteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDiscoverability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSharePrincipal.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSharePrincipalType.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareSaveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareSaveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareTarget.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateDiscoverability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateTargetsParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateTargetsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSkillReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSkillReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginUninstallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginUninstallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginsMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessExitedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessOutputStream.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessTerminalSize.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProfileV2.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitReachedType.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitSnapshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitWindow.js +0 -1
- package/bundle/dist/codex-protocol/v2/RawResponseItemCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningEffortOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningSummaryPartAddedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningSummaryTextDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningTextDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/RemoteControlConnectionStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/RemoteControlStatusChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/RequestPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/ResidencyRequirement.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewDelivery.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewTarget.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxWorkspaceWrite.js +0 -1
- package/bundle/dist/codex-protocol/v2/SendAddCreditsNudgeEmailParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SendAddCreditsNudgeEmailResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ServerRequestResolvedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/SessionMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/SessionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillDependencies.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillToolDependency.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsConfigWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsConfigWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/SortDirection.js +0 -1
- package/bundle/dist/codex-protocol/v2/SubagentMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/TerminalInteractionNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextElement.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextPosition.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextRange.js +0 -1
- package/bundle/dist/codex-protocol/v2/Thread.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadActiveFlag.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadApproveGuardianDeniedActionParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadApproveGuardianDeniedActionResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchiveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchiveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchivedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadClosedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadCompactStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadCompactStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadForkParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadForkResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoal.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalClearedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadInjectItemsParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadInjectItemsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadLoadedListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadLoadedListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataGitInfoUpdateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataUpdateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataUpdateResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadNameUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeAudioChunk.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeClosedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeErrorNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeItemAddedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeOutputAudioDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeSdpNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeStartTransport.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeTranscriptDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeTranscriptDoneNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadResumeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadResumeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRollbackParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRollbackResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSetNameParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSetNameResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadShellCommandParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadShellCommandResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSortKey.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSourceKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStatusChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadTokenUsage.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadTokenUsageUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchiveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchiveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchivedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TokenUsageBreakdown.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputAnswer.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputQuestion.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolsV2.js +0 -1
- package/bundle/dist/codex-protocol/v2/Turn.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnDiffUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnEnvironmentParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnError.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnInterruptParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnInterruptResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnItemsView.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanStep.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanStepStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnSteerParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnSteerResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/UserInput.js +0 -1
- package/bundle/dist/codex-protocol/v2/WarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WebSearchAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxReadiness.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxReadinessResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsWorldWritableWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WriteStatus.js +0 -1
- package/bundle/dist/i18n/en.js +1 -2
- package/bundle/dist/i18n/ko.js +1 -2
- package/bundle/dist/i18n/sd.generated.js +54 -21
- package/bundle/dist/index.js +1 -2
- package/bundle/dist/migrations/20260410171405_create__request_logs.js +1 -2
- package/bundle/dist/migrations/20260410171406_create__tokens.js +1 -2
- package/bundle/dist/migrations/20260411120624_alter_tokens_alter2.js +1 -2
- package/bundle/dist/migrations/20260415113716_alter_tokens_add_ord.js +1 -2
- package/bundle/dist/migrations/20260415134649_alter_request_logs_alter1.js +1 -2
- package/bundle/dist/migrations/20260421223627_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260423180818_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260423182017_alter_request_logs_add2_drop1_alter1.js +1 -2
- package/bundle/dist/migrations/20260423183613_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260518145411_alter_tokens_add2_drop4_alter1.js +1 -2
- package/bundle/dist/migrations/20260520112853_alter_request_logs_add3_alter1.js +1 -2
- package/bundle/dist/migrations/20260520124755_alter_request_logs_drop1_alter1.js +1 -2
- package/bundle/dist/migrations/20260520130420_create__request_log_steps.js +1 -2
- package/bundle/dist/migrations/20260520134908_alter_request_logs_add2_alter8.js +1 -2
- package/bundle/dist/migrations/20260520134909_alter_request_log_steps_add1_alter3.js +1 -2
- package/bundle/dist/migrations/20260520141449_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260521134025_alter_request_log_steps_alter1.js +1 -2
- package/bundle/dist/migrations/20260521134026_alter_request_log_steps_foreigns.js +1 -2
- package/bundle/dist/migrations/20260522181721_alter_request_log_steps_add2_alter1.js +1 -2
- package/bundle/dist/migrations/20260630223950_alter_tokens_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260701105327_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260701105328_alter_request_log_steps_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260705140614_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260706120000_alter_request_logs_add_image_cost.js +1 -2
- package/bundle/dist/migrations/20260710090000_alter_tokens_add_weight.js +1 -2
- package/bundle/dist/migrations/20260718180824_alter_request_logs_add5_alter1.js +1 -2
- package/bundle/dist/migrations/20260718180825_alter_request_log_steps_add7_alter1.js +1 -2
- package/bundle/dist/migrations/20260722174410_alter_request_logs_alter3.js +17 -0
- package/bundle/dist/migrations/20260722174411_alter_request_log_steps_alter3.js +17 -0
- package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +255 -4
- package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +1507 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +887 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +2756 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +8 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +8 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +922 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +386 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +121 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +51 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +1317 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +561 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +40 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +272 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +27 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +77 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +381 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +51 -0
- package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +103 -3
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +1 -1
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +1 -1
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +1 -1
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +1 -1
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +1 -1
- package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +2 -3
- package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +4 -4
- package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +2 -2
- package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +18 -7
- package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +18 -3
- package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.11.2_@emnapi_runtime@1.11.2_@types_node@25.0.7_esbuild@0.27.4_2519c2e8d8013fcbc7b443879bc9da6d/node_modules/vite/dist/node/module-runner.js +1265 -0
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +6 -3
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +8 -8
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +5 -5
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +3 -3
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +46 -0
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +66 -6
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +3044 -0
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +19 -4
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/index.js +28 -0
- package/bundle/dist/server-bootstrap.js +1 -2
- package/bundle/dist/sonamu.config.js +11 -27
- package/bundle/dist/startup-migrations.js +1 -2
- package/bundle/dist/testing/fixture.js +1 -2
- package/bundle/dist/testing/global.js +6 -7
- package/bundle/dist/testing/setup-mocks.js +3 -4
- package/bundle/dist/testing/test-database-name.js +5 -8
- package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +8 -8
- package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +1 -2
- package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +1 -2
- package/bundle/dist/utils/providers/anthropic/claude-session.js +5 -7
- package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +1 -2
- package/bundle/dist/utils/providers/common/credentials.js +1 -2
- package/bundle/dist/utils/providers/common/model-cost.js +3 -3
- package/bundle/dist/utils/providers/common/provider-dispatcher.js +0 -1
- package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -2
- package/bundle/dist/utils/providers/common/strictifier.js +2 -2
- package/bundle/dist/utils/providers/common/token-picker.js +1 -2
- package/bundle/dist/utils/providers/common/ttft.js +1 -2
- package/bundle/dist/utils/providers/openai/codex-rpc.js +4 -2
- package/bundle/dist/utils/providers/openai/codex-worker.js +2 -2
- package/bundle/dist/utils/providers/openai/openai-constants.js +1 -2
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +103 -40
- package/bundle/dist/utils/providers/openai/openai-quota.js +1 -2
- package/bundle/dist/utils/providers/openai/openai-refresh.js +1 -2
- package/bundle/dist/utils/subset-loaders.js +1 -2
- package/bundle/src/application/monit/monit.frame.test.ts +2 -2
- package/bundle/src/application/monit/monit.frame.ts +2 -2
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +242 -8
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +97 -57
- package/bundle/src/application/qgrid/qgrid.frame.test.ts +400 -96
- package/bundle/src/application/qgrid/qgrid.frame.ts +85 -123
- package/bundle/src/application/qgrid/qgrid.types.ts +35 -27
- package/bundle/src/application/request-log/request-log.entity.json +2 -2
- package/bundle/src/application/request-log/request-log.model.test.ts +325 -21
- package/bundle/src/application/request-log/request-log.model.ts +233 -125
- package/bundle/src/application/request-log-step/request-log-step.entity.json +2 -2
- package/bundle/src/application/sonamu.generated.http +2 -2
- package/bundle/src/application/sonamu.generated.ts +13 -13
- package/bundle/src/i18n/sd.generated.ts +83 -14
- package/bundle/src/migrations/20260722174410_alter_request_logs_alter3.ts +19 -0
- package/bundle/src/migrations/20260722174411_alter_request_log_steps_alter3.ts +19 -0
- package/bundle/src/sonamu.config.ts +5 -23
- package/bundle/src/testing/global.ts +5 -5
- package/bundle/src/testing/test-database-name.test.ts +5 -5
- package/bundle/src/testing/test-database-name.ts +9 -8
- package/bundle/src/utils/providers/anthropic/anthropic-constants.test.ts +10 -6
- package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +9 -5
- package/bundle/src/utils/providers/anthropic/claude-session.test.ts +18 -3
- package/bundle/src/utils/providers/anthropic/claude-session.ts +4 -4
- package/bundle/src/utils/providers/common/model-cost.test.ts +1 -0
- package/bundle/src/utils/providers/common/model-cost.ts +1 -0
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +440 -0
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +143 -45
- package/bundle/web-dist/client/assets/{index-CmuPjbCl.js → index-B8Qj0LZK.js} +3 -3
- package/bundle/web-dist/client/assets/logs-C7R8Hvyy.js +1 -0
- package/bundle/web-dist/client/assets/{monit-B5Edhvy-.js → monit-Cj2KSodR.js} +1 -1
- package/bundle/web-dist/client/assets/{routes-UPWScORY.js → routes-DI1rjqGY.js} +1 -1
- package/bundle/web-dist/client/assets/{sd.generated-DYuKzBY6.js → sd.generated-DbBC73_z.js} +1 -1
- package/bundle/web-dist/client/assets/{services.generated-D_SkWOo-.js → services.generated-BWyAypSh.js} +1 -1
- package/bundle/web-dist/client/assets/{show-pRp-eZIK.js → show-B9hDSX9F.js} +2 -2
- package/bundle/web-dist/client/assets/{tokens-DJlttxCM.js → tokens-xUexYz3u.js} +1 -1
- package/bundle/web-dist/client/assets/{use-update-token-mutation-CpFGLWUl.js → use-update-token-mutation-DeDBiZiM.js} +1 -1
- package/bundle/web-dist/client/index.html +2 -2
- package/bundle/web-dist/server/assets/{lazyRouteComponent-Cu6IkL8A.js → lazyRouteComponent-BCJr868T.js} +1 -1
- package/bundle/web-dist/server/assets/{logs-Dx2knN2T.js → logs-33YNafdW.js} +32 -11
- package/bundle/web-dist/server/assets/{monit-DU6PLatf.js → monit--9mVsjNU.js} +2 -2
- package/bundle/web-dist/server/assets/{routes-CTco1oJZ.js → routes-BK3Xh1UB.js} +3 -3
- package/bundle/web-dist/server/assets/{sd.generated-qzuRe35X.js → sd.generated-C3gcvRcU.js} +1 -0
- package/bundle/web-dist/server/assets/{services.generated-C8q1M41a.js → services.generated-B2_Auwvk.js} +1 -1
- package/bundle/web-dist/server/assets/{show-B3q8_GDh.js → show-Dxxxe608.js} +15 -9
- package/bundle/web-dist/server/assets/{tokens-Bvjn15h9.js → tokens-BWPVvdfi.js} +3 -3
- package/bundle/web-dist/server/assets/{use-update-token-mutation-BlZo6swF.js → use-update-token-mutation-CNBgTysy.js} +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +23 -23
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +18 -12
- package/package.json +6 -6
- package/skills/qgrid/SKILL.md +4 -0
- package/skills/qgrid/references/ai-sdk-provider-contract.md +28 -2
- package/skills/qgrid/references/anthropic-claude-code-runtime.md +5 -4
- package/skills/qgrid/references/cli-env-and-server-boot.md +20 -8
- package/skills/qgrid/references/decision-rationale.md +4 -0
- package/skills/qgrid/references/docs-workflow.md +10 -0
- package/skills/qgrid/references/openai-codex-runtime.md +11 -3
- package/skills/qgrid/references/provider-runtime-differences.md +3 -3
- package/skills/qgrid/references/request-log-run-lifecycle.md +46 -28
- package/skills/qgrid/references/sonamu-api-web-flow.md +4 -0
- package/skills/qgrid/references/token-auth-quota-lifecycle.md +6 -0
- package/skills/qgrid/references/tool-calling-and-multiturn.md +8 -7
- package/skills/qgrid/references/verification-and-debugging.md +1 -1
- package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +0 -1484
- package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +0 -887
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2746
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +0 -8
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +0 -8
- package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +0 -662
- package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +0 -386
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -82
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +0 -48
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +0 -1307
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +0 -558
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +0 -33
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +0 -226
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +0 -27
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +0 -77
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +0 -374
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +0 -37
- package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.9.2_@emnapi_runtime@1.9.2_@types_node@25.0.7_esbuild@0.27.4_jiti@2.6.1_sass@1.98.0_tsx@4.21.0/node_modules/vite/dist/node/module-runner.js +0 -426
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496/node_modules/vitest/dist/chunks/index.DOa3dzoN.js +0 -16
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496/node_modules/vitest/dist/chunks/test.p_J6dB8a.js +0 -2910
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496/node_modules/vitest/dist/index.js +0 -28
- package/bundle/web-dist/client/assets/logs-cXOsDli3.js +0 -1
|
@@ -0,0 +1,1507 @@
|
|
|
1
|
+
import y from "../../../../../tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js";
|
|
2
|
+
import { stringify } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js";
|
|
3
|
+
import { assertTypes, getType, isObject, noop, ordinal } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js";
|
|
4
|
+
import { diff, printDiffOrStringify } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js";
|
|
5
|
+
import { processError } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js";
|
|
6
|
+
import { isMockFunction } from "../../../../../@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js";
|
|
7
|
+
import { chai_exports, use, util as utils_exports } from "../../../../../chai@6.2.2/node_modules/chai/index.js";
|
|
8
|
+
//#region ../../node_modules/.pnpm/@vitest+expect@4.1.10/node_modules/@vitest/expect/dist/index.js
|
|
9
|
+
const ChaiStyleAssertions = (chai, utils) => {
|
|
10
|
+
function defProperty(name, delegateTo) {
|
|
11
|
+
utils.addProperty(chai.Assertion.prototype, name, function() {
|
|
12
|
+
const jestMethod = chai.Assertion.prototype[delegateTo];
|
|
13
|
+
if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
|
|
14
|
+
return jestMethod.call(this);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function defPropertyWithArgs(name, delegateTo, ...args) {
|
|
18
|
+
utils.addProperty(chai.Assertion.prototype, name, function() {
|
|
19
|
+
const jestMethod = chai.Assertion.prototype[delegateTo];
|
|
20
|
+
if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
|
|
21
|
+
return jestMethod.call(this, ...args);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function defMethod(name, delegateTo) {
|
|
25
|
+
utils.addMethod(chai.Assertion.prototype, name, function(...args) {
|
|
26
|
+
const jestMethod = chai.Assertion.prototype[delegateTo];
|
|
27
|
+
if (!jestMethod) throw new Error(`Cannot delegate to ${String(delegateTo)}: method not found. Ensure JestChaiExpect plugin is loaded first.`);
|
|
28
|
+
return jestMethod.call(this, ...args);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
defProperty("called", "toHaveBeenCalled");
|
|
32
|
+
defProperty("calledOnce", "toHaveBeenCalledOnce");
|
|
33
|
+
defPropertyWithArgs("calledTwice", "toHaveBeenCalledTimes", 2);
|
|
34
|
+
defPropertyWithArgs("calledThrice", "toHaveBeenCalledTimes", 3);
|
|
35
|
+
defMethod("callCount", "toHaveBeenCalledTimes");
|
|
36
|
+
defMethod("calledWith", "toHaveBeenCalledWith");
|
|
37
|
+
defMethod("calledOnceWith", "toHaveBeenCalledExactlyOnceWith");
|
|
38
|
+
defMethod("lastCalledWith", "toHaveBeenLastCalledWith");
|
|
39
|
+
defMethod("nthCalledWith", "toHaveBeenNthCalledWith");
|
|
40
|
+
defMethod("returned", "toHaveReturned");
|
|
41
|
+
defMethod("returnedWith", "toHaveReturnedWith");
|
|
42
|
+
defMethod("returnedTimes", "toHaveReturnedTimes");
|
|
43
|
+
defMethod("lastReturnedWith", "toHaveLastReturnedWith");
|
|
44
|
+
defMethod("nthReturnedWith", "toHaveNthReturnedWith");
|
|
45
|
+
defMethod("calledBefore", "toHaveBeenCalledBefore");
|
|
46
|
+
defMethod("calledAfter", "toHaveBeenCalledAfter");
|
|
47
|
+
};
|
|
48
|
+
const MATCHERS_OBJECT = Symbol.for("matchers-object");
|
|
49
|
+
const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
|
|
50
|
+
const GLOBAL_EXPECT = Symbol.for("expect-global");
|
|
51
|
+
const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object");
|
|
52
|
+
const customMatchers = {
|
|
53
|
+
toSatisfy(actual, expected, message) {
|
|
54
|
+
const { printReceived, printExpected, matcherHint } = this.utils;
|
|
55
|
+
const pass = expected(actual);
|
|
56
|
+
return {
|
|
57
|
+
pass,
|
|
58
|
+
message: () => pass ? `\
|
|
59
|
+
${matcherHint(".not.toSatisfy", "received", "")}
|
|
60
|
+
|
|
61
|
+
Expected value to not satisfy:
|
|
62
|
+
${message || printExpected(expected)}
|
|
63
|
+
Received:
|
|
64
|
+
${printReceived(actual)}` : `\
|
|
65
|
+
${matcherHint(".toSatisfy", "received", "")}
|
|
66
|
+
|
|
67
|
+
Expected value to satisfy:
|
|
68
|
+
${message || printExpected(expected)}
|
|
69
|
+
|
|
70
|
+
Received:
|
|
71
|
+
${printReceived(actual)}`
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
toBeOneOf(actual, expected) {
|
|
75
|
+
const { equals, customTesters } = this;
|
|
76
|
+
const { printReceived, printExpected, matcherHint } = this.utils;
|
|
77
|
+
let pass;
|
|
78
|
+
if (Array.isArray(expected)) pass = expected.length === 0 || expected.some((item) => equals(item, actual, customTesters));
|
|
79
|
+
else if (expected instanceof Set) pass = expected.size === 0 || expected.has(actual) || [...expected].some((item) => equals(item, actual, customTesters));
|
|
80
|
+
else throw new TypeError(`You must provide an array or set to ${matcherHint(".toBeOneOf")}, not '${typeof expected}'.`);
|
|
81
|
+
return {
|
|
82
|
+
pass,
|
|
83
|
+
message: () => pass ? `\
|
|
84
|
+
${matcherHint(".not.toBeOneOf", "received", "")}
|
|
85
|
+
|
|
86
|
+
Expected value to not be one of:
|
|
87
|
+
${printExpected(expected)}
|
|
88
|
+
Received:
|
|
89
|
+
${printReceived(actual)}` : `\
|
|
90
|
+
${matcherHint(".toBeOneOf", "received", "")}
|
|
91
|
+
|
|
92
|
+
Expected value to be one of:
|
|
93
|
+
${printExpected(expected)}
|
|
94
|
+
|
|
95
|
+
Received:
|
|
96
|
+
${printReceived(actual)}`
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const EXPECTED_COLOR = y.green;
|
|
101
|
+
const RECEIVED_COLOR = y.red;
|
|
102
|
+
const INVERTED_COLOR = y.inverse;
|
|
103
|
+
const BOLD_WEIGHT = y.bold;
|
|
104
|
+
const DIM_COLOR = y.dim;
|
|
105
|
+
function matcherHint(matcherName, received = "received", expected = "expected", options = {}) {
|
|
106
|
+
const { comment = "", isDirectExpectCall = false, isNot = false, promise = "", secondArgument = "", expectedColor = EXPECTED_COLOR, receivedColor = RECEIVED_COLOR, secondArgumentColor = EXPECTED_COLOR } = options;
|
|
107
|
+
let hint = "";
|
|
108
|
+
let dimString = "expect";
|
|
109
|
+
if (!isDirectExpectCall && received !== "") {
|
|
110
|
+
hint += DIM_COLOR(`${dimString}(`) + receivedColor(received);
|
|
111
|
+
dimString = ")";
|
|
112
|
+
}
|
|
113
|
+
if (promise !== "") {
|
|
114
|
+
hint += DIM_COLOR(`${dimString}.`) + promise;
|
|
115
|
+
dimString = "";
|
|
116
|
+
}
|
|
117
|
+
if (isNot) {
|
|
118
|
+
hint += `${DIM_COLOR(`${dimString}.`)}not`;
|
|
119
|
+
dimString = "";
|
|
120
|
+
}
|
|
121
|
+
if (matcherName.includes(".")) dimString += matcherName;
|
|
122
|
+
else {
|
|
123
|
+
hint += DIM_COLOR(`${dimString}.`) + matcherName;
|
|
124
|
+
dimString = "";
|
|
125
|
+
}
|
|
126
|
+
if (expected === "") dimString += "()";
|
|
127
|
+
else {
|
|
128
|
+
hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
|
|
129
|
+
if (secondArgument) hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument);
|
|
130
|
+
dimString = ")";
|
|
131
|
+
}
|
|
132
|
+
if (comment !== "") dimString += ` // ${comment}`;
|
|
133
|
+
if (dimString !== "") hint += DIM_COLOR(dimString);
|
|
134
|
+
return hint;
|
|
135
|
+
}
|
|
136
|
+
const SPACE_SYMBOL = "·";
|
|
137
|
+
function replaceTrailingSpaces(text) {
|
|
138
|
+
return text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
|
|
139
|
+
}
|
|
140
|
+
function printReceived(object) {
|
|
141
|
+
return RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
|
|
142
|
+
}
|
|
143
|
+
function printExpected(value) {
|
|
144
|
+
return EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
|
|
145
|
+
}
|
|
146
|
+
function getMatcherUtils() {
|
|
147
|
+
return {
|
|
148
|
+
EXPECTED_COLOR,
|
|
149
|
+
RECEIVED_COLOR,
|
|
150
|
+
INVERTED_COLOR,
|
|
151
|
+
BOLD_WEIGHT,
|
|
152
|
+
DIM_COLOR,
|
|
153
|
+
diff,
|
|
154
|
+
matcherHint,
|
|
155
|
+
printReceived,
|
|
156
|
+
printExpected,
|
|
157
|
+
printDiffOrStringify,
|
|
158
|
+
printWithType
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function printWithType(name, value, print) {
|
|
162
|
+
const type = getType(value);
|
|
163
|
+
return (type !== "null" && type !== "undefined" ? `${name} has type: ${type}\n` : "") + `${name} has value: ${print(value)}`;
|
|
164
|
+
}
|
|
165
|
+
function addCustomEqualityTesters(newTesters) {
|
|
166
|
+
if (!Array.isArray(newTesters)) throw new TypeError(`expect.customEqualityTesters: Must be set to an array of Testers. Was given "${getType(newTesters)}"`);
|
|
167
|
+
globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters.push(...newTesters);
|
|
168
|
+
}
|
|
169
|
+
function getCustomEqualityTesters() {
|
|
170
|
+
return globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters;
|
|
171
|
+
}
|
|
172
|
+
function equals(a, b, customTesters, strictCheck) {
|
|
173
|
+
customTesters = customTesters || [];
|
|
174
|
+
return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey);
|
|
175
|
+
}
|
|
176
|
+
const functionToString = Function.prototype.toString;
|
|
177
|
+
function isAsymmetric(obj) {
|
|
178
|
+
return !!obj && typeof obj === "object" && "asymmetricMatch" in obj && isA("Function", obj.asymmetricMatch);
|
|
179
|
+
}
|
|
180
|
+
function hasAsymmetric(obj, seen = /* @__PURE__ */ new Set()) {
|
|
181
|
+
if (seen.has(obj)) return false;
|
|
182
|
+
seen.add(obj);
|
|
183
|
+
if (isAsymmetric(obj)) return true;
|
|
184
|
+
if (Array.isArray(obj)) return obj.some((i) => hasAsymmetric(i, seen));
|
|
185
|
+
if (obj instanceof Set) return Array.from(obj).some((i) => hasAsymmetric(i, seen));
|
|
186
|
+
if (isObject(obj)) return Object.values(obj).some((v) => hasAsymmetric(v, seen));
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
function asymmetricMatch(a, b, customTesters) {
|
|
190
|
+
const asymmetricA = isAsymmetric(a);
|
|
191
|
+
const asymmetricB = isAsymmetric(b);
|
|
192
|
+
if (asymmetricA && asymmetricB) return;
|
|
193
|
+
if (asymmetricA) return a.asymmetricMatch(b, customTesters);
|
|
194
|
+
if (asymmetricB) return b.asymmetricMatch(a, customTesters);
|
|
195
|
+
}
|
|
196
|
+
function isError(value) {
|
|
197
|
+
if (typeof Error.isError === "function") return Error.isError(value);
|
|
198
|
+
switch (Object.prototype.toString.call(value)) {
|
|
199
|
+
case "[object Error]":
|
|
200
|
+
case "[object Exception]":
|
|
201
|
+
case "[object DOMException]": return true;
|
|
202
|
+
default: return value instanceof Error;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function eq(a, b, aStack, bStack, customTesters, hasKey) {
|
|
206
|
+
let result = true;
|
|
207
|
+
const asymmetricResult = asymmetricMatch(a, b, customTesters);
|
|
208
|
+
if (asymmetricResult !== void 0) return asymmetricResult;
|
|
209
|
+
const testerContext = { equals };
|
|
210
|
+
for (let i = 0; i < customTesters.length; i++) {
|
|
211
|
+
const customTesterResult = customTesters[i].call(testerContext, a, b, customTesters);
|
|
212
|
+
if (customTesterResult !== void 0) return customTesterResult;
|
|
213
|
+
}
|
|
214
|
+
if (typeof URL === "function" && a instanceof URL && b instanceof URL) return a.href === b.href;
|
|
215
|
+
if (Object.is(a, b)) return true;
|
|
216
|
+
if (a === null || b === null) return a === b;
|
|
217
|
+
const className = Object.prototype.toString.call(a);
|
|
218
|
+
if (className !== Object.prototype.toString.call(b)) return false;
|
|
219
|
+
switch (className) {
|
|
220
|
+
case "[object Boolean]":
|
|
221
|
+
case "[object String]":
|
|
222
|
+
case "[object Number]": if (typeof a !== typeof b) return false;
|
|
223
|
+
else if (typeof a !== "object" && typeof b !== "object") return Object.is(a, b);
|
|
224
|
+
else return Object.is(a.valueOf(), b.valueOf());
|
|
225
|
+
case "[object Date]": {
|
|
226
|
+
const numA = +a;
|
|
227
|
+
const numB = +b;
|
|
228
|
+
return numA === numB || Number.isNaN(numA) && Number.isNaN(numB);
|
|
229
|
+
}
|
|
230
|
+
case "[object RegExp]": return a.source === b.source && a.flags === b.flags;
|
|
231
|
+
case "[object Temporal.Instant]":
|
|
232
|
+
case "[object Temporal.ZonedDateTime]":
|
|
233
|
+
case "[object Temporal.PlainDateTime]":
|
|
234
|
+
case "[object Temporal.PlainDate]":
|
|
235
|
+
case "[object Temporal.PlainTime]":
|
|
236
|
+
case "[object Temporal.PlainYearMonth]":
|
|
237
|
+
case "[object Temporal.PlainMonthDay]": return a.equals(b);
|
|
238
|
+
case "[object Temporal.Duration]": return a.toString() === b.toString();
|
|
239
|
+
}
|
|
240
|
+
if (typeof a !== "object" || typeof b !== "object") return false;
|
|
241
|
+
if (isDomNode(a) && isDomNode(b)) return a.isEqualNode(b);
|
|
242
|
+
let length = aStack.length;
|
|
243
|
+
while (length--) if (aStack[length] === a) return bStack[length] === b;
|
|
244
|
+
else if (bStack[length] === b) return false;
|
|
245
|
+
aStack.push(a);
|
|
246
|
+
bStack.push(b);
|
|
247
|
+
if (className === "[object Array]" && a.length !== b.length) return false;
|
|
248
|
+
if (isError(a) && isError(b)) try {
|
|
249
|
+
return isErrorEqual(a, b, aStack, bStack, customTesters, hasKey);
|
|
250
|
+
} finally {
|
|
251
|
+
aStack.pop();
|
|
252
|
+
bStack.pop();
|
|
253
|
+
}
|
|
254
|
+
const aKeys = keys(a, hasKey);
|
|
255
|
+
let key;
|
|
256
|
+
let size = aKeys.length;
|
|
257
|
+
if (keys(b, hasKey).length !== size) return false;
|
|
258
|
+
while (size--) {
|
|
259
|
+
key = aKeys[size];
|
|
260
|
+
result = hasKey(b, key) && eq(a[key], b[key], aStack, bStack, customTesters, hasKey);
|
|
261
|
+
if (!result) return false;
|
|
262
|
+
}
|
|
263
|
+
aStack.pop();
|
|
264
|
+
bStack.pop();
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
function isErrorEqual(a, b, aStack, bStack, customTesters, hasKey) {
|
|
268
|
+
let result = Object.prototype.toString.call(a) === Object.prototype.toString.call(b) && a.name === b.name && a.message === b.message;
|
|
269
|
+
if (typeof b.cause !== "undefined") result &&= eq(a.cause, b.cause, aStack, bStack, customTesters, hasKey);
|
|
270
|
+
if (a instanceof AggregateError && b instanceof AggregateError) result &&= eq(a.errors, b.errors, aStack, bStack, customTesters, hasKey);
|
|
271
|
+
result &&= eq({ ...a }, { ...b }, aStack, bStack, customTesters, hasKey);
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
function keys(obj, hasKey) {
|
|
275
|
+
const keys = [];
|
|
276
|
+
for (const key in obj) if (hasKey(obj, key)) keys.push(key);
|
|
277
|
+
return keys.concat(Object.getOwnPropertySymbols(obj).filter((symbol) => Object.getOwnPropertyDescriptor(obj, symbol).enumerable));
|
|
278
|
+
}
|
|
279
|
+
function hasDefinedKey(obj, key) {
|
|
280
|
+
return hasKey(obj, key) && obj[key] !== void 0;
|
|
281
|
+
}
|
|
282
|
+
function hasKey(obj, key) {
|
|
283
|
+
return Object.hasOwn(obj, key);
|
|
284
|
+
}
|
|
285
|
+
function isA(typeName, value) {
|
|
286
|
+
return Object.prototype.toString.apply(value) === `[object ${typeName}]`;
|
|
287
|
+
}
|
|
288
|
+
function isDomNode(obj) {
|
|
289
|
+
return obj !== null && typeof obj === "object" && "nodeType" in obj && typeof obj.nodeType === "number" && "nodeName" in obj && typeof obj.nodeName === "string" && "isEqualNode" in obj && typeof obj.isEqualNode === "function";
|
|
290
|
+
}
|
|
291
|
+
function fnNameFor(func) {
|
|
292
|
+
if (func.name) return func.name;
|
|
293
|
+
const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/);
|
|
294
|
+
return matches ? matches[1] : "<anonymous>";
|
|
295
|
+
}
|
|
296
|
+
function getPrototype(obj) {
|
|
297
|
+
if (Object.getPrototypeOf) return Object.getPrototypeOf(obj);
|
|
298
|
+
if (obj.constructor.prototype === obj) return null;
|
|
299
|
+
return obj.constructor.prototype;
|
|
300
|
+
}
|
|
301
|
+
function hasProperty(obj, property) {
|
|
302
|
+
if (!obj) return false;
|
|
303
|
+
if (Object.hasOwn(obj, property)) return true;
|
|
304
|
+
return hasProperty(getPrototype(obj), property);
|
|
305
|
+
}
|
|
306
|
+
const IS_KEYED_SENTINEL = "@@__IMMUTABLE_KEYED__@@";
|
|
307
|
+
const IS_SET_SENTINEL = "@@__IMMUTABLE_SET__@@";
|
|
308
|
+
const IS_LIST_SENTINEL = "@@__IMMUTABLE_LIST__@@";
|
|
309
|
+
const IS_ORDERED_SENTINEL = "@@__IMMUTABLE_ORDERED__@@";
|
|
310
|
+
const IS_RECORD_SYMBOL = "@@__IMMUTABLE_RECORD__@@";
|
|
311
|
+
function isImmutableUnorderedKeyed(maybeKeyed) {
|
|
312
|
+
return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL] && !maybeKeyed[IS_ORDERED_SENTINEL]);
|
|
313
|
+
}
|
|
314
|
+
function isImmutableUnorderedSet(maybeSet) {
|
|
315
|
+
return !!(maybeSet && maybeSet[IS_SET_SENTINEL] && !maybeSet[IS_ORDERED_SENTINEL]);
|
|
316
|
+
}
|
|
317
|
+
function isObjectLiteral(source) {
|
|
318
|
+
return source != null && typeof source === "object" && !Array.isArray(source);
|
|
319
|
+
}
|
|
320
|
+
function isImmutableList(source) {
|
|
321
|
+
return Boolean(source && isObjectLiteral(source) && source[IS_LIST_SENTINEL]);
|
|
322
|
+
}
|
|
323
|
+
function isImmutableOrderedKeyed(source) {
|
|
324
|
+
return Boolean(source && isObjectLiteral(source) && source[IS_KEYED_SENTINEL] && source[IS_ORDERED_SENTINEL]);
|
|
325
|
+
}
|
|
326
|
+
function isImmutableOrderedSet(source) {
|
|
327
|
+
return Boolean(source && isObjectLiteral(source) && source[IS_SET_SENTINEL] && source[IS_ORDERED_SENTINEL]);
|
|
328
|
+
}
|
|
329
|
+
function isImmutableRecord(source) {
|
|
330
|
+
return Boolean(source && isObjectLiteral(source) && source[IS_RECORD_SYMBOL]);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
|
334
|
+
*
|
|
335
|
+
* This source code is licensed under the MIT license found in the
|
|
336
|
+
* LICENSE file in the root directory of this source tree.
|
|
337
|
+
*
|
|
338
|
+
*/
|
|
339
|
+
const IteratorSymbol = Symbol.iterator;
|
|
340
|
+
function hasIterator(object) {
|
|
341
|
+
return !!(object != null && object[IteratorSymbol]);
|
|
342
|
+
}
|
|
343
|
+
function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
|
|
344
|
+
if (typeof a !== "object" || typeof b !== "object" || Array.isArray(a) || Array.isArray(b) || !hasIterator(a) || !hasIterator(b)) return;
|
|
345
|
+
if (a.constructor !== b.constructor) return false;
|
|
346
|
+
let length = aStack.length;
|
|
347
|
+
while (length--) if (aStack[length] === a) return bStack[length] === b;
|
|
348
|
+
aStack.push(a);
|
|
349
|
+
bStack.push(b);
|
|
350
|
+
const filteredCustomTesters = [...customTesters.filter((t) => t !== iterableEquality), iterableEqualityWithStack];
|
|
351
|
+
function iterableEqualityWithStack(a, b) {
|
|
352
|
+
return iterableEquality(a, b, [...customTesters], [...aStack], [...bStack]);
|
|
353
|
+
}
|
|
354
|
+
if (a.size !== void 0) {
|
|
355
|
+
if (a.size !== b.size) return false;
|
|
356
|
+
else if (isA("Set", a) || isImmutableUnorderedSet(a)) {
|
|
357
|
+
let allFound = true;
|
|
358
|
+
for (const aValue of a) if (!b.has(aValue)) {
|
|
359
|
+
let has = false;
|
|
360
|
+
for (const bValue of b) if (equals(aValue, bValue, filteredCustomTesters) === true) has = true;
|
|
361
|
+
if (has === false) {
|
|
362
|
+
allFound = false;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
aStack.pop();
|
|
367
|
+
bStack.pop();
|
|
368
|
+
return allFound;
|
|
369
|
+
} else if (isA("Map", a) || isImmutableUnorderedKeyed(a)) {
|
|
370
|
+
let allFound = true;
|
|
371
|
+
for (const aEntry of a) if (!b.has(aEntry[0]) || !equals(aEntry[1], b.get(aEntry[0]), filteredCustomTesters)) {
|
|
372
|
+
let has = false;
|
|
373
|
+
for (const bEntry of b) {
|
|
374
|
+
const matchedKey = equals(aEntry[0], bEntry[0], filteredCustomTesters);
|
|
375
|
+
let matchedValue = false;
|
|
376
|
+
if (matchedKey === true) matchedValue = equals(aEntry[1], bEntry[1], filteredCustomTesters);
|
|
377
|
+
if (matchedValue === true) has = true;
|
|
378
|
+
}
|
|
379
|
+
if (has === false) {
|
|
380
|
+
allFound = false;
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
aStack.pop();
|
|
385
|
+
bStack.pop();
|
|
386
|
+
return allFound;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const bIterator = b[IteratorSymbol]();
|
|
390
|
+
for (const aValue of a) {
|
|
391
|
+
const nextB = bIterator.next();
|
|
392
|
+
if (nextB.done || !equals(aValue, nextB.value, filteredCustomTesters)) return false;
|
|
393
|
+
}
|
|
394
|
+
if (!bIterator.next().done) return false;
|
|
395
|
+
if (!isImmutableList(a) && !isImmutableOrderedKeyed(a) && !isImmutableOrderedSet(a) && !isImmutableRecord(a)) {
|
|
396
|
+
if (!equals(Object.entries(a), Object.entries(b), filteredCustomTesters)) return false;
|
|
397
|
+
}
|
|
398
|
+
aStack.pop();
|
|
399
|
+
bStack.pop();
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Checks if `hasOwnProperty(object, key)` up the prototype chain, stopping at `Object.prototype`.
|
|
404
|
+
*/
|
|
405
|
+
function hasPropertyInObject(object, key) {
|
|
406
|
+
if (!object || typeof object !== "object" || object === Object.prototype) return false;
|
|
407
|
+
return Object.hasOwn(object, key) || hasPropertyInObject(Object.getPrototypeOf(object), key);
|
|
408
|
+
}
|
|
409
|
+
function isObjectWithKeys(a) {
|
|
410
|
+
return isObject(a) && !isError(a) && !Array.isArray(a) && !(a instanceof Date) && !(a instanceof Set) && !(a instanceof Map);
|
|
411
|
+
}
|
|
412
|
+
function subsetEquality(object, subset, customTesters = []) {
|
|
413
|
+
const filteredCustomTesters = customTesters.filter((t) => t !== subsetEquality);
|
|
414
|
+
const subsetEqualityWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object, subset) => {
|
|
415
|
+
if (!isObjectWithKeys(subset)) return;
|
|
416
|
+
return Object.keys(subset).every((key) => {
|
|
417
|
+
if (subset[key] != null && typeof subset[key] === "object") {
|
|
418
|
+
if (seenReferences.has(subset[key])) return equals(object[key], subset[key], filteredCustomTesters);
|
|
419
|
+
seenReferences.set(subset[key], true);
|
|
420
|
+
}
|
|
421
|
+
const result = object != null && hasPropertyInObject(object, key) && equals(object[key], subset[key], [...filteredCustomTesters, subsetEqualityWithContext(seenReferences)]);
|
|
422
|
+
seenReferences.delete(subset[key]);
|
|
423
|
+
return result;
|
|
424
|
+
});
|
|
425
|
+
};
|
|
426
|
+
return subsetEqualityWithContext()(object, subset);
|
|
427
|
+
}
|
|
428
|
+
function typeEquality(a, b) {
|
|
429
|
+
if (a == null || b == null || a.constructor === b.constructor) return;
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
function arrayBufferEquality(a, b) {
|
|
433
|
+
let dataViewA = a;
|
|
434
|
+
let dataViewB = b;
|
|
435
|
+
if (!(a instanceof DataView && b instanceof DataView)) {
|
|
436
|
+
if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) return;
|
|
437
|
+
try {
|
|
438
|
+
dataViewA = new DataView(a);
|
|
439
|
+
dataViewB = new DataView(b);
|
|
440
|
+
} catch {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (dataViewA.byteLength !== dataViewB.byteLength) return false;
|
|
445
|
+
for (let i = 0; i < dataViewA.byteLength; i++) if (dataViewA.getUint8(i) !== dataViewB.getUint8(i)) return false;
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
function sparseArrayEquality(a, b, customTesters = []) {
|
|
449
|
+
if (!Array.isArray(a) || !Array.isArray(b)) return;
|
|
450
|
+
const aKeys = Object.keys(a);
|
|
451
|
+
const bKeys = Object.keys(b);
|
|
452
|
+
return equals(a, b, customTesters.filter((t) => t !== sparseArrayEquality), true) && equals(aKeys, bKeys);
|
|
453
|
+
}
|
|
454
|
+
function generateToBeMessage(deepEqualityName, expected = "#{this}", actual = "#{exp}") {
|
|
455
|
+
const toBeMessage = `expected ${expected} to be ${actual} // Object.is equality`;
|
|
456
|
+
if (["toStrictEqual", "toEqual"].includes(deepEqualityName)) return `${toBeMessage}\n\nIf it should pass with deep equality, replace "toBe" with "${deepEqualityName}"\n\nExpected: ${expected}\nReceived: serializes to the same string\n`;
|
|
457
|
+
return toBeMessage;
|
|
458
|
+
}
|
|
459
|
+
function pluralize(word, count) {
|
|
460
|
+
return `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
461
|
+
}
|
|
462
|
+
function getObjectKeys(object) {
|
|
463
|
+
return [...Object.keys(object), ...Object.getOwnPropertySymbols(object).filter((s) => Object.getOwnPropertyDescriptor(object, s)?.enumerable)];
|
|
464
|
+
}
|
|
465
|
+
function getObjectSubset(object, subset, customTesters) {
|
|
466
|
+
let stripped = 0;
|
|
467
|
+
const getObjectSubsetWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object, subset) => {
|
|
468
|
+
if (Array.isArray(object)) {
|
|
469
|
+
if (Array.isArray(subset) && subset.length === object.length) return subset.map((sub, i) => getObjectSubsetWithContext(seenReferences)(object[i], sub));
|
|
470
|
+
} else if (object instanceof Date) return object;
|
|
471
|
+
else if (isObject(object) && isObject(subset)) {
|
|
472
|
+
if (equals(object, subset, [
|
|
473
|
+
...customTesters,
|
|
474
|
+
iterableEquality,
|
|
475
|
+
subsetEquality
|
|
476
|
+
])) return subset;
|
|
477
|
+
const trimmed = {};
|
|
478
|
+
seenReferences.set(object, trimmed);
|
|
479
|
+
if (typeof object.constructor === "function" && typeof object.constructor.name === "string") Object.defineProperty(trimmed, "constructor", {
|
|
480
|
+
enumerable: false,
|
|
481
|
+
value: object.constructor
|
|
482
|
+
});
|
|
483
|
+
for (const key of getObjectKeys(object)) if (hasPropertyInObject(subset, key)) trimmed[key] = seenReferences.has(object[key]) ? seenReferences.get(object[key]) : getObjectSubsetWithContext(seenReferences)(object[key], subset[key]);
|
|
484
|
+
else if (!seenReferences.has(object[key])) {
|
|
485
|
+
stripped += 1;
|
|
486
|
+
if (isObject(object[key])) stripped += getObjectKeys(object[key]).length;
|
|
487
|
+
getObjectSubsetWithContext(seenReferences)(object[key], subset[key]);
|
|
488
|
+
}
|
|
489
|
+
if (getObjectKeys(trimmed).length > 0) return trimmed;
|
|
490
|
+
}
|
|
491
|
+
return object;
|
|
492
|
+
};
|
|
493
|
+
return {
|
|
494
|
+
subset: getObjectSubsetWithContext()(object, subset),
|
|
495
|
+
stripped
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Detects if an object is a Standard Schema V1 compatible schema
|
|
500
|
+
*/
|
|
501
|
+
function isStandardSchema(obj) {
|
|
502
|
+
return !!obj && (typeof obj === "object" || typeof obj === "function") && obj["~standard"] && typeof obj["~standard"].validate === "function";
|
|
503
|
+
}
|
|
504
|
+
if (!Object.hasOwn(globalThis, MATCHERS_OBJECT)) {
|
|
505
|
+
const globalState = /* @__PURE__ */ new WeakMap();
|
|
506
|
+
const matchers = Object.create(null);
|
|
507
|
+
const customEqualityTesters = [];
|
|
508
|
+
const asymmetricMatchers = Object.create(null);
|
|
509
|
+
Object.defineProperty(globalThis, MATCHERS_OBJECT, { get: () => globalState });
|
|
510
|
+
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
|
|
511
|
+
configurable: true,
|
|
512
|
+
get: () => ({
|
|
513
|
+
state: globalState.get(globalThis[GLOBAL_EXPECT]),
|
|
514
|
+
matchers,
|
|
515
|
+
customEqualityTesters
|
|
516
|
+
})
|
|
517
|
+
});
|
|
518
|
+
Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, { get: () => asymmetricMatchers });
|
|
519
|
+
}
|
|
520
|
+
function getState(expect) {
|
|
521
|
+
return globalThis[MATCHERS_OBJECT].get(expect);
|
|
522
|
+
}
|
|
523
|
+
function setState(state, expect) {
|
|
524
|
+
const map = globalThis[MATCHERS_OBJECT];
|
|
525
|
+
const current = map.get(expect) || {};
|
|
526
|
+
const results = Object.defineProperties(current, {
|
|
527
|
+
...Object.getOwnPropertyDescriptors(current),
|
|
528
|
+
...Object.getOwnPropertyDescriptors(state)
|
|
529
|
+
});
|
|
530
|
+
map.set(expect, results);
|
|
531
|
+
}
|
|
532
|
+
var AsymmetricMatcher = class {
|
|
533
|
+
$$typeof = Symbol.for("jest.asymmetricMatcher");
|
|
534
|
+
constructor(sample, inverse = false) {
|
|
535
|
+
this.sample = sample;
|
|
536
|
+
this.inverse = inverse;
|
|
537
|
+
}
|
|
538
|
+
getMatcherContext(expect) {
|
|
539
|
+
return {
|
|
540
|
+
...getState(expect || globalThis[GLOBAL_EXPECT]),
|
|
541
|
+
equals,
|
|
542
|
+
isNot: this.inverse,
|
|
543
|
+
customTesters: getCustomEqualityTesters(),
|
|
544
|
+
utils: {
|
|
545
|
+
...getMatcherUtils(),
|
|
546
|
+
diff,
|
|
547
|
+
stringify,
|
|
548
|
+
iterableEquality,
|
|
549
|
+
subsetEquality
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
AsymmetricMatcher.prototype[Symbol.for("chai/inspect")] = function(options) {
|
|
555
|
+
const result = stringify(this, options.depth, { min: true });
|
|
556
|
+
if (result.length <= options.truncate) return result;
|
|
557
|
+
return `${this.toString()}{…}`;
|
|
558
|
+
};
|
|
559
|
+
var StringContaining = class extends AsymmetricMatcher {
|
|
560
|
+
constructor(sample, inverse = false) {
|
|
561
|
+
if (!isA("String", sample)) throw new Error("Expected is not a string");
|
|
562
|
+
super(sample, inverse);
|
|
563
|
+
}
|
|
564
|
+
asymmetricMatch(other) {
|
|
565
|
+
const result = isA("String", other) && other.includes(this.sample);
|
|
566
|
+
return this.inverse ? !result : result;
|
|
567
|
+
}
|
|
568
|
+
toString() {
|
|
569
|
+
return `String${this.inverse ? "Not" : ""}Containing`;
|
|
570
|
+
}
|
|
571
|
+
getExpectedType() {
|
|
572
|
+
return "string";
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
var Anything = class extends AsymmetricMatcher {
|
|
576
|
+
asymmetricMatch(other) {
|
|
577
|
+
return other != null;
|
|
578
|
+
}
|
|
579
|
+
toString() {
|
|
580
|
+
return "Anything";
|
|
581
|
+
}
|
|
582
|
+
toAsymmetricMatcher() {
|
|
583
|
+
return "Anything";
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
var ObjectContaining = class extends AsymmetricMatcher {
|
|
587
|
+
constructor(sample, inverse = false) {
|
|
588
|
+
super(sample, inverse);
|
|
589
|
+
}
|
|
590
|
+
getPrototype(obj) {
|
|
591
|
+
if (Object.getPrototypeOf) return Object.getPrototypeOf(obj);
|
|
592
|
+
if (obj.constructor.prototype === obj) return null;
|
|
593
|
+
return obj.constructor.prototype;
|
|
594
|
+
}
|
|
595
|
+
hasProperty(obj, property) {
|
|
596
|
+
if (!obj) return false;
|
|
597
|
+
if (Object.hasOwn(obj, property)) return true;
|
|
598
|
+
return this.hasProperty(this.getPrototype(obj), property);
|
|
599
|
+
}
|
|
600
|
+
getProperties(obj) {
|
|
601
|
+
return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj).filter((s) => Object.getOwnPropertyDescriptor(obj, s)?.enumerable)];
|
|
602
|
+
}
|
|
603
|
+
asymmetricMatch(other, customTesters) {
|
|
604
|
+
if (typeof this.sample !== "object") throw new TypeError(`You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`);
|
|
605
|
+
let result = true;
|
|
606
|
+
const properties = this.getProperties(this.sample);
|
|
607
|
+
for (const property of properties) {
|
|
608
|
+
if (!this.hasProperty(other, property)) {
|
|
609
|
+
result = false;
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
const value = this.sample[property];
|
|
613
|
+
const otherValue = other[property];
|
|
614
|
+
if (!equals(value, otherValue, customTesters)) {
|
|
615
|
+
result = false;
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return this.inverse ? !result : result;
|
|
620
|
+
}
|
|
621
|
+
toString() {
|
|
622
|
+
return `Object${this.inverse ? "Not" : ""}Containing`;
|
|
623
|
+
}
|
|
624
|
+
getExpectedType() {
|
|
625
|
+
return "object";
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
var ArrayContaining = class extends AsymmetricMatcher {
|
|
629
|
+
constructor(sample, inverse = false) {
|
|
630
|
+
super(sample, inverse);
|
|
631
|
+
}
|
|
632
|
+
asymmetricMatch(other, customTesters) {
|
|
633
|
+
if (!Array.isArray(this.sample)) throw new TypeError(`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`);
|
|
634
|
+
const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every((item) => other.some((another) => equals(item, another, customTesters)));
|
|
635
|
+
return this.inverse ? !result : result;
|
|
636
|
+
}
|
|
637
|
+
toString() {
|
|
638
|
+
return `Array${this.inverse ? "Not" : ""}Containing`;
|
|
639
|
+
}
|
|
640
|
+
getExpectedType() {
|
|
641
|
+
return "array";
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
var Any = class extends AsymmetricMatcher {
|
|
645
|
+
constructor(sample) {
|
|
646
|
+
if (typeof sample === "undefined") throw new TypeError("any() expects to be passed a constructor function. Please pass one or use anything() to match any object.");
|
|
647
|
+
super(sample);
|
|
648
|
+
}
|
|
649
|
+
fnNameFor(func) {
|
|
650
|
+
if (func.name) return func.name;
|
|
651
|
+
const matches = Function.prototype.toString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/);
|
|
652
|
+
return matches ? matches[1] : "<anonymous>";
|
|
653
|
+
}
|
|
654
|
+
asymmetricMatch(other) {
|
|
655
|
+
if (this.sample === String) return typeof other == "string" || other instanceof String;
|
|
656
|
+
if (this.sample === Number) return typeof other == "number" || other instanceof Number;
|
|
657
|
+
if (this.sample === Function) return typeof other == "function" || typeof other === "function";
|
|
658
|
+
if (this.sample === Boolean) return typeof other == "boolean" || other instanceof Boolean;
|
|
659
|
+
if (this.sample === BigInt) return typeof other == "bigint" || other instanceof BigInt;
|
|
660
|
+
if (this.sample === Symbol) return typeof other == "symbol" || other instanceof Symbol;
|
|
661
|
+
if (this.sample === Object) return typeof other == "object";
|
|
662
|
+
return other instanceof this.sample;
|
|
663
|
+
}
|
|
664
|
+
toString() {
|
|
665
|
+
return "Any";
|
|
666
|
+
}
|
|
667
|
+
getExpectedType() {
|
|
668
|
+
if (this.sample === String) return "string";
|
|
669
|
+
if (this.sample === Number) return "number";
|
|
670
|
+
if (this.sample === Function) return "function";
|
|
671
|
+
if (this.sample === Object) return "object";
|
|
672
|
+
if (this.sample === Boolean) return "boolean";
|
|
673
|
+
return this.fnNameFor(this.sample);
|
|
674
|
+
}
|
|
675
|
+
toAsymmetricMatcher() {
|
|
676
|
+
return `Any<${this.fnNameFor(this.sample)}>`;
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
var StringMatching = class extends AsymmetricMatcher {
|
|
680
|
+
constructor(sample, inverse = false) {
|
|
681
|
+
if (!isA("String", sample) && !isA("RegExp", sample)) throw new Error("Expected is not a String or a RegExp");
|
|
682
|
+
super(new RegExp(sample), inverse);
|
|
683
|
+
}
|
|
684
|
+
asymmetricMatch(other) {
|
|
685
|
+
const result = isA("String", other) && this.sample.test(other);
|
|
686
|
+
return this.inverse ? !result : result;
|
|
687
|
+
}
|
|
688
|
+
toString() {
|
|
689
|
+
return `String${this.inverse ? "Not" : ""}Matching`;
|
|
690
|
+
}
|
|
691
|
+
getExpectedType() {
|
|
692
|
+
return "string";
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
var CloseTo = class extends AsymmetricMatcher {
|
|
696
|
+
precision;
|
|
697
|
+
constructor(sample, precision = 2, inverse = false) {
|
|
698
|
+
if (!isA("Number", sample)) throw new Error("Expected is not a Number");
|
|
699
|
+
if (!isA("Number", precision)) throw new Error("Precision is not a Number");
|
|
700
|
+
super(sample);
|
|
701
|
+
this.inverse = inverse;
|
|
702
|
+
this.precision = precision;
|
|
703
|
+
}
|
|
704
|
+
asymmetricMatch(other) {
|
|
705
|
+
if (!isA("Number", other)) return false;
|
|
706
|
+
let result = false;
|
|
707
|
+
if (other === Number.POSITIVE_INFINITY && this.sample === Number.POSITIVE_INFINITY) result = true;
|
|
708
|
+
else if (other === Number.NEGATIVE_INFINITY && this.sample === Number.NEGATIVE_INFINITY) result = true;
|
|
709
|
+
else result = Math.abs(this.sample - other) < 10 ** -this.precision / 2;
|
|
710
|
+
return this.inverse ? !result : result;
|
|
711
|
+
}
|
|
712
|
+
toString() {
|
|
713
|
+
return `Number${this.inverse ? "Not" : ""}CloseTo`;
|
|
714
|
+
}
|
|
715
|
+
getExpectedType() {
|
|
716
|
+
return "number";
|
|
717
|
+
}
|
|
718
|
+
toAsymmetricMatcher() {
|
|
719
|
+
return [
|
|
720
|
+
this.toString(),
|
|
721
|
+
this.sample,
|
|
722
|
+
`(${pluralize("digit", this.precision)})`
|
|
723
|
+
].join(" ");
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
var SchemaMatching = class extends AsymmetricMatcher {
|
|
727
|
+
result;
|
|
728
|
+
constructor(sample, inverse = false) {
|
|
729
|
+
if (!isStandardSchema(sample)) throw new TypeError("SchemaMatching expected to receive a Standard Schema.");
|
|
730
|
+
super(sample, inverse);
|
|
731
|
+
}
|
|
732
|
+
asymmetricMatch(other) {
|
|
733
|
+
const result = this.sample["~standard"].validate(other);
|
|
734
|
+
if (result instanceof Promise) throw new TypeError("Async schema validation is not supported in asymmetric matchers.");
|
|
735
|
+
this.result = result;
|
|
736
|
+
const pass = !this.result.issues || this.result.issues.length === 0;
|
|
737
|
+
return this.inverse ? !pass : pass;
|
|
738
|
+
}
|
|
739
|
+
toString() {
|
|
740
|
+
return `Schema${this.inverse ? "Not" : ""}Matching`;
|
|
741
|
+
}
|
|
742
|
+
getExpectedType() {
|
|
743
|
+
return "object";
|
|
744
|
+
}
|
|
745
|
+
toAsymmetricMatcher() {
|
|
746
|
+
const { utils } = this.getMatcherContext();
|
|
747
|
+
if ((this.result?.issues || []).length > 0) return `${this.toString()} ${utils.stringify(this.result, void 0, { printBasicPrototype: false })}`;
|
|
748
|
+
return this.toString();
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
const JestAsymmetricMatchers = (chai, utils) => {
|
|
752
|
+
utils.addMethod(chai.expect, "anything", () => new Anything());
|
|
753
|
+
utils.addMethod(chai.expect, "any", (expected) => new Any(expected));
|
|
754
|
+
utils.addMethod(chai.expect, "stringContaining", (expected) => new StringContaining(expected));
|
|
755
|
+
utils.addMethod(chai.expect, "objectContaining", (expected) => new ObjectContaining(expected));
|
|
756
|
+
utils.addMethod(chai.expect, "arrayContaining", (expected) => new ArrayContaining(expected));
|
|
757
|
+
utils.addMethod(chai.expect, "stringMatching", (expected) => new StringMatching(expected));
|
|
758
|
+
utils.addMethod(chai.expect, "closeTo", (expected, precision) => new CloseTo(expected, precision));
|
|
759
|
+
utils.addMethod(chai.expect, "schemaMatching", (expected) => new SchemaMatching(expected));
|
|
760
|
+
chai.expect.not = {
|
|
761
|
+
stringContaining: (expected) => new StringContaining(expected, true),
|
|
762
|
+
objectContaining: (expected) => new ObjectContaining(expected, true),
|
|
763
|
+
arrayContaining: (expected) => new ArrayContaining(expected, true),
|
|
764
|
+
stringMatching: (expected) => new StringMatching(expected, true),
|
|
765
|
+
closeTo: (expected, precision) => new CloseTo(expected, precision, true),
|
|
766
|
+
schemaMatching: (expected) => new SchemaMatching(expected, true)
|
|
767
|
+
};
|
|
768
|
+
};
|
|
769
|
+
function createAssertionMessage(util, assertion, hasArgs) {
|
|
770
|
+
const soft = util.flag(assertion, "soft") ? ".soft" : "";
|
|
771
|
+
const not = util.flag(assertion, "negate") ? "not." : "";
|
|
772
|
+
const name = `${util.flag(assertion, "_name")}(${hasArgs ? "expected" : ""})`;
|
|
773
|
+
const promiseName = util.flag(assertion, "promise");
|
|
774
|
+
return `expect${soft}(actual)${promiseName ? `.${promiseName}` : ""}.${not}${name}`;
|
|
775
|
+
}
|
|
776
|
+
function recordAsyncExpect(_test, promise, assertion, error, isSoft) {
|
|
777
|
+
const test = _test;
|
|
778
|
+
if (test && promise instanceof Promise) {
|
|
779
|
+
promise = promise.finally(() => {
|
|
780
|
+
if (!test.promises) return;
|
|
781
|
+
const index = test.promises.indexOf(promise);
|
|
782
|
+
if (index !== -1) test.promises.splice(index, 1);
|
|
783
|
+
});
|
|
784
|
+
if (!test.promises) test.promises = [];
|
|
785
|
+
if (isSoft) promise = promise.then(noop, (err) => {
|
|
786
|
+
handleTestError(test, err);
|
|
787
|
+
});
|
|
788
|
+
test.promises.push(promise);
|
|
789
|
+
let resolved = false;
|
|
790
|
+
test.onFinished ??= [];
|
|
791
|
+
test.onFinished.push(() => {
|
|
792
|
+
if (!resolved) {
|
|
793
|
+
const stack = (globalThis.__vitest_worker__?.onFilterStackTrace || ((s) => s || ""))(error.stack);
|
|
794
|
+
console.warn([
|
|
795
|
+
`Promise returned by \`${assertion}\` was not awaited. `,
|
|
796
|
+
"Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in the next Vitest major. ",
|
|
797
|
+
"Please remember to await the assertion.\n",
|
|
798
|
+
stack
|
|
799
|
+
].join(""));
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
return {
|
|
803
|
+
then(onFulfilled, onRejected) {
|
|
804
|
+
resolved = true;
|
|
805
|
+
return promise.then(onFulfilled, onRejected);
|
|
806
|
+
},
|
|
807
|
+
catch(onRejected) {
|
|
808
|
+
resolved = true;
|
|
809
|
+
return promise.catch(onRejected);
|
|
810
|
+
},
|
|
811
|
+
finally(onFinally) {
|
|
812
|
+
resolved = true;
|
|
813
|
+
return promise.finally(onFinally);
|
|
814
|
+
},
|
|
815
|
+
[Symbol.toStringTag]: "Promise"
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
return promise;
|
|
819
|
+
}
|
|
820
|
+
function handleTestError(test, err) {
|
|
821
|
+
test.result ||= { state: "fail" };
|
|
822
|
+
test.result.state = "fail";
|
|
823
|
+
test.result.errors ||= [];
|
|
824
|
+
test.result.errors.push(processError(err));
|
|
825
|
+
}
|
|
826
|
+
/** wrap assertion function to support `expect.soft` and provide assertion name as `_name` */
|
|
827
|
+
function wrapAssertion(utils, name, fn) {
|
|
828
|
+
return function(...args) {
|
|
829
|
+
if (name !== "withTest") utils.flag(this, "_name", name);
|
|
830
|
+
if (!utils.flag(this, "soft")) try {
|
|
831
|
+
return fn.apply(this, args);
|
|
832
|
+
} finally {}
|
|
833
|
+
const test = utils.flag(this, "vitest-test");
|
|
834
|
+
if (!test) throw new Error("expect.soft() can only be used inside a test");
|
|
835
|
+
try {
|
|
836
|
+
const result = fn.apply(this, args);
|
|
837
|
+
if (result && typeof result === "object" && typeof result.then === "function") return result.then(noop, (err) => {
|
|
838
|
+
handleTestError(test, err);
|
|
839
|
+
});
|
|
840
|
+
return result;
|
|
841
|
+
} catch (err) {
|
|
842
|
+
handleTestError(test, err);
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
const JestChaiExpect = (chai, utils) => {
|
|
847
|
+
const { AssertionError } = chai;
|
|
848
|
+
const customTesters = getCustomEqualityTesters();
|
|
849
|
+
function def(name, fn) {
|
|
850
|
+
const addMethod = (n) => {
|
|
851
|
+
const softWrapper = wrapAssertion(utils, n, fn);
|
|
852
|
+
utils.addMethod(chai.Assertion.prototype, n, softWrapper);
|
|
853
|
+
utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, softWrapper);
|
|
854
|
+
};
|
|
855
|
+
if (Array.isArray(name)) name.forEach((n) => addMethod(n));
|
|
856
|
+
else addMethod(name);
|
|
857
|
+
}
|
|
858
|
+
[
|
|
859
|
+
"throw",
|
|
860
|
+
"throws",
|
|
861
|
+
"Throw"
|
|
862
|
+
].forEach((m) => {
|
|
863
|
+
utils.overwriteMethod(chai.Assertion.prototype, m, (_super) => {
|
|
864
|
+
return function(...args) {
|
|
865
|
+
const promise = utils.flag(this, "promise");
|
|
866
|
+
const object = utils.flag(this, "object");
|
|
867
|
+
const isNot = utils.flag(this, "negate");
|
|
868
|
+
if (promise === "rejects") utils.flag(this, "object", () => {
|
|
869
|
+
throw object;
|
|
870
|
+
});
|
|
871
|
+
else if (promise === "resolves" && typeof object !== "function") if (!isNot) {
|
|
872
|
+
const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't";
|
|
873
|
+
throw new AssertionError(message, { showDiff: false }, utils.flag(this, "ssfi"));
|
|
874
|
+
} else return;
|
|
875
|
+
_super.apply(this, args);
|
|
876
|
+
};
|
|
877
|
+
});
|
|
878
|
+
});
|
|
879
|
+
def("withTest", function(test) {
|
|
880
|
+
utils.flag(this, "vitest-test", test);
|
|
881
|
+
return this;
|
|
882
|
+
});
|
|
883
|
+
def("toEqual", function(expected) {
|
|
884
|
+
const actual = utils.flag(this, "object");
|
|
885
|
+
const equal = equals(actual, expected, [...customTesters, iterableEquality]);
|
|
886
|
+
return this.assert(equal, "expected #{this} to deeply equal #{exp}", "expected #{this} to not deeply equal #{exp}", expected, actual);
|
|
887
|
+
});
|
|
888
|
+
def("toStrictEqual", function(expected) {
|
|
889
|
+
const obj = utils.flag(this, "object");
|
|
890
|
+
const equal = equals(obj, expected, [
|
|
891
|
+
...customTesters,
|
|
892
|
+
iterableEquality,
|
|
893
|
+
typeEquality,
|
|
894
|
+
sparseArrayEquality,
|
|
895
|
+
arrayBufferEquality
|
|
896
|
+
], true);
|
|
897
|
+
return this.assert(equal, "expected #{this} to strictly equal #{exp}", "expected #{this} to not strictly equal #{exp}", expected, obj);
|
|
898
|
+
});
|
|
899
|
+
def("toBe", function(expected) {
|
|
900
|
+
const actual = this._obj;
|
|
901
|
+
const pass = Object.is(actual, expected);
|
|
902
|
+
let deepEqualityName = "";
|
|
903
|
+
if (!pass) {
|
|
904
|
+
if (equals(actual, expected, [
|
|
905
|
+
...customTesters,
|
|
906
|
+
iterableEquality,
|
|
907
|
+
typeEquality,
|
|
908
|
+
sparseArrayEquality,
|
|
909
|
+
arrayBufferEquality
|
|
910
|
+
], true)) deepEqualityName = "toStrictEqual";
|
|
911
|
+
else if (equals(actual, expected, [...customTesters, iterableEquality])) deepEqualityName = "toEqual";
|
|
912
|
+
}
|
|
913
|
+
return this.assert(pass, generateToBeMessage(deepEqualityName), "expected #{this} not to be #{exp} // Object.is equality", expected, actual);
|
|
914
|
+
});
|
|
915
|
+
def("toMatchObject", function(expected) {
|
|
916
|
+
const actual = this._obj;
|
|
917
|
+
const pass = equals(actual, expected, [
|
|
918
|
+
...customTesters,
|
|
919
|
+
iterableEquality,
|
|
920
|
+
subsetEquality
|
|
921
|
+
]);
|
|
922
|
+
const isNot = utils.flag(this, "negate");
|
|
923
|
+
const { subset: actualSubset, stripped } = getObjectSubset(actual, expected, customTesters);
|
|
924
|
+
if (pass && isNot || !pass && !isNot) {
|
|
925
|
+
const msg = utils.getMessage(this, [
|
|
926
|
+
pass,
|
|
927
|
+
"expected #{this} to match object #{exp}",
|
|
928
|
+
"expected #{this} to not match object #{exp}",
|
|
929
|
+
expected,
|
|
930
|
+
actualSubset,
|
|
931
|
+
false
|
|
932
|
+
]);
|
|
933
|
+
const message = stripped === 0 ? msg : `${msg}\n(${stripped} matching ${stripped === 1 ? "property" : "properties"} omitted from actual)`;
|
|
934
|
+
throw new AssertionError(message, {
|
|
935
|
+
showDiff: true,
|
|
936
|
+
expected,
|
|
937
|
+
actual: actualSubset
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
});
|
|
941
|
+
def("toMatch", function(expected) {
|
|
942
|
+
const actual = this._obj;
|
|
943
|
+
if (typeof actual !== "string") throw new TypeError(`.toMatch() expects to receive a string, but got ${typeof actual}`);
|
|
944
|
+
return this.assert(typeof expected === "string" ? actual.includes(expected) : actual.match(expected), `expected #{this} to match #{exp}`, `expected #{this} not to match #{exp}`, expected, actual);
|
|
945
|
+
});
|
|
946
|
+
def("toContain", function(item) {
|
|
947
|
+
const actual = this._obj;
|
|
948
|
+
if (typeof Node !== "undefined" && actual instanceof Node) {
|
|
949
|
+
if (!(item instanceof Node)) throw new TypeError(`toContain() expected a DOM node as the argument, but got ${typeof item}`);
|
|
950
|
+
return this.assert(actual.contains(item), "expected #{this} to contain element #{exp}", "expected #{this} not to contain element #{exp}", item, actual);
|
|
951
|
+
}
|
|
952
|
+
if (typeof DOMTokenList !== "undefined" && actual instanceof DOMTokenList) {
|
|
953
|
+
assertTypes(item, "class name", ["string"]);
|
|
954
|
+
const expectedClassList = utils.flag(this, "negate") ? actual.value.replace(item, "").trim() : `${actual.value} ${item}`;
|
|
955
|
+
return this.assert(actual.contains(item), `expected "${actual.value}" to contain "${item}"`, `expected "${actual.value}" not to contain "${item}"`, expectedClassList, actual.value);
|
|
956
|
+
}
|
|
957
|
+
if (typeof actual === "string" && typeof item === "string") return this.assert(actual.includes(item), `expected #{this} to contain #{exp}`, `expected #{this} not to contain #{exp}`, item, actual);
|
|
958
|
+
if (actual != null && typeof actual !== "string") utils.flag(this, "object", Array.from(actual));
|
|
959
|
+
return this.contain(item);
|
|
960
|
+
});
|
|
961
|
+
def("toContainEqual", function(expected) {
|
|
962
|
+
const obj = utils.flag(this, "object");
|
|
963
|
+
const index = Array.from(obj).findIndex((item) => {
|
|
964
|
+
return equals(item, expected, customTesters);
|
|
965
|
+
});
|
|
966
|
+
this.assert(index !== -1, "expected #{this} to deep equally contain #{exp}", "expected #{this} to not deep equally contain #{exp}", expected);
|
|
967
|
+
});
|
|
968
|
+
def("toBeTruthy", function() {
|
|
969
|
+
const obj = utils.flag(this, "object");
|
|
970
|
+
this.assert(Boolean(obj), "expected #{this} to be truthy", "expected #{this} to not be truthy", true, obj);
|
|
971
|
+
});
|
|
972
|
+
def("toBeFalsy", function() {
|
|
973
|
+
const obj = utils.flag(this, "object");
|
|
974
|
+
this.assert(!obj, "expected #{this} to be falsy", "expected #{this} to not be falsy", false, obj);
|
|
975
|
+
});
|
|
976
|
+
def("toBeGreaterThan", function(expected) {
|
|
977
|
+
const actual = this._obj;
|
|
978
|
+
assertTypes(actual, "actual", ["number", "bigint"]);
|
|
979
|
+
assertTypes(expected, "expected", ["number", "bigint"]);
|
|
980
|
+
return this.assert(actual > expected, `expected ${actual} to be greater than ${expected}`, `expected ${actual} to be not greater than ${expected}`, expected, actual, false);
|
|
981
|
+
});
|
|
982
|
+
def("toBeGreaterThanOrEqual", function(expected) {
|
|
983
|
+
const actual = this._obj;
|
|
984
|
+
assertTypes(actual, "actual", ["number", "bigint"]);
|
|
985
|
+
assertTypes(expected, "expected", ["number", "bigint"]);
|
|
986
|
+
return this.assert(actual >= expected, `expected ${actual} to be greater than or equal to ${expected}`, `expected ${actual} to be not greater than or equal to ${expected}`, expected, actual, false);
|
|
987
|
+
});
|
|
988
|
+
def("toBeLessThan", function(expected) {
|
|
989
|
+
const actual = this._obj;
|
|
990
|
+
assertTypes(actual, "actual", ["number", "bigint"]);
|
|
991
|
+
assertTypes(expected, "expected", ["number", "bigint"]);
|
|
992
|
+
return this.assert(actual < expected, `expected ${actual} to be less than ${expected}`, `expected ${actual} to be not less than ${expected}`, expected, actual, false);
|
|
993
|
+
});
|
|
994
|
+
def("toBeLessThanOrEqual", function(expected) {
|
|
995
|
+
const actual = this._obj;
|
|
996
|
+
assertTypes(actual, "actual", ["number", "bigint"]);
|
|
997
|
+
assertTypes(expected, "expected", ["number", "bigint"]);
|
|
998
|
+
return this.assert(actual <= expected, `expected ${actual} to be less than or equal to ${expected}`, `expected ${actual} to be not less than or equal to ${expected}`, expected, actual, false);
|
|
999
|
+
});
|
|
1000
|
+
def("toBeNaN", function() {
|
|
1001
|
+
const obj = utils.flag(this, "object");
|
|
1002
|
+
this.assert(Number.isNaN(obj), "expected #{this} to be NaN", "expected #{this} not to be NaN", NaN, obj);
|
|
1003
|
+
});
|
|
1004
|
+
def("toBeUndefined", function() {
|
|
1005
|
+
const obj = utils.flag(this, "object");
|
|
1006
|
+
this.assert(void 0 === obj, "expected #{this} to be undefined", "expected #{this} not to be undefined", void 0, obj);
|
|
1007
|
+
});
|
|
1008
|
+
def("toBeNull", function() {
|
|
1009
|
+
const obj = utils.flag(this, "object");
|
|
1010
|
+
this.assert(obj === null, "expected #{this} to be null", "expected #{this} not to be null", null, obj);
|
|
1011
|
+
});
|
|
1012
|
+
def("toBeNullable", function() {
|
|
1013
|
+
const obj = utils.flag(this, "object");
|
|
1014
|
+
this.assert(obj == null, "expected #{this} to be nullish", "expected #{this} not to be nullish", null, obj);
|
|
1015
|
+
});
|
|
1016
|
+
def("toBeDefined", function() {
|
|
1017
|
+
const obj = utils.flag(this, "object");
|
|
1018
|
+
this.assert(typeof obj !== "undefined", "expected #{this} to be defined", "expected #{this} to be undefined", obj);
|
|
1019
|
+
});
|
|
1020
|
+
def("toBeTypeOf", function(expected) {
|
|
1021
|
+
const actual = typeof this._obj;
|
|
1022
|
+
const equal = expected === actual;
|
|
1023
|
+
return this.assert(equal, "expected #{this} to be type of #{exp}", "expected #{this} not to be type of #{exp}", expected, actual);
|
|
1024
|
+
});
|
|
1025
|
+
def("toBeInstanceOf", function(obj) {
|
|
1026
|
+
return this.instanceOf(obj);
|
|
1027
|
+
});
|
|
1028
|
+
def("toHaveLength", function(length) {
|
|
1029
|
+
return this.have.length(length);
|
|
1030
|
+
});
|
|
1031
|
+
def("toHaveProperty", function(...args) {
|
|
1032
|
+
if (Array.isArray(args[0])) args[0] = args[0].map((key) => String(key).replace(/([.[\]])/g, "\\$1")).join(".");
|
|
1033
|
+
const actual = this._obj;
|
|
1034
|
+
const [propertyName, expected] = args;
|
|
1035
|
+
const getValue = () => {
|
|
1036
|
+
if (Object.hasOwn(actual, propertyName)) return {
|
|
1037
|
+
value: actual[propertyName],
|
|
1038
|
+
exists: true
|
|
1039
|
+
};
|
|
1040
|
+
return utils.getPathInfo(actual, propertyName);
|
|
1041
|
+
};
|
|
1042
|
+
const { value, exists } = getValue();
|
|
1043
|
+
const pass = exists && (args.length === 1 || equals(expected, value, customTesters));
|
|
1044
|
+
const valueString = args.length === 1 ? "" : ` with value ${utils.objDisplay(expected)}`;
|
|
1045
|
+
return this.assert(pass, `expected #{this} to have property "${propertyName}"${valueString}`, `expected #{this} to not have property "${propertyName}"${valueString}`, expected, exists ? value : void 0);
|
|
1046
|
+
});
|
|
1047
|
+
def("toBeCloseTo", function(received, precision = 2) {
|
|
1048
|
+
const expected = this._obj;
|
|
1049
|
+
let pass = false;
|
|
1050
|
+
let expectedDiff = 0;
|
|
1051
|
+
let receivedDiff = 0;
|
|
1052
|
+
if (received === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) pass = true;
|
|
1053
|
+
else if (received === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) pass = true;
|
|
1054
|
+
else {
|
|
1055
|
+
expectedDiff = 10 ** -precision / 2;
|
|
1056
|
+
receivedDiff = Math.abs(expected - received);
|
|
1057
|
+
pass = receivedDiff < expectedDiff;
|
|
1058
|
+
}
|
|
1059
|
+
return this.assert(pass, `expected #{this} to be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, `expected #{this} to not be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`, received, expected, false);
|
|
1060
|
+
});
|
|
1061
|
+
function assertIsMock(assertion) {
|
|
1062
|
+
if (!isMockFunction(assertion._obj)) throw new TypeError(`${utils.inspect(assertion._obj)} is not a spy or a call to a spy!`);
|
|
1063
|
+
}
|
|
1064
|
+
function getSpy(assertion) {
|
|
1065
|
+
assertIsMock(assertion);
|
|
1066
|
+
return assertion._obj;
|
|
1067
|
+
}
|
|
1068
|
+
def(["toHaveBeenCalledTimes", "toBeCalledTimes"], function(number) {
|
|
1069
|
+
const spy = getSpy(this);
|
|
1070
|
+
const spyName = spy.getMockName();
|
|
1071
|
+
const callCount = spy.mock.calls.length;
|
|
1072
|
+
return this.assert(callCount === number, `expected "${spyName}" to be called #{exp} times, but got ${callCount} times`, `expected "${spyName}" to not be called #{exp} times`, number, callCount, false);
|
|
1073
|
+
});
|
|
1074
|
+
def("toHaveBeenCalledOnce", function() {
|
|
1075
|
+
const spy = getSpy(this);
|
|
1076
|
+
const spyName = spy.getMockName();
|
|
1077
|
+
const callCount = spy.mock.calls.length;
|
|
1078
|
+
return this.assert(callCount === 1, `expected "${spyName}" to be called once, but got ${callCount} times`, `expected "${spyName}" to not be called once`, 1, callCount, false);
|
|
1079
|
+
});
|
|
1080
|
+
def(["toHaveBeenCalled", "toBeCalled"], function() {
|
|
1081
|
+
const spy = getSpy(this);
|
|
1082
|
+
const spyName = spy.getMockName();
|
|
1083
|
+
const callCount = spy.mock.calls.length;
|
|
1084
|
+
const called = callCount > 0;
|
|
1085
|
+
const isNot = utils.flag(this, "negate");
|
|
1086
|
+
let msg = utils.getMessage(this, [
|
|
1087
|
+
called,
|
|
1088
|
+
`expected "${spyName}" to be called at least once`,
|
|
1089
|
+
`expected "${spyName}" to not be called at all, but actually been called ${callCount} times`,
|
|
1090
|
+
true,
|
|
1091
|
+
called
|
|
1092
|
+
]);
|
|
1093
|
+
if (called && isNot) msg = formatCalls(spy, msg);
|
|
1094
|
+
if (called && isNot || !called && !isNot) throw new AssertionError(msg);
|
|
1095
|
+
});
|
|
1096
|
+
function equalsArgumentArray(a, b) {
|
|
1097
|
+
return a.length === b.length && a.every((aItem, i) => equals(aItem, b[i], [...customTesters, iterableEquality]));
|
|
1098
|
+
}
|
|
1099
|
+
def(["toHaveBeenCalledWith", "toBeCalledWith"], function(...args) {
|
|
1100
|
+
const spy = getSpy(this);
|
|
1101
|
+
const spyName = spy.getMockName();
|
|
1102
|
+
const pass = spy.mock.calls.some((callArg) => equalsArgumentArray(callArg, args));
|
|
1103
|
+
const isNot = utils.flag(this, "negate");
|
|
1104
|
+
const msg = utils.getMessage(this, [
|
|
1105
|
+
pass,
|
|
1106
|
+
`expected "${spyName}" to be called with arguments: #{exp}`,
|
|
1107
|
+
`expected "${spyName}" to not be called with arguments: #{exp}`,
|
|
1108
|
+
args
|
|
1109
|
+
]);
|
|
1110
|
+
if (pass && isNot || !pass && !isNot) throw new AssertionError(formatCalls(spy, msg, args));
|
|
1111
|
+
});
|
|
1112
|
+
def("toHaveBeenCalledExactlyOnceWith", function(...args) {
|
|
1113
|
+
const spy = getSpy(this);
|
|
1114
|
+
const spyName = spy.getMockName();
|
|
1115
|
+
const callCount = spy.mock.calls.length;
|
|
1116
|
+
const pass = spy.mock.calls.some((callArg) => equalsArgumentArray(callArg, args)) && callCount === 1;
|
|
1117
|
+
const isNot = utils.flag(this, "negate");
|
|
1118
|
+
const msg = utils.getMessage(this, [
|
|
1119
|
+
pass,
|
|
1120
|
+
`expected "${spyName}" to be called once with arguments: #{exp}`,
|
|
1121
|
+
`expected "${spyName}" to not be called once with arguments: #{exp}`,
|
|
1122
|
+
args
|
|
1123
|
+
]);
|
|
1124
|
+
if (pass && isNot || !pass && !isNot) throw new AssertionError(formatCalls(spy, msg, args));
|
|
1125
|
+
});
|
|
1126
|
+
def("toHaveBeenNthCalledWith", function(times, ...args) {
|
|
1127
|
+
const spy = getSpy(this);
|
|
1128
|
+
const spyName = spy.getMockName();
|
|
1129
|
+
const nthCall = spy.mock.calls[times - 1];
|
|
1130
|
+
const callCount = spy.mock.calls.length;
|
|
1131
|
+
const isCalled = times <= callCount;
|
|
1132
|
+
this.assert(nthCall && equalsArgumentArray(nthCall, args), `expected ${ordinal(times)} "${spyName}" call to have been called with #{exp}${isCalled ? `` : `, but called only ${callCount} times`}`, `expected ${ordinal(times)} "${spyName}" call to not have been called with #{exp}`, args, nthCall, isCalled);
|
|
1133
|
+
});
|
|
1134
|
+
def("toHaveBeenLastCalledWith", function(...args) {
|
|
1135
|
+
const spy = getSpy(this);
|
|
1136
|
+
const spyName = spy.getMockName();
|
|
1137
|
+
const lastCall = spy.mock.calls.at(-1);
|
|
1138
|
+
this.assert(lastCall && equalsArgumentArray(lastCall, args), `expected last "${spyName}" call to have been called with #{exp}`, `expected last "${spyName}" call to not have been called with #{exp}`, args, lastCall);
|
|
1139
|
+
});
|
|
1140
|
+
/**
|
|
1141
|
+
* Used for `toHaveBeenCalledBefore` and `toHaveBeenCalledAfter` to determine if the expected spy was called before the result spy.
|
|
1142
|
+
*/
|
|
1143
|
+
function isSpyCalledBeforeAnotherSpy(beforeSpy, afterSpy, failIfNoFirstInvocation) {
|
|
1144
|
+
const beforeInvocationCallOrder = beforeSpy.mock.invocationCallOrder;
|
|
1145
|
+
const afterInvocationCallOrder = afterSpy.mock.invocationCallOrder;
|
|
1146
|
+
if (beforeInvocationCallOrder.length === 0) return !failIfNoFirstInvocation;
|
|
1147
|
+
if (afterInvocationCallOrder.length === 0) return false;
|
|
1148
|
+
return beforeInvocationCallOrder[0] < afterInvocationCallOrder[0];
|
|
1149
|
+
}
|
|
1150
|
+
def(["toHaveBeenCalledBefore"], function(resultSpy, failIfNoFirstInvocation = true) {
|
|
1151
|
+
const expectSpy = getSpy(this);
|
|
1152
|
+
if (!isMockFunction(resultSpy)) throw new TypeError(`${utils.inspect(resultSpy)} is not a spy or a call to a spy`);
|
|
1153
|
+
this.assert(isSpyCalledBeforeAnotherSpy(expectSpy, resultSpy, failIfNoFirstInvocation), `expected "${expectSpy.getMockName()}" to have been called before "${resultSpy.getMockName()}"`, `expected "${expectSpy.getMockName()}" to not have been called before "${resultSpy.getMockName()}"`, resultSpy, expectSpy);
|
|
1154
|
+
});
|
|
1155
|
+
def(["toHaveBeenCalledAfter"], function(resultSpy, failIfNoFirstInvocation = true) {
|
|
1156
|
+
const expectSpy = getSpy(this);
|
|
1157
|
+
if (!isMockFunction(resultSpy)) throw new TypeError(`${utils.inspect(resultSpy)} is not a spy or a call to a spy`);
|
|
1158
|
+
this.assert(isSpyCalledBeforeAnotherSpy(resultSpy, expectSpy, failIfNoFirstInvocation), `expected "${expectSpy.getMockName()}" to have been called after "${resultSpy.getMockName()}"`, `expected "${expectSpy.getMockName()}" to not have been called after "${resultSpy.getMockName()}"`, resultSpy, expectSpy);
|
|
1159
|
+
});
|
|
1160
|
+
def(["toThrow", "toThrowError"], function(expected) {
|
|
1161
|
+
if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp) return this.throws(expected === "" ? /^$/ : expected);
|
|
1162
|
+
const obj = this._obj;
|
|
1163
|
+
const promise = utils.flag(this, "promise");
|
|
1164
|
+
const isNot = utils.flag(this, "negate");
|
|
1165
|
+
let thrown = null;
|
|
1166
|
+
if (promise === "rejects") thrown = obj;
|
|
1167
|
+
else if (promise === "resolves" && typeof obj !== "function") if (!isNot) {
|
|
1168
|
+
const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't";
|
|
1169
|
+
throw new AssertionError(message, { showDiff: false }, utils.flag(this, "ssfi"));
|
|
1170
|
+
} else return;
|
|
1171
|
+
else {
|
|
1172
|
+
let isThrow = false;
|
|
1173
|
+
try {
|
|
1174
|
+
obj();
|
|
1175
|
+
} catch (err) {
|
|
1176
|
+
isThrow = true;
|
|
1177
|
+
thrown = err;
|
|
1178
|
+
}
|
|
1179
|
+
if (!isThrow && !isNot) {
|
|
1180
|
+
const message = utils.flag(this, "message") || "expected function to throw an error, but it didn't";
|
|
1181
|
+
throw new AssertionError(message, { showDiff: false }, utils.flag(this, "ssfi"));
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
if (typeof expected === "function") {
|
|
1185
|
+
const name = expected.name || expected.prototype.constructor.name;
|
|
1186
|
+
return this.assert(thrown && thrown instanceof expected, `expected error to be instance of ${name}`, `expected error not to be instance of ${name}`, expected, thrown);
|
|
1187
|
+
}
|
|
1188
|
+
if (isError(expected)) {
|
|
1189
|
+
const equal = equals(thrown, expected, [...customTesters, iterableEquality]);
|
|
1190
|
+
return this.assert(equal, "expected a thrown error to be #{exp}", "expected a thrown error not to be #{exp}", expected, thrown);
|
|
1191
|
+
}
|
|
1192
|
+
if (typeof expected === "object" && "asymmetricMatch" in expected && typeof expected.asymmetricMatch === "function") {
|
|
1193
|
+
const matcher = expected;
|
|
1194
|
+
return this.assert(thrown && matcher.asymmetricMatch(thrown), "expected error to match asymmetric matcher", "expected error not to match asymmetric matcher", matcher, thrown);
|
|
1195
|
+
}
|
|
1196
|
+
const equal = equals(thrown, expected, [...customTesters, iterableEquality]);
|
|
1197
|
+
return this.assert(equal, "expected a thrown value to equal #{exp}", "expected a thrown value not to equal #{exp}", expected, thrown);
|
|
1198
|
+
});
|
|
1199
|
+
[{
|
|
1200
|
+
name: "toHaveResolved",
|
|
1201
|
+
condition: (spy) => spy.mock.settledResults.length > 0 && spy.mock.settledResults.some(({ type }) => type === "fulfilled"),
|
|
1202
|
+
action: "resolved"
|
|
1203
|
+
}, {
|
|
1204
|
+
name: ["toHaveReturned", "toReturn"],
|
|
1205
|
+
condition: (spy) => spy.mock.calls.length > 0 && spy.mock.results.some(({ type }) => type !== "throw"),
|
|
1206
|
+
action: "called"
|
|
1207
|
+
}].forEach(({ name, condition, action }) => {
|
|
1208
|
+
def(name, function() {
|
|
1209
|
+
const spy = getSpy(this);
|
|
1210
|
+
const spyName = spy.getMockName();
|
|
1211
|
+
const pass = condition(spy);
|
|
1212
|
+
this.assert(pass, `expected "${spyName}" to be successfully ${action} at least once`, `expected "${spyName}" to not be successfully ${action}`, pass, !pass, false);
|
|
1213
|
+
});
|
|
1214
|
+
});
|
|
1215
|
+
[{
|
|
1216
|
+
name: "toHaveResolvedTimes",
|
|
1217
|
+
condition: (spy, times) => spy.mock.settledResults.reduce((s, { type }) => type === "fulfilled" ? ++s : s, 0) === times,
|
|
1218
|
+
action: "resolved"
|
|
1219
|
+
}, {
|
|
1220
|
+
name: ["toHaveReturnedTimes", "toReturnTimes"],
|
|
1221
|
+
condition: (spy, times) => spy.mock.results.reduce((s, { type }) => type === "throw" ? s : ++s, 0) === times,
|
|
1222
|
+
action: "called"
|
|
1223
|
+
}].forEach(({ name, condition, action }) => {
|
|
1224
|
+
def(name, function(times) {
|
|
1225
|
+
const spy = getSpy(this);
|
|
1226
|
+
const spyName = spy.getMockName();
|
|
1227
|
+
const pass = condition(spy, times);
|
|
1228
|
+
this.assert(pass, `expected "${spyName}" to be successfully ${action} ${times} times`, `expected "${spyName}" to not be successfully ${action} ${times} times`, `expected resolved times: ${times}`, `received resolved times: ${pass}`, false);
|
|
1229
|
+
});
|
|
1230
|
+
});
|
|
1231
|
+
[{
|
|
1232
|
+
name: "toHaveResolvedWith",
|
|
1233
|
+
condition: (spy, value) => spy.mock.settledResults.some(({ type, value: result }) => type === "fulfilled" && equals(value, result)),
|
|
1234
|
+
action: "resolve"
|
|
1235
|
+
}, {
|
|
1236
|
+
name: ["toHaveReturnedWith", "toReturnWith"],
|
|
1237
|
+
condition: (spy, value) => spy.mock.results.some(({ type, value: result }) => type === "return" && equals(value, result)),
|
|
1238
|
+
action: "return"
|
|
1239
|
+
}].forEach(({ name, condition, action }) => {
|
|
1240
|
+
def(name, function(value) {
|
|
1241
|
+
const spy = getSpy(this);
|
|
1242
|
+
const pass = condition(spy, value);
|
|
1243
|
+
const isNot = utils.flag(this, "negate");
|
|
1244
|
+
if (pass && isNot || !pass && !isNot) {
|
|
1245
|
+
const spyName = spy.getMockName();
|
|
1246
|
+
const msg = utils.getMessage(this, [
|
|
1247
|
+
pass,
|
|
1248
|
+
`expected "${spyName}" to ${action} with: #{exp} at least once`,
|
|
1249
|
+
`expected "${spyName}" to not ${action} with: #{exp}`,
|
|
1250
|
+
value
|
|
1251
|
+
]);
|
|
1252
|
+
const results = action === "return" ? spy.mock.results : spy.mock.settledResults;
|
|
1253
|
+
throw new AssertionError(formatReturns(spy, results, msg, value));
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
});
|
|
1257
|
+
[{
|
|
1258
|
+
name: "toHaveLastResolvedWith",
|
|
1259
|
+
condition: (spy, value) => {
|
|
1260
|
+
const result = spy.mock.settledResults.at(-1);
|
|
1261
|
+
return Boolean(result && result.type === "fulfilled" && equals(result.value, value));
|
|
1262
|
+
},
|
|
1263
|
+
action: "resolve"
|
|
1264
|
+
}, {
|
|
1265
|
+
name: "toHaveLastReturnedWith",
|
|
1266
|
+
condition: (spy, value) => {
|
|
1267
|
+
const result = spy.mock.results.at(-1);
|
|
1268
|
+
return Boolean(result && result.type === "return" && equals(result.value, value));
|
|
1269
|
+
},
|
|
1270
|
+
action: "return"
|
|
1271
|
+
}].forEach(({ name, condition, action }) => {
|
|
1272
|
+
def(name, function(value) {
|
|
1273
|
+
const spy = getSpy(this);
|
|
1274
|
+
const result = (action === "return" ? spy.mock.results : spy.mock.settledResults).at(-1);
|
|
1275
|
+
const spyName = spy.getMockName();
|
|
1276
|
+
this.assert(condition(spy, value), `expected last "${spyName}" call to ${action} #{exp}`, `expected last "${spyName}" call to not ${action} #{exp}`, value, result?.value);
|
|
1277
|
+
});
|
|
1278
|
+
});
|
|
1279
|
+
[{
|
|
1280
|
+
name: "toHaveNthResolvedWith",
|
|
1281
|
+
condition: (spy, index, value) => {
|
|
1282
|
+
const result = spy.mock.settledResults[index - 1];
|
|
1283
|
+
return result && result.type === "fulfilled" && equals(result.value, value);
|
|
1284
|
+
},
|
|
1285
|
+
action: "resolve"
|
|
1286
|
+
}, {
|
|
1287
|
+
name: "toHaveNthReturnedWith",
|
|
1288
|
+
condition: (spy, index, value) => {
|
|
1289
|
+
const result = spy.mock.results[index - 1];
|
|
1290
|
+
return result && result.type === "return" && equals(result.value, value);
|
|
1291
|
+
},
|
|
1292
|
+
action: "return"
|
|
1293
|
+
}].forEach(({ name, condition, action }) => {
|
|
1294
|
+
def(name, function(nthCall, value) {
|
|
1295
|
+
const spy = getSpy(this);
|
|
1296
|
+
const spyName = spy.getMockName();
|
|
1297
|
+
const result = (action === "return" ? spy.mock.results : spy.mock.settledResults)[nthCall - 1];
|
|
1298
|
+
const ordinalCall = `${ordinal(nthCall)} call`;
|
|
1299
|
+
this.assert(condition(spy, nthCall, value), `expected ${ordinalCall} "${spyName}" call to ${action} #{exp}`, `expected ${ordinalCall} "${spyName}" call to not ${action} #{exp}`, value, result?.value);
|
|
1300
|
+
});
|
|
1301
|
+
});
|
|
1302
|
+
def("withContext", function(context) {
|
|
1303
|
+
for (const key in context) utils.flag(this, key, context[key]);
|
|
1304
|
+
return this;
|
|
1305
|
+
});
|
|
1306
|
+
utils.addProperty(chai.Assertion.prototype, "resolves", function __VITEST_RESOLVES__() {
|
|
1307
|
+
const error = /* @__PURE__ */ new Error("resolves");
|
|
1308
|
+
utils.flag(this, "promise", "resolves");
|
|
1309
|
+
utils.flag(this, "error", error);
|
|
1310
|
+
const test = utils.flag(this, "vitest-test");
|
|
1311
|
+
const obj = utils.flag(this, "object");
|
|
1312
|
+
if (utils.flag(this, "poll")) throw new SyntaxError(`expect.poll() is not supported in combination with .resolves`);
|
|
1313
|
+
if (typeof obj?.then !== "function") throw new TypeError(`You must provide a Promise to expect() when using .resolves, not '${typeof obj}'.`);
|
|
1314
|
+
const proxy = new Proxy(this, { get: (target, key, receiver) => {
|
|
1315
|
+
const result = Reflect.get(target, key, receiver);
|
|
1316
|
+
if (typeof result !== "function") return result instanceof chai.Assertion ? proxy : result;
|
|
1317
|
+
return (...args) => {
|
|
1318
|
+
utils.flag(this, "_name", key);
|
|
1319
|
+
const promise = Promise.resolve(obj).then((value) => {
|
|
1320
|
+
utils.flag(this, "object", value);
|
|
1321
|
+
return result.call(this, ...args);
|
|
1322
|
+
}, (err) => {
|
|
1323
|
+
const _error = new AssertionError(`promise rejected "${utils.inspect(err)}" instead of resolving`, { showDiff: false });
|
|
1324
|
+
_error.cause = err;
|
|
1325
|
+
throw _error;
|
|
1326
|
+
}).catch((err) => {
|
|
1327
|
+
if (isError(err) && error.stack) err.stack = error.stack.replace(error.message, err.message);
|
|
1328
|
+
throw err;
|
|
1329
|
+
});
|
|
1330
|
+
return recordAsyncExpect(test, promise, createAssertionMessage(utils, this, !!args.length), error, utils.flag(this, "soft"));
|
|
1331
|
+
};
|
|
1332
|
+
} });
|
|
1333
|
+
return proxy;
|
|
1334
|
+
});
|
|
1335
|
+
utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() {
|
|
1336
|
+
const error = /* @__PURE__ */ new Error("rejects");
|
|
1337
|
+
utils.flag(this, "promise", "rejects");
|
|
1338
|
+
utils.flag(this, "error", error);
|
|
1339
|
+
const test = utils.flag(this, "vitest-test");
|
|
1340
|
+
const obj = utils.flag(this, "object");
|
|
1341
|
+
const wrapper = typeof obj === "function" ? obj() : obj;
|
|
1342
|
+
if (utils.flag(this, "poll")) throw new SyntaxError(`expect.poll() is not supported in combination with .rejects`);
|
|
1343
|
+
if (typeof wrapper?.then !== "function") throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`);
|
|
1344
|
+
const proxy = new Proxy(this, { get: (target, key, receiver) => {
|
|
1345
|
+
const result = Reflect.get(target, key, receiver);
|
|
1346
|
+
if (typeof result !== "function") return result instanceof chai.Assertion ? proxy : result;
|
|
1347
|
+
return (...args) => {
|
|
1348
|
+
utils.flag(this, "_name", key);
|
|
1349
|
+
const promise = Promise.resolve(wrapper).then((value) => {
|
|
1350
|
+
throw new AssertionError(`promise resolved "${utils.inspect(value)}" instead of rejecting`, {
|
|
1351
|
+
showDiff: true,
|
|
1352
|
+
expected: /* @__PURE__ */ new Error("rejected promise"),
|
|
1353
|
+
actual: value
|
|
1354
|
+
});
|
|
1355
|
+
}, (err) => {
|
|
1356
|
+
utils.flag(this, "object", err);
|
|
1357
|
+
return result.call(this, ...args);
|
|
1358
|
+
}).catch((err) => {
|
|
1359
|
+
if (isError(err) && error.stack) err.stack = error.stack.replace(error.message, err.message);
|
|
1360
|
+
throw err;
|
|
1361
|
+
});
|
|
1362
|
+
return recordAsyncExpect(test, promise, createAssertionMessage(utils, this, !!args.length), error, utils.flag(this, "soft"));
|
|
1363
|
+
};
|
|
1364
|
+
} });
|
|
1365
|
+
return proxy;
|
|
1366
|
+
});
|
|
1367
|
+
};
|
|
1368
|
+
function formatCalls(spy, msg, showActualCall) {
|
|
1369
|
+
if (spy.mock.calls.length) msg += y.gray(`\n\nReceived:\n\n${spy.mock.calls.map((callArg, i) => {
|
|
1370
|
+
let methodCall = y.bold(` ${ordinal(i + 1)} ${spy.getMockName()} call:\n\n`);
|
|
1371
|
+
if (showActualCall) methodCall += diff(showActualCall, callArg, { omitAnnotationLines: true });
|
|
1372
|
+
else methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n");
|
|
1373
|
+
methodCall += "\n";
|
|
1374
|
+
return methodCall;
|
|
1375
|
+
}).join("\n")}`);
|
|
1376
|
+
msg += y.gray(`\n\nNumber of calls: ${y.bold(spy.mock.calls.length)}\n`);
|
|
1377
|
+
return msg;
|
|
1378
|
+
}
|
|
1379
|
+
function formatReturns(spy, results, msg, showActualReturn) {
|
|
1380
|
+
if (results.length) msg += y.gray(`\n\nReceived:\n\n${results.map((callReturn, i) => {
|
|
1381
|
+
let methodCall = y.bold(` ${ordinal(i + 1)} ${spy.getMockName()} call return:\n\n`);
|
|
1382
|
+
if (showActualReturn) methodCall += diff(showActualReturn, callReturn.value, { omitAnnotationLines: true });
|
|
1383
|
+
else methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n");
|
|
1384
|
+
methodCall += "\n";
|
|
1385
|
+
return methodCall;
|
|
1386
|
+
}).join("\n")}`);
|
|
1387
|
+
msg += y.gray(`\n\nNumber of calls: ${y.bold(spy.mock.calls.length)}\n`);
|
|
1388
|
+
return msg;
|
|
1389
|
+
}
|
|
1390
|
+
function getMatcherState(assertion, expect) {
|
|
1391
|
+
const obj = assertion._obj;
|
|
1392
|
+
const isNot = utils_exports.flag(assertion, "negate");
|
|
1393
|
+
const promise = utils_exports.flag(assertion, "promise") || "";
|
|
1394
|
+
const customMessage = utils_exports.flag(assertion, "message");
|
|
1395
|
+
const jestUtils = {
|
|
1396
|
+
...getMatcherUtils(),
|
|
1397
|
+
diff,
|
|
1398
|
+
stringify,
|
|
1399
|
+
iterableEquality,
|
|
1400
|
+
subsetEquality
|
|
1401
|
+
};
|
|
1402
|
+
let task = utils_exports.flag(assertion, "vitest-test");
|
|
1403
|
+
const currentTestName = task?.fullTestName ?? "";
|
|
1404
|
+
if (task?.type !== "test") task = void 0;
|
|
1405
|
+
const matcherState = {
|
|
1406
|
+
...getState(expect),
|
|
1407
|
+
currentTestName,
|
|
1408
|
+
customTesters: getCustomEqualityTesters(),
|
|
1409
|
+
isNot,
|
|
1410
|
+
utils: jestUtils,
|
|
1411
|
+
promise,
|
|
1412
|
+
equals,
|
|
1413
|
+
suppressedErrors: [],
|
|
1414
|
+
soft: utils_exports.flag(assertion, "soft"),
|
|
1415
|
+
poll: utils_exports.flag(assertion, "poll"),
|
|
1416
|
+
assertion
|
|
1417
|
+
};
|
|
1418
|
+
Object.assign(matcherState, { task });
|
|
1419
|
+
return {
|
|
1420
|
+
state: matcherState,
|
|
1421
|
+
isNot,
|
|
1422
|
+
obj,
|
|
1423
|
+
customMessage
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
var JestExtendError = class extends Error {
|
|
1427
|
+
constructor(message, actual, expected, __vitest_error_context__) {
|
|
1428
|
+
super(message);
|
|
1429
|
+
this.actual = actual;
|
|
1430
|
+
this.expected = expected;
|
|
1431
|
+
this.__vitest_error_context__ = __vitest_error_context__;
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1434
|
+
function JestExtendPlugin(c, expect, matchers) {
|
|
1435
|
+
return (_, utils) => {
|
|
1436
|
+
Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
|
|
1437
|
+
function __VITEST_EXTEND_ASSERTION__(...args) {
|
|
1438
|
+
const { state, isNot, obj, customMessage } = getMatcherState(this, expect);
|
|
1439
|
+
const result = expectAssertion.call(state, obj, ...args);
|
|
1440
|
+
if (result && typeof result === "object" && typeof result.then === "function") return result.then(({ pass, message, actual, expected, meta }) => {
|
|
1441
|
+
if (pass && isNot || !pass && !isNot) throw new JestExtendError((customMessage ? `${customMessage}: ` : "") + message(), actual, expected, {
|
|
1442
|
+
assertionName: expectAssertionName,
|
|
1443
|
+
meta
|
|
1444
|
+
});
|
|
1445
|
+
});
|
|
1446
|
+
const { pass, message, actual, expected, meta } = result;
|
|
1447
|
+
if (pass && isNot || !pass && !isNot) throw new JestExtendError((customMessage ? `${customMessage}: ` : "") + message(), actual, expected, {
|
|
1448
|
+
assertionName: expectAssertionName,
|
|
1449
|
+
meta
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
const softWrapper = wrapAssertion(utils, expectAssertionName, __VITEST_EXTEND_ASSERTION__);
|
|
1453
|
+
utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, softWrapper);
|
|
1454
|
+
utils.addMethod(c.Assertion.prototype, expectAssertionName, softWrapper);
|
|
1455
|
+
if (expectAssertion.__vitest_poll_takeover__) {
|
|
1456
|
+
const addedMethod = c.Assertion.prototype[expectAssertionName];
|
|
1457
|
+
Object.defineProperty(addedMethod, "__vitest_poll_takeover__", { value: true });
|
|
1458
|
+
}
|
|
1459
|
+
class CustomMatcher extends AsymmetricMatcher {
|
|
1460
|
+
constructor(inverse = false, ...sample) {
|
|
1461
|
+
super(sample, inverse);
|
|
1462
|
+
}
|
|
1463
|
+
asymmetricMatch(other) {
|
|
1464
|
+
const { pass } = expectAssertion.call(this.getMatcherContext(expect), other, ...this.sample);
|
|
1465
|
+
return this.inverse ? !pass : pass;
|
|
1466
|
+
}
|
|
1467
|
+
toString() {
|
|
1468
|
+
return `${this.inverse ? "not." : ""}${expectAssertionName}`;
|
|
1469
|
+
}
|
|
1470
|
+
getExpectedType() {
|
|
1471
|
+
return "any";
|
|
1472
|
+
}
|
|
1473
|
+
toAsymmetricMatcher() {
|
|
1474
|
+
return `${this.toString()}<${this.sample.map((item) => stringify(item)).join(", ")}>`;
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
const customMatcher = (...sample) => new CustomMatcher(false, ...sample);
|
|
1478
|
+
Object.defineProperty(expect, expectAssertionName, {
|
|
1479
|
+
configurable: true,
|
|
1480
|
+
enumerable: true,
|
|
1481
|
+
value: customMatcher,
|
|
1482
|
+
writable: true
|
|
1483
|
+
});
|
|
1484
|
+
Object.defineProperty(expect.not, expectAssertionName, {
|
|
1485
|
+
configurable: true,
|
|
1486
|
+
enumerable: true,
|
|
1487
|
+
value: (...sample) => new CustomMatcher(true, ...sample),
|
|
1488
|
+
writable: true
|
|
1489
|
+
});
|
|
1490
|
+
Object.defineProperty(globalThis[ASYMMETRIC_MATCHERS_OBJECT], expectAssertionName, {
|
|
1491
|
+
configurable: true,
|
|
1492
|
+
enumerable: true,
|
|
1493
|
+
value: customMatcher,
|
|
1494
|
+
writable: true
|
|
1495
|
+
});
|
|
1496
|
+
});
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
const JestExtend = (chai, utils) => {
|
|
1500
|
+
utils.addMethod(chai.expect, "extend", (expect, expects) => {
|
|
1501
|
+
use(JestExtendPlugin(chai, expect, expects));
|
|
1502
|
+
});
|
|
1503
|
+
};
|
|
1504
|
+
//#endregion
|
|
1505
|
+
export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, ChaiStyleAssertions, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, SchemaMatching, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, chai_exports as chai, createAssertionMessage, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isError, isImmutableUnorderedKeyed, isImmutableUnorderedSet, isStandardSchema, iterableEquality, pluralize, recordAsyncExpect, setState, sparseArrayEquality, subsetEquality, typeEquality, wrapAssertion };
|
|
1506
|
+
|
|
1507
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJjIiwidXRpbCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9Adml0ZXN0K2V4cGVjdEA0LjEuMTAvbm9kZV9tb2R1bGVzL0B2aXRlc3QvZXhwZWN0L2Rpc3QvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcHJpbnREaWZmT3JTdHJpbmdpZnksIGRpZmYgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2RpZmYnO1xuaW1wb3J0IHsgc3RyaW5naWZ5IH0gZnJvbSAnQHZpdGVzdC91dGlscy9kaXNwbGF5JztcbmltcG9ydCB7IGdldFR5cGUsIGlzT2JqZWN0LCBub29wLCBhc3NlcnRUeXBlcywgb3JkaW5hbCB9IGZyb20gJ0B2aXRlc3QvdXRpbHMvaGVscGVycyc7XG5pbXBvcnQgYyBmcm9tICd0aW55cmFpbmJvdyc7XG5pbXBvcnQgeyBpc01vY2tGdW5jdGlvbiB9IGZyb20gJ0B2aXRlc3Qvc3B5JztcbmltcG9ydCB7IHByb2Nlc3NFcnJvciB9IGZyb20gJ0B2aXRlc3QvdXRpbHMvZXJyb3InO1xuaW1wb3J0IHsgdXNlLCB1dGlsIH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQgKiBhcyBjaGFpIGZyb20gJ2NoYWknO1xuZXhwb3J0IHsgY2hhaSB9O1xuXG5jb25zdCBDaGFpU3R5bGVBc3NlcnRpb25zID0gKGNoYWksIHV0aWxzKSA9PiB7XG5cdGZ1bmN0aW9uIGRlZlByb3BlcnR5KG5hbWUsIGRlbGVnYXRlVG8pIHtcblx0XHR1dGlscy5hZGRQcm9wZXJ0eShjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIG5hbWUsIGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29uc3QgamVzdE1ldGhvZCA9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZVtkZWxlZ2F0ZVRvXTtcblx0XHRcdGlmICghamVzdE1ldGhvZCkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkZWxlZ2F0ZSB0byAke1N0cmluZyhkZWxlZ2F0ZVRvKX06IG1ldGhvZCBub3QgZm91bmQuIEVuc3VyZSBKZXN0Q2hhaUV4cGVjdCBwbHVnaW4gaXMgbG9hZGVkIGZpcnN0LmApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGplc3RNZXRob2QuY2FsbCh0aGlzKTtcblx0XHR9KTtcblx0fVxuXHRmdW5jdGlvbiBkZWZQcm9wZXJ0eVdpdGhBcmdzKG5hbWUsIGRlbGVnYXRlVG8sIC4uLmFyZ3MpIHtcblx0XHR1dGlscy5hZGRQcm9wZXJ0eShjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIG5hbWUsIGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29uc3QgamVzdE1ldGhvZCA9IGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZVtkZWxlZ2F0ZVRvXTtcblx0XHRcdGlmICghamVzdE1ldGhvZCkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkZWxlZ2F0ZSB0byAke1N0cmluZyhkZWxlZ2F0ZVRvKX06IG1ldGhvZCBub3QgZm91bmQuIEVuc3VyZSBKZXN0Q2hhaUV4cGVjdCBwbHVnaW4gaXMgbG9hZGVkIGZpcnN0LmApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGplc3RNZXRob2QuY2FsbCh0aGlzLCAuLi5hcmdzKTtcblx0XHR9KTtcblx0fVxuXHRmdW5jdGlvbiBkZWZNZXRob2QobmFtZSwgZGVsZWdhdGVUbykge1xuXHRcdHV0aWxzLmFkZE1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIG5hbWUsIGZ1bmN0aW9uKC4uLmFyZ3MpIHtcblx0XHRcdGNvbnN0IGplc3RNZXRob2QgPSBjaGFpLkFzc2VydGlvbi5wcm90b3R5cGVbZGVsZWdhdGVUb107XG5cdFx0XHRpZiAoIWplc3RNZXRob2QpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZGVsZWdhdGUgdG8gJHtTdHJpbmcoZGVsZWdhdGVUbyl9OiBtZXRob2Qgbm90IGZvdW5kLiBFbnN1cmUgSmVzdENoYWlFeHBlY3QgcGx1Z2luIGlzIGxvYWRlZCBmaXJzdC5gKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBqZXN0TWV0aG9kLmNhbGwodGhpcywgLi4uYXJncyk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gQVBJIHRvIChzb21ld2hhdCkgbWlycm9yIHNpbm9uLWNoYWlcblx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9zaW5vbi1jaGFpXG5cdGRlZlByb3BlcnR5KFwiY2FsbGVkXCIsIFwidG9IYXZlQmVlbkNhbGxlZFwiKTtcblx0ZGVmUHJvcGVydHkoXCJjYWxsZWRPbmNlXCIsIFwidG9IYXZlQmVlbkNhbGxlZE9uY2VcIik7XG5cdGRlZlByb3BlcnR5V2l0aEFyZ3MoXCJjYWxsZWRUd2ljZVwiLCBcInRvSGF2ZUJlZW5DYWxsZWRUaW1lc1wiLCAyKTtcblx0ZGVmUHJvcGVydHlXaXRoQXJncyhcImNhbGxlZFRocmljZVwiLCBcInRvSGF2ZUJlZW5DYWxsZWRUaW1lc1wiLCAzKTtcblx0ZGVmTWV0aG9kKFwiY2FsbENvdW50XCIsIFwidG9IYXZlQmVlbkNhbGxlZFRpbWVzXCIpO1xuXHRkZWZNZXRob2QoXCJjYWxsZWRXaXRoXCIsIFwidG9IYXZlQmVlbkNhbGxlZFdpdGhcIik7XG5cdGRlZk1ldGhvZChcImNhbGxlZE9uY2VXaXRoXCIsIFwidG9IYXZlQmVlbkNhbGxlZEV4YWN0bHlPbmNlV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwibGFzdENhbGxlZFdpdGhcIiwgXCJ0b0hhdmVCZWVuTGFzdENhbGxlZFdpdGhcIik7XG5cdGRlZk1ldGhvZChcIm50aENhbGxlZFdpdGhcIiwgXCJ0b0hhdmVCZWVuTnRoQ2FsbGVkV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwicmV0dXJuZWRcIiwgXCJ0b0hhdmVSZXR1cm5lZFwiKTtcblx0ZGVmTWV0aG9kKFwicmV0dXJuZWRXaXRoXCIsIFwidG9IYXZlUmV0dXJuZWRXaXRoXCIpO1xuXHRkZWZNZXRob2QoXCJyZXR1cm5lZFRpbWVzXCIsIFwidG9IYXZlUmV0dXJuZWRUaW1lc1wiKTtcblx0ZGVmTWV0aG9kKFwibGFzdFJldHVybmVkV2l0aFwiLCBcInRvSGF2ZUxhc3RSZXR1cm5lZFdpdGhcIik7XG5cdGRlZk1ldGhvZChcIm50aFJldHVybmVkV2l0aFwiLCBcInRvSGF2ZU50aFJldHVybmVkV2l0aFwiKTtcblx0ZGVmTWV0aG9kKFwiY2FsbGVkQmVmb3JlXCIsIFwidG9IYXZlQmVlbkNhbGxlZEJlZm9yZVwiKTtcblx0ZGVmTWV0aG9kKFwiY2FsbGVkQWZ0ZXJcIiwgXCJ0b0hhdmVCZWVuQ2FsbGVkQWZ0ZXJcIik7XG5cdC8vIFRPRE86IGltcGxlbWVudFxuXHQvLyBkZWZNZXRob2QoJ3Rocm93bicsICd0b0hhdmVUaHJvd24nKVxufTtcblxuY29uc3QgTUFUQ0hFUlNfT0JKRUNUID0gU3ltYm9sLmZvcihcIm1hdGNoZXJzLW9iamVjdFwiKTtcbmNvbnN0IEpFU1RfTUFUQ0hFUlNfT0JKRUNUID0gU3ltYm9sLmZvcihcIiQkamVzdC1tYXRjaGVycy1vYmplY3RcIik7XG5jb25zdCBHTE9CQUxfRVhQRUNUID0gU3ltYm9sLmZvcihcImV4cGVjdC1nbG9iYWxcIik7XG5jb25zdCBBU1lNTUVUUklDX01BVENIRVJTX09CSkVDVCA9IFN5bWJvbC5mb3IoXCJhc3ltbWV0cmljLW1hdGNoZXJzLW9iamVjdFwiKTtcblxuLy8gc2VsZWN0aXZlbHkgcG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2plc3QtY29tbXVuaXR5L2plc3QtZXh0ZW5kZWRcbmNvbnN0IGN1c3RvbU1hdGNoZXJzID0ge1xuXHR0b1NhdGlzZnkoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuXHRcdGNvbnN0IHsgcHJpbnRSZWNlaXZlZCwgcHJpbnRFeHBlY3RlZCwgbWF0Y2hlckhpbnQgfSA9IHRoaXMudXRpbHM7XG5cdFx0Y29uc3QgcGFzcyA9IGV4cGVjdGVkKGFjdHVhbCk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHBhc3MsXG5cdFx0XHRtZXNzYWdlOiAoKSA9PiBwYXNzID8gYFxcXG4ke21hdGNoZXJIaW50KFwiLm5vdC50b1NhdGlzZnlcIiwgXCJyZWNlaXZlZFwiLCBcIlwiKX1cblxuRXhwZWN0ZWQgdmFsdWUgdG8gbm90IHNhdGlzZnk6XG4ke21lc3NhZ2UgfHwgcHJpbnRFeHBlY3RlZChleHBlY3RlZCl9XG5SZWNlaXZlZDpcbiR7cHJpbnRSZWNlaXZlZChhY3R1YWwpfWAgOiBgXFxcbiR7bWF0Y2hlckhpbnQoXCIudG9TYXRpc2Z5XCIsIFwicmVjZWl2ZWRcIiwgXCJcIil9XG5cbkV4cGVjdGVkIHZhbHVlIHRvIHNhdGlzZnk6XG4ke21lc3NhZ2UgfHwgcHJpbnRFeHBlY3RlZChleHBlY3RlZCl9XG5cblJlY2VpdmVkOlxuJHtwcmludFJlY2VpdmVkKGFjdHVhbCl9YFxuXHRcdH07XG5cdH0sXG5cdHRvQmVPbmVPZihhY3R1YWwsIGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgeyBlcXVhbHMsIGN1c3RvbVRlc3RlcnMgfSA9IHRoaXM7XG5cdFx0Y29uc3QgeyBwcmludFJlY2VpdmVkLCBwcmludEV4cGVjdGVkLCBtYXRjaGVySGludCB9ID0gdGhpcy51dGlscztcblx0XHRsZXQgcGFzcztcblx0XHRpZiAoQXJyYXkuaXNBcnJheShleHBlY3RlZCkpIHtcblx0XHRcdHBhc3MgPSBleHBlY3RlZC5sZW5ndGggPT09IDAgfHwgZXhwZWN0ZWQuc29tZSgoaXRlbSkgPT4gZXF1YWxzKGl0ZW0sIGFjdHVhbCwgY3VzdG9tVGVzdGVycykpO1xuXHRcdH0gZWxzZSBpZiAoZXhwZWN0ZWQgaW5zdGFuY2VvZiBTZXQpIHtcblx0XHRcdHBhc3MgPSBleHBlY3RlZC5zaXplID09PSAwIHx8IGV4cGVjdGVkLmhhcyhhY3R1YWwpIHx8IFsuLi5leHBlY3RlZF0uc29tZSgoaXRlbSkgPT4gZXF1YWxzKGl0ZW0sIGFjdHVhbCwgY3VzdG9tVGVzdGVycykpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBZb3UgbXVzdCBwcm92aWRlIGFuIGFycmF5IG9yIHNldCB0byAke21hdGNoZXJIaW50KFwiLnRvQmVPbmVPZlwiKX0sIG5vdCAnJHt0eXBlb2YgZXhwZWN0ZWR9Jy5gKTtcblx0XHR9XG5cdFx0cmV0dXJuIHtcblx0XHRcdHBhc3MsXG5cdFx0XHRtZXNzYWdlOiAoKSA9PiBwYXNzID8gYFxcXG4ke21hdGNoZXJIaW50KFwiLm5vdC50b0JlT25lT2ZcIiwgXCJyZWNlaXZlZFwiLCBcIlwiKX1cblxuRXhwZWN0ZWQgdmFsdWUgdG8gbm90IGJlIG9uZSBvZjpcbiR7cHJpbnRFeHBlY3RlZChleHBlY3RlZCl9XG5SZWNlaXZlZDpcbiR7cHJpbnRSZWNlaXZlZChhY3R1YWwpfWAgOiBgXFxcbiR7bWF0Y2hlckhpbnQoXCIudG9CZU9uZU9mXCIsIFwicmVjZWl2ZWRcIiwgXCJcIil9XG5cbkV4cGVjdGVkIHZhbHVlIHRvIGJlIG9uZSBvZjpcbiR7cHJpbnRFeHBlY3RlZChleHBlY3RlZCl9XG5cblJlY2VpdmVkOlxuJHtwcmludFJlY2VpdmVkKGFjdHVhbCl9YFxuXHRcdH07XG5cdH1cbn07XG5cbmNvbnN0IEVYUEVDVEVEX0NPTE9SID0gYy5ncmVlbjtcbmNvbnN0IFJFQ0VJVkVEX0NPTE9SID0gYy5yZWQ7XG5jb25zdCBJTlZFUlRFRF9DT0xPUiA9IGMuaW52ZXJzZTtcbmNvbnN0IEJPTERfV0VJR0hUID0gYy5ib2xkO1xuY29uc3QgRElNX0NPTE9SID0gYy5kaW07XG5mdW5jdGlvbiBtYXRjaGVySGludChtYXRjaGVyTmFtZSwgcmVjZWl2ZWQgPSBcInJlY2VpdmVkXCIsIGV4cGVjdGVkID0gXCJleHBlY3RlZFwiLCBvcHRpb25zID0ge30pIHtcblx0Y29uc3QgeyBjb21tZW50ID0gXCJcIiwgaXNEaXJlY3RFeHBlY3RDYWxsID0gZmFsc2UsIGlzTm90ID0gZmFsc2UsIHByb21pc2UgPSBcIlwiLCBzZWNvbmRBcmd1bWVudCA9IFwiXCIsIGV4cGVjdGVkQ29sb3IgPSBFWFBFQ1RFRF9DT0xPUiwgcmVjZWl2ZWRDb2xvciA9IFJFQ0VJVkVEX0NPTE9SLCBzZWNvbmRBcmd1bWVudENvbG9yID0gRVhQRUNURURfQ09MT1IgfSA9IG9wdGlvbnM7XG5cdGxldCBoaW50ID0gXCJcIjtcblx0bGV0IGRpbVN0cmluZyA9IFwiZXhwZWN0XCI7XG5cdGlmICghaXNEaXJlY3RFeHBlY3RDYWxsICYmIHJlY2VpdmVkICE9PSBcIlwiKSB7XG5cdFx0aGludCArPSBESU1fQ09MT1IoYCR7ZGltU3RyaW5nfShgKSArIHJlY2VpdmVkQ29sb3IocmVjZWl2ZWQpO1xuXHRcdGRpbVN0cmluZyA9IFwiKVwiO1xuXHR9XG5cdGlmIChwcm9taXNlICE9PSBcIlwiKSB7XG5cdFx0aGludCArPSBESU1fQ09MT1IoYCR7ZGltU3RyaW5nfS5gKSArIHByb21pc2U7XG5cdFx0ZGltU3RyaW5nID0gXCJcIjtcblx0fVxuXHRpZiAoaXNOb3QpIHtcblx0XHRoaW50ICs9IGAke0RJTV9DT0xPUihgJHtkaW1TdHJpbmd9LmApfW5vdGA7XG5cdFx0ZGltU3RyaW5nID0gXCJcIjtcblx0fVxuXHRpZiAobWF0Y2hlck5hbWUuaW5jbHVkZXMoXCIuXCIpKSB7XG5cdFx0Ly8gT2xkIGZvcm1hdDogZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksXG5cdFx0Ly8gZXNwZWNpYWxseSB3aXRob3V0IHByb21pc2Ugb3IgaXNOb3Qgb3B0aW9uc1xuXHRcdGRpbVN0cmluZyArPSBtYXRjaGVyTmFtZTtcblx0fSBlbHNlIHtcblx0XHQvLyBOZXcgZm9ybWF0OiBvbWl0IHBlcmlvZCBmcm9tIG1hdGNoZXJOYW1lIGFyZ1xuXHRcdGhpbnQgKz0gRElNX0NPTE9SKGAke2RpbVN0cmluZ30uYCkgKyBtYXRjaGVyTmFtZTtcblx0XHRkaW1TdHJpbmcgPSBcIlwiO1xuXHR9XG5cdGlmIChleHBlY3RlZCA9PT0gXCJcIikge1xuXHRcdGRpbVN0cmluZyArPSBcIigpXCI7XG5cdH0gZWxzZSB7XG5cdFx0aGludCArPSBESU1fQ09MT1IoYCR7ZGltU3RyaW5nfShgKSArIGV4cGVjdGVkQ29sb3IoZXhwZWN0ZWQpO1xuXHRcdGlmIChzZWNvbmRBcmd1bWVudCkge1xuXHRcdFx0aGludCArPSBESU1fQ09MT1IoXCIsIFwiKSArIHNlY29uZEFyZ3VtZW50Q29sb3Ioc2Vjb25kQXJndW1lbnQpO1xuXHRcdH1cblx0XHRkaW1TdHJpbmcgPSBcIilcIjtcblx0fVxuXHRpZiAoY29tbWVudCAhPT0gXCJcIikge1xuXHRcdGRpbVN0cmluZyArPSBgIC8vICR7Y29tbWVudH1gO1xuXHR9XG5cdGlmIChkaW1TdHJpbmcgIT09IFwiXCIpIHtcblx0XHRoaW50ICs9IERJTV9DT0xPUihkaW1TdHJpbmcpO1xuXHR9XG5cdHJldHVybiBoaW50O1xufVxuY29uc3QgU1BBQ0VfU1lNQk9MID0gXCLCt1wiO1xuLy8gSW5zdGVhZCBvZiBpbnZlcnNlIGhpZ2hsaWdodCB3aGljaCBub3cgaW1wbGllcyBhIGNoYW5nZSxcbi8vIHJlcGxhY2UgY29tbW9uIHNwYWNlcyB3aXRoIG1pZGRsZSBkb3QgYXQgdGhlIGVuZCBvZiBhbnkgbGluZS5cbmZ1bmN0aW9uIHJlcGxhY2VUcmFpbGluZ1NwYWNlcyh0ZXh0KSB7XG5cdHJldHVybiB0ZXh0LnJlcGxhY2UoL1xccyskL2dtLCAoc3BhY2VzKSA9PiBTUEFDRV9TWU1CT0wucmVwZWF0KHNwYWNlcy5sZW5ndGgpKTtcbn1cbmZ1bmN0aW9uIHByaW50UmVjZWl2ZWQob2JqZWN0KSB7XG5cdHJldHVybiBSRUNFSVZFRF9DT0xPUihyZXBsYWNlVHJhaWxpbmdTcGFjZXMoc3RyaW5naWZ5KG9iamVjdCkpKTtcbn1cbmZ1bmN0aW9uIHByaW50RXhwZWN0ZWQodmFsdWUpIHtcblx0cmV0dXJuIEVYUEVDVEVEX0NPTE9SKHJlcGxhY2VUcmFpbGluZ1NwYWNlcyhzdHJpbmdpZnkodmFsdWUpKSk7XG59XG5mdW5jdGlvbiBnZXRNYXRjaGVyVXRpbHMoKSB7XG5cdHJldHVybiB7XG5cdFx0RVhQRUNURURfQ09MT1IsXG5cdFx0UkVDRUlWRURfQ09MT1IsXG5cdFx0SU5WRVJURURfQ09MT1IsXG5cdFx0Qk9MRF9XRUlHSFQsXG5cdFx0RElNX0NPTE9SLFxuXHRcdGRpZmYsXG5cdFx0bWF0Y2hlckhpbnQsXG5cdFx0cHJpbnRSZWNlaXZlZCxcblx0XHRwcmludEV4cGVjdGVkLFxuXHRcdHByaW50RGlmZk9yU3RyaW5naWZ5LFxuXHRcdHByaW50V2l0aFR5cGVcblx0fTtcbn1cbmZ1bmN0aW9uIHByaW50V2l0aFR5cGUobmFtZSwgdmFsdWUsIHByaW50KSB7XG5cdGNvbnN0IHR5cGUgPSBnZXRUeXBlKHZhbHVlKTtcblx0Y29uc3QgaGFzVHlwZSA9IHR5cGUgIT09IFwibnVsbFwiICYmIHR5cGUgIT09IFwidW5kZWZpbmVkXCIgPyBgJHtuYW1lfSBoYXMgdHlwZTogICR7dHlwZX1cXG5gIDogXCJcIjtcblx0Y29uc3QgaGFzVmFsdWUgPSBgJHtuYW1lfSBoYXMgdmFsdWU6ICR7cHJpbnQodmFsdWUpfWA7XG5cdHJldHVybiBoYXNUeXBlICsgaGFzVmFsdWU7XG59XG5mdW5jdGlvbiBhZGRDdXN0b21FcXVhbGl0eVRlc3RlcnMobmV3VGVzdGVycykge1xuXHRpZiAoIUFycmF5LmlzQXJyYXkobmV3VGVzdGVycykpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBleHBlY3QuY3VzdG9tRXF1YWxpdHlUZXN0ZXJzOiBNdXN0IGJlIHNldCB0byBhbiBhcnJheSBvZiBUZXN0ZXJzLiBXYXMgZ2l2ZW4gXCIke2dldFR5cGUobmV3VGVzdGVycyl9XCJgKTtcblx0fVxuXHRnbG9iYWxUaGlzW0pFU1RfTUFUQ0hFUlNfT0JKRUNUXS5jdXN0b21FcXVhbGl0eVRlc3RlcnMucHVzaCguLi5uZXdUZXN0ZXJzKTtcbn1cbmZ1bmN0aW9uIGdldEN1c3RvbUVxdWFsaXR5VGVzdGVycygpIHtcblx0cmV0dXJuIGdsb2JhbFRoaXNbSkVTVF9NQVRDSEVSU19PQkpFQ1RdLmN1c3RvbUVxdWFsaXR5VGVzdGVycztcbn1cblxuLy8gRXh0cmFjdGVkIG91dCBvZiBqYXNtaW5lIDIuNS4yXG5mdW5jdGlvbiBlcXVhbHMoYSwgYiwgY3VzdG9tVGVzdGVycywgc3RyaWN0Q2hlY2spIHtcblx0Y3VzdG9tVGVzdGVycyA9IGN1c3RvbVRlc3RlcnMgfHwgW107XG5cdHJldHVybiBlcShhLCBiLCBbXSwgW10sIGN1c3RvbVRlc3RlcnMsIHN0cmljdENoZWNrID8gaGFzS2V5IDogaGFzRGVmaW5lZEtleSk7XG59XG5jb25zdCBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuZnVuY3Rpb24gaXNBc3ltbWV0cmljKG9iaikge1xuXHRyZXR1cm4gISFvYmogJiYgdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiAmJiBcImFzeW1tZXRyaWNNYXRjaFwiIGluIG9iaiAmJiBpc0EoXCJGdW5jdGlvblwiLCBvYmouYXN5bW1ldHJpY01hdGNoKTtcbn1cbmZ1bmN0aW9uIGhhc0FzeW1tZXRyaWMob2JqLCBzZWVuID0gbmV3IFNldCgpKSB7XG5cdGlmIChzZWVuLmhhcyhvYmopKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHNlZW4uYWRkKG9iaik7XG5cdGlmIChpc0FzeW1tZXRyaWMob2JqKSkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcblx0XHRyZXR1cm4gb2JqLnNvbWUoKGkpID0+IGhhc0FzeW1tZXRyaWMoaSwgc2VlbikpO1xuXHR9XG5cdGlmIChvYmogaW5zdGFuY2VvZiBTZXQpIHtcblx0XHRyZXR1cm4gQXJyYXkuZnJvbShvYmopLnNvbWUoKGkpID0+IGhhc0FzeW1tZXRyaWMoaSwgc2VlbikpO1xuXHR9XG5cdGlmIChpc09iamVjdChvYmopKSB7XG5cdFx0cmV0dXJuIE9iamVjdC52YWx1ZXMob2JqKS5zb21lKCh2KSA9PiBoYXNBc3ltbWV0cmljKHYsIHNlZW4pKTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBhc3ltbWV0cmljTWF0Y2goYSwgYiwgY3VzdG9tVGVzdGVycykge1xuXHRjb25zdCBhc3ltbWV0cmljQSA9IGlzQXN5bW1ldHJpYyhhKTtcblx0Y29uc3QgYXN5bW1ldHJpY0IgPSBpc0FzeW1tZXRyaWMoYik7XG5cdGlmIChhc3ltbWV0cmljQSAmJiBhc3ltbWV0cmljQikge1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0aWYgKGFzeW1tZXRyaWNBKSB7XG5cdFx0cmV0dXJuIGEuYXN5bW1ldHJpY01hdGNoKGIsIGN1c3RvbVRlc3RlcnMpO1xuXHR9XG5cdGlmIChhc3ltbWV0cmljQikge1xuXHRcdHJldHVybiBiLmFzeW1tZXRyaWNNYXRjaChhLCBjdXN0b21UZXN0ZXJzKTtcblx0fVxufVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2plc3Rqcy9qZXN0L2Jsb2IvOTA1YmNiY2VkM2Q0MGNkZjdhYWRjNGNkZjZmYjczMWM0YmIzZGJlMy9wYWNrYWdlcy9leHBlY3QtdXRpbHMvc3JjL3V0aWxzLnRzI0w1MDlcbmZ1bmN0aW9uIGlzRXJyb3IodmFsdWUpIHtcblx0aWYgKHR5cGVvZiBFcnJvci5pc0Vycm9yID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRyZXR1cm4gRXJyb3IuaXNFcnJvcih2YWx1ZSk7XG5cdH1cblx0c3dpdGNoIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpKSB7XG5cdFx0Y2FzZSBcIltvYmplY3QgRXJyb3JdXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgRXhjZXB0aW9uXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IERPTUV4Y2VwdGlvbl1cIjogcmV0dXJuIHRydWU7XG5cdFx0ZGVmYXVsdDogcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgRXJyb3I7XG5cdH1cbn1cbi8vIEVxdWFsaXR5IGZ1bmN0aW9uIGxvdmluZ2x5IGFkYXB0ZWQgZnJvbSBpc0VxdWFsIGluXG4vLyAgIFtVbmRlcnNjb3JlXShodHRwOi8vdW5kZXJzY29yZWpzLm9yZylcbmZ1bmN0aW9uIGVxKGEsIGIsIGFTdGFjaywgYlN0YWNrLCBjdXN0b21UZXN0ZXJzLCBoYXNLZXkpIHtcblx0bGV0IHJlc3VsdCA9IHRydWU7XG5cdGNvbnN0IGFzeW1tZXRyaWNSZXN1bHQgPSBhc3ltbWV0cmljTWF0Y2goYSwgYiwgY3VzdG9tVGVzdGVycyk7XG5cdGlmIChhc3ltbWV0cmljUmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gYXN5bW1ldHJpY1Jlc3VsdDtcblx0fVxuXHRjb25zdCB0ZXN0ZXJDb250ZXh0ID0geyBlcXVhbHMgfTtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjdXN0b21UZXN0ZXJzLmxlbmd0aDsgaSsrKSB7XG5cdFx0Y29uc3QgY3VzdG9tVGVzdGVyUmVzdWx0ID0gY3VzdG9tVGVzdGVyc1tpXS5jYWxsKHRlc3RlckNvbnRleHQsIGEsIGIsIGN1c3RvbVRlc3RlcnMpO1xuXHRcdGlmIChjdXN0b21UZXN0ZXJSZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIGN1c3RvbVRlc3RlclJlc3VsdDtcblx0XHR9XG5cdH1cblx0aWYgKHR5cGVvZiBVUkwgPT09IFwiZnVuY3Rpb25cIiAmJiBhIGluc3RhbmNlb2YgVVJMICYmIGIgaW5zdGFuY2VvZiBVUkwpIHtcblx0XHRyZXR1cm4gYS5ocmVmID09PSBiLmhyZWY7XG5cdH1cblx0aWYgKE9iamVjdC5pcyhhLCBiKSkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdC8vIEEgc3RyaWN0IGNvbXBhcmlzb24gaXMgbmVjZXNzYXJ5IGJlY2F1c2UgYG51bGwgPT0gdW5kZWZpbmVkYC5cblx0aWYgKGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBhID09PSBiO1xuXHR9XG5cdGNvbnN0IGNsYXNzTmFtZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhKTtcblx0aWYgKGNsYXNzTmFtZSAhPT0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGIpKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHN3aXRjaCAoY2xhc3NOYW1lKSB7XG5cdFx0Y2FzZSBcIltvYmplY3QgQm9vbGVhbl1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBTdHJpbmddXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgTnVtYmVyXVwiOiBpZiAodHlwZW9mIGEgIT09IHR5cGVvZiBiKSB7XG5cdFx0XHQvLyBPbmUgaXMgYSBwcmltaXRpdmUsIG9uZSBhIGBuZXcgUHJpbWl0aXZlKClgXG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fSBlbHNlIGlmICh0eXBlb2YgYSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgYiAhPT0gXCJvYmplY3RcIikge1xuXHRcdFx0Ly8gYm90aCBhcmUgcHJvcGVyIHByaW1pdGl2ZXNcblx0XHRcdHJldHVybiBPYmplY3QuaXMoYSwgYik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGJvdGggYXJlIGBuZXcgUHJpbWl0aXZlKClgc1xuXHRcdFx0cmV0dXJuIE9iamVjdC5pcyhhLnZhbHVlT2YoKSwgYi52YWx1ZU9mKCkpO1xuXHRcdH1cblx0XHRjYXNlIFwiW29iamVjdCBEYXRlXVwiOiB7XG5cdFx0XHRjb25zdCBudW1BID0gK2E7XG5cdFx0XHRjb25zdCBudW1CID0gK2I7XG5cdFx0XHQvLyBDb2VyY2UgZGF0ZXMgdG8gbnVtZXJpYyBwcmltaXRpdmUgdmFsdWVzLiBEYXRlcyBhcmUgY29tcGFyZWQgYnkgdGhlaXJcblx0XHRcdC8vIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9ucy4gTm90ZSB0aGF0IGludmFsaWQgZGF0ZXMgd2l0aCBtaWxsaXNlY29uZCByZXByZXNlbnRhdGlvbnNcblx0XHRcdC8vIG9mIGBOYU5gIGFyZSBlcXVpdmFsZW50LlxuXHRcdFx0cmV0dXJuIG51bUEgPT09IG51bUIgfHwgTnVtYmVyLmlzTmFOKG51bUEpICYmIE51bWJlci5pc05hTihudW1CKTtcblx0XHR9XG5cdFx0Y2FzZSBcIltvYmplY3QgUmVnRXhwXVwiOiByZXR1cm4gYS5zb3VyY2UgPT09IGIuc291cmNlICYmIGEuZmxhZ3MgPT09IGIuZmxhZ3M7XG5cdFx0Y2FzZSBcIltvYmplY3QgVGVtcG9yYWwuSW5zdGFudF1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5ab25lZERhdGVUaW1lXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IFRlbXBvcmFsLlBsYWluRGF0ZVRpbWVdXCI6XG5cdFx0Y2FzZSBcIltvYmplY3QgVGVtcG9yYWwuUGxhaW5EYXRlXVwiOlxuXHRcdGNhc2UgXCJbb2JqZWN0IFRlbXBvcmFsLlBsYWluVGltZV1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5QbGFpblllYXJNb250aF1cIjpcblx0XHRjYXNlIFwiW29iamVjdCBUZW1wb3JhbC5QbGFpbk1vbnRoRGF5XVwiOiByZXR1cm4gYS5lcXVhbHMoYik7XG5cdFx0Y2FzZSBcIltvYmplY3QgVGVtcG9yYWwuRHVyYXRpb25dXCI6IHJldHVybiBhLnRvU3RyaW5nKCkgPT09IGIudG9TdHJpbmcoKTtcblx0fVxuXHRpZiAodHlwZW9mIGEgIT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGIgIT09IFwib2JqZWN0XCIpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0Ly8gVXNlIERPTTMgbWV0aG9kIGlzRXF1YWxOb2RlIChJRT49OSlcblx0aWYgKGlzRG9tTm9kZShhKSAmJiBpc0RvbU5vZGUoYikpIHtcblx0XHRyZXR1cm4gYS5pc0VxdWFsTm9kZShiKTtcblx0fVxuXHQvLyBVc2VkIHRvIGRldGVjdCBjaXJjdWxhciByZWZlcmVuY2VzLlxuXHRsZXQgbGVuZ3RoID0gYVN0YWNrLmxlbmd0aDtcblx0d2hpbGUgKGxlbmd0aC0tKSB7XG5cdFx0Ly8gTGluZWFyIHNlYXJjaC4gUGVyZm9ybWFuY2UgaXMgaW52ZXJzZWx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mXG5cdFx0Ly8gdW5pcXVlIG5lc3RlZCBzdHJ1Y3R1cmVzLlxuXHRcdC8vIGNpcmN1bGFyIHJlZmVyZW5jZXMgYXQgc2FtZSBkZXB0aCBhcmUgZXF1YWxcblx0XHQvLyBjaXJjdWxhciByZWZlcmVuY2UgaXMgbm90IGVxdWFsIHRvIG5vbi1jaXJjdWxhciBvbmVcblx0XHRpZiAoYVN0YWNrW2xlbmd0aF0gPT09IGEpIHtcblx0XHRcdHJldHVybiBiU3RhY2tbbGVuZ3RoXSA9PT0gYjtcblx0XHR9IGVsc2UgaWYgKGJTdGFja1tsZW5ndGhdID09PSBiKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdC8vIEFkZCB0aGUgZmlyc3Qgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cblx0YVN0YWNrLnB1c2goYSk7XG5cdGJTdGFjay5wdXNoKGIpO1xuXHQvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgYW5kIGFycmF5cy5cblx0Ly8gQ29tcGFyZSBhcnJheSBsZW5ndGhzIHRvIGRldGVybWluZSBpZiBhIGRlZXAgY29tcGFyaXNvbiBpcyBuZWNlc3NhcnkuXG5cdGlmIChjbGFzc05hbWUgPT09IFwiW29iamVjdCBBcnJheV1cIiAmJiBhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0aWYgKGlzRXJyb3IoYSkgJiYgaXNFcnJvcihiKSkge1xuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gaXNFcnJvckVxdWFsKGEsIGIsIGFTdGFjaywgYlN0YWNrLCBjdXN0b21UZXN0ZXJzLCBoYXNLZXkpO1xuXHRcdH0gZmluYWxseSB7XG5cdFx0XHRhU3RhY2sucG9wKCk7XG5cdFx0XHRiU3RhY2sucG9wKCk7XG5cdFx0fVxuXHR9XG5cdC8vIERlZXAgY29tcGFyZSBvYmplY3RzLlxuXHRjb25zdCBhS2V5cyA9IGtleXMoYSwgaGFzS2V5KTtcblx0bGV0IGtleTtcblx0bGV0IHNpemUgPSBhS2V5cy5sZW5ndGg7XG5cdC8vIEVuc3VyZSB0aGF0IGJvdGggb2JqZWN0cyBjb250YWluIHRoZSBzYW1lIG51bWJlciBvZiBwcm9wZXJ0aWVzIGJlZm9yZSBjb21wYXJpbmcgZGVlcCBlcXVhbGl0eS5cblx0aWYgKGtleXMoYiwgaGFzS2V5KS5sZW5ndGggIT09IHNpemUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0d2hpbGUgKHNpemUtLSkge1xuXHRcdGtleSA9IGFLZXlzW3NpemVdO1xuXHRcdC8vIERlZXAgY29tcGFyZSBlYWNoIG1lbWJlclxuXHRcdHJlc3VsdCA9IGhhc0tleShiLCBrZXkpICYmIGVxKGFba2V5XSwgYltrZXldLCBhU3RhY2ssIGJTdGFjaywgY3VzdG9tVGVzdGVycywgaGFzS2V5KTtcblx0XHRpZiAoIXJlc3VsdCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXHQvLyBSZW1vdmUgdGhlIGZpcnN0IG9iamVjdCBmcm9tIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cblx0YVN0YWNrLnBvcCgpO1xuXHRiU3RhY2sucG9wKCk7XG5cdHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBpc0Vycm9yRXF1YWwoYSwgYiwgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSkge1xuXHQvLyBodHRwczovL25vZGVqcy5vcmcvZG9jcy9sYXRlc3QtdjIyLngvYXBpL2Fzc2VydC5odG1sI2NvbXBhcmlzb24tZGV0YWlsc1xuXHQvLyAtIFtbUHJvdG90eXBlXV0gb2Ygb2JqZWN0cyBhcmUgY29tcGFyZWQgdXNpbmcgdGhlID09PSBvcGVyYXRvci5cblx0Ly8gLSBPbmx5IGVudW1lcmFibGUgXCJvd25cIiBwcm9wZXJ0aWVzIGFyZSBjb25zaWRlcmVkLlxuXHQvLyAtIEVycm9yIG5hbWVzLCBtZXNzYWdlcywgY2F1c2VzLCBhbmQgZXJyb3JzIGFyZSBhbHdheXMgY29tcGFyZWQsIGV2ZW4gaWYgdGhlc2UgYXJlIG5vdCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIGVycm9ycyBpcyBhbHNvIGNvbXBhcmVkLlxuXHRsZXQgcmVzdWx0ID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGEpID09PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYikgJiYgYS5uYW1lID09PSBiLm5hbWUgJiYgYS5tZXNzYWdlID09PSBiLm1lc3NhZ2U7XG5cdC8vIGNoZWNrIEVycm9yLmNhdXNlIGFzeW1tZXRyaWNhbGx5XG5cdGlmICh0eXBlb2YgYi5jYXVzZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHRcdHJlc3VsdCAmJj0gZXEoYS5jYXVzZSwgYi5jYXVzZSwgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSk7XG5cdH1cblx0Ly8gQWdncmVnYXRlRXJyb3IuZXJyb3JzXG5cdGlmIChhIGluc3RhbmNlb2YgQWdncmVnYXRlRXJyb3IgJiYgYiBpbnN0YW5jZW9mIEFnZ3JlZ2F0ZUVycm9yKSB7XG5cdFx0cmVzdWx0ICYmPSBlcShhLmVycm9ycywgYi5lcnJvcnMsIGFTdGFjaywgYlN0YWNrLCBjdXN0b21UZXN0ZXJzLCBoYXNLZXkpO1xuXHR9XG5cdC8vIHNwcmVhZCB0byBjb21wYXJlIGVudW1lcmFibGUgcHJvcGVydGllc1xuXHRyZXN1bHQgJiY9IGVxKHsgLi4uYSB9LCB7IC4uLmIgfSwgYVN0YWNrLCBiU3RhY2ssIGN1c3RvbVRlc3RlcnMsIGhhc0tleSk7XG5cdHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBrZXlzKG9iaiwgaGFzS2V5KSB7XG5cdGNvbnN0IGtleXMgPSBbXTtcblx0Zm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XG5cdFx0aWYgKGhhc0tleShvYmosIGtleSkpIHtcblx0XHRcdGtleXMucHVzaChrZXkpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4ga2V5cy5jb25jYXQoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmopLmZpbHRlcigoc3ltYm9sKSA9PiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltYm9sKS5lbnVtZXJhYmxlKSk7XG59XG5mdW5jdGlvbiBoYXNEZWZpbmVkS2V5KG9iaiwga2V5KSB7XG5cdHJldHVybiBoYXNLZXkob2JqLCBrZXkpICYmIG9ialtrZXldICE9PSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBoYXNLZXkob2JqLCBrZXkpIHtcblx0cmV0dXJuIE9iamVjdC5oYXNPd24ob2JqLCBrZXkpO1xufVxuZnVuY3Rpb24gaXNBKHR5cGVOYW1lLCB2YWx1ZSkge1xuXHRyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSh2YWx1ZSkgPT09IGBbb2JqZWN0ICR7dHlwZU5hbWV9XWA7XG59XG5mdW5jdGlvbiBpc0RvbU5vZGUob2JqKSB7XG5cdHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiAmJiBcIm5vZGVUeXBlXCIgaW4gb2JqICYmIHR5cGVvZiBvYmoubm9kZVR5cGUgPT09IFwibnVtYmVyXCIgJiYgXCJub2RlTmFtZVwiIGluIG9iaiAmJiB0eXBlb2Ygb2JqLm5vZGVOYW1lID09PSBcInN0cmluZ1wiICYmIFwiaXNFcXVhbE5vZGVcIiBpbiBvYmogJiYgdHlwZW9mIG9iai5pc0VxdWFsTm9kZSA9PT0gXCJmdW5jdGlvblwiO1xufVxuZnVuY3Rpb24gZm5OYW1lRm9yKGZ1bmMpIHtcblx0aWYgKGZ1bmMubmFtZSkge1xuXHRcdHJldHVybiBmdW5jLm5hbWU7XG5cdH1cblx0Y29uc3QgbWF0Y2hlcyA9IGZ1bmN0aW9uVG9TdHJpbmcuY2FsbChmdW5jKS5tYXRjaCgvXig/OmFzeW5jKT9cXHMqZnVuY3Rpb25cXHMqKD86XFwqXFxzKik/KFtcXHckXSspXFxzKlxcKC8pO1xuXHRyZXR1cm4gbWF0Y2hlcyA/IG1hdGNoZXNbMV0gOiBcIjxhbm9ueW1vdXM+XCI7XG59XG5mdW5jdGlvbiBnZXRQcm90b3R5cGUob2JqKSB7XG5cdGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YpIHtcblx0XHRyZXR1cm4gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG5cdH1cblx0aWYgKG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IG9iaikge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cdHJldHVybiBvYmouY29uc3RydWN0b3IucHJvdG90eXBlO1xufVxuZnVuY3Rpb24gaGFzUHJvcGVydHkob2JqLCBwcm9wZXJ0eSkge1xuXHRpZiAoIW9iaikge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRpZiAoT2JqZWN0Lmhhc093bihvYmosIHByb3BlcnR5KSkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiBoYXNQcm9wZXJ0eShnZXRQcm90b3R5cGUob2JqKSwgcHJvcGVydHkpO1xufVxuLy8gU0VOVElORUwgY29uc3RhbnRzIGFyZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9pbW11dGFibGUtanNcbmNvbnN0IElTX0tFWUVEX1NFTlRJTkVMID0gXCJAQF9fSU1NVVRBQkxFX0tFWUVEX19AQFwiO1xuY29uc3QgSVNfU0VUX1NFTlRJTkVMID0gXCJAQF9fSU1NVVRBQkxFX1NFVF9fQEBcIjtcbmNvbnN0IElTX0xJU1RfU0VOVElORUwgPSBcIkBAX19JTU1VVEFCTEVfTElTVF9fQEBcIjtcbmNvbnN0IElTX09SREVSRURfU0VOVElORUwgPSBcIkBAX19JTU1VVEFCTEVfT1JERVJFRF9fQEBcIjtcbmNvbnN0IElTX1JFQ09SRF9TWU1CT0wgPSBcIkBAX19JTU1VVEFCTEVfUkVDT1JEX19AQFwiO1xuZnVuY3Rpb24gaXNJbW11dGFibGVVbm9yZGVyZWRLZXllZChtYXliZUtleWVkKSB7XG5cdHJldHVybiAhIShtYXliZUtleWVkICYmIG1heWJlS2V5ZWRbSVNfS0VZRURfU0VOVElORUxdICYmICFtYXliZUtleWVkW0lTX09SREVSRURfU0VOVElORUxdKTtcbn1cbmZ1bmN0aW9uIGlzSW1tdXRhYmxlVW5vcmRlcmVkU2V0KG1heWJlU2V0KSB7XG5cdHJldHVybiAhIShtYXliZVNldCAmJiBtYXliZVNldFtJU19TRVRfU0VOVElORUxdICYmICFtYXliZVNldFtJU19PUkRFUkVEX1NFTlRJTkVMXSk7XG59XG5mdW5jdGlvbiBpc09iamVjdExpdGVyYWwoc291cmNlKSB7XG5cdHJldHVybiBzb3VyY2UgIT0gbnVsbCAmJiB0eXBlb2Ygc291cmNlID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHNvdXJjZSk7XG59XG5mdW5jdGlvbiBpc0ltbXV0YWJsZUxpc3Qoc291cmNlKSB7XG5cdHJldHVybiBCb29sZWFuKHNvdXJjZSAmJiBpc09iamVjdExpdGVyYWwoc291cmNlKSAmJiBzb3VyY2VbSVNfTElTVF9TRU5USU5FTF0pO1xufVxuZnVuY3Rpb24gaXNJbW11dGFibGVPcmRlcmVkS2V5ZWQoc291cmNlKSB7XG5cdHJldHVybiBCb29sZWFuKHNvdXJjZSAmJiBpc09iamVjdExpdGVyYWwoc291cmNlKSAmJiBzb3VyY2VbSVNfS0VZRURfU0VOVElORUxdICYmIHNvdXJjZVtJU19PUkRFUkVEX1NFTlRJTkVMXSk7XG59XG5mdW5jdGlvbiBpc0ltbXV0YWJsZU9yZGVyZWRTZXQoc291cmNlKSB7XG5cdHJldHVybiBCb29sZWFuKHNvdXJjZSAmJiBpc09iamVjdExpdGVyYWwoc291cmNlKSAmJiBzb3VyY2VbSVNfU0VUX1NFTlRJTkVMXSAmJiBzb3VyY2VbSVNfT1JERVJFRF9TRU5USU5FTF0pO1xufVxuZnVuY3Rpb24gaXNJbW11dGFibGVSZWNvcmQoc291cmNlKSB7XG5cdHJldHVybiBCb29sZWFuKHNvdXJjZSAmJiBpc09iamVjdExpdGVyYWwoc291cmNlKSAmJiBzb3VyY2VbSVNfUkVDT1JEX1NZTUJPTF0pO1xufVxuLyoqXG4qIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuKlxuKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuKlxuKi9cbmNvbnN0IEl0ZXJhdG9yU3ltYm9sID0gU3ltYm9sLml0ZXJhdG9yO1xuZnVuY3Rpb24gaGFzSXRlcmF0b3Iob2JqZWN0KSB7XG5cdHJldHVybiAhIShvYmplY3QgIT0gbnVsbCAmJiBvYmplY3RbSXRlcmF0b3JTeW1ib2xdKTtcbn1cbmZ1bmN0aW9uIGl0ZXJhYmxlRXF1YWxpdHkoYSwgYiwgY3VzdG9tVGVzdGVycyA9IFtdLCBhU3RhY2sgPSBbXSwgYlN0YWNrID0gW10pIHtcblx0aWYgKHR5cGVvZiBhICE9PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBiICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoYSkgfHwgQXJyYXkuaXNBcnJheShiKSB8fCAhaGFzSXRlcmF0b3IoYSkgfHwgIWhhc0l0ZXJhdG9yKGIpKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXHRpZiAoYS5jb25zdHJ1Y3RvciAhPT0gYi5jb25zdHJ1Y3Rvcikge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRsZXQgbGVuZ3RoID0gYVN0YWNrLmxlbmd0aDtcblx0d2hpbGUgKGxlbmd0aC0tKSB7XG5cdFx0Ly8gTGluZWFyIHNlYXJjaC4gUGVyZm9ybWFuY2UgaXMgaW52ZXJzZWx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mXG5cdFx0Ly8gdW5pcXVlIG5lc3RlZCBzdHJ1Y3R1cmVzLlxuXHRcdC8vIGNpcmN1bGFyIHJlZmVyZW5jZXMgYXQgc2FtZSBkZXB0aCBhcmUgZXF1YWxcblx0XHQvLyBjaXJjdWxhciByZWZlcmVuY2UgaXMgbm90IGVxdWFsIHRvIG5vbi1jaXJjdWxhciBvbmVcblx0XHRpZiAoYVN0YWNrW2xlbmd0aF0gPT09IGEpIHtcblx0XHRcdHJldHVybiBiU3RhY2tbbGVuZ3RoXSA9PT0gYjtcblx0XHR9XG5cdH1cblx0YVN0YWNrLnB1c2goYSk7XG5cdGJTdGFjay5wdXNoKGIpO1xuXHRjb25zdCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMgPSBbLi4uY3VzdG9tVGVzdGVycy5maWx0ZXIoKHQpID0+IHQgIT09IGl0ZXJhYmxlRXF1YWxpdHkpLCBpdGVyYWJsZUVxdWFsaXR5V2l0aFN0YWNrXTtcblx0ZnVuY3Rpb24gaXRlcmFibGVFcXVhbGl0eVdpdGhTdGFjayhhLCBiKSB7XG5cdFx0cmV0dXJuIGl0ZXJhYmxlRXF1YWxpdHkoYSwgYiwgWy4uLmN1c3RvbVRlc3RlcnNdLCBbLi4uYVN0YWNrXSwgWy4uLmJTdGFja10pO1xuXHR9XG5cdGlmIChhLnNpemUgIT09IHVuZGVmaW5lZCkge1xuXHRcdGlmIChhLnNpemUgIT09IGIuc2l6ZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0gZWxzZSBpZiAoaXNBKFwiU2V0XCIsIGEpIHx8IGlzSW1tdXRhYmxlVW5vcmRlcmVkU2V0KGEpKSB7XG5cdFx0XHRsZXQgYWxsRm91bmQgPSB0cnVlO1xuXHRcdFx0Zm9yIChjb25zdCBhVmFsdWUgb2YgYSkge1xuXHRcdFx0XHRpZiAoIWIuaGFzKGFWYWx1ZSkpIHtcblx0XHRcdFx0XHRsZXQgaGFzID0gZmFsc2U7XG5cdFx0XHRcdFx0Zm9yIChjb25zdCBiVmFsdWUgb2YgYikge1xuXHRcdFx0XHRcdFx0Y29uc3QgaXNFcXVhbCA9IGVxdWFscyhhVmFsdWUsIGJWYWx1ZSwgZmlsdGVyZWRDdXN0b21UZXN0ZXJzKTtcblx0XHRcdFx0XHRcdGlmIChpc0VxdWFsID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdGhhcyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChoYXMgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHRhbGxGb3VuZCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvLyBSZW1vdmUgdGhlIGZpcnN0IHZhbHVlIGZyb20gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCB2YWx1ZXMuXG5cdFx0XHRhU3RhY2sucG9wKCk7XG5cdFx0XHRiU3RhY2sucG9wKCk7XG5cdFx0XHRyZXR1cm4gYWxsRm91bmQ7XG5cdFx0fSBlbHNlIGlmIChpc0EoXCJNYXBcIiwgYSkgfHwgaXNJbW11dGFibGVVbm9yZGVyZWRLZXllZChhKSkge1xuXHRcdFx0bGV0IGFsbEZvdW5kID0gdHJ1ZTtcblx0XHRcdGZvciAoY29uc3QgYUVudHJ5IG9mIGEpIHtcblx0XHRcdFx0aWYgKCFiLmhhcyhhRW50cnlbMF0pIHx8ICFlcXVhbHMoYUVudHJ5WzFdLCBiLmdldChhRW50cnlbMF0pLCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMpKSB7XG5cdFx0XHRcdFx0bGV0IGhhcyA9IGZhbHNlO1xuXHRcdFx0XHRcdGZvciAoY29uc3QgYkVudHJ5IG9mIGIpIHtcblx0XHRcdFx0XHRcdGNvbnN0IG1hdGNoZWRLZXkgPSBlcXVhbHMoYUVudHJ5WzBdLCBiRW50cnlbMF0sIGZpbHRlcmVkQ3VzdG9tVGVzdGVycyk7XG5cdFx0XHRcdFx0XHRsZXQgbWF0Y2hlZFZhbHVlID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRpZiAobWF0Y2hlZEtleSA9PT0gdHJ1ZSkge1xuXHRcdFx0XHRcdFx0XHRtYXRjaGVkVmFsdWUgPSBlcXVhbHMoYUVudHJ5WzFdLCBiRW50cnlbMV0sIGZpbHRlcmVkQ3VzdG9tVGVzdGVycyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAobWF0Y2hlZFZhbHVlID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdGhhcyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChoYXMgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHRhbGxGb3VuZCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvLyBSZW1vdmUgdGhlIGZpcnN0IHZhbHVlIGZyb20gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCB2YWx1ZXMuXG5cdFx0XHRhU3RhY2sucG9wKCk7XG5cdFx0XHRiU3RhY2sucG9wKCk7XG5cdFx0XHRyZXR1cm4gYWxsRm91bmQ7XG5cdFx0fVxuXHR9XG5cdGNvbnN0IGJJdGVyYXRvciA9IGJbSXRlcmF0b3JTeW1ib2xdKCk7XG5cdGZvciAoY29uc3QgYVZhbHVlIG9mIGEpIHtcblx0XHRjb25zdCBuZXh0QiA9IGJJdGVyYXRvci5uZXh0KCk7XG5cdFx0aWYgKG5leHRCLmRvbmUgfHwgIWVxdWFscyhhVmFsdWUsIG5leHRCLnZhbHVlLCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdGlmICghYkl0ZXJhdG9yLm5leHQoKS5kb25lKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmICghaXNJbW11dGFibGVMaXN0KGEpICYmICFpc0ltbXV0YWJsZU9yZGVyZWRLZXllZChhKSAmJiAhaXNJbW11dGFibGVPcmRlcmVkU2V0KGEpICYmICFpc0ltbXV0YWJsZVJlY29yZChhKSkge1xuXHRcdGNvbnN0IGFFbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoYSk7XG5cdFx0Y29uc3QgYkVudHJpZXMgPSBPYmplY3QuZW50cmllcyhiKTtcblx0XHRpZiAoIWVxdWFscyhhRW50cmllcywgYkVudHJpZXMsIGZpbHRlcmVkQ3VzdG9tVGVzdGVycykpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblx0Ly8gUmVtb3ZlIHRoZSBmaXJzdCB2YWx1ZSBmcm9tIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgdmFsdWVzLlxuXHRhU3RhY2sucG9wKCk7XG5cdGJTdGFjay5wb3AoKTtcblx0cmV0dXJuIHRydWU7XG59XG4vKipcbiogQ2hlY2tzIGlmIGBoYXNPd25Qcm9wZXJ0eShvYmplY3QsIGtleSlgIHVwIHRoZSBwcm90b3R5cGUgY2hhaW4sIHN0b3BwaW5nIGF0IGBPYmplY3QucHJvdG90eXBlYC5cbiovXG5mdW5jdGlvbiBoYXNQcm9wZXJ0eUluT2JqZWN0KG9iamVjdCwga2V5KSB7XG5cdGNvbnN0IHNob3VsZFRlcm1pbmF0ZSA9ICFvYmplY3QgfHwgdHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIiB8fCBvYmplY3QgPT09IE9iamVjdC5wcm90b3R5cGU7XG5cdGlmIChzaG91bGRUZXJtaW5hdGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0cmV0dXJuIE9iamVjdC5oYXNPd24ob2JqZWN0LCBrZXkpIHx8IGhhc1Byb3BlcnR5SW5PYmplY3QoT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCksIGtleSk7XG59XG5mdW5jdGlvbiBpc09iamVjdFdpdGhLZXlzKGEpIHtcblx0cmV0dXJuIGlzT2JqZWN0KGEpICYmICFpc0Vycm9yKGEpICYmICFBcnJheS5pc0FycmF5KGEpICYmICEoYSBpbnN0YW5jZW9mIERhdGUpICYmICEoYSBpbnN0YW5jZW9mIFNldCkgJiYgIShhIGluc3RhbmNlb2YgTWFwKTtcbn1cbmZ1bmN0aW9uIHN1YnNldEVxdWFsaXR5KG9iamVjdCwgc3Vic2V0LCBjdXN0b21UZXN0ZXJzID0gW10pIHtcblx0Y29uc3QgZmlsdGVyZWRDdXN0b21UZXN0ZXJzID0gY3VzdG9tVGVzdGVycy5maWx0ZXIoKHQpID0+IHQgIT09IHN1YnNldEVxdWFsaXR5KTtcblx0Ly8gc3Vic2V0RXF1YWxpdHkgbmVlZHMgdG8ga2VlcCB0cmFjayBvZiB0aGUgcmVmZXJlbmNlc1xuXHQvLyBpdCBoYXMgYWxyZWFkeSB2aXNpdGVkIHRvIGF2b2lkIGluZmluaXRlIGxvb3BzIGluIGNhc2Vcblx0Ly8gdGhlcmUgYXJlIGNpcmN1bGFyIHJlZmVyZW5jZXMgaW4gdGhlIHN1YnNldCBwYXNzZWQgdG8gaXQuXG5cdGNvbnN0IHN1YnNldEVxdWFsaXR5V2l0aENvbnRleHQgPSAoc2VlblJlZmVyZW5jZXMgPSBuZXcgV2Vha01hcCgpKSA9PiAob2JqZWN0LCBzdWJzZXQpID0+IHtcblx0XHRpZiAoIWlzT2JqZWN0V2l0aEtleXMoc3Vic2V0KSkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0cmV0dXJuIE9iamVjdC5rZXlzKHN1YnNldCkuZXZlcnkoKGtleSkgPT4ge1xuXHRcdFx0aWYgKHN1YnNldFtrZXldICE9IG51bGwgJiYgdHlwZW9mIHN1YnNldFtrZXldID09PSBcIm9iamVjdFwiKSB7XG5cdFx0XHRcdGlmIChzZWVuUmVmZXJlbmNlcy5oYXMoc3Vic2V0W2tleV0pKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGVxdWFscyhvYmplY3Rba2V5XSwgc3Vic2V0W2tleV0sIGZpbHRlcmVkQ3VzdG9tVGVzdGVycyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0c2VlblJlZmVyZW5jZXMuc2V0KHN1YnNldFtrZXldLCB0cnVlKTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IHJlc3VsdCA9IG9iamVjdCAhPSBudWxsICYmIGhhc1Byb3BlcnR5SW5PYmplY3Qob2JqZWN0LCBrZXkpICYmIGVxdWFscyhvYmplY3Rba2V5XSwgc3Vic2V0W2tleV0sIFsuLi5maWx0ZXJlZEN1c3RvbVRlc3RlcnMsIHN1YnNldEVxdWFsaXR5V2l0aENvbnRleHQoc2VlblJlZmVyZW5jZXMpXSk7XG5cdFx0XHQvLyBUaGUgbWFpbiBnb2FsIG9mIHVzaW5nIHNlZW5SZWZlcmVuY2UgaXMgdG8gYXZvaWQgY2lyY3VsYXIgbm9kZSBvbiB0cmVlLlxuXHRcdFx0Ly8gSXQgd2lsbCBvbmx5IGhhcHBlbiB3aXRoaW4gYSBwYXJlbnQgYW5kIGl0cyBjaGlsZCwgbm90IGEgbm9kZSBhbmQgbm9kZXMgbmV4dCB0byBpdCAoc2FtZSBsZXZlbClcblx0XHRcdC8vIFdlIHNob3VsZCBrZWVwIHRoZSByZWZlcmVuY2UgZm9yIGEgcGFyZW50IGFuZCBpdHMgY2hpbGQgb25seVxuXHRcdFx0Ly8gVGh1cyB3ZSBzaG91bGQgZGVsZXRlIHRoZSByZWZlcmVuY2UgaW1tZWRpYXRlbHkgc28gdGhhdCBpdCBkb2Vzbid0IGludGVyZmVyZVxuXHRcdFx0Ly8gb3RoZXIgbm9kZXMgd2l0aGluIHRoZSBzYW1lIGxldmVsIG9uIHRyZWUuXG5cdFx0XHRzZWVuUmVmZXJlbmNlcy5kZWxldGUoc3Vic2V0W2tleV0pO1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9KTtcblx0fTtcblx0cmV0dXJuIHN1YnNldEVxdWFsaXR5V2l0aENvbnRleHQoKShvYmplY3QsIHN1YnNldCk7XG59XG5mdW5jdGlvbiB0eXBlRXF1YWxpdHkoYSwgYikge1xuXHRpZiAoYSA9PSBudWxsIHx8IGIgPT0gbnVsbCB8fCBhLmNvbnN0cnVjdG9yID09PSBiLmNvbnN0cnVjdG9yKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBhcnJheUJ1ZmZlckVxdWFsaXR5KGEsIGIpIHtcblx0bGV0IGRhdGFWaWV3QSA9IGE7XG5cdGxldCBkYXRhVmlld0IgPSBiO1xuXHRpZiAoIShhIGluc3RhbmNlb2YgRGF0YVZpZXcgJiYgYiBpbnN0YW5jZW9mIERhdGFWaWV3KSkge1xuXHRcdGlmICghKGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgIShiIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHR0cnkge1xuXHRcdFx0ZGF0YVZpZXdBID0gbmV3IERhdGFWaWV3KGEpO1xuXHRcdFx0ZGF0YVZpZXdCID0gbmV3IERhdGFWaWV3KGIpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0Ly8gQnVmZmVycyBhcmUgbm90IGVxdWFsIHdoZW4gdGhleSBkbyBub3QgaGF2ZSB0aGUgc2FtZSBieXRlIGxlbmd0aFxuXHRpZiAoZGF0YVZpZXdBLmJ5dGVMZW5ndGggIT09IGRhdGFWaWV3Qi5ieXRlTGVuZ3RoKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdC8vIENoZWNrIGlmIGV2ZXJ5IGJ5dGUgdmFsdWUgaXMgZXF1YWwgdG8gZWFjaCBvdGhlclxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFWaWV3QS5ieXRlTGVuZ3RoOyBpKyspIHtcblx0XHRpZiAoZGF0YVZpZXdBLmdldFVpbnQ4KGkpICE9PSBkYXRhVmlld0IuZ2V0VWludDgoaSkpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBzcGFyc2VBcnJheUVxdWFsaXR5KGEsIGIsIGN1c3RvbVRlc3RlcnMgPSBbXSkge1xuXHRpZiAoIUFycmF5LmlzQXJyYXkoYSkgfHwgIUFycmF5LmlzQXJyYXkoYikpIHtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cdC8vIEEgc3BhcnNlIGFycmF5IFssICwgMV0gd2lsbCBoYXZlIGtleXMgW1wiMlwiXSB3aGVyZWFzIFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMV0gd2lsbCBoYXZlIGtleXMgW1wiMFwiLCBcIjFcIiwgXCIyXCJdXG5cdGNvbnN0IGFLZXlzID0gT2JqZWN0LmtleXMoYSk7XG5cdGNvbnN0IGJLZXlzID0gT2JqZWN0LmtleXMoYik7XG5cdGNvbnN0IGZpbHRlcmVkQ3VzdG9tVGVzdGVycyA9IGN1c3RvbVRlc3RlcnMuZmlsdGVyKCh0KSA9PiB0ICE9PSBzcGFyc2VBcnJheUVxdWFsaXR5KTtcblx0cmV0dXJuIGVxdWFscyhhLCBiLCBmaWx0ZXJlZEN1c3RvbVRlc3RlcnMsIHRydWUpICYmIGVxdWFscyhhS2V5cywgYktleXMpO1xufVxuZnVuY3Rpb24gZ2VuZXJhdGVUb0JlTWVzc2FnZShkZWVwRXF1YWxpdHlOYW1lLCBleHBlY3RlZCA9IFwiI3t0aGlzfVwiLCBhY3R1YWwgPSBcIiN7ZXhwfVwiKSB7XG5cdGNvbnN0IHRvQmVNZXNzYWdlID0gYGV4cGVjdGVkICR7ZXhwZWN0ZWR9IHRvIGJlICR7YWN0dWFsfSAvLyBPYmplY3QuaXMgZXF1YWxpdHlgO1xuXHRpZiAoW1widG9TdHJpY3RFcXVhbFwiLCBcInRvRXF1YWxcIl0uaW5jbHVkZXMoZGVlcEVxdWFsaXR5TmFtZSkpIHtcblx0XHRyZXR1cm4gYCR7dG9CZU1lc3NhZ2V9XFxuXFxuSWYgaXQgc2hvdWxkIHBhc3Mgd2l0aCBkZWVwIGVxdWFsaXR5LCByZXBsYWNlIFwidG9CZVwiIHdpdGggXCIke2RlZXBFcXVhbGl0eU5hbWV9XCJcXG5cXG5FeHBlY3RlZDogJHtleHBlY3RlZH1cXG5SZWNlaXZlZDogc2VyaWFsaXplcyB0byB0aGUgc2FtZSBzdHJpbmdcXG5gO1xuXHR9XG5cdHJldHVybiB0b0JlTWVzc2FnZTtcbn1cbmZ1bmN0aW9uIHBsdXJhbGl6ZSh3b3JkLCBjb3VudCkge1xuXHRyZXR1cm4gYCR7Y291bnR9ICR7d29yZH0ke2NvdW50ID09PSAxID8gXCJcIiA6IFwic1wifWA7XG59XG5mdW5jdGlvbiBnZXRPYmplY3RLZXlzKG9iamVjdCkge1xuXHRyZXR1cm4gWy4uLk9iamVjdC5rZXlzKG9iamVjdCksIC4uLk9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqZWN0KS5maWx0ZXIoKHMpID0+IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBzKT8uZW51bWVyYWJsZSldO1xufVxuZnVuY3Rpb24gZ2V0T2JqZWN0U3Vic2V0KG9iamVjdCwgc3Vic2V0LCBjdXN0b21UZXN0ZXJzKSB7XG5cdGxldCBzdHJpcHBlZCA9IDA7XG5cdGNvbnN0IGdldE9iamVjdFN1YnNldFdpdGhDb250ZXh0ID0gKHNlZW5SZWZlcmVuY2VzID0gbmV3IFdlYWtNYXAoKSkgPT4gKG9iamVjdCwgc3Vic2V0KSA9PiB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuXHRcdFx0aWYgKEFycmF5LmlzQXJyYXkoc3Vic2V0KSAmJiBzdWJzZXQubGVuZ3RoID09PSBvYmplY3QubGVuZ3RoKSB7XG5cdFx0XHRcdC8vIFRoZSBtYXAgbWV0aG9kIHJldHVybnMgY29ycmVjdCBzdWJjbGFzcyBvZiBzdWJzZXQuXG5cdFx0XHRcdHJldHVybiBzdWJzZXQubWFwKChzdWIsIGkpID0+IGdldE9iamVjdFN1YnNldFdpdGhDb250ZXh0KHNlZW5SZWZlcmVuY2VzKShvYmplY3RbaV0sIHN1YikpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAob2JqZWN0IGluc3RhbmNlb2YgRGF0ZSkge1xuXHRcdFx0cmV0dXJuIG9iamVjdDtcblx0XHR9IGVsc2UgaWYgKGlzT2JqZWN0KG9iamVjdCkgJiYgaXNPYmplY3Qoc3Vic2V0KSkge1xuXHRcdFx0aWYgKGVxdWFscyhvYmplY3QsIHN1YnNldCwgW1xuXHRcdFx0XHQuLi5jdXN0b21UZXN0ZXJzLFxuXHRcdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0XHRzdWJzZXRFcXVhbGl0eVxuXHRcdFx0XSkpIHtcblx0XHRcdFx0Ly8gcmV0dXJuIFwiZXhwZWN0ZWRcIiBzdWJzZXQgdG8gYXZvaWQgc2hvd2luZyBpcnJlbGV2YW50IHRvTWF0Y2hPYmplY3QgZGlmZlxuXHRcdFx0XHRyZXR1cm4gc3Vic2V0O1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgdHJpbW1lZCA9IHt9O1xuXHRcdFx0c2VlblJlZmVyZW5jZXMuc2V0KG9iamVjdCwgdHJpbW1lZCk7XG5cdFx0XHQvLyBwcmVzZXJ2ZSBjb25zdHJ1Y3RvciBmb3IgdG9NYXRjaE9iamVjdCBkaWZmXG5cdFx0XHRpZiAodHlwZW9mIG9iamVjdC5jb25zdHJ1Y3RvciA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IubmFtZSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkodHJpbW1lZCwgXCJjb25zdHJ1Y3RvclwiLCB7XG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dmFsdWU6IG9iamVjdC5jb25zdHJ1Y3RvclxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdGZvciAoY29uc3Qga2V5IG9mIGdldE9iamVjdEtleXMob2JqZWN0KSkge1xuXHRcdFx0XHRpZiAoaGFzUHJvcGVydHlJbk9iamVjdChzdWJzZXQsIGtleSkpIHtcblx0XHRcdFx0XHR0cmltbWVkW2tleV0gPSBzZWVuUmVmZXJlbmNlcy5oYXMob2JqZWN0W2tleV0pID8gc2VlblJlZmVyZW5jZXMuZ2V0KG9iamVjdFtrZXldKSA6IGdldE9iamVjdFN1YnNldFdpdGhDb250ZXh0KHNlZW5SZWZlcmVuY2VzKShvYmplY3Rba2V5XSwgc3Vic2V0W2tleV0pO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmICghc2VlblJlZmVyZW5jZXMuaGFzKG9iamVjdFtrZXldKSkge1xuXHRcdFx0XHRcdFx0c3RyaXBwZWQgKz0gMTtcblx0XHRcdFx0XHRcdGlmIChpc09iamVjdChvYmplY3Rba2V5XSkpIHtcblx0XHRcdFx0XHRcdFx0c3RyaXBwZWQgKz0gZ2V0T2JqZWN0S2V5cyhvYmplY3Rba2V5XSkubGVuZ3RoO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Z2V0T2JqZWN0U3Vic2V0V2l0aENvbnRleHQoc2VlblJlZmVyZW5jZXMpKG9iamVjdFtrZXldLCBzdWJzZXRba2V5XSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAoZ2V0T2JqZWN0S2V5cyh0cmltbWVkKS5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdHJldHVybiB0cmltbWVkO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gb2JqZWN0O1xuXHR9O1xuXHRyZXR1cm4ge1xuXHRcdHN1YnNldDogZ2V0T2JqZWN0U3Vic2V0V2l0aENvbnRleHQoKShvYmplY3QsIHN1YnNldCksXG5cdFx0c3RyaXBwZWRcblx0fTtcbn1cbi8qKlxuKiBEZXRlY3RzIGlmIGFuIG9iamVjdCBpcyBhIFN0YW5kYXJkIFNjaGVtYSBWMSBjb21wYXRpYmxlIHNjaGVtYVxuKi9cbmZ1bmN0aW9uIGlzU3RhbmRhcmRTY2hlbWEob2JqKSB7XG5cdHJldHVybiAhIW9iaiAmJiAodHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIpICYmIG9ialtcIn5zdGFuZGFyZFwiXSAmJiB0eXBlb2Ygb2JqW1wifnN0YW5kYXJkXCJdLnZhbGlkYXRlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbmlmICghT2JqZWN0Lmhhc093bihnbG9iYWxUaGlzLCBNQVRDSEVSU19PQkpFQ1QpKSB7XG5cdGNvbnN0IGdsb2JhbFN0YXRlID0gbmV3IFdlYWtNYXAoKTtcblx0Y29uc3QgbWF0Y2hlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXHRjb25zdCBjdXN0b21FcXVhbGl0eVRlc3RlcnMgPSBbXTtcblx0Y29uc3QgYXN5bW1ldHJpY01hdGNoZXJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbFRoaXMsIE1BVENIRVJTX09CSkVDVCwgeyBnZXQ6ICgpID0+IGdsb2JhbFN0YXRlIH0pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgSkVTVF9NQVRDSEVSU19PQkpFQ1QsIHtcblx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0Z2V0OiAoKSA9PiAoe1xuXHRcdFx0c3RhdGU6IGdsb2JhbFN0YXRlLmdldChnbG9iYWxUaGlzW0dMT0JBTF9FWFBFQ1RdKSxcblx0XHRcdG1hdGNoZXJzLFxuXHRcdFx0Y3VzdG9tRXF1YWxpdHlUZXN0ZXJzXG5cdFx0fSlcblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLCBBU1lNTUVUUklDX01BVENIRVJTX09CSkVDVCwgeyBnZXQ6ICgpID0+IGFzeW1tZXRyaWNNYXRjaGVycyB9KTtcbn1cbmZ1bmN0aW9uIGdldFN0YXRlKGV4cGVjdCkge1xuXHRyZXR1cm4gZ2xvYmFsVGhpc1tNQVRDSEVSU19PQkpFQ1RdLmdldChleHBlY3QpO1xufVxuZnVuY3Rpb24gc2V0U3RhdGUoc3RhdGUsIGV4cGVjdCkge1xuXHRjb25zdCBtYXAgPSBnbG9iYWxUaGlzW01BVENIRVJTX09CSkVDVF07XG5cdGNvbnN0IGN1cnJlbnQgPSBtYXAuZ2V0KGV4cGVjdCkgfHwge307XG5cdC8vIHNvIGl0IGtlZXBzIGdldHRlcnMgZnJvbSBgdGVzdFBhdGhgXG5cdGNvbnN0IHJlc3VsdHMgPSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjdXJyZW50LCB7XG5cdFx0Li4uT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoY3VycmVudCksXG5cdFx0Li4uT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc3RhdGUpXG5cdH0pO1xuXHRtYXAuc2V0KGV4cGVjdCwgcmVzdWx0cyk7XG59XG5cbmNsYXNzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Ly8gc2hvdWxkIGhhdmUgXCJqZXN0XCIgdG8gYmUgY29tcGF0aWJsZSB3aXRoIGl0cyBlY29zeXN0ZW1cblx0JCR0eXBlb2YgPSBTeW1ib2wuZm9yKFwiamVzdC5hc3ltbWV0cmljTWF0Y2hlclwiKTtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHR0aGlzLnNhbXBsZSA9IHNhbXBsZTtcblx0XHR0aGlzLmludmVyc2UgPSBpbnZlcnNlO1xuXHR9XG5cdGdldE1hdGNoZXJDb250ZXh0KGV4cGVjdCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHQuLi5nZXRTdGF0ZShleHBlY3QgfHwgZ2xvYmFsVGhpc1tHTE9CQUxfRVhQRUNUXSksXG5cdFx0XHRlcXVhbHMsXG5cdFx0XHRpc05vdDogdGhpcy5pbnZlcnNlLFxuXHRcdFx0Y3VzdG9tVGVzdGVyczogZ2V0Q3VzdG9tRXF1YWxpdHlUZXN0ZXJzKCksXG5cdFx0XHR1dGlsczoge1xuXHRcdFx0XHQuLi5nZXRNYXRjaGVyVXRpbHMoKSxcblx0XHRcdFx0ZGlmZixcblx0XHRcdFx0c3RyaW5naWZ5LFxuXHRcdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0XHRzdWJzZXRFcXVhbGl0eVxuXHRcdFx0fVxuXHRcdH07XG5cdH1cbn1cbi8vIGltcGxlbWVudCBjdXN0b20gY2hhaS9sb3VwZSBpbnNwZWN0IGZvciBiZXR0ZXIgQXNzZXJ0aW9uRXJyb3IubWVzc2FnZSBmb3JtYXR0aW5nXG4vLyBodHRwczovL2dpdGh1Yi5jb20vY2hhaWpzL2xvdXBlL2Jsb2IvOWI4YTZkZWFiY2Q1MGFkYzA1NmE2NGZiNzA1ODk2MTk0NzEwYzVjNi9zcmMvaW5kZXgudHMjTDI5XG4vLyBAdHMtZXhwZWN0LWVycm9yIGNvbXB1dGVkIHByb3BlcnRpZXMgaXMgbm90IHN1cHBvcnRlZCB3aGVuIGlzb2xhdGVkRGVjbGFyYXRpb25zIGlzIGVuYWJsZWRcbi8vIEZJWE1FOiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzYxMDY4XG5Bc3ltbWV0cmljTWF0Y2hlci5wcm90b3R5cGVbU3ltYm9sLmZvcihcImNoYWkvaW5zcGVjdFwiKV0gPSBmdW5jdGlvbihvcHRpb25zKSB7XG5cdC8vIG1pbmltYWwgcHJldHR5LWZvcm1hdCB3aXRoIHNpbXBsZSBtYW51YWwgdHJ1bmNhdGlvblxuXHRjb25zdCByZXN1bHQgPSBzdHJpbmdpZnkodGhpcywgb3B0aW9ucy5kZXB0aCwgeyBtaW46IHRydWUgfSk7XG5cdGlmIChyZXN1bHQubGVuZ3RoIDw9IG9wdGlvbnMudHJ1bmNhdGUpIHtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cdHJldHVybiBgJHt0aGlzLnRvU3RyaW5nKCl9e+KApn1gO1xufTtcbmNsYXNzIFN0cmluZ0NvbnRhaW5pbmcgZXh0ZW5kcyBBc3ltbWV0cmljTWF0Y2hlciB7XG5cdGNvbnN0cnVjdG9yKHNhbXBsZSwgaW52ZXJzZSA9IGZhbHNlKSB7XG5cdFx0aWYgKCFpc0EoXCJTdHJpbmdcIiwgc2FtcGxlKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgaXMgbm90IGEgc3RyaW5nXCIpO1xuXHRcdH1cblx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdGNvbnN0IHJlc3VsdCA9IGlzQShcIlN0cmluZ1wiLCBvdGhlcikgJiYgb3RoZXIuaW5jbHVkZXModGhpcy5zYW1wbGUpO1xuXHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcmVzdWx0IDogcmVzdWx0O1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgU3RyaW5nJHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1Db250YWluaW5nYDtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0cmV0dXJuIFwic3RyaW5nXCI7XG5cdH1cbn1cbmNsYXNzIEFueXRoaW5nIGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRhc3ltbWV0cmljTWF0Y2gob3RoZXIpIHtcblx0XHRyZXR1cm4gb3RoZXIgIT0gbnVsbDtcblx0fVxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gXCJBbnl0aGluZ1wiO1xuXHR9XG5cdHRvQXN5bW1ldHJpY01hdGNoZXIoKSB7XG5cdFx0cmV0dXJuIFwiQW55dGhpbmdcIjtcblx0fVxufVxuY2xhc3MgT2JqZWN0Q29udGFpbmluZyBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHR9XG5cdGdldFByb3RvdHlwZShvYmopIHtcblx0XHRpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKSB7XG5cdFx0XHRyZXR1cm4gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaik7XG5cdFx0fVxuXHRcdGlmIChvYmouY29uc3RydWN0b3IucHJvdG90eXBlID09PSBvYmopIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0XHRyZXR1cm4gb2JqLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblx0fVxuXHRoYXNQcm9wZXJ0eShvYmosIHByb3BlcnR5KSB7XG5cdFx0aWYgKCFvYmopIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKE9iamVjdC5oYXNPd24ob2JqLCBwcm9wZXJ0eSkpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5oYXNQcm9wZXJ0eSh0aGlzLmdldFByb3RvdHlwZShvYmopLCBwcm9wZXJ0eSk7XG5cdH1cblx0Z2V0UHJvcGVydGllcyhvYmopIHtcblx0XHRyZXR1cm4gWy4uLk9iamVjdC5rZXlzKG9iaiksIC4uLk9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKS5maWx0ZXIoKHMpID0+IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBzKT8uZW51bWVyYWJsZSldO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlciwgY3VzdG9tVGVzdGVycykge1xuXHRcdGlmICh0eXBlb2YgdGhpcy5zYW1wbGUgIT09IFwib2JqZWN0XCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYFlvdSBtdXN0IHByb3ZpZGUgYW4gb2JqZWN0IHRvICR7dGhpcy50b1N0cmluZygpfSwgbm90ICcke3R5cGVvZiB0aGlzLnNhbXBsZX0nLmApO1xuXHRcdH1cblx0XHRsZXQgcmVzdWx0ID0gdHJ1ZTtcblx0XHRjb25zdCBwcm9wZXJ0aWVzID0gdGhpcy5nZXRQcm9wZXJ0aWVzKHRoaXMuc2FtcGxlKTtcblx0XHRmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHByb3BlcnRpZXMpIHtcblx0XHRcdGlmICghdGhpcy5oYXNQcm9wZXJ0eShvdGhlciwgcHJvcGVydHkpKSB7XG5cdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNvbnN0IHZhbHVlID0gdGhpcy5zYW1wbGVbcHJvcGVydHldO1xuXHRcdFx0Y29uc3Qgb3RoZXJWYWx1ZSA9IG90aGVyW3Byb3BlcnR5XTtcblx0XHRcdGlmICghZXF1YWxzKHZhbHVlLCBvdGhlclZhbHVlLCBjdXN0b21UZXN0ZXJzKSkge1xuXHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcmVzdWx0IDogcmVzdWx0O1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgT2JqZWN0JHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1Db250YWluaW5nYDtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0cmV0dXJuIFwib2JqZWN0XCI7XG5cdH1cbn1cbmNsYXNzIEFycmF5Q29udGFpbmluZyBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlciwgY3VzdG9tVGVzdGVycykge1xuXHRcdGlmICghQXJyYXkuaXNBcnJheSh0aGlzLnNhbXBsZSkpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYFlvdSBtdXN0IHByb3ZpZGUgYW4gYXJyYXkgdG8gJHt0aGlzLnRvU3RyaW5nKCl9LCBub3QgJyR7dHlwZW9mIHRoaXMuc2FtcGxlfScuYCk7XG5cdFx0fVxuXHRcdGNvbnN0IHJlc3VsdCA9IHRoaXMuc2FtcGxlLmxlbmd0aCA9PT0gMCB8fCBBcnJheS5pc0FycmF5KG90aGVyKSAmJiB0aGlzLnNhbXBsZS5ldmVyeSgoaXRlbSkgPT4gb3RoZXIuc29tZSgoYW5vdGhlcikgPT4gZXF1YWxzKGl0ZW0sIGFub3RoZXIsIGN1c3RvbVRlc3RlcnMpKSk7XG5cdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFyZXN1bHQgOiByZXN1bHQ7XG5cdH1cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIGBBcnJheSR7dGhpcy5pbnZlcnNlID8gXCJOb3RcIiA6IFwiXCJ9Q29udGFpbmluZ2A7XG5cdH1cblx0Z2V0RXhwZWN0ZWRUeXBlKCkge1xuXHRcdHJldHVybiBcImFycmF5XCI7XG5cdH1cbn1cbmNsYXNzIEFueSBleHRlbmRzIEFzeW1tZXRyaWNNYXRjaGVyIHtcblx0Y29uc3RydWN0b3Ioc2FtcGxlKSB7XG5cdFx0aWYgKHR5cGVvZiBzYW1wbGUgPT09IFwidW5kZWZpbmVkXCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoXCJhbnkoKSBleHBlY3RzIHRvIGJlIHBhc3NlZCBhIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLiBcIiArIFwiUGxlYXNlIHBhc3Mgb25lIG9yIHVzZSBhbnl0aGluZygpIHRvIG1hdGNoIGFueSBvYmplY3QuXCIpO1xuXHRcdH1cblx0XHRzdXBlcihzYW1wbGUpO1xuXHR9XG5cdGZuTmFtZUZvcihmdW5jKSB7XG5cdFx0aWYgKGZ1bmMubmFtZSkge1xuXHRcdFx0cmV0dXJuIGZ1bmMubmFtZTtcblx0XHR9XG5cdFx0Y29uc3QgZnVuY3Rpb25Ub1N0cmluZyA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZztcblx0XHRjb25zdCBtYXRjaGVzID0gZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGZ1bmMpLm1hdGNoKC9eKD86YXN5bmMpP1xccypmdW5jdGlvblxccyooPzpcXCpcXHMqKT8oW1xcdyRdKylcXHMqXFwoLyk7XG5cdFx0cmV0dXJuIG1hdGNoZXMgPyBtYXRjaGVzWzFdIDogXCI8YW5vbnltb3VzPlwiO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gU3RyaW5nKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIG90aGVyID09IFwic3RyaW5nXCIgfHwgb3RoZXIgaW5zdGFuY2VvZiBTdHJpbmc7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gTnVtYmVyKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIG90aGVyID09IFwibnVtYmVyXCIgfHwgb3RoZXIgaW5zdGFuY2VvZiBOdW1iZXI7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gRnVuY3Rpb24pIHtcblx0XHRcdHJldHVybiB0eXBlb2Ygb3RoZXIgPT0gXCJmdW5jdGlvblwiIHx8IHR5cGVvZiBvdGhlciA9PT0gXCJmdW5jdGlvblwiO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IEJvb2xlYW4pIHtcblx0XHRcdHJldHVybiB0eXBlb2Ygb3RoZXIgPT0gXCJib29sZWFuXCIgfHwgb3RoZXIgaW5zdGFuY2VvZiBCb29sZWFuO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IEJpZ0ludCkge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiBvdGhlciA9PSBcImJpZ2ludFwiIHx8IG90aGVyIGluc3RhbmNlb2YgQmlnSW50O1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IFN5bWJvbCkge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiBvdGhlciA9PSBcInN5bWJvbFwiIHx8IG90aGVyIGluc3RhbmNlb2YgU3ltYm9sO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IE9iamVjdCkge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiBvdGhlciA9PSBcIm9iamVjdFwiO1xuXHRcdH1cblx0XHRyZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiB0aGlzLnNhbXBsZTtcblx0fVxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gXCJBbnlcIjtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBTdHJpbmcpIHtcblx0XHRcdHJldHVybiBcInN0cmluZ1wiO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zYW1wbGUgPT09IE51bWJlcikge1xuXHRcdFx0cmV0dXJuIFwibnVtYmVyXCI7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gRnVuY3Rpb24pIHtcblx0XHRcdHJldHVybiBcImZ1bmN0aW9uXCI7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnNhbXBsZSA9PT0gT2JqZWN0KSB7XG5cdFx0XHRyZXR1cm4gXCJvYmplY3RcIjtcblx0XHR9XG5cdFx0aWYgKHRoaXMuc2FtcGxlID09PSBCb29sZWFuKSB7XG5cdFx0XHRyZXR1cm4gXCJib29sZWFuXCI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmZuTmFtZUZvcih0aGlzLnNhbXBsZSk7XG5cdH1cblx0dG9Bc3ltbWV0cmljTWF0Y2hlcigpIHtcblx0XHRyZXR1cm4gYEFueTwke3RoaXMuZm5OYW1lRm9yKHRoaXMuc2FtcGxlKX0+YDtcblx0fVxufVxuY2xhc3MgU3RyaW5nTWF0Y2hpbmcgZXh0ZW5kcyBBc3ltbWV0cmljTWF0Y2hlciB7XG5cdGNvbnN0cnVjdG9yKHNhbXBsZSwgaW52ZXJzZSA9IGZhbHNlKSB7XG5cdFx0aWYgKCFpc0EoXCJTdHJpbmdcIiwgc2FtcGxlKSAmJiAhaXNBKFwiUmVnRXhwXCIsIHNhbXBsZSkpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIGlzIG5vdCBhIFN0cmluZyBvciBhIFJlZ0V4cFwiKTtcblx0XHR9XG5cdFx0c3VwZXIobmV3IFJlZ0V4cChzYW1wbGUpLCBpbnZlcnNlKTtcblx0fVxuXHRhc3ltbWV0cmljTWF0Y2gob3RoZXIpIHtcblx0XHRjb25zdCByZXN1bHQgPSBpc0EoXCJTdHJpbmdcIiwgb3RoZXIpICYmIHRoaXMuc2FtcGxlLnRlc3Qob3RoZXIpO1xuXHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcmVzdWx0IDogcmVzdWx0O1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgU3RyaW5nJHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1NYXRjaGluZ2A7XG5cdH1cblx0Z2V0RXhwZWN0ZWRUeXBlKCkge1xuXHRcdHJldHVybiBcInN0cmluZ1wiO1xuXHR9XG59XG5jbGFzcyBDbG9zZVRvIGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRwcmVjaXNpb247XG5cdGNvbnN0cnVjdG9yKHNhbXBsZSwgcHJlY2lzaW9uID0gMiwgaW52ZXJzZSA9IGZhbHNlKSB7XG5cdFx0aWYgKCFpc0EoXCJOdW1iZXJcIiwgc2FtcGxlKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgaXMgbm90IGEgTnVtYmVyXCIpO1xuXHRcdH1cblx0XHRpZiAoIWlzQShcIk51bWJlclwiLCBwcmVjaXNpb24pKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJQcmVjaXNpb24gaXMgbm90IGEgTnVtYmVyXCIpO1xuXHRcdH1cblx0XHRzdXBlcihzYW1wbGUpO1xuXHRcdHRoaXMuaW52ZXJzZSA9IGludmVyc2U7XG5cdFx0dGhpcy5wcmVjaXNpb24gPSBwcmVjaXNpb247XG5cdH1cblx0YXN5bW1ldHJpY01hdGNoKG90aGVyKSB7XG5cdFx0aWYgKCFpc0EoXCJOdW1iZXJcIiwgb3RoZXIpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGxldCByZXN1bHQgPSBmYWxzZTtcblx0XHRpZiAob3RoZXIgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSAmJiB0aGlzLnNhbXBsZSA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKSB7XG5cdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdH0gZWxzZSBpZiAob3RoZXIgPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSAmJiB0aGlzLnNhbXBsZSA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZKSB7XG5cdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXN1bHQgPSBNYXRoLmFicyh0aGlzLnNhbXBsZSAtIG90aGVyKSA8IDEwICoqIC10aGlzLnByZWNpc2lvbiAvIDI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmludmVyc2UgPyAhcmVzdWx0IDogcmVzdWx0O1xuXHR9XG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBgTnVtYmVyJHt0aGlzLmludmVyc2UgPyBcIk5vdFwiIDogXCJcIn1DbG9zZVRvYDtcblx0fVxuXHRnZXRFeHBlY3RlZFR5cGUoKSB7XG5cdFx0cmV0dXJuIFwibnVtYmVyXCI7XG5cdH1cblx0dG9Bc3ltbWV0cmljTWF0Y2hlcigpIHtcblx0XHRyZXR1cm4gW1xuXHRcdFx0dGhpcy50b1N0cmluZygpLFxuXHRcdFx0dGhpcy5zYW1wbGUsXG5cdFx0XHRgKCR7cGx1cmFsaXplKFwiZGlnaXRcIiwgdGhpcy5wcmVjaXNpb24pfSlgXG5cdFx0XS5qb2luKFwiIFwiKTtcblx0fVxufVxuY2xhc3MgU2NoZW1hTWF0Y2hpbmcgZXh0ZW5kcyBBc3ltbWV0cmljTWF0Y2hlciB7XG5cdHJlc3VsdDtcblx0Y29uc3RydWN0b3Ioc2FtcGxlLCBpbnZlcnNlID0gZmFsc2UpIHtcblx0XHRpZiAoIWlzU3RhbmRhcmRTY2hlbWEoc2FtcGxlKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihcIlNjaGVtYU1hdGNoaW5nIGV4cGVjdGVkIHRvIHJlY2VpdmUgYSBTdGFuZGFyZCBTY2hlbWEuXCIpO1xuXHRcdH1cblx0XHRzdXBlcihzYW1wbGUsIGludmVyc2UpO1xuXHR9XG5cdGFzeW1tZXRyaWNNYXRjaChvdGhlcikge1xuXHRcdGNvbnN0IHJlc3VsdCA9IHRoaXMuc2FtcGxlW1wifnN0YW5kYXJkXCJdLnZhbGlkYXRlKG90aGVyKTtcblx0XHQvLyBDaGVjayBpZiB0aGUgcmVzdWx0IGlzIGEgUHJvbWlzZSAoYXN5bmMgdmFsaWRhdGlvbilcblx0XHRpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihcIkFzeW5jIHNjaGVtYSB2YWxpZGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gYXN5bW1ldHJpYyBtYXRjaGVycy5cIik7XG5cdFx0fVxuXHRcdHRoaXMucmVzdWx0ID0gcmVzdWx0O1xuXHRcdGNvbnN0IHBhc3MgPSAhdGhpcy5yZXN1bHQuaXNzdWVzIHx8IHRoaXMucmVzdWx0Lmlzc3Vlcy5sZW5ndGggPT09IDA7XG5cdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFwYXNzIDogcGFzcztcblx0fVxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gYFNjaGVtYSR7dGhpcy5pbnZlcnNlID8gXCJOb3RcIiA6IFwiXCJ9TWF0Y2hpbmdgO1xuXHR9XG5cdGdldEV4cGVjdGVkVHlwZSgpIHtcblx0XHRyZXR1cm4gXCJvYmplY3RcIjtcblx0fVxuXHR0b0FzeW1tZXRyaWNNYXRjaGVyKCkge1xuXHRcdGNvbnN0IHsgdXRpbHMgfSA9IHRoaXMuZ2V0TWF0Y2hlckNvbnRleHQoKTtcblx0XHRjb25zdCBpc3N1ZXMgPSB0aGlzLnJlc3VsdD8uaXNzdWVzIHx8IFtdO1xuXHRcdGlmIChpc3N1ZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0cmV0dXJuIGAke3RoaXMudG9TdHJpbmcoKX0gJHt1dGlscy5zdHJpbmdpZnkodGhpcy5yZXN1bHQsIHVuZGVmaW5lZCwgeyBwcmludEJhc2ljUHJvdG90eXBlOiBmYWxzZSB9KX1gO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy50b1N0cmluZygpO1xuXHR9XG59XG5jb25zdCBKZXN0QXN5bW1ldHJpY01hdGNoZXJzID0gKGNoYWksIHV0aWxzKSA9PiB7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJhbnl0aGluZ1wiLCAoKSA9PiBuZXcgQW55dGhpbmcoKSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJhbnlcIiwgKGV4cGVjdGVkKSA9PiBuZXcgQW55KGV4cGVjdGVkKSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJzdHJpbmdDb250YWluaW5nXCIsIChleHBlY3RlZCkgPT4gbmV3IFN0cmluZ0NvbnRhaW5pbmcoZXhwZWN0ZWQpKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcIm9iamVjdENvbnRhaW5pbmdcIiwgKGV4cGVjdGVkKSA9PiBuZXcgT2JqZWN0Q29udGFpbmluZyhleHBlY3RlZCkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5leHBlY3QsIFwiYXJyYXlDb250YWluaW5nXCIsIChleHBlY3RlZCkgPT4gbmV3IEFycmF5Q29udGFpbmluZyhleHBlY3RlZCkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5leHBlY3QsIFwic3RyaW5nTWF0Y2hpbmdcIiwgKGV4cGVjdGVkKSA9PiBuZXcgU3RyaW5nTWF0Y2hpbmcoZXhwZWN0ZWQpKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcImNsb3NlVG9cIiwgKGV4cGVjdGVkLCBwcmVjaXNpb24pID0+IG5ldyBDbG9zZVRvKGV4cGVjdGVkLCBwcmVjaXNpb24pKTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcInNjaGVtYU1hdGNoaW5nXCIsIChleHBlY3RlZCkgPT4gbmV3IFNjaGVtYU1hdGNoaW5nKGV4cGVjdGVkKSk7XG5cdC8vIGRlZmluZVByb3BlcnR5IGRvZXMgbm90IHdvcmtcblx0Y2hhaS5leHBlY3Qubm90ID0ge1xuXHRcdHN0cmluZ0NvbnRhaW5pbmc6IChleHBlY3RlZCkgPT4gbmV3IFN0cmluZ0NvbnRhaW5pbmcoZXhwZWN0ZWQsIHRydWUpLFxuXHRcdG9iamVjdENvbnRhaW5pbmc6IChleHBlY3RlZCkgPT4gbmV3IE9iamVjdENvbnRhaW5pbmcoZXhwZWN0ZWQsIHRydWUpLFxuXHRcdGFycmF5Q29udGFpbmluZzogKGV4cGVjdGVkKSA9PiBuZXcgQXJyYXlDb250YWluaW5nKGV4cGVjdGVkLCB0cnVlKSxcblx0XHRzdHJpbmdNYXRjaGluZzogKGV4cGVjdGVkKSA9PiBuZXcgU3RyaW5nTWF0Y2hpbmcoZXhwZWN0ZWQsIHRydWUpLFxuXHRcdGNsb3NlVG86IChleHBlY3RlZCwgcHJlY2lzaW9uKSA9PiBuZXcgQ2xvc2VUbyhleHBlY3RlZCwgcHJlY2lzaW9uLCB0cnVlKSxcblx0XHRzY2hlbWFNYXRjaGluZzogKGV4cGVjdGVkKSA9PiBuZXcgU2NoZW1hTWF0Y2hpbmcoZXhwZWN0ZWQsIHRydWUpXG5cdH07XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVBc3NlcnRpb25NZXNzYWdlKHV0aWwsIGFzc2VydGlvbiwgaGFzQXJncykge1xuXHRjb25zdCBzb2Z0ID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJzb2Z0XCIpID8gXCIuc29mdFwiIDogXCJcIjtcblx0Y29uc3Qgbm90ID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJuZWdhdGVcIikgPyBcIm5vdC5cIiA6IFwiXCI7XG5cdGNvbnN0IG5hbWUgPSBgJHt1dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9uYW1lXCIpfSgke2hhc0FyZ3MgPyBcImV4cGVjdGVkXCIgOiBcIlwifSlgO1xuXHRjb25zdCBwcm9taXNlTmFtZSA9IHV0aWwuZmxhZyhhc3NlcnRpb24sIFwicHJvbWlzZVwiKTtcblx0Y29uc3QgcHJvbWlzZSA9IHByb21pc2VOYW1lID8gYC4ke3Byb21pc2VOYW1lfWAgOiBcIlwiO1xuXHRyZXR1cm4gYGV4cGVjdCR7c29mdH0oYWN0dWFsKSR7cHJvbWlzZX0uJHtub3R9JHtuYW1lfWA7XG59XG5mdW5jdGlvbiByZWNvcmRBc3luY0V4cGVjdChfdGVzdCwgcHJvbWlzZSwgYXNzZXJ0aW9uLCBlcnJvciwgaXNTb2Z0KSB7XG5cdGNvbnN0IHRlc3QgPSBfdGVzdDtcblx0Ly8gcmVjb3JkIHByb21pc2UgZm9yIHRlc3QsIHRoYXQgcmVzb2x2ZXMgYmVmb3JlIHRlc3QgZW5kc1xuXHRpZiAodGVzdCAmJiBwcm9taXNlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuXHRcdC8vIGlmIHByb21pc2UgaXMgZXhwbGljaXRseSBhd2FpdGVkLCByZW1vdmUgaXQgZnJvbSB0aGUgbGlzdFxuXHRcdHByb21pc2UgPSBwcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuXHRcdFx0aWYgKCF0ZXN0LnByb21pc2VzKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGNvbnN0IGluZGV4ID0gdGVzdC5wcm9taXNlcy5pbmRleE9mKHByb21pc2UpO1xuXHRcdFx0aWYgKGluZGV4ICE9PSAtMSkge1xuXHRcdFx0XHR0ZXN0LnByb21pc2VzLnNwbGljZShpbmRleCwgMSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0Ly8gcmVjb3JkIHByb21pc2Vcblx0XHRpZiAoIXRlc3QucHJvbWlzZXMpIHtcblx0XHRcdHRlc3QucHJvbWlzZXMgPSBbXTtcblx0XHR9XG5cdFx0Ly8gc2V0dXAgYGV4cGVjdC5zb2Z0YCBoYW5kbGVyIGhlcmUgaW5zdGVhZCBvZiBgd3JhcEFzc2VydGlvbmBcblx0XHQvLyB0byBhdm9pZCBkb3VibGUgZXJyb3IgdHJhY2tpbmcgd2hpbGUga2VlcGluZyBub24tYXdhaXQgcHJvbWlzZSBkZXRlY3Rpb24uXG5cdFx0aWYgKGlzU29mdCkge1xuXHRcdFx0cHJvbWlzZSA9IHByb21pc2UudGhlbihub29wLCAoZXJyKSA9PiB7XG5cdFx0XHRcdGhhbmRsZVRlc3RFcnJvcih0ZXN0LCBlcnIpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHRlc3QucHJvbWlzZXMucHVzaChwcm9taXNlKTtcblx0XHRsZXQgcmVzb2x2ZWQgPSBmYWxzZTtcblx0XHR0ZXN0Lm9uRmluaXNoZWQgPz89IFtdO1xuXHRcdHRlc3Qub25GaW5pc2hlZC5wdXNoKCgpID0+IHtcblx0XHRcdGlmICghcmVzb2x2ZWQpIHtcblx0XHRcdFx0Y29uc3QgcHJvY2Vzc29yID0gZ2xvYmFsVGhpcy5fX3ZpdGVzdF93b3JrZXJfXz8ub25GaWx0ZXJTdGFja1RyYWNlIHx8ICgocykgPT4gcyB8fCBcIlwiKTtcblx0XHRcdFx0Y29uc3Qgc3RhY2sgPSBwcm9jZXNzb3IoZXJyb3Iuc3RhY2spO1xuXHRcdFx0XHRjb25zb2xlLndhcm4oW1xuXHRcdFx0XHRcdGBQcm9taXNlIHJldHVybmVkIGJ5IFxcYCR7YXNzZXJ0aW9ufVxcYCB3YXMgbm90IGF3YWl0ZWQuIGAsXG5cdFx0XHRcdFx0XCJWaXRlc3QgY3VycmVudGx5IGF1dG8tYXdhaXRzIGhhbmdpbmcgYXNzZXJ0aW9ucyBhdCB0aGUgZW5kIG9mIHRoZSB0ZXN0LCBidXQgdGhpcyB3aWxsIGNhdXNlIHRoZSB0ZXN0IHRvIGZhaWwgaW4gdGhlIG5leHQgVml0ZXN0IG1ham9yLiBcIixcblx0XHRcdFx0XHRcIlBsZWFzZSByZW1lbWJlciB0byBhd2FpdCB0aGUgYXNzZXJ0aW9uLlxcblwiLFxuXHRcdFx0XHRcdHN0YWNrXG5cdFx0XHRcdF0uam9pbihcIlwiKSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcblx0XHRcdFx0cmVzb2x2ZWQgPSB0cnVlO1xuXHRcdFx0XHRyZXR1cm4gcHJvbWlzZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKTtcblx0XHRcdH0sXG5cdFx0XHRjYXRjaChvblJlamVjdGVkKSB7XG5cdFx0XHRcdHJlc29sdmVkID0gdHJ1ZTtcblx0XHRcdFx0cmV0dXJuIHByb21pc2UuY2F0Y2gob25SZWplY3RlZCk7XG5cdFx0XHR9LFxuXHRcdFx0ZmluYWxseShvbkZpbmFsbHkpIHtcblx0XHRcdFx0cmVzb2x2ZWQgPSB0cnVlO1xuXHRcdFx0XHRyZXR1cm4gcHJvbWlzZS5maW5hbGx5KG9uRmluYWxseSk7XG5cdFx0XHR9LFxuXHRcdFx0W1N5bWJvbC50b1N0cmluZ1RhZ106IFwiUHJvbWlzZVwiXG5cdFx0fTtcblx0fVxuXHRyZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIGhhbmRsZVRlc3RFcnJvcih0ZXN0LCBlcnIpIHtcblx0dGVzdC5yZXN1bHQgfHw9IHsgc3RhdGU6IFwiZmFpbFwiIH07XG5cdHRlc3QucmVzdWx0LnN0YXRlID0gXCJmYWlsXCI7XG5cdHRlc3QucmVzdWx0LmVycm9ycyB8fD0gW107XG5cdHRlc3QucmVzdWx0LmVycm9ycy5wdXNoKHByb2Nlc3NFcnJvcihlcnIpKTtcbn1cbi8qKiB3cmFwIGFzc2VydGlvbiBmdW5jdGlvbiB0byBzdXBwb3J0IGBleHBlY3Quc29mdGAgYW5kIHByb3ZpZGUgYXNzZXJ0aW9uIG5hbWUgYXMgYF9uYW1lYCAqL1xuZnVuY3Rpb24gd3JhcEFzc2VydGlvbih1dGlscywgbmFtZSwgZm4pIHtcblx0cmV0dXJuIGZ1bmN0aW9uKC4uLmFyZ3MpIHtcblx0XHQvLyBwcml2YXRlXG5cdFx0aWYgKG5hbWUgIT09IFwid2l0aFRlc3RcIikge1xuXHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIl9uYW1lXCIsIG5hbWUpO1xuXHRcdH1cblx0XHRpZiAoIXV0aWxzLmZsYWcodGhpcywgXCJzb2Z0XCIpKSB7XG5cdFx0XHQvLyBhdm9pZCBXZWJLaXQncyBwcm9wZXIgdGFpbCBjYWxsIHRvIHByZXNlcnZlIHN0YWNrdHJhY2Ugb2Zmc2V0IGZvciBpbmxpbmUgc25hcHNob3Rcblx0XHRcdC8vIGh0dHBzOi8vd2Via2l0Lm9yZy9ibG9nLzYyNDAvZWNtYXNjcmlwdC02LXByb3Blci10YWlsLWNhbGxzLWluLXdlYmtpdFxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0cmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0fSBmaW5hbGx5IHt9XG5cdFx0fVxuXHRcdGNvbnN0IHRlc3QgPSB1dGlscy5mbGFnKHRoaXMsIFwidml0ZXN0LXRlc3RcIik7XG5cdFx0aWYgKCF0ZXN0KSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJleHBlY3Quc29mdCgpIGNhbiBvbmx5IGJlIHVzZWQgaW5zaWRlIGEgdGVzdFwiKTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0aWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdHJldHVybiByZXN1bHQudGhlbihub29wLCAoZXJyKSA9PiB7XG5cdFx0XHRcdFx0aGFuZGxlVGVzdEVycm9yKHRlc3QsIGVycik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdGhhbmRsZVRlc3RFcnJvcih0ZXN0LCBlcnIpO1xuXHRcdH1cblx0fTtcbn1cblxuLy8gSmVzdCBFeHBlY3QgQ29tcGFjdFxuY29uc3QgSmVzdENoYWlFeHBlY3QgPSAoY2hhaSwgdXRpbHMpID0+IHtcblx0Y29uc3QgeyBBc3NlcnRpb25FcnJvciB9ID0gY2hhaTtcblx0Y29uc3QgY3VzdG9tVGVzdGVycyA9IGdldEN1c3RvbUVxdWFsaXR5VGVzdGVycygpO1xuXHRmdW5jdGlvbiBkZWYobmFtZSwgZm4pIHtcblx0XHRjb25zdCBhZGRNZXRob2QgPSAobikgPT4ge1xuXHRcdFx0Y29uc3Qgc29mdFdyYXBwZXIgPSB3cmFwQXNzZXJ0aW9uKHV0aWxzLCBuLCBmbik7XG5cdFx0XHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBuLCBzb2Z0V3JhcHBlcik7XG5cdFx0XHR1dGlscy5hZGRNZXRob2QoZ2xvYmFsVGhpc1tKRVNUX01BVENIRVJTX09CSkVDVF0ubWF0Y2hlcnMsIG4sIHNvZnRXcmFwcGVyKTtcblx0XHR9O1xuXHRcdGlmIChBcnJheS5pc0FycmF5KG5hbWUpKSB7XG5cdFx0XHRuYW1lLmZvckVhY2goKG4pID0+IGFkZE1ldGhvZChuKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFkZE1ldGhvZChuYW1lKTtcblx0XHR9XG5cdH1cblx0W1xuXHRcdFwidGhyb3dcIixcblx0XHRcInRocm93c1wiLFxuXHRcdFwiVGhyb3dcIlxuXHRdLmZvckVhY2goKG0pID0+IHtcblx0XHR1dGlscy5vdmVyd3JpdGVNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBtLCAoX3N1cGVyKSA9PiB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdFx0XHRjb25zdCBwcm9taXNlID0gdXRpbHMuZmxhZyh0aGlzLCBcInByb21pc2VcIik7XG5cdFx0XHRcdGNvbnN0IG9iamVjdCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0XHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRcdFx0aWYgKHByb21pc2UgPT09IFwicmVqZWN0c1wiKSB7XG5cdFx0XHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiLCAoKSA9PiB7XG5cdFx0XHRcdFx0XHR0aHJvdyBvYmplY3Q7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAocHJvbWlzZSA9PT0gXCJyZXNvbHZlc1wiICYmIHR5cGVvZiBvYmplY3QgIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0XHRcdGlmICghaXNOb3QpIHtcblx0XHRcdFx0XHRcdGNvbnN0IG1lc3NhZ2UgPSB1dGlscy5mbGFnKHRoaXMsIFwibWVzc2FnZVwiKSB8fCBcImV4cGVjdGVkIHByb21pc2UgdG8gdGhyb3cgYW4gZXJyb3IsIGJ1dCBpdCBkaWRuJ3RcIjtcblx0XHRcdFx0XHRcdGNvbnN0IGVycm9yID0geyBzaG93RGlmZjogZmFsc2UgfTtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNzZmlcIikpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdF9zdXBlci5hcHBseSh0aGlzLCBhcmdzKTtcblx0XHRcdH07XG5cdFx0fSk7XG5cdH0pO1xuXHQvLyBAdHMtZXhwZWN0LWVycm9yIEBpbnRlcm5hbFxuXHRkZWYoXCJ3aXRoVGVzdFwiLCBmdW5jdGlvbih0ZXN0KSB7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcInZpdGVzdC10ZXN0XCIsIHRlc3QpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9KTtcblx0ZGVmKFwidG9FcXVhbFwiLCBmdW5jdGlvbihleHBlY3RlZCkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3QgZXF1YWwgPSBlcXVhbHMoYWN0dWFsLCBleHBlY3RlZCwgWy4uLmN1c3RvbVRlc3RlcnMsIGl0ZXJhYmxlRXF1YWxpdHldKTtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoZXF1YWwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBkZWVwbHkgZXF1YWwgI3tleHB9XCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZGVlcGx5IGVxdWFsICN7ZXhwfVwiLCBleHBlY3RlZCwgYWN0dWFsKTtcblx0fSk7XG5cdGRlZihcInRvU3RyaWN0RXF1YWxcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IGVxdWFsID0gZXF1YWxzKG9iaiwgZXhwZWN0ZWQsIFtcblx0XHRcdC4uLmN1c3RvbVRlc3RlcnMsXG5cdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0dHlwZUVxdWFsaXR5LFxuXHRcdFx0c3BhcnNlQXJyYXlFcXVhbGl0eSxcblx0XHRcdGFycmF5QnVmZmVyRXF1YWxpdHlcblx0XHRdLCB0cnVlKTtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoZXF1YWwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBzdHJpY3RseSBlcXVhbCAje2V4cH1cIiwgXCJleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBzdHJpY3RseSBlcXVhbCAje2V4cH1cIiwgZXhwZWN0ZWQsIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGNvbnN0IHBhc3MgPSBPYmplY3QuaXMoYWN0dWFsLCBleHBlY3RlZCk7XG5cdFx0bGV0IGRlZXBFcXVhbGl0eU5hbWUgPSBcIlwiO1xuXHRcdGlmICghcGFzcykge1xuXHRcdFx0Y29uc3QgdG9TdHJpY3RFcXVhbFBhc3MgPSBlcXVhbHMoYWN0dWFsLCBleHBlY3RlZCwgW1xuXHRcdFx0XHQuLi5jdXN0b21UZXN0ZXJzLFxuXHRcdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0XHR0eXBlRXF1YWxpdHksXG5cdFx0XHRcdHNwYXJzZUFycmF5RXF1YWxpdHksXG5cdFx0XHRcdGFycmF5QnVmZmVyRXF1YWxpdHlcblx0XHRcdF0sIHRydWUpO1xuXHRcdFx0aWYgKHRvU3RyaWN0RXF1YWxQYXNzKSB7XG5cdFx0XHRcdGRlZXBFcXVhbGl0eU5hbWUgPSBcInRvU3RyaWN0RXF1YWxcIjtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IHRvRXF1YWxQYXNzID0gZXF1YWxzKGFjdHVhbCwgZXhwZWN0ZWQsIFsuLi5jdXN0b21UZXN0ZXJzLCBpdGVyYWJsZUVxdWFsaXR5XSk7XG5cdFx0XHRcdGlmICh0b0VxdWFsUGFzcykge1xuXHRcdFx0XHRcdGRlZXBFcXVhbGl0eU5hbWUgPSBcInRvRXF1YWxcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQocGFzcywgZ2VuZXJhdGVUb0JlTWVzc2FnZShkZWVwRXF1YWxpdHlOYW1lKSwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSAje2V4cH0gLy8gT2JqZWN0LmlzIGVxdWFsaXR5XCIsIGV4cGVjdGVkLCBhY3R1YWwpO1xuXHR9KTtcblx0ZGVmKFwidG9NYXRjaE9iamVjdFwiLCBmdW5jdGlvbihleHBlY3RlZCkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHRoaXMuX29iajtcblx0XHRjb25zdCBwYXNzID0gZXF1YWxzKGFjdHVhbCwgZXhwZWN0ZWQsIFtcblx0XHRcdC4uLmN1c3RvbVRlc3RlcnMsXG5cdFx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdFx0c3Vic2V0RXF1YWxpdHlcblx0XHRdKTtcblx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0Y29uc3QgeyBzdWJzZXQ6IGFjdHVhbFN1YnNldCwgc3RyaXBwZWQgfSA9IGdldE9iamVjdFN1YnNldChhY3R1YWwsIGV4cGVjdGVkLCBjdXN0b21UZXN0ZXJzKTtcblx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdGNvbnN0IG1zZyA9IHV0aWxzLmdldE1lc3NhZ2UodGhpcywgW1xuXHRcdFx0XHRwYXNzLFxuXHRcdFx0XHRcImV4cGVjdGVkICN7dGhpc30gdG8gbWF0Y2ggb2JqZWN0ICN7ZXhwfVwiLFxuXHRcdFx0XHRcImV4cGVjdGVkICN7dGhpc30gdG8gbm90IG1hdGNoIG9iamVjdCAje2V4cH1cIixcblx0XHRcdFx0ZXhwZWN0ZWQsXG5cdFx0XHRcdGFjdHVhbFN1YnNldCxcblx0XHRcdFx0ZmFsc2Vcblx0XHRcdF0pO1xuXHRcdFx0Y29uc3QgbWVzc2FnZSA9IHN0cmlwcGVkID09PSAwID8gbXNnIDogYCR7bXNnfVxcbigke3N0cmlwcGVkfSBtYXRjaGluZyAke3N0cmlwcGVkID09PSAxID8gXCJwcm9wZXJ0eVwiIDogXCJwcm9wZXJ0aWVzXCJ9IG9taXR0ZWQgZnJvbSBhY3R1YWwpYDtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG5cdFx0XHRcdHNob3dEaWZmOiB0cnVlLFxuXHRcdFx0XHRleHBlY3RlZCxcblx0XHRcdFx0YWN0dWFsOiBhY3R1YWxTdWJzZXRcblx0XHRcdH0pO1xuXHRcdH1cblx0fSk7XG5cdGRlZihcInRvTWF0Y2hcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBhY3R1YWwgPSB0aGlzLl9vYmo7XG5cdFx0aWYgKHR5cGVvZiBhY3R1YWwgIT09IFwic3RyaW5nXCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYC50b01hdGNoKCkgZXhwZWN0cyB0byByZWNlaXZlIGEgc3RyaW5nLCBidXQgZ290ICR7dHlwZW9mIGFjdHVhbH1gKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KHR5cGVvZiBleHBlY3RlZCA9PT0gXCJzdHJpbmdcIiA/IGFjdHVhbC5pbmNsdWRlcyhleHBlY3RlZCkgOiBhY3R1YWwubWF0Y2goZXhwZWN0ZWQpLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBtYXRjaCAje2V4cH1gLCBgZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gbWF0Y2ggI3tleHB9YCwgZXhwZWN0ZWQsIGFjdHVhbCk7XG5cdH0pO1xuXHRkZWYoXCJ0b0NvbnRhaW5cIiwgZnVuY3Rpb24oaXRlbSkge1xuXHRcdGNvbnN0IGFjdHVhbCA9IHRoaXMuX29iajtcblx0XHRpZiAodHlwZW9mIE5vZGUgIT09IFwidW5kZWZpbmVkXCIgJiYgYWN0dWFsIGluc3RhbmNlb2YgTm9kZSkge1xuXHRcdFx0aWYgKCEoaXRlbSBpbnN0YW5jZW9mIE5vZGUpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYHRvQ29udGFpbigpIGV4cGVjdGVkIGEgRE9NIG5vZGUgYXMgdGhlIGFyZ3VtZW50LCBidXQgZ290ICR7dHlwZW9mIGl0ZW19YCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoYWN0dWFsLmNvbnRhaW5zKGl0ZW0pLCBcImV4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiBlbGVtZW50ICN7ZXhwfVwiLCBcImV4cGVjdGVkICN7dGhpc30gbm90IHRvIGNvbnRhaW4gZWxlbWVudCAje2V4cH1cIiwgaXRlbSwgYWN0dWFsKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBET01Ub2tlbkxpc3QgIT09IFwidW5kZWZpbmVkXCIgJiYgYWN0dWFsIGluc3RhbmNlb2YgRE9NVG9rZW5MaXN0KSB7XG5cdFx0XHRhc3NlcnRUeXBlcyhpdGVtLCBcImNsYXNzIG5hbWVcIiwgW1wic3RyaW5nXCJdKTtcblx0XHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRcdGNvbnN0IGV4cGVjdGVkQ2xhc3NMaXN0ID0gaXNOb3QgPyBhY3R1YWwudmFsdWUucmVwbGFjZShpdGVtLCBcIlwiKS50cmltKCkgOiBgJHthY3R1YWwudmFsdWV9ICR7aXRlbX1gO1xuXHRcdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGFjdHVhbC5jb250YWlucyhpdGVtKSwgYGV4cGVjdGVkIFwiJHthY3R1YWwudmFsdWV9XCIgdG8gY29udGFpbiBcIiR7aXRlbX1cImAsIGBleHBlY3RlZCBcIiR7YWN0dWFsLnZhbHVlfVwiIG5vdCB0byBjb250YWluIFwiJHtpdGVtfVwiYCwgZXhwZWN0ZWRDbGFzc0xpc3QsIGFjdHVhbC52YWx1ZSk7XG5cdFx0fVxuXHRcdC8vIGhhbmRsZSBzaW1wbGUgY2FzZSBvbiBvdXIgb3duIHVzaW5nIGB0aGlzLmFzc2VydGAgdG8gaW5jbHVkZSBkaWZmIGluIGVycm9yIG1lc3NhZ2Vcblx0XHRpZiAodHlwZW9mIGFjdHVhbCA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgaXRlbSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGFjdHVhbC5pbmNsdWRlcyhpdGVtKSwgYGV4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiAje2V4cH1gLCBgZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gY29udGFpbiAje2V4cH1gLCBpdGVtLCBhY3R1YWwpO1xuXHRcdH1cblx0XHQvLyBtYWtlIFwiYWN0dWFsXCIgaW5kZXhhYmxlIHRvIGhhdmUgY29tcGF0aWJpbGl0eSB3aXRoIGplc3Rcblx0XHRpZiAoYWN0dWFsICE9IG51bGwgJiYgdHlwZW9mIGFjdHVhbCAhPT0gXCJzdHJpbmdcIikge1xuXHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiLCBBcnJheS5mcm9tKGFjdHVhbCkpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5jb250YWluKGl0ZW0pO1xuXHR9KTtcblx0ZGVmKFwidG9Db250YWluRXF1YWxcIiwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdGNvbnN0IGluZGV4ID0gQXJyYXkuZnJvbShvYmopLmZpbmRJbmRleCgoaXRlbSkgPT4ge1xuXHRcdFx0cmV0dXJuIGVxdWFscyhpdGVtLCBleHBlY3RlZCwgY3VzdG9tVGVzdGVycyk7XG5cdFx0fSk7XG5cdFx0dGhpcy5hc3NlcnQoaW5kZXggIT09IC0xLCBcImV4cGVjdGVkICN7dGhpc30gdG8gZGVlcCBlcXVhbGx5IGNvbnRhaW4gI3tleHB9XCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZGVlcCBlcXVhbGx5IGNvbnRhaW4gI3tleHB9XCIsIGV4cGVjdGVkKTtcblx0fSk7XG5cdGRlZihcInRvQmVUcnV0aHlcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydChCb29sZWFuKG9iaiksIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB0cnV0aHlcIiwgXCJleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBiZSB0cnV0aHlcIiwgdHJ1ZSwgb2JqKTtcblx0fSk7XG5cdGRlZihcInRvQmVGYWxzeVwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdHRoaXMuYXNzZXJ0KCFvYmosIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzeVwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGZhbHN5XCIsIGZhbHNlLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZUdyZWF0ZXJUaGFuXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPiBleHBlY3RlZCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBncmVhdGVyIHRoYW4gJHtleHBlY3RlZH1gLCBgZXhwZWN0ZWQgJHthY3R1YWx9IHRvIGJlIG5vdCBncmVhdGVyIHRoYW4gJHtleHBlY3RlZH1gLCBleHBlY3RlZCwgYWN0dWFsLCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlR3JlYXRlclRoYW5PckVxdWFsXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPj0gZXhwZWN0ZWQsIGBleHBlY3RlZCAke2FjdHVhbH0gdG8gYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBub3QgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgZXhwZWN0ZWQsIGFjdHVhbCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFwidG9CZUxlc3NUaGFuXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPCBleHBlY3RlZCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBsZXNzIHRoYW4gJHtleHBlY3RlZH1gLCBgZXhwZWN0ZWQgJHthY3R1YWx9IHRvIGJlIG5vdCBsZXNzIHRoYW4gJHtleHBlY3RlZH1gLCBleHBlY3RlZCwgYWN0dWFsLCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlTGVzc1RoYW5PckVxdWFsXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdGhpcy5fb2JqO1xuXHRcdGFzc2VydFR5cGVzKGFjdHVhbCwgXCJhY3R1YWxcIiwgW1wibnVtYmVyXCIsIFwiYmlnaW50XCJdKTtcblx0XHRhc3NlcnRUeXBlcyhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBbXCJudW1iZXJcIiwgXCJiaWdpbnRcIl0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChhY3R1YWwgPD0gZXhwZWN0ZWQsIGBleHBlY3RlZCAke2FjdHVhbH0gdG8gYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgYGV4cGVjdGVkICR7YWN0dWFsfSB0byBiZSBub3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgZXhwZWN0ZWQsIGFjdHVhbCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFwidG9CZU5hTlwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBvYmogPSB1dGlscy5mbGFnKHRoaXMsIFwib2JqZWN0XCIpO1xuXHRcdHRoaXMuYXNzZXJ0KE51bWJlci5pc05hTihvYmopLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgTmFOXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgTmFOXCIsIE51bWJlci5OYU4sIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlVW5kZWZpbmVkXCIsIGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0dGhpcy5hc3NlcnQodW5kZWZpbmVkID09PSBvYmosIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB1bmRlZmluZWRcIiwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB1bmRlZmluZWRcIiwgdW5kZWZpbmVkLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZU51bGxcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydChvYmogPT09IG51bGwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBudWxsXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgbnVsbFwiLCBudWxsLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZU51bGxhYmxlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0dGhpcy5hc3NlcnQob2JqID09IG51bGwsIFwiZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBudWxsaXNoXCIsIFwiZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgbnVsbGlzaFwiLCBudWxsLCBvYmopO1xuXHR9KTtcblx0ZGVmKFwidG9CZURlZmluZWRcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHR0aGlzLmFzc2VydCh0eXBlb2Ygb2JqICE9PSBcInVuZGVmaW5lZFwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgZGVmaW5lZFwiLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgdW5kZWZpbmVkXCIsIG9iaik7XG5cdH0pO1xuXHRkZWYoXCJ0b0JlVHlwZU9mXCIsIGZ1bmN0aW9uKGV4cGVjdGVkKSB7XG5cdFx0Y29uc3QgYWN0dWFsID0gdHlwZW9mIHRoaXMuX29iajtcblx0XHRjb25zdCBlcXVhbCA9IGV4cGVjdGVkID09PSBhY3R1YWw7XG5cdFx0cmV0dXJuIHRoaXMuYXNzZXJ0KGVxdWFsLCBcImV4cGVjdGVkICN7dGhpc30gdG8gYmUgdHlwZSBvZiAje2V4cH1cIiwgXCJleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB0eXBlIG9mICN7ZXhwfVwiLCBleHBlY3RlZCwgYWN0dWFsKTtcblx0fSk7XG5cdGRlZihcInRvQmVJbnN0YW5jZU9mXCIsIGZ1bmN0aW9uKG9iaikge1xuXHRcdHJldHVybiB0aGlzLmluc3RhbmNlT2Yob2JqKTtcblx0fSk7XG5cdGRlZihcInRvSGF2ZUxlbmd0aFwiLCBmdW5jdGlvbihsZW5ndGgpIHtcblx0XHRyZXR1cm4gdGhpcy5oYXZlLmxlbmd0aChsZW5ndGgpO1xuXHR9KTtcblx0Ly8gZGVzdHJ1Y3R1cmluZywgYmVjYXVzZSBpdCBjaGVja3MgYGFyZ3VtZW50c2AgaW5zaWRlLCBhbmQgdmFsdWUgaXMgcGFzc2luZyBhcyBgdW5kZWZpbmVkYFxuXHRkZWYoXCJ0b0hhdmVQcm9wZXJ0eVwiLCBmdW5jdGlvbiguLi5hcmdzKSB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcblx0XHRcdGFyZ3NbMF0gPSBhcmdzWzBdLm1hcCgoa2V5KSA9PiBTdHJpbmcoa2V5KS5yZXBsYWNlKC8oWy5bXFxdXSkvZywgXCJcXFxcJDFcIikpLmpvaW4oXCIuXCIpO1xuXHRcdH1cblx0XHRjb25zdCBhY3R1YWwgPSB0aGlzLl9vYmo7XG5cdFx0Y29uc3QgW3Byb3BlcnR5TmFtZSwgZXhwZWN0ZWRdID0gYXJncztcblx0XHRjb25zdCBnZXRWYWx1ZSA9ICgpID0+IHtcblx0XHRcdGNvbnN0IGhhc093biA9IE9iamVjdC5oYXNPd24oYWN0dWFsLCBwcm9wZXJ0eU5hbWUpO1xuXHRcdFx0aWYgKGhhc093bikge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdHZhbHVlOiBhY3R1YWxbcHJvcGVydHlOYW1lXSxcblx0XHRcdFx0XHRleGlzdHM6IHRydWVcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB1dGlscy5nZXRQYXRoSW5mbyhhY3R1YWwsIHByb3BlcnR5TmFtZSk7XG5cdFx0fTtcblx0XHRjb25zdCB7IHZhbHVlLCBleGlzdHMgfSA9IGdldFZhbHVlKCk7XG5cdFx0Y29uc3QgcGFzcyA9IGV4aXN0cyAmJiAoYXJncy5sZW5ndGggPT09IDEgfHwgZXF1YWxzKGV4cGVjdGVkLCB2YWx1ZSwgY3VzdG9tVGVzdGVycykpO1xuXHRcdGNvbnN0IHZhbHVlU3RyaW5nID0gYXJncy5sZW5ndGggPT09IDEgPyBcIlwiIDogYCB3aXRoIHZhbHVlICR7dXRpbHMub2JqRGlzcGxheShleHBlY3RlZCl9YDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQocGFzcywgYGV4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBwcm9wZXJ0eSBcIiR7cHJvcGVydHlOYW1lfVwiJHt2YWx1ZVN0cmluZ31gLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBwcm9wZXJ0eSBcIiR7cHJvcGVydHlOYW1lfVwiJHt2YWx1ZVN0cmluZ31gLCBleHBlY3RlZCwgZXhpc3RzID8gdmFsdWUgOiB1bmRlZmluZWQpO1xuXHR9KTtcblx0ZGVmKFwidG9CZUNsb3NlVG9cIiwgZnVuY3Rpb24ocmVjZWl2ZWQsIHByZWNpc2lvbiA9IDIpIHtcblx0XHRjb25zdCBleHBlY3RlZCA9IHRoaXMuX29iajtcblx0XHRsZXQgcGFzcyA9IGZhbHNlO1xuXHRcdGxldCBleHBlY3RlZERpZmYgPSAwO1xuXHRcdGxldCByZWNlaXZlZERpZmYgPSAwO1xuXHRcdGlmIChyZWNlaXZlZCA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZICYmIGV4cGVjdGVkID09PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpIHtcblx0XHRcdHBhc3MgPSB0cnVlO1xuXHRcdH0gZWxzZSBpZiAocmVjZWl2ZWQgPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSAmJiBleHBlY3RlZCA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZKSB7XG5cdFx0XHRwYXNzID0gdHJ1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZXhwZWN0ZWREaWZmID0gMTAgKiogLXByZWNpc2lvbiAvIDI7XG5cdFx0XHRyZWNlaXZlZERpZmYgPSBNYXRoLmFicyhleHBlY3RlZCAtIHJlY2VpdmVkKTtcblx0XHRcdHBhc3MgPSByZWNlaXZlZERpZmYgPCBleHBlY3RlZERpZmY7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmFzc2VydChwYXNzLCBgZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBjbG9zZSB0byAje2V4cH0sIHJlY2VpdmVkIGRpZmZlcmVuY2UgaXMgJHtyZWNlaXZlZERpZmZ9LCBidXQgZXhwZWN0ZWQgJHtleHBlY3RlZERpZmZ9YCwgYGV4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGNsb3NlIHRvICN7ZXhwfSwgcmVjZWl2ZWQgZGlmZmVyZW5jZSBpcyAke3JlY2VpdmVkRGlmZn0sIGJ1dCBleHBlY3RlZCAke2V4cGVjdGVkRGlmZn1gLCByZWNlaXZlZCwgZXhwZWN0ZWQsIGZhbHNlKTtcblx0fSk7XG5cdGZ1bmN0aW9uIGFzc2VydElzTW9jayhhc3NlcnRpb24pIHtcblx0XHRpZiAoIWlzTW9ja0Z1bmN0aW9uKGFzc2VydGlvbi5fb2JqKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgJHt1dGlscy5pbnNwZWN0KGFzc2VydGlvbi5fb2JqKX0gaXMgbm90IGEgc3B5IG9yIGEgY2FsbCB0byBhIHNweSFgKTtcblx0XHR9XG5cdH1cblx0ZnVuY3Rpb24gZ2V0U3B5KGFzc2VydGlvbikge1xuXHRcdGFzc2VydElzTW9jayhhc3NlcnRpb24pO1xuXHRcdHJldHVybiBhc3NlcnRpb24uX29iajtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZFRpbWVzXCIsIFwidG9CZUNhbGxlZFRpbWVzXCJdLCBmdW5jdGlvbihudW1iZXIpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoY2FsbENvdW50ID09PSBudW1iZXIsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBiZSBjYWxsZWQgI3tleHB9IHRpbWVzLCBidXQgZ290ICR7Y2FsbENvdW50fSB0aW1lc2AsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgY2FsbGVkICN7ZXhwfSB0aW1lc2AsIG51bWJlciwgY2FsbENvdW50LCBmYWxzZSk7XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuQ2FsbGVkT25jZVwiLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRyZXR1cm4gdGhpcy5hc3NlcnQoY2FsbENvdW50ID09PSAxLCBgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIG9uY2UsIGJ1dCBnb3QgJHtjYWxsQ291bnR9IHRpbWVzYCwgYGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgb25jZWAsIDEsIGNhbGxDb3VudCwgZmFsc2UpO1xuXHR9KTtcblx0ZGVmKFtcInRvSGF2ZUJlZW5DYWxsZWRcIiwgXCJ0b0JlQ2FsbGVkXCJdLCBmdW5jdGlvbigpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRjb25zdCBjYWxsZWQgPSBjYWxsQ291bnQgPiAwO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRsZXQgbXNnID0gdXRpbHMuZ2V0TWVzc2FnZSh0aGlzLCBbXG5cdFx0XHRjYWxsZWQsXG5cdFx0XHRgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIGF0IGxlYXN0IG9uY2VgLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgYXQgYWxsLCBidXQgYWN0dWFsbHkgYmVlbiBjYWxsZWQgJHtjYWxsQ291bnR9IHRpbWVzYCxcblx0XHRcdHRydWUsXG5cdFx0XHRjYWxsZWRcblx0XHRdKTtcblx0XHRpZiAoY2FsbGVkICYmIGlzTm90KSB7XG5cdFx0XHRtc2cgPSBmb3JtYXRDYWxscyhzcHksIG1zZyk7XG5cdFx0fVxuXHRcdGlmIChjYWxsZWQgJiYgaXNOb3QgfHwgIWNhbGxlZCAmJiAhaXNOb3QpIHtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpO1xuXHRcdH1cblx0fSk7XG5cdC8vIG1hbnVhbGx5IGNvbXBhcmUgYXJyYXkgZWxlbWVudHMgc2luY2UgYGplc3RFcXVhbHNgIGNhbm5vdFxuXHQvLyBhcHBseSBhc3ltbWV0cmljIG1hdGNoZXIgdG8gYHVuZGVmaW5lZGAgYXJyYXkgZWxlbWVudC5cblx0ZnVuY3Rpb24gZXF1YWxzQXJndW1lbnRBcnJheShhLCBiKSB7XG5cdFx0cmV0dXJuIGEubGVuZ3RoID09PSBiLmxlbmd0aCAmJiBhLmV2ZXJ5KChhSXRlbSwgaSkgPT4gZXF1YWxzKGFJdGVtLCBiW2ldLCBbLi4uY3VzdG9tVGVzdGVycywgaXRlcmFibGVFcXVhbGl0eV0pKTtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZFdpdGhcIiwgXCJ0b0JlQ2FsbGVkV2l0aFwiXSwgZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0Y29uc3QgcGFzcyA9IHNweS5tb2NrLmNhbGxzLnNvbWUoKGNhbGxBcmcpID0+IGVxdWFsc0FyZ3VtZW50QXJyYXkoY2FsbEFyZywgYXJncykpO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRjb25zdCBtc2cgPSB1dGlscy5nZXRNZXNzYWdlKHRoaXMsIFtcblx0XHRcdHBhc3MsXG5cdFx0XHRgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgY2FsbGVkIHdpdGggYXJndW1lbnRzOiAje2V4cH1gLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgd2l0aCBhcmd1bWVudHM6ICN7ZXhwfWAsXG5cdFx0XHRhcmdzXG5cdFx0XSk7XG5cdFx0aWYgKHBhc3MgJiYgaXNOb3QgfHwgIXBhc3MgJiYgIWlzTm90KSB7XG5cdFx0XHR0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZm9ybWF0Q2FsbHMoc3B5LCBtc2csIGFyZ3MpKTtcblx0XHR9XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuQ2FsbGVkRXhhY3RseU9uY2VXaXRoXCIsIGZ1bmN0aW9uKC4uLmFyZ3MpIHtcblx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdGNvbnN0IGNhbGxDb3VudCA9IHNweS5tb2NrLmNhbGxzLmxlbmd0aDtcblx0XHRjb25zdCBoYXNDYWxsV2l0aEFyZ3MgPSBzcHkubW9jay5jYWxscy5zb21lKChjYWxsQXJnKSA9PiBlcXVhbHNBcmd1bWVudEFycmF5KGNhbGxBcmcsIGFyZ3MpKTtcblx0XHRjb25zdCBwYXNzID0gaGFzQ2FsbFdpdGhBcmdzICYmIGNhbGxDb3VudCA9PT0gMTtcblx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0Y29uc3QgbXNnID0gdXRpbHMuZ2V0TWVzc2FnZSh0aGlzLCBbXG5cdFx0XHRwYXNzLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIGJlIGNhbGxlZCBvbmNlIHdpdGggYXJndW1lbnRzOiAje2V4cH1gLFxuXHRcdFx0YGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIG5vdCBiZSBjYWxsZWQgb25jZSB3aXRoIGFyZ3VtZW50czogI3tleHB9YCxcblx0XHRcdGFyZ3Ncblx0XHRdKTtcblx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihmb3JtYXRDYWxscyhzcHksIG1zZywgYXJncykpO1xuXHRcdH1cblx0fSk7XG5cdGRlZihcInRvSGF2ZUJlZW5OdGhDYWxsZWRXaXRoXCIsIGZ1bmN0aW9uKHRpbWVzLCAuLi5hcmdzKSB7XG5cdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdGNvbnN0IHNweU5hbWUgPSBzcHkuZ2V0TW9ja05hbWUoKTtcblx0XHRjb25zdCBudGhDYWxsID0gc3B5Lm1vY2suY2FsbHNbdGltZXMgLSAxXTtcblx0XHRjb25zdCBjYWxsQ291bnQgPSBzcHkubW9jay5jYWxscy5sZW5ndGg7XG5cdFx0Y29uc3QgaXNDYWxsZWQgPSB0aW1lcyA8PSBjYWxsQ291bnQ7XG5cdFx0dGhpcy5hc3NlcnQobnRoQ2FsbCAmJiBlcXVhbHNBcmd1bWVudEFycmF5KG50aENhbGwsIGFyZ3MpLCBgZXhwZWN0ZWQgJHtvcmRpbmFsKHRpbWVzKX0gXCIke3NweU5hbWV9XCIgY2FsbCB0byBoYXZlIGJlZW4gY2FsbGVkIHdpdGggI3tleHB9JHtpc0NhbGxlZCA/IGBgIDogYCwgYnV0IGNhbGxlZCBvbmx5ICR7Y2FsbENvdW50fSB0aW1lc2B9YCwgYGV4cGVjdGVkICR7b3JkaW5hbCh0aW1lcyl9IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90IGhhdmUgYmVlbiBjYWxsZWQgd2l0aCAje2V4cH1gLCBhcmdzLCBudGhDYWxsLCBpc0NhbGxlZCk7XG5cdH0pO1xuXHRkZWYoXCJ0b0hhdmVCZWVuTGFzdENhbGxlZFdpdGhcIiwgZnVuY3Rpb24oLi4uYXJncykge1xuXHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0Y29uc3QgbGFzdENhbGwgPSBzcHkubW9jay5jYWxscy5hdCgtMSk7XG5cdFx0dGhpcy5hc3NlcnQobGFzdENhbGwgJiYgZXF1YWxzQXJndW1lbnRBcnJheShsYXN0Q2FsbCwgYXJncyksIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gaGF2ZSBiZWVuIGNhbGxlZCB3aXRoICN7ZXhwfWAsIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90IGhhdmUgYmVlbiBjYWxsZWQgd2l0aCAje2V4cH1gLCBhcmdzLCBsYXN0Q2FsbCk7XG5cdH0pO1xuXHQvKipcblx0KiBVc2VkIGZvciBgdG9IYXZlQmVlbkNhbGxlZEJlZm9yZWAgYW5kIGB0b0hhdmVCZWVuQ2FsbGVkQWZ0ZXJgIHRvIGRldGVybWluZSBpZiB0aGUgZXhwZWN0ZWQgc3B5IHdhcyBjYWxsZWQgYmVmb3JlIHRoZSByZXN1bHQgc3B5LlxuXHQqL1xuXHRmdW5jdGlvbiBpc1NweUNhbGxlZEJlZm9yZUFub3RoZXJTcHkoYmVmb3JlU3B5LCBhZnRlclNweSwgZmFpbElmTm9GaXJzdEludm9jYXRpb24pIHtcblx0XHRjb25zdCBiZWZvcmVJbnZvY2F0aW9uQ2FsbE9yZGVyID0gYmVmb3JlU3B5Lm1vY2suaW52b2NhdGlvbkNhbGxPcmRlcjtcblx0XHRjb25zdCBhZnRlckludm9jYXRpb25DYWxsT3JkZXIgPSBhZnRlclNweS5tb2NrLmludm9jYXRpb25DYWxsT3JkZXI7XG5cdFx0aWYgKGJlZm9yZUludm9jYXRpb25DYWxsT3JkZXIubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gIWZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uO1xuXHRcdH1cblx0XHRpZiAoYWZ0ZXJJbnZvY2F0aW9uQ2FsbE9yZGVyLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gYmVmb3JlSW52b2NhdGlvbkNhbGxPcmRlclswXSA8IGFmdGVySW52b2NhdGlvbkNhbGxPcmRlclswXTtcblx0fVxuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZEJlZm9yZVwiXSwgZnVuY3Rpb24ocmVzdWx0U3B5LCBmYWlsSWZOb0ZpcnN0SW52b2NhdGlvbiA9IHRydWUpIHtcblx0XHRjb25zdCBleHBlY3RTcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0aWYgKCFpc01vY2tGdW5jdGlvbihyZXN1bHRTcHkpKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGAke3V0aWxzLmluc3BlY3QocmVzdWx0U3B5KX0gaXMgbm90IGEgc3B5IG9yIGEgY2FsbCB0byBhIHNweWApO1xuXHRcdH1cblx0XHR0aGlzLmFzc2VydChpc1NweUNhbGxlZEJlZm9yZUFub3RoZXJTcHkoZXhwZWN0U3B5LCByZXN1bHRTcHksIGZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uKSwgYGV4cGVjdGVkIFwiJHtleHBlY3RTcHkuZ2V0TW9ja05hbWUoKX1cIiB0byBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZSBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCBgZXhwZWN0ZWQgXCIke2V4cGVjdFNweS5nZXRNb2NrTmFtZSgpfVwiIHRvIG5vdCBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZSBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCByZXN1bHRTcHksIGV4cGVjdFNweSk7XG5cdH0pO1xuXHRkZWYoW1widG9IYXZlQmVlbkNhbGxlZEFmdGVyXCJdLCBmdW5jdGlvbihyZXN1bHRTcHksIGZhaWxJZk5vRmlyc3RJbnZvY2F0aW9uID0gdHJ1ZSkge1xuXHRcdGNvbnN0IGV4cGVjdFNweSA9IGdldFNweSh0aGlzKTtcblx0XHRpZiAoIWlzTW9ja0Z1bmN0aW9uKHJlc3VsdFNweSkpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7dXRpbHMuaW5zcGVjdChyZXN1bHRTcHkpfSBpcyBub3QgYSBzcHkgb3IgYSBjYWxsIHRvIGEgc3B5YCk7XG5cdFx0fVxuXHRcdHRoaXMuYXNzZXJ0KGlzU3B5Q2FsbGVkQmVmb3JlQW5vdGhlclNweShyZXN1bHRTcHksIGV4cGVjdFNweSwgZmFpbElmTm9GaXJzdEludm9jYXRpb24pLCBgZXhwZWN0ZWQgXCIke2V4cGVjdFNweS5nZXRNb2NrTmFtZSgpfVwiIHRvIGhhdmUgYmVlbiBjYWxsZWQgYWZ0ZXIgXCIke3Jlc3VsdFNweS5nZXRNb2NrTmFtZSgpfVwiYCwgYGV4cGVjdGVkIFwiJHtleHBlY3RTcHkuZ2V0TW9ja05hbWUoKX1cIiB0byBub3QgaGF2ZSBiZWVuIGNhbGxlZCBhZnRlciBcIiR7cmVzdWx0U3B5LmdldE1vY2tOYW1lKCl9XCJgLCByZXN1bHRTcHksIGV4cGVjdFNweSk7XG5cdH0pO1xuXHRkZWYoW1widG9UaHJvd1wiLCBcInRvVGhyb3dFcnJvclwiXSwgZnVuY3Rpb24oZXhwZWN0ZWQpIHtcblx0XHRpZiAodHlwZW9mIGV4cGVjdGVkID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiBleHBlY3RlZCA9PT0gXCJ1bmRlZmluZWRcIiB8fCBleHBlY3RlZCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuXHRcdFx0Ly8gRml4ZXMgdGhlIGlzc3VlIHJlbGF0ZWQgdG8gYGNoYWlgIDxodHRwczovL2dpdGh1Yi5jb20vdml0ZXN0LWRldi92aXRlc3QvaXNzdWVzLzY2MTg+XG5cdFx0XHRyZXR1cm4gdGhpcy50aHJvd3MoZXhwZWN0ZWQgPT09IFwiXCIgPyAvXiQvIDogZXhwZWN0ZWQpO1xuXHRcdH1cblx0XHRjb25zdCBvYmogPSB0aGlzLl9vYmo7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IHV0aWxzLmZsYWcodGhpcywgXCJwcm9taXNlXCIpO1xuXHRcdGNvbnN0IGlzTm90ID0gdXRpbHMuZmxhZyh0aGlzLCBcIm5lZ2F0ZVwiKTtcblx0XHRsZXQgdGhyb3duID0gbnVsbDtcblx0XHRpZiAocHJvbWlzZSA9PT0gXCJyZWplY3RzXCIpIHtcblx0XHRcdHRocm93biA9IG9iajtcblx0XHR9IGVsc2UgaWYgKHByb21pc2UgPT09IFwicmVzb2x2ZXNcIiAmJiB0eXBlb2Ygb2JqICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdGlmICghaXNOb3QpIHtcblx0XHRcdFx0Y29uc3QgbWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpIHx8IFwiZXhwZWN0ZWQgcHJvbWlzZSB0byB0aHJvdyBhbiBlcnJvciwgYnV0IGl0IGRpZG4ndFwiO1xuXHRcdFx0XHRjb25zdCBlcnJvciA9IHsgc2hvd0RpZmY6IGZhbHNlIH07XG5cdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNzZmlcIikpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRsZXQgaXNUaHJvdyA9IGZhbHNlO1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0b2JqKCk7XG5cdFx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdFx0aXNUaHJvdyA9IHRydWU7XG5cdFx0XHRcdHRocm93biA9IGVycjtcblx0XHRcdH1cblx0XHRcdGlmICghaXNUaHJvdyAmJiAhaXNOb3QpIHtcblx0XHRcdFx0Y29uc3QgbWVzc2FnZSA9IHV0aWxzLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpIHx8IFwiZXhwZWN0ZWQgZnVuY3Rpb24gdG8gdGhyb3cgYW4gZXJyb3IsIGJ1dCBpdCBkaWRuJ3RcIjtcblx0XHRcdFx0Y29uc3QgZXJyb3IgPSB7IHNob3dEaWZmOiBmYWxzZSB9O1xuXHRcdFx0XHR0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSwgZXJyb3IsIHV0aWxzLmZsYWcodGhpcywgXCJzc2ZpXCIpKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRjb25zdCBuYW1lID0gZXhwZWN0ZWQubmFtZSB8fCBleHBlY3RlZC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZTtcblx0XHRcdHJldHVybiB0aGlzLmFzc2VydCh0aHJvd24gJiYgdGhyb3duIGluc3RhbmNlb2YgZXhwZWN0ZWQsIGBleHBlY3RlZCBlcnJvciB0byBiZSBpbnN0YW5jZSBvZiAke25hbWV9YCwgYGV4cGVjdGVkIGVycm9yIG5vdCB0byBiZSBpbnN0YW5jZSBvZiAke25hbWV9YCwgZXhwZWN0ZWQsIHRocm93bik7XG5cdFx0fVxuXHRcdGlmIChpc0Vycm9yKGV4cGVjdGVkKSkge1xuXHRcdFx0Y29uc3QgZXF1YWwgPSBlcXVhbHModGhyb3duLCBleHBlY3RlZCwgWy4uLmN1c3RvbVRlc3RlcnMsIGl0ZXJhYmxlRXF1YWxpdHldKTtcblx0XHRcdHJldHVybiB0aGlzLmFzc2VydChlcXVhbCwgXCJleHBlY3RlZCBhIHRocm93biBlcnJvciB0byBiZSAje2V4cH1cIiwgXCJleHBlY3RlZCBhIHRocm93biBlcnJvciBub3QgdG8gYmUgI3tleHB9XCIsIGV4cGVjdGVkLCB0aHJvd24pO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIGV4cGVjdGVkID09PSBcIm9iamVjdFwiICYmIFwiYXN5bW1ldHJpY01hdGNoXCIgaW4gZXhwZWN0ZWQgJiYgdHlwZW9mIGV4cGVjdGVkLmFzeW1tZXRyaWNNYXRjaCA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRjb25zdCBtYXRjaGVyID0gZXhwZWN0ZWQ7XG5cdFx0XHRyZXR1cm4gdGhpcy5hc3NlcnQodGhyb3duICYmIG1hdGNoZXIuYXN5bW1ldHJpY01hdGNoKHRocm93biksIFwiZXhwZWN0ZWQgZXJyb3IgdG8gbWF0Y2ggYXN5bW1ldHJpYyBtYXRjaGVyXCIsIFwiZXhwZWN0ZWQgZXJyb3Igbm90IHRvIG1hdGNoIGFzeW1tZXRyaWMgbWF0Y2hlclwiLCBtYXRjaGVyLCB0aHJvd24pO1xuXHRcdH1cblx0XHRjb25zdCBlcXVhbCA9IGVxdWFscyh0aHJvd24sIGV4cGVjdGVkLCBbLi4uY3VzdG9tVGVzdGVycywgaXRlcmFibGVFcXVhbGl0eV0pO1xuXHRcdHJldHVybiB0aGlzLmFzc2VydChlcXVhbCwgXCJleHBlY3RlZCBhIHRocm93biB2YWx1ZSB0byBlcXVhbCAje2V4cH1cIiwgXCJleHBlY3RlZCBhIHRocm93biB2YWx1ZSBub3QgdG8gZXF1YWwgI3tleHB9XCIsIGV4cGVjdGVkLCB0aHJvd24pO1xuXHR9KTtcblx0W3tcblx0XHRuYW1lOiBcInRvSGF2ZVJlc29sdmVkXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5KSA9PiBzcHkubW9jay5zZXR0bGVkUmVzdWx0cy5sZW5ndGggPiAwICYmIHNweS5tb2NrLnNldHRsZWRSZXN1bHRzLnNvbWUoKHsgdHlwZSB9KSA9PiB0eXBlID09PSBcImZ1bGZpbGxlZFwiKSxcblx0XHRhY3Rpb246IFwicmVzb2x2ZWRcIlxuXHR9LCB7XG5cdFx0bmFtZTogW1widG9IYXZlUmV0dXJuZWRcIiwgXCJ0b1JldHVyblwiXSxcblx0XHRjb25kaXRpb246IChzcHkpID0+IHNweS5tb2NrLmNhbGxzLmxlbmd0aCA+IDAgJiYgc3B5Lm1vY2sucmVzdWx0cy5zb21lKCh7IHR5cGUgfSkgPT4gdHlwZSAhPT0gXCJ0aHJvd1wiKSxcblx0XHRhY3Rpb246IFwiY2FsbGVkXCJcblx0fV0uZm9yRWFjaCgoeyBuYW1lLCBjb25kaXRpb24sIGFjdGlvbiB9KSA9PiB7XG5cdFx0ZGVmKG5hbWUsIGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0Y29uc3QgcGFzcyA9IGNvbmRpdGlvbihzcHkpO1xuXHRcdFx0dGhpcy5hc3NlcnQocGFzcywgYGV4cGVjdGVkIFwiJHtzcHlOYW1lfVwiIHRvIGJlIHN1Y2Nlc3NmdWxseSAke2FjdGlvbn0gYXQgbGVhc3Qgb25jZWAsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufWAsIHBhc3MsICFwYXNzLCBmYWxzZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlUmVzb2x2ZWRUaW1lc1wiLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdGltZXMpID0+IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzLnJlZHVjZSgocywgeyB0eXBlIH0pID0+IHR5cGUgPT09IFwiZnVsZmlsbGVkXCIgPyArK3MgOiBzLCAwKSA9PT0gdGltZXMsXG5cdFx0YWN0aW9uOiBcInJlc29sdmVkXCJcblx0fSwge1xuXHRcdG5hbWU6IFtcInRvSGF2ZVJldHVybmVkVGltZXNcIiwgXCJ0b1JldHVyblRpbWVzXCJdLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdGltZXMpID0+IHNweS5tb2NrLnJlc3VsdHMucmVkdWNlKChzLCB7IHR5cGUgfSkgPT4gdHlwZSA9PT0gXCJ0aHJvd1wiID8gcyA6ICsrcywgMCkgPT09IHRpbWVzLFxuXHRcdGFjdGlvbjogXCJjYWxsZWRcIlxuXHR9XS5mb3JFYWNoKCh7IG5hbWUsIGNvbmRpdGlvbiwgYWN0aW9uIH0pID0+IHtcblx0XHRkZWYobmFtZSwgZnVuY3Rpb24odGltZXMpIHtcblx0XHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRcdGNvbnN0IHNweU5hbWUgPSBzcHkuZ2V0TW9ja05hbWUoKTtcblx0XHRcdGNvbnN0IHBhc3MgPSBjb25kaXRpb24oc3B5LCB0aW1lcyk7XG5cdFx0XHR0aGlzLmFzc2VydChwYXNzLCBgZXhwZWN0ZWQgXCIke3NweU5hbWV9XCIgdG8gYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufSAke3RpbWVzfSB0aW1lc2AsIGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgYmUgc3VjY2Vzc2Z1bGx5ICR7YWN0aW9ufSAke3RpbWVzfSB0aW1lc2AsIGBleHBlY3RlZCByZXNvbHZlZCB0aW1lczogJHt0aW1lc31gLCBgcmVjZWl2ZWQgcmVzb2x2ZWQgdGltZXM6ICR7cGFzc31gLCBmYWxzZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlUmVzb2x2ZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCB2YWx1ZSkgPT4gc3B5Lm1vY2suc2V0dGxlZFJlc3VsdHMuc29tZSgoeyB0eXBlLCB2YWx1ZTogcmVzdWx0IH0pID0+IHR5cGUgPT09IFwiZnVsZmlsbGVkXCIgJiYgZXF1YWxzKHZhbHVlLCByZXN1bHQpKSxcblx0XHRhY3Rpb246IFwicmVzb2x2ZVwiXG5cdH0sIHtcblx0XHRuYW1lOiBbXCJ0b0hhdmVSZXR1cm5lZFdpdGhcIiwgXCJ0b1JldHVybldpdGhcIl0sXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCB2YWx1ZSkgPT4gc3B5Lm1vY2sucmVzdWx0cy5zb21lKCh7IHR5cGUsIHZhbHVlOiByZXN1bHQgfSkgPT4gdHlwZSA9PT0gXCJyZXR1cm5cIiAmJiBlcXVhbHModmFsdWUsIHJlc3VsdCkpLFxuXHRcdGFjdGlvbjogXCJyZXR1cm5cIlxuXHR9XS5mb3JFYWNoKCh7IG5hbWUsIGNvbmRpdGlvbiwgYWN0aW9uIH0pID0+IHtcblx0XHRkZWYobmFtZSwgZnVuY3Rpb24odmFsdWUpIHtcblx0XHRcdGNvbnN0IHNweSA9IGdldFNweSh0aGlzKTtcblx0XHRcdGNvbnN0IHBhc3MgPSBjb25kaXRpb24oc3B5LCB2YWx1ZSk7XG5cdFx0XHRjb25zdCBpc05vdCA9IHV0aWxzLmZsYWcodGhpcywgXCJuZWdhdGVcIik7XG5cdFx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0XHRjb25zdCBtc2cgPSB1dGlscy5nZXRNZXNzYWdlKHRoaXMsIFtcblx0XHRcdFx0XHRwYXNzLFxuXHRcdFx0XHRcdGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byAke2FjdGlvbn0gd2l0aDogI3tleHB9IGF0IGxlYXN0IG9uY2VgLFxuXHRcdFx0XHRcdGBleHBlY3RlZCBcIiR7c3B5TmFtZX1cIiB0byBub3QgJHthY3Rpb259IHdpdGg6ICN7ZXhwfWAsXG5cdFx0XHRcdFx0dmFsdWVcblx0XHRcdFx0XSk7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdHMgPSBhY3Rpb24gPT09IFwicmV0dXJuXCIgPyBzcHkubW9jay5yZXN1bHRzIDogc3B5Lm1vY2suc2V0dGxlZFJlc3VsdHM7XG5cdFx0XHRcdHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihmb3JtYXRSZXR1cm5zKHNweSwgcmVzdWx0cywgbXNnLCB2YWx1ZSkpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9KTtcblx0W3tcblx0XHRuYW1lOiBcInRvSGF2ZUxhc3RSZXNvbHZlZFdpdGhcIixcblx0XHRjb25kaXRpb246IChzcHksIHZhbHVlKSA9PiB7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBzcHkubW9jay5zZXR0bGVkUmVzdWx0cy5hdCgtMSk7XG5cdFx0XHRyZXR1cm4gQm9vbGVhbihyZXN1bHQgJiYgcmVzdWx0LnR5cGUgPT09IFwiZnVsZmlsbGVkXCIgJiYgZXF1YWxzKHJlc3VsdC52YWx1ZSwgdmFsdWUpKTtcblx0XHR9LFxuXHRcdGFjdGlvbjogXCJyZXNvbHZlXCJcblx0fSwge1xuXHRcdG5hbWU6IFwidG9IYXZlTGFzdFJldHVybmVkV2l0aFwiLFxuXHRcdGNvbmRpdGlvbjogKHNweSwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnJlc3VsdHMuYXQoLTEpO1xuXHRcdFx0cmV0dXJuIEJvb2xlYW4ocmVzdWx0ICYmIHJlc3VsdC50eXBlID09PSBcInJldHVyblwiICYmIGVxdWFscyhyZXN1bHQudmFsdWUsIHZhbHVlKSk7XG5cdFx0fSxcblx0XHRhY3Rpb246IFwicmV0dXJuXCJcblx0fV0uZm9yRWFjaCgoeyBuYW1lLCBjb25kaXRpb24sIGFjdGlvbiB9KSA9PiB7XG5cdFx0ZGVmKG5hbWUsIGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHRjb25zdCBzcHkgPSBnZXRTcHkodGhpcyk7XG5cdFx0XHRjb25zdCByZXN1bHRzID0gYWN0aW9uID09PSBcInJldHVyblwiID8gc3B5Lm1vY2sucmVzdWx0cyA6IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzO1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gcmVzdWx0cy5hdCgtMSk7XG5cdFx0XHRjb25zdCBzcHlOYW1lID0gc3B5LmdldE1vY2tOYW1lKCk7XG5cdFx0XHR0aGlzLmFzc2VydChjb25kaXRpb24oc3B5LCB2YWx1ZSksIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gJHthY3Rpb259ICN7ZXhwfWAsIGBleHBlY3RlZCBsYXN0IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gbm90ICR7YWN0aW9ufSAje2V4cH1gLCB2YWx1ZSwgcmVzdWx0Py52YWx1ZSk7XG5cdFx0fSk7XG5cdH0pO1xuXHRbe1xuXHRcdG5hbWU6IFwidG9IYXZlTnRoUmVzb2x2ZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCBpbmRleCwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnNldHRsZWRSZXN1bHRzW2luZGV4IC0gMV07XG5cdFx0XHRyZXR1cm4gcmVzdWx0ICYmIHJlc3VsdC50eXBlID09PSBcImZ1bGZpbGxlZFwiICYmIGVxdWFscyhyZXN1bHQudmFsdWUsIHZhbHVlKTtcblx0XHR9LFxuXHRcdGFjdGlvbjogXCJyZXNvbHZlXCJcblx0fSwge1xuXHRcdG5hbWU6IFwidG9IYXZlTnRoUmV0dXJuZWRXaXRoXCIsXG5cdFx0Y29uZGl0aW9uOiAoc3B5LCBpbmRleCwgdmFsdWUpID0+IHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHNweS5tb2NrLnJlc3VsdHNbaW5kZXggLSAxXTtcblx0XHRcdHJldHVybiByZXN1bHQgJiYgcmVzdWx0LnR5cGUgPT09IFwicmV0dXJuXCIgJiYgZXF1YWxzKHJlc3VsdC52YWx1ZSwgdmFsdWUpO1xuXHRcdH0sXG5cdFx0YWN0aW9uOiBcInJldHVyblwiXG5cdH1dLmZvckVhY2goKHsgbmFtZSwgY29uZGl0aW9uLCBhY3Rpb24gfSkgPT4ge1xuXHRcdGRlZihuYW1lLCBmdW5jdGlvbihudGhDYWxsLCB2YWx1ZSkge1xuXHRcdFx0Y29uc3Qgc3B5ID0gZ2V0U3B5KHRoaXMpO1xuXHRcdFx0Y29uc3Qgc3B5TmFtZSA9IHNweS5nZXRNb2NrTmFtZSgpO1xuXHRcdFx0Y29uc3QgcmVzdWx0cyA9IGFjdGlvbiA9PT0gXCJyZXR1cm5cIiA/IHNweS5tb2NrLnJlc3VsdHMgOiBzcHkubW9jay5zZXR0bGVkUmVzdWx0cztcblx0XHRcdGNvbnN0IHJlc3VsdCA9IHJlc3VsdHNbbnRoQ2FsbCAtIDFdO1xuXHRcdFx0Y29uc3Qgb3JkaW5hbENhbGwgPSBgJHtvcmRpbmFsKG50aENhbGwpfSBjYWxsYDtcblx0XHRcdHRoaXMuYXNzZXJ0KGNvbmRpdGlvbihzcHksIG50aENhbGwsIHZhbHVlKSwgYGV4cGVjdGVkICR7b3JkaW5hbENhbGx9IFwiJHtzcHlOYW1lfVwiIGNhbGwgdG8gJHthY3Rpb259ICN7ZXhwfWAsIGBleHBlY3RlZCAke29yZGluYWxDYWxsfSBcIiR7c3B5TmFtZX1cIiBjYWxsIHRvIG5vdCAke2FjdGlvbn0gI3tleHB9YCwgdmFsdWUsIHJlc3VsdD8udmFsdWUpO1xuXHRcdH0pO1xuXHR9KTtcblx0Ly8gQHRzLWV4cGVjdC1lcnJvciBAaW50ZXJuYWxcblx0ZGVmKFwid2l0aENvbnRleHRcIiwgZnVuY3Rpb24oY29udGV4dCkge1xuXHRcdGZvciAoY29uc3Qga2V5IGluIGNvbnRleHQpIHtcblx0XHRcdHV0aWxzLmZsYWcodGhpcywga2V5LCBjb250ZXh0W2tleV0pO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fSk7XG5cdHV0aWxzLmFkZFByb3BlcnR5KGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgXCJyZXNvbHZlc1wiLCBmdW5jdGlvbiBfX1ZJVEVTVF9SRVNPTFZFU19fKCkge1xuXHRcdGNvbnN0IGVycm9yID0gbmV3IEVycm9yKFwicmVzb2x2ZXNcIik7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcInByb21pc2VcIiwgXCJyZXNvbHZlc1wiKTtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwiZXJyb3JcIiwgZXJyb3IpO1xuXHRcdGNvbnN0IHRlc3QgPSB1dGlscy5mbGFnKHRoaXMsIFwidml0ZXN0LXRlc3RcIik7XG5cdFx0Y29uc3Qgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKTtcblx0XHRpZiAodXRpbHMuZmxhZyh0aGlzLCBcInBvbGxcIikpIHtcblx0XHRcdHRocm93IG5ldyBTeW50YXhFcnJvcihgZXhwZWN0LnBvbGwoKSBpcyBub3Qgc3VwcG9ydGVkIGluIGNvbWJpbmF0aW9uIHdpdGggLnJlc29sdmVzYCk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2Ygb2JqPy50aGVuICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYFlvdSBtdXN0IHByb3ZpZGUgYSBQcm9taXNlIHRvIGV4cGVjdCgpIHdoZW4gdXNpbmcgLnJlc29sdmVzLCBub3QgJyR7dHlwZW9mIG9ian0nLmApO1xuXHRcdH1cblx0XHRjb25zdCBwcm94eSA9IG5ldyBQcm94eSh0aGlzLCB7IGdldDogKHRhcmdldCwga2V5LCByZWNlaXZlcikgPT4ge1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBrZXksIHJlY2VpdmVyKTtcblx0XHRcdGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdCBpbnN0YW5jZW9mIGNoYWkuQXNzZXJ0aW9uID8gcHJveHkgOiByZXN1bHQ7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gKC4uLmFyZ3MpID0+IHtcblx0XHRcdFx0dXRpbHMuZmxhZyh0aGlzLCBcIl9uYW1lXCIsIGtleSk7XG5cdFx0XHRcdGNvbnN0IHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUob2JqKS50aGVuKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIiwgdmFsdWUpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQuY2FsbCh0aGlzLCAuLi5hcmdzKTtcblx0XHRcdFx0fSwgKGVycikgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IF9lcnJvciA9IG5ldyBBc3NlcnRpb25FcnJvcihgcHJvbWlzZSByZWplY3RlZCBcIiR7dXRpbHMuaW5zcGVjdChlcnIpfVwiIGluc3RlYWQgb2YgcmVzb2x2aW5nYCwgeyBzaG93RGlmZjogZmFsc2UgfSk7XG5cdFx0XHRcdFx0X2Vycm9yLmNhdXNlID0gZXJyO1xuXHRcdFx0XHRcdHRocm93IF9lcnJvcjtcblx0XHRcdFx0fSkuY2F0Y2goKGVycikgPT4ge1xuXHRcdFx0XHRcdGlmIChpc0Vycm9yKGVycikgJiYgZXJyb3Iuc3RhY2spIHtcblx0XHRcdFx0XHRcdGVyci5zdGFjayA9IGVycm9yLnN0YWNrLnJlcGxhY2UoZXJyb3IubWVzc2FnZSwgZXJyLm1lc3NhZ2UpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aHJvdyBlcnI7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm4gcmVjb3JkQXN5bmNFeHBlY3QodGVzdCwgcHJvbWlzZSwgY3JlYXRlQXNzZXJ0aW9uTWVzc2FnZSh1dGlscywgdGhpcywgISFhcmdzLmxlbmd0aCksIGVycm9yLCB1dGlscy5mbGFnKHRoaXMsIFwic29mdFwiKSk7XG5cdFx0XHR9O1xuXHRcdH0gfSk7XG5cdFx0cmV0dXJuIHByb3h5O1xuXHR9KTtcblx0dXRpbHMuYWRkUHJvcGVydHkoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInJlamVjdHNcIiwgZnVuY3Rpb24gX19WSVRFU1RfUkVKRUNUU19fKCkge1xuXHRcdGNvbnN0IGVycm9yID0gbmV3IEVycm9yKFwicmVqZWN0c1wiKTtcblx0XHR1dGlscy5mbGFnKHRoaXMsIFwicHJvbWlzZVwiLCBcInJlamVjdHNcIik7XG5cdFx0dXRpbHMuZmxhZyh0aGlzLCBcImVycm9yXCIsIGVycm9yKTtcblx0XHRjb25zdCB0ZXN0ID0gdXRpbHMuZmxhZyh0aGlzLCBcInZpdGVzdC10ZXN0XCIpO1xuXHRcdGNvbnN0IG9iaiA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3Qgd3JhcHBlciA9IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiA/IG9iaigpIDogb2JqO1xuXHRcdGlmICh1dGlscy5mbGFnKHRoaXMsIFwicG9sbFwiKSkge1xuXHRcdFx0dGhyb3cgbmV3IFN5bnRheEVycm9yKGBleHBlY3QucG9sbCgpIGlzIG5vdCBzdXBwb3J0ZWQgaW4gY29tYmluYXRpb24gd2l0aCAucmVqZWN0c2ApO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHdyYXBwZXI/LnRoZW4gIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgWW91IG11c3QgcHJvdmlkZSBhIFByb21pc2UgdG8gZXhwZWN0KCkgd2hlbiB1c2luZyAucmVqZWN0cywgbm90ICcke3R5cGVvZiB3cmFwcGVyfScuYCk7XG5cdFx0fVxuXHRcdGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KHRoaXMsIHsgZ2V0OiAodGFyZ2V0LCBrZXksIHJlY2VpdmVyKSA9PiB7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuXHRcdFx0aWYgKHR5cGVvZiByZXN1bHQgIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0IGluc3RhbmNlb2YgY2hhaS5Bc3NlcnRpb24gPyBwcm94eSA6IHJlc3VsdDtcblx0XHRcdH1cblx0XHRcdHJldHVybiAoLi4uYXJncykgPT4ge1xuXHRcdFx0XHR1dGlscy5mbGFnKHRoaXMsIFwiX25hbWVcIiwga2V5KTtcblx0XHRcdFx0Y29uc3QgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh3cmFwcGVyKS50aGVuKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IF9lcnJvciA9IG5ldyBBc3NlcnRpb25FcnJvcihgcHJvbWlzZSByZXNvbHZlZCBcIiR7dXRpbHMuaW5zcGVjdCh2YWx1ZSl9XCIgaW5zdGVhZCBvZiByZWplY3RpbmdgLCB7XG5cdFx0XHRcdFx0XHRzaG93RGlmZjogdHJ1ZSxcblx0XHRcdFx0XHRcdGV4cGVjdGVkOiBuZXcgRXJyb3IoXCJyZWplY3RlZCBwcm9taXNlXCIpLFxuXHRcdFx0XHRcdFx0YWN0dWFsOiB2YWx1ZVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdHRocm93IF9lcnJvcjtcblx0XHRcdFx0fSwgKGVycikgPT4ge1xuXHRcdFx0XHRcdHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIiwgZXJyKTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgLi4uYXJncyk7XG5cdFx0XHRcdH0pLmNhdGNoKChlcnIpID0+IHtcblx0XHRcdFx0XHRpZiAoaXNFcnJvcihlcnIpICYmIGVycm9yLnN0YWNrKSB7XG5cdFx0XHRcdFx0XHRlcnIuc3RhY2sgPSBlcnJvci5zdGFjay5yZXBsYWNlKGVycm9yLm1lc3NhZ2UsIGVyci5tZXNzYWdlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhyb3cgZXJyO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmV0dXJuIHJlY29yZEFzeW5jRXhwZWN0KHRlc3QsIHByb21pc2UsIGNyZWF0ZUFzc2VydGlvbk1lc3NhZ2UodXRpbHMsIHRoaXMsICEhYXJncy5sZW5ndGgpLCBlcnJvciwgdXRpbHMuZmxhZyh0aGlzLCBcInNvZnRcIikpO1xuXHRcdFx0fTtcblx0XHR9IH0pO1xuXHRcdHJldHVybiBwcm94eTtcblx0fSk7XG59O1xuZnVuY3Rpb24gZm9ybWF0Q2FsbHMoc3B5LCBtc2csIHNob3dBY3R1YWxDYWxsKSB7XG5cdGlmIChzcHkubW9jay5jYWxscy5sZW5ndGgpIHtcblx0XHRtc2cgKz0gYy5ncmF5KGBcXG5cXG5SZWNlaXZlZDpcXG5cXG4ke3NweS5tb2NrLmNhbGxzLm1hcCgoY2FsbEFyZywgaSkgPT4ge1xuXHRcdFx0bGV0IG1ldGhvZENhbGwgPSBjLmJvbGQoYCAgJHtvcmRpbmFsKGkgKyAxKX0gJHtzcHkuZ2V0TW9ja05hbWUoKX0gY2FsbDpcXG5cXG5gKTtcblx0XHRcdGlmIChzaG93QWN0dWFsQ2FsbCkge1xuXHRcdFx0XHRtZXRob2RDYWxsICs9IGRpZmYoc2hvd0FjdHVhbENhbGwsIGNhbGxBcmcsIHsgb21pdEFubm90YXRpb25MaW5lczogdHJ1ZSB9KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1ldGhvZENhbGwgKz0gc3RyaW5naWZ5KGNhbGxBcmcpLnNwbGl0KFwiXFxuXCIpLm1hcCgobGluZSkgPT4gYCAgICAke2xpbmV9YCkuam9pbihcIlxcblwiKTtcblx0XHRcdH1cblx0XHRcdG1ldGhvZENhbGwgKz0gXCJcXG5cIjtcblx0XHRcdHJldHVybiBtZXRob2RDYWxsO1xuXHRcdH0pLmpvaW4oXCJcXG5cIil9YCk7XG5cdH1cblx0bXNnICs9IGMuZ3JheShgXFxuXFxuTnVtYmVyIG9mIGNhbGxzOiAke2MuYm9sZChzcHkubW9jay5jYWxscy5sZW5ndGgpfVxcbmApO1xuXHRyZXR1cm4gbXNnO1xufVxuZnVuY3Rpb24gZm9ybWF0UmV0dXJucyhzcHksIHJlc3VsdHMsIG1zZywgc2hvd0FjdHVhbFJldHVybikge1xuXHRpZiAocmVzdWx0cy5sZW5ndGgpIHtcblx0XHRtc2cgKz0gYy5ncmF5KGBcXG5cXG5SZWNlaXZlZDpcXG5cXG4ke3Jlc3VsdHMubWFwKChjYWxsUmV0dXJuLCBpKSA9PiB7XG5cdFx0XHRsZXQgbWV0aG9kQ2FsbCA9IGMuYm9sZChgICAke29yZGluYWwoaSArIDEpfSAke3NweS5nZXRNb2NrTmFtZSgpfSBjYWxsIHJldHVybjpcXG5cXG5gKTtcblx0XHRcdGlmIChzaG93QWN0dWFsUmV0dXJuKSB7XG5cdFx0XHRcdG1ldGhvZENhbGwgKz0gZGlmZihzaG93QWN0dWFsUmV0dXJuLCBjYWxsUmV0dXJuLnZhbHVlLCB7IG9taXRBbm5vdGF0aW9uTGluZXM6IHRydWUgfSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtZXRob2RDYWxsICs9IHN0cmluZ2lmeShjYWxsUmV0dXJuKS5zcGxpdChcIlxcblwiKS5tYXAoKGxpbmUpID0+IGAgICAgJHtsaW5lfWApLmpvaW4oXCJcXG5cIik7XG5cdFx0XHR9XG5cdFx0XHRtZXRob2RDYWxsICs9IFwiXFxuXCI7XG5cdFx0XHRyZXR1cm4gbWV0aG9kQ2FsbDtcblx0XHR9KS5qb2luKFwiXFxuXCIpfWApO1xuXHR9XG5cdG1zZyArPSBjLmdyYXkoYFxcblxcbk51bWJlciBvZiBjYWxsczogJHtjLmJvbGQoc3B5Lm1vY2suY2FsbHMubGVuZ3RoKX1cXG5gKTtcblx0cmV0dXJuIG1zZztcbn1cblxuZnVuY3Rpb24gZ2V0TWF0Y2hlclN0YXRlKGFzc2VydGlvbiwgZXhwZWN0KSB7XG5cdGNvbnN0IG9iaiA9IGFzc2VydGlvbi5fb2JqO1xuXHRjb25zdCBpc05vdCA9IHV0aWwuZmxhZyhhc3NlcnRpb24sIFwibmVnYXRlXCIpO1xuXHRjb25zdCBwcm9taXNlID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJwcm9taXNlXCIpIHx8IFwiXCI7XG5cdGNvbnN0IGN1c3RvbU1lc3NhZ2UgPSB1dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIm1lc3NhZ2VcIik7XG5cdGNvbnN0IGplc3RVdGlscyA9IHtcblx0XHQuLi5nZXRNYXRjaGVyVXRpbHMoKSxcblx0XHRkaWZmLFxuXHRcdHN0cmluZ2lmeSxcblx0XHRpdGVyYWJsZUVxdWFsaXR5LFxuXHRcdHN1YnNldEVxdWFsaXR5XG5cdH07XG5cdGxldCB0YXNrID0gdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0Y29uc3QgY3VycmVudFRlc3ROYW1lID0gdGFzaz8uZnVsbFRlc3ROYW1lID8/IFwiXCI7XG5cdGlmICh0YXNrPy50eXBlICE9PSBcInRlc3RcIikge1xuXHRcdHRhc2sgPSB1bmRlZmluZWQ7XG5cdH1cblx0Y29uc3QgbWF0Y2hlclN0YXRlID0ge1xuXHRcdC4uLmdldFN0YXRlKGV4cGVjdCksXG5cdFx0Y3VycmVudFRlc3ROYW1lLFxuXHRcdGN1c3RvbVRlc3RlcnM6IGdldEN1c3RvbUVxdWFsaXR5VGVzdGVycygpLFxuXHRcdGlzTm90LFxuXHRcdHV0aWxzOiBqZXN0VXRpbHMsXG5cdFx0cHJvbWlzZSxcblx0XHRlcXVhbHMsXG5cdFx0c3VwcHJlc3NlZEVycm9yczogW10sXG5cdFx0c29mdDogdXRpbC5mbGFnKGFzc2VydGlvbiwgXCJzb2Z0XCIpLFxuXHRcdHBvbGw6IHV0aWwuZmxhZyhhc3NlcnRpb24sIFwicG9sbFwiKSxcblx0XHRhc3NlcnRpb25cblx0fTtcblx0T2JqZWN0LmFzc2lnbihtYXRjaGVyU3RhdGUsIHsgdGFzayB9KTtcblx0cmV0dXJuIHtcblx0XHRzdGF0ZTogbWF0Y2hlclN0YXRlLFxuXHRcdGlzTm90LFxuXHRcdG9iaixcblx0XHRjdXN0b21NZXNzYWdlXG5cdH07XG59XG5jbGFzcyBKZXN0RXh0ZW5kRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGFjdHVhbCwgZXhwZWN0ZWQsIF9fdml0ZXN0X2Vycm9yX2NvbnRleHRfXykge1xuXHRcdHN1cGVyKG1lc3NhZ2UpO1xuXHRcdHRoaXMuYWN0dWFsID0gYWN0dWFsO1xuXHRcdHRoaXMuZXhwZWN0ZWQgPSBleHBlY3RlZDtcblx0XHR0aGlzLl9fdml0ZXN0X2Vycm9yX2NvbnRleHRfXyA9IF9fdml0ZXN0X2Vycm9yX2NvbnRleHRfXztcblx0fVxufVxuZnVuY3Rpb24gSmVzdEV4dGVuZFBsdWdpbihjLCBleHBlY3QsIG1hdGNoZXJzKSB7XG5cdHJldHVybiAoXywgdXRpbHMpID0+IHtcblx0XHRPYmplY3QuZW50cmllcyhtYXRjaGVycykuZm9yRWFjaCgoW2V4cGVjdEFzc2VydGlvbk5hbWUsIGV4cGVjdEFzc2VydGlvbl0pID0+IHtcblx0XHRcdGZ1bmN0aW9uIF9fVklURVNUX0VYVEVORF9BU1NFUlRJT05fXyguLi5hcmdzKSB7XG5cdFx0XHRcdGNvbnN0IHsgc3RhdGUsIGlzTm90LCBvYmosIGN1c3RvbU1lc3NhZ2UgfSA9IGdldE1hdGNoZXJTdGF0ZSh0aGlzLCBleHBlY3QpO1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBleHBlY3RBc3NlcnRpb24uY2FsbChzdGF0ZSwgb2JqLCAuLi5hcmdzKTtcblx0XHRcdFx0aWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdFx0Y29uc3QgdGhlbmFibGUgPSByZXN1bHQ7XG5cdFx0XHRcdFx0cmV0dXJuIHRoZW5hYmxlLnRoZW4oKHsgcGFzcywgbWVzc2FnZSwgYWN0dWFsLCBleHBlY3RlZCwgbWV0YSB9KSA9PiB7XG5cdFx0XHRcdFx0XHRpZiAocGFzcyAmJiBpc05vdCB8fCAhcGFzcyAmJiAhaXNOb3QpIHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgZXJyb3JNZXNzYWdlID0gKGN1c3RvbU1lc3NhZ2UgPyBgJHtjdXN0b21NZXNzYWdlfTogYCA6IFwiXCIpICsgbWVzc2FnZSgpO1xuXHRcdFx0XHRcdFx0XHR0aHJvdyBuZXcgSmVzdEV4dGVuZEVycm9yKGVycm9yTWVzc2FnZSwgYWN0dWFsLCBleHBlY3RlZCwge1xuXHRcdFx0XHRcdFx0XHRcdGFzc2VydGlvbk5hbWU6IGV4cGVjdEFzc2VydGlvbk5hbWUsXG5cdFx0XHRcdFx0XHRcdFx0bWV0YVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjb25zdCB7IHBhc3MsIG1lc3NhZ2UsIGFjdHVhbCwgZXhwZWN0ZWQsIG1ldGEgfSA9IHJlc3VsdDtcblx0XHRcdFx0aWYgKHBhc3MgJiYgaXNOb3QgfHwgIXBhc3MgJiYgIWlzTm90KSB7XG5cdFx0XHRcdFx0Y29uc3QgZXJyb3JNZXNzYWdlID0gKGN1c3RvbU1lc3NhZ2UgPyBgJHtjdXN0b21NZXNzYWdlfTogYCA6IFwiXCIpICsgbWVzc2FnZSgpO1xuXHRcdFx0XHRcdHRocm93IG5ldyBKZXN0RXh0ZW5kRXJyb3IoZXJyb3JNZXNzYWdlLCBhY3R1YWwsIGV4cGVjdGVkLCB7XG5cdFx0XHRcdFx0XHRhc3NlcnRpb25OYW1lOiBleHBlY3RBc3NlcnRpb25OYW1lLFxuXHRcdFx0XHRcdFx0bWV0YVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBzb2Z0V3JhcHBlciA9IHdyYXBBc3NlcnRpb24odXRpbHMsIGV4cGVjdEFzc2VydGlvbk5hbWUsIF9fVklURVNUX0VYVEVORF9BU1NFUlRJT05fXyk7XG5cdFx0XHR1dGlscy5hZGRNZXRob2QoZ2xvYmFsVGhpc1tKRVNUX01BVENIRVJTX09CSkVDVF0ubWF0Y2hlcnMsIGV4cGVjdEFzc2VydGlvbk5hbWUsIHNvZnRXcmFwcGVyKTtcblx0XHRcdHV0aWxzLmFkZE1ldGhvZChjLkFzc2VydGlvbi5wcm90b3R5cGUsIGV4cGVjdEFzc2VydGlvbk5hbWUsIHNvZnRXcmFwcGVyKTtcblx0XHRcdC8vIGBleHBlY3QucG9sbCgpYCBpbnNwZWN0cyB0aGUgaW5zdGFsbGVkIENoYWkgYXNzZXJ0aW9uIG1ldGhvZCxcblx0XHRcdC8vIHNvIGNvcHkgdGhlIGludGVybmFsIG1hcmtlciBmcm9tIHRoZSBvcmlnaW5hbCBtYXRjaGVyIGZ1bmN0aW9uLlxuXHRcdFx0Ly8gdGhpcyBpcyBvbmx5IGZvciBkb21haW4gc25hcHNob3QgbWF0Y2hlcnMgZm9yIG5vdy5cblx0XHRcdGlmIChleHBlY3RBc3NlcnRpb24uX192aXRlc3RfcG9sbF90YWtlb3Zlcl9fKSB7XG5cdFx0XHRcdGNvbnN0IGFkZGVkTWV0aG9kID0gYy5Bc3NlcnRpb24ucHJvdG90eXBlW2V4cGVjdEFzc2VydGlvbk5hbWVdO1xuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoYWRkZWRNZXRob2QsIFwiX192aXRlc3RfcG9sbF90YWtlb3Zlcl9fXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdFx0XHR9XG5cdFx0XHRjbGFzcyBDdXN0b21NYXRjaGVyIGV4dGVuZHMgQXN5bW1ldHJpY01hdGNoZXIge1xuXHRcdFx0XHRjb25zdHJ1Y3RvcihpbnZlcnNlID0gZmFsc2UsIC4uLnNhbXBsZSkge1xuXHRcdFx0XHRcdHN1cGVyKHNhbXBsZSwgaW52ZXJzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0YXN5bW1ldHJpY01hdGNoKG90aGVyKSB7XG5cdFx0XHRcdFx0Y29uc3QgeyBwYXNzIH0gPSBleHBlY3RBc3NlcnRpb24uY2FsbCh0aGlzLmdldE1hdGNoZXJDb250ZXh0KGV4cGVjdCksIG90aGVyLCAuLi50aGlzLnNhbXBsZSk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuaW52ZXJzZSA/ICFwYXNzIDogcGFzcztcblx0XHRcdFx0fVxuXHRcdFx0XHR0b1N0cmluZygpIHtcblx0XHRcdFx0XHRyZXR1cm4gYCR7dGhpcy5pbnZlcnNlID8gXCJub3QuXCIgOiBcIlwifSR7ZXhwZWN0QXNzZXJ0aW9uTmFtZX1gO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGdldEV4cGVjdGVkVHlwZSgpIHtcblx0XHRcdFx0XHRyZXR1cm4gXCJhbnlcIjtcblx0XHRcdFx0fVxuXHRcdFx0XHR0b0FzeW1tZXRyaWNNYXRjaGVyKCkge1xuXHRcdFx0XHRcdHJldHVybiBgJHt0aGlzLnRvU3RyaW5nKCl9PCR7dGhpcy5zYW1wbGUubWFwKChpdGVtKSA9PiBzdHJpbmdpZnkoaXRlbSkpLmpvaW4oXCIsIFwiKX0+YDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Y29uc3QgY3VzdG9tTWF0Y2hlciA9ICguLi5zYW1wbGUpID0+IG5ldyBDdXN0b21NYXRjaGVyKGZhbHNlLCAuLi5zYW1wbGUpO1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cGVjdCwgZXhwZWN0QXNzZXJ0aW9uTmFtZSwge1xuXHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRcdHZhbHVlOiBjdXN0b21NYXRjaGVyLFxuXHRcdFx0XHR3cml0YWJsZTogdHJ1ZVxuXHRcdFx0fSk7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwZWN0Lm5vdCwgZXhwZWN0QXNzZXJ0aW9uTmFtZSwge1xuXHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRcdHZhbHVlOiAoLi4uc2FtcGxlKSA9PiBuZXcgQ3VzdG9tTWF0Y2hlcih0cnVlLCAuLi5zYW1wbGUpLFxuXHRcdFx0XHR3cml0YWJsZTogdHJ1ZVxuXHRcdFx0fSk7XG5cdFx0XHQvLyBrZWVwIHRyYWNrIG9mIGFzeW1tZXRyaWMgbWF0Y2hlcnMgb24gZ2xvYmFsIHNvIHRoYXQgaXQgY2FuIGJlIGNvcGllZCBvdmVyIHRvIGxvY2FsIGNvbnRleHQncyBgZXhwZWN0YC5cblx0XHRcdC8vIG5vdGUgdGhhdCB0aGUgbmVnYXRlZCB2YXJpYW50IGlzIGF1dG9tYXRpY2FsbHkgc2hhcmVkIHNpbmNlIGl0J3MgYXNzaWduZWQgb24gdGhlIHNpbmdsZSBgZXhwZWN0Lm5vdGAgb2JqZWN0LlxuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbFRoaXNbQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1RdLCBleHBlY3RBc3NlcnRpb25OYW1lLCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdFx0dmFsdWU6IGN1c3RvbU1hdGNoZXIsXG5cdFx0XHRcdHdyaXRhYmxlOiB0cnVlXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fTtcbn1cbmNvbnN0IEplc3RFeHRlbmQgPSAoY2hhaSwgdXRpbHMpID0+IHtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuZXhwZWN0LCBcImV4dGVuZFwiLCAoZXhwZWN0LCBleHBlY3RzKSA9PiB7XG5cdFx0dXNlKEplc3RFeHRlbmRQbHVnaW4oY2hhaSwgZXhwZWN0LCBleHBlY3RzKSk7XG5cdH0pO1xufTtcblxuZXhwb3J0IHsgQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1QsIEFueSwgQW55dGhpbmcsIEFycmF5Q29udGFpbmluZywgQXN5bW1ldHJpY01hdGNoZXIsIENoYWlTdHlsZUFzc2VydGlvbnMsIEdMT0JBTF9FWFBFQ1QsIEpFU1RfTUFUQ0hFUlNfT0JKRUNULCBKZXN0QXN5bW1ldHJpY01hdGNoZXJzLCBKZXN0Q2hhaUV4cGVjdCwgSmVzdEV4dGVuZCwgTUFUQ0hFUlNfT0JKRUNULCBPYmplY3RDb250YWluaW5nLCBTY2hlbWFNYXRjaGluZywgU3RyaW5nQ29udGFpbmluZywgU3RyaW5nTWF0Y2hpbmcsIGFkZEN1c3RvbUVxdWFsaXR5VGVzdGVycywgYXJyYXlCdWZmZXJFcXVhbGl0eSwgY3JlYXRlQXNzZXJ0aW9uTWVzc2FnZSwgY3VzdG9tTWF0Y2hlcnMsIGVxdWFscywgZm5OYW1lRm9yLCBnZW5lcmF0ZVRvQmVNZXNzYWdlLCBnZXRPYmplY3RLZXlzLCBnZXRPYmplY3RTdWJzZXQsIGdldFN0YXRlLCBoYXNBc3ltbWV0cmljLCBoYXNQcm9wZXJ0eSwgaXNBLCBpc0FzeW1tZXRyaWMsIGlzRXJyb3IsIGlzSW1tdXRhYmxlVW5vcmRlcmVkS2V5ZWQsIGlzSW1tdXRhYmxlVW5vcmRlcmVkU2V0LCBpc1N0YW5kYXJkU2NoZW1hLCBpdGVyYWJsZUVxdWFsaXR5LCBwbHVyYWxpemUsIHJlY29yZEFzeW5jRXhwZWN0LCBzZXRTdGF0ZSwgc3BhcnNlQXJyYXlFcXVhbGl0eSwgc3Vic2V0RXF1YWxpdHksIHR5cGVFcXVhbGl0eSwgd3JhcEFzc2VydGlvbiB9O1xuIl0sInhfZ29vZ2xlX2lnbm9yZUxpc3QiOlswXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBVUEsTUFBTSx1QkFBdUIsTUFBTSxVQUFVO0NBQzVDLFNBQVMsWUFBWSxNQUFNLFlBQVk7RUFDdEMsTUFBTSxZQUFZLEtBQUssVUFBVSxXQUFXLE1BQU0sV0FBVztHQUM1RCxNQUFNLGFBQWEsS0FBSyxVQUFVLFVBQVU7R0FDNUMsSUFBSSxDQUFDLFlBQ0osTUFBTSxJQUFJLE1BQU0sc0JBQXNCLE9BQU8sVUFBVSxFQUFFLGtFQUFrRTtHQUU1SCxPQUFPLFdBQVcsS0FBSyxJQUFJO0VBQzVCLENBQUM7Q0FDRjtDQUNBLFNBQVMsb0JBQW9CLE1BQU0sWUFBWSxHQUFHLE1BQU07RUFDdkQsTUFBTSxZQUFZLEtBQUssVUFBVSxXQUFXLE1BQU0sV0FBVztHQUM1RCxNQUFNLGFBQWEsS0FBSyxVQUFVLFVBQVU7R0FDNUMsSUFBSSxDQUFDLFlBQ0osTUFBTSxJQUFJLE1BQU0sc0JBQXNCLE9BQU8sVUFBVSxFQUFFLGtFQUFrRTtHQUU1SCxPQUFPLFdBQVcsS0FBSyxNQUFNLEdBQUcsSUFBSTtFQUNyQyxDQUFDO0NBQ0Y7Q0FDQSxTQUFTLFVBQVUsTUFBTSxZQUFZO0VBQ3BDLE1BQU0sVUFBVSxLQUFLLFVBQVUsV0FBVyxNQUFNLFNBQVMsR0FBRyxNQUFNO0dBQ2pFLE1BQU0sYUFBYSxLQUFLLFVBQVUsVUFBVTtHQUM1QyxJQUFJLENBQUMsWUFDSixNQUFNLElBQUksTUFBTSxzQkFBc0IsT0FBTyxVQUFVLEVBQUUsa0VBQWtFO0dBRTVILE9BQU8sV0FBVyxLQUFLLE1BQU0sR0FBRyxJQUFJO0VBQ3JDLENBQUM7Q0FDRjtDQUdBLFlBQVksVUFBVSxrQkFBa0I7Q0FDeEMsWUFBWSxjQUFjLHNCQUFzQjtDQUNoRCxvQkFBb0IsZUFBZSx5QkFBeUIsQ0FBQztDQUM3RCxvQkFBb0IsZ0JBQWdCLHlCQUF5QixDQUFDO0NBQzlELFVBQVUsYUFBYSx1QkFBdUI7Q0FDOUMsVUFBVSxjQUFjLHNCQUFzQjtDQUM5QyxVQUFVLGtCQUFrQixpQ0FBaUM7Q0FDN0QsVUFBVSxrQkFBa0IsMEJBQTBCO0NBQ3RELFVBQVUsaUJBQWlCLHlCQUF5QjtDQUNwRCxVQUFVLFlBQVksZ0JBQWdCO0NBQ3RDLFVBQVUsZ0JBQWdCLG9CQUFvQjtDQUM5QyxVQUFVLGlCQUFpQixxQkFBcUI7Q0FDaEQsVUFBVSxvQkFBb0Isd0JBQXdCO0NBQ3RELFVBQVUsbUJBQW1CLHVCQUF1QjtDQUNwRCxVQUFVLGdCQUFnQix3QkFBd0I7Q0FDbEQsVUFBVSxlQUFlLHVCQUF1QjtBQUdqRDtBQUVBLE1BQU0sa0JBQWtCLE9BQU8sSUFBSSxpQkFBaUI7QUFDcEQsTUFBTSx1QkFBdUIsT0FBTyxJQUFJLHdCQUF3QjtBQUNoRSxNQUFNLGdCQUFnQixPQUFPLElBQUksZUFBZTtBQUNoRCxNQUFNLDZCQUE2QixPQUFPLElBQUksNEJBQTRCO0FBRzFFLE1BQU0saUJBQWlCO0NBQ3RCLFVBQVUsUUFBUSxVQUFVLFNBQVM7RUFDcEMsTUFBTSxFQUFFLGVBQWUsZUFBZSxnQkFBZ0IsS0FBSztFQUMzRCxNQUFNLE9BQU8sU0FBUyxNQUFNO0VBQzVCLE9BQU87R0FDTjtHQUNBLGVBQWUsT0FBTztFQUN2QixZQUFZLGtCQUFrQixZQUFZLEVBQUUsRUFBRTs7O0VBRzlDLFdBQVcsY0FBYyxRQUFRLEVBQUU7O0VBRW5DLGNBQWMsTUFBTSxNQUFNO0VBQzFCLFlBQVksY0FBYyxZQUFZLEVBQUUsRUFBRTs7O0VBRzFDLFdBQVcsY0FBYyxRQUFRLEVBQUU7OztFQUduQyxjQUFjLE1BQU07RUFDcEI7Q0FDRDtDQUNBLFVBQVUsUUFBUSxVQUFVO0VBQzNCLE1BQU0sRUFBRSxRQUFRLGtCQUFrQjtFQUNsQyxNQUFNLEVBQUUsZUFBZSxlQUFlLGdCQUFnQixLQUFLO0VBQzNELElBQUk7RUFDSixJQUFJLE1BQU0sUUFBUSxRQUFRLEdBQ3pCLE9BQU8sU0FBUyxXQUFXLEtBQUssU0FBUyxNQUFNLFNBQVMsT0FBTyxNQUFNLFFBQVEsYUFBYSxDQUFDO09BQ3JGLElBQUksb0JBQW9CLEtBQzlCLE9BQU8sU0FBUyxTQUFTLEtBQUssU0FBUyxJQUFJLE1BQU0sS0FBSyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsTUFBTSxTQUFTLE9BQU8sTUFBTSxRQUFRLGFBQWEsQ0FBQztPQUV0SCxNQUFNLElBQUksVUFBVSx1Q0FBdUMsWUFBWSxZQUFZLEVBQUUsU0FBUyxPQUFPLFNBQVMsR0FBRztFQUVsSCxPQUFPO0dBQ047R0FDQSxlQUFlLE9BQU87RUFDdkIsWUFBWSxrQkFBa0IsWUFBWSxFQUFFLEVBQUU7OztFQUc5QyxjQUFjLFFBQVEsRUFBRTs7RUFFeEIsY0FBYyxNQUFNLE1BQU07RUFDMUIsWUFBWSxjQUFjLFlBQVksRUFBRSxFQUFFOzs7RUFHMUMsY0FBYyxRQUFRLEVBQUU7OztFQUd4QixjQUFjLE1BQU07RUFDcEI7Q0FDRDtBQUNEO0FBRUEsTUFBTSxpQkFBaUJBLEVBQUU7QUFDekIsTUFBTSxpQkFBaUJBLEVBQUU7QUFDekIsTUFBTSxpQkFBaUJBLEVBQUU7QUFDekIsTUFBTSxjQUFjQSxFQUFFO0FBQ3RCLE1BQU0sWUFBWUEsRUFBRTtBQUNwQixTQUFTLFlBQVksYUFBYSxXQUFXLFlBQVksV0FBVyxZQUFZLFVBQVUsQ0FBQyxHQUFHO0NBQzdGLE1BQU0sRUFBRSxVQUFVLElBQUkscUJBQXFCLE9BQU8sUUFBUSxPQUFPLFVBQVUsSUFBSSxpQkFBaUIsSUFBSSxnQkFBZ0IsZ0JBQWdCLGdCQUFnQixnQkFBZ0Isc0JBQXNCLG1CQUFtQjtDQUM3TSxJQUFJLE9BQU87Q0FDWCxJQUFJLFlBQVk7Q0FDaEIsSUFBSSxDQUFDLHNCQUFzQixhQUFhLElBQUk7RUFDM0MsUUFBUSxVQUFVLEdBQUcsVUFBVSxFQUFFLElBQUksY0FBYyxRQUFRO0VBQzNELFlBQVk7Q0FDYjtDQUNBLElBQUksWUFBWSxJQUFJO0VBQ25CLFFBQVEsVUFBVSxHQUFHLFVBQVUsRUFBRSxJQUFJO0VBQ3JDLFlBQVk7Q0FDYjtDQUNBLElBQUksT0FBTztFQUNWLFFBQVEsR0FBRyxVQUFVLEdBQUcsVUFBVSxFQUFFLEVBQUU7RUFDdEMsWUFBWTtDQUNiO0NBQ0EsSUFBSSxZQUFZLFNBQVMsR0FBRyxHQUczQixhQUFhO01BQ1A7RUFFTixRQUFRLFVBQVUsR0FBRyxVQUFVLEVBQUUsSUFBSTtFQUNyQyxZQUFZO0NBQ2I7Q0FDQSxJQUFJLGFBQWEsSUFDaEIsYUFBYTtNQUNQO0VBQ04sUUFBUSxVQUFVLEdBQUcsVUFBVSxFQUFFLElBQUksY0FBYyxRQUFRO0VBQzNELElBQUksZ0JBQ0gsUUFBUSxVQUFVLElBQUksSUFBSSxvQkFBb0IsY0FBYztFQUU3RCxZQUFZO0NBQ2I7Q0FDQSxJQUFJLFlBQVksSUFDZixhQUFhLE9BQU87Q0FFckIsSUFBSSxjQUFjLElBQ2pCLFFBQVEsVUFBVSxTQUFTO0NBRTVCLE9BQU87QUFDUjtBQUNBLE1BQU0sZUFBZTtBQUdyQixTQUFTLHNCQUFzQixNQUFNO0NBQ3BDLE9BQU8sS0FBSyxRQUFRLFdBQVcsV0FBVyxhQUFhLE9BQU8sT0FBTyxNQUFNLENBQUM7QUFDN0U7QUFDQSxTQUFTLGNBQWMsUUFBUTtDQUM5QixPQUFPLGVBQWUsc0JBQXNCLFVBQVUsTUFBTSxDQUFDLENBQUM7QUFDL0Q7QUFDQSxTQUFTLGNBQWMsT0FBTztDQUM3QixPQUFPLGVBQWUsc0JBQXNCLFVBQVUsS0FBSyxDQUFDLENBQUM7QUFDOUQ7QUFDQSxTQUFTLGtCQUFrQjtDQUMxQixPQUFPO0VBQ047RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtDQUNEO0FBQ0Q7QUFDQSxTQUFTLGNBQWMsTUFBTSxPQUFPLE9BQU87Q0FDMUMsTUFBTSxPQUFPLFFBQVEsS0FBSztDQUcxQixRQUZnQixTQUFTLFVBQVUsU0FBUyxjQUFjLEdBQUcsS0FBSyxjQUFjLEtBQUssTUFBTSxNQUUxRSxHQURHLEtBQUssY0FBYyxNQUFNLEtBQUs7QUFFbkQ7QUFDQSxTQUFTLHlCQUF5QixZQUFZO0NBQzdDLElBQUksQ0FBQyxNQUFNLFFBQVEsVUFBVSxHQUM1QixNQUFNLElBQUksVUFBVSxnRkFBZ0YsUUFBUSxVQUFVLEVBQUUsRUFBRTtDQUUzSCxXQUFXLHFCQUFxQixDQUFDLHNCQUFzQixLQUFLLEdBQUcsVUFBVTtBQUMxRTtBQUNBLFNBQVMsMkJBQTJCO0NBQ25DLE9BQU8sV0FBVyxxQkFBcUIsQ0FBQztBQUN6QztBQUdBLFNBQVMsT0FBTyxHQUFHLEdBQUcsZUFBZSxhQUFhO0NBQ2pELGdCQUFnQixpQkFBaUIsQ0FBQztDQUNsQyxPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsZUFBZSxjQUFjLFNBQVMsYUFBYTtBQUM1RTtBQUNBLE1BQU0sbUJBQW1CLFNBQVMsVUFBVTtBQUM1QyxTQUFTLGFBQWEsS0FBSztDQUMxQixPQUFPLENBQUMsQ0FBQyxPQUFPLE9BQU8sUUFBUSxZQUFZLHFCQUFxQixPQUFPLElBQUksWUFBWSxJQUFJLGVBQWU7QUFDM0c7QUFDQSxTQUFTLGNBQWMsS0FBSyx1QkFBTyxJQUFJLElBQUksR0FBRztDQUM3QyxJQUFJLEtBQUssSUFBSSxHQUFHLEdBQ2YsT0FBTztDQUVSLEtBQUssSUFBSSxHQUFHO0NBQ1osSUFBSSxhQUFhLEdBQUcsR0FDbkIsT0FBTztDQUVSLElBQUksTUFBTSxRQUFRLEdBQUcsR0FDcEIsT0FBTyxJQUFJLE1BQU0sTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDO0NBRTlDLElBQUksZUFBZSxLQUNsQixPQUFPLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxNQUFNLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQztDQUUxRCxJQUFJLFNBQVMsR0FBRyxHQUNmLE9BQU8sT0FBTyxPQUFPLEdBQUcsQ0FBQyxDQUFDLE1BQU0sTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDO0NBRTdELE9BQU87QUFDUjtBQUNBLFNBQVMsZ0JBQWdCLEdBQUcsR0FBRyxlQUFlO0NBQzdDLE1BQU0sY0FBYyxhQUFhLENBQUM7Q0FDbEMsTUFBTSxjQUFjLGFBQWEsQ0FBQztDQUNsQyxJQUFJLGVBQWUsYUFDbEI7Q0FFRCxJQUFJLGFBQ0gsT0FBTyxFQUFFLGdCQUFnQixHQUFHLGFBQWE7Q0FFMUMsSUFBSSxhQUNILE9BQU8sRUFBRSxnQkFBZ0IsR0FBRyxhQUFhO0FBRTNDO0FBRUEsU0FBUyxRQUFRLE9BQU87Q0FDdkIsSUFBSSxPQUFPLE1BQU0sWUFBWSxZQUM1QixPQUFPLE1BQU0sUUFBUSxLQUFLO0NBRTNCLFFBQVEsT0FBTyxVQUFVLFNBQVMsS0FBSyxLQUFLLEdBQTVDO0VBQ0MsS0FBSztFQUNMLEtBQUs7RUFDTCxLQUFLLHlCQUF5QixPQUFPO0VBQ3JDLFNBQVMsT0FBTyxpQkFBaUI7Q0FDbEM7QUFDRDtBQUdBLFNBQVMsR0FBRyxHQUFHLEdBQUcsUUFBUSxRQUFRLGVBQWUsUUFBUTtDQUN4RCxJQUFJLFNBQVM7Q0FDYixNQUFNLG1CQUFtQixnQkFBZ0IsR0FBRyxHQUFHLGFBQWE7Q0FDNUQsSUFBSSxxQkFBcUIsUUFDeEIsT0FBTztDQUVSLE1BQU0sZ0JBQWdCLEVBQUUsT0FBTztDQUMvQixLQUFLLElBQUksSUFBSSxHQUFHLElBQUksY0FBYyxRQUFRLEtBQUs7RUFDOUMsTUFBTSxxQkFBcUIsY0FBYyxFQUFFLENBQUMsS0FBSyxlQUFlLEdBQUcsR0FBRyxhQUFhO0VBQ25GLElBQUksdUJBQXVCLFFBQzFCLE9BQU87Q0FFVDtDQUNBLElBQUksT0FBTyxRQUFRLGNBQWMsYUFBYSxPQUFPLGFBQWEsS0FDakUsT0FBTyxFQUFFLFNBQVMsRUFBRTtDQUVyQixJQUFJLE9BQU8sR0FBRyxHQUFHLENBQUMsR0FDakIsT0FBTztDQUdSLElBQUksTUFBTSxRQUFRLE1BQU0sTUFDdkIsT0FBTyxNQUFNO0NBRWQsTUFBTSxZQUFZLE9BQU8sVUFBVSxTQUFTLEtBQUssQ0FBQztDQUNsRCxJQUFJLGNBQWMsT0FBTyxVQUFVLFNBQVMsS0FBSyxDQUFDLEdBQ2pELE9BQU87Q0FFUixRQUFRLFdBQVI7RUFDQyxLQUFLO0VBQ0wsS0FBSztFQUNMLEtBQUssbUJBQW1CLElBQUksT0FBTyxNQUFNLE9BQU8sR0FFL0MsT0FBTztPQUNELElBQUksT0FBTyxNQUFNLFlBQVksT0FBTyxNQUFNLFVBRWhELE9BQU8sT0FBTyxHQUFHLEdBQUcsQ0FBQztPQUdyQixPQUFPLE9BQU8sR0FBRyxFQUFFLFFBQVEsR0FBRyxFQUFFLFFBQVEsQ0FBQztFQUUxQyxLQUFLLGlCQUFpQjtHQUNyQixNQUFNLE9BQU8sQ0FBQztHQUNkLE1BQU0sT0FBTyxDQUFDO0dBSWQsT0FBTyxTQUFTLFFBQVEsT0FBTyxNQUFNLElBQUksS0FBSyxPQUFPLE1BQU0sSUFBSTtFQUNoRTtFQUNBLEtBQUssbUJBQW1CLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRTtFQUN0RSxLQUFLO0VBQ0wsS0FBSztFQUNMLEtBQUs7RUFDTCxLQUFLO0VBQ0wsS0FBSztFQUNMLEtBQUs7RUFDTCxLQUFLLG1DQUFtQyxPQUFPLEVBQUUsT0FBTyxDQUFDO0VBQ3pELEtBQUssOEJBQThCLE9BQU8sRUFBRSxTQUFTLE1BQU0sRUFBRSxTQUFTO0NBQ3ZFO0NBQ0EsSUFBSSxPQUFPLE1BQU0sWUFBWSxPQUFPLE1BQU0sVUFDekMsT0FBTztDQUdSLElBQUksVUFBVSxDQUFDLEtBQUssVUFBVSxDQUFDLEdBQzlCLE9BQU8sRUFBRSxZQUFZLENBQUM7Q0FHdkIsSUFBSSxTQUFTLE9BQU87Q0FDcEIsT0FBTyxVQUtOLElBQUksT0FBTyxZQUFZLEdBQ3RCLE9BQU8sT0FBTyxZQUFZO01BQ3BCLElBQUksT0FBTyxZQUFZLEdBQzdCLE9BQU87Q0FJVCxPQUFPLEtBQUssQ0FBQztDQUNiLE9BQU8sS0FBSyxDQUFDO0NBR2IsSUFBSSxjQUFjLG9CQUFvQixFQUFFLFdBQVcsRUFBRSxRQUNwRCxPQUFPO0NBRVIsSUFBSSxRQUFRLENBQUMsS0FBSyxRQUFRLENBQUMsR0FDMUIsSUFBSTtFQUNILE9BQU8sYUFBYSxHQUFHLEdBQUcsUUFBUSxRQUFRLGVBQWUsTUFBTTtDQUNoRSxVQUFVO0VBQ1QsT0FBTyxJQUFJO0VBQ1gsT0FBTyxJQUFJO0NBQ1o7Q0FHRCxNQUFNLFFBQVEsS0FBSyxHQUFHLE1BQU07Q0FDNUIsSUFBSTtDQUNKLElBQUksT0FBTyxNQUFNO0NBRWpCLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLFdBQVcsTUFDOUIsT0FBTztDQUVSLE9BQU8sUUFBUTtFQUNkLE1BQU0sTUFBTTtFQUVaLFNBQVMsT0FBTyxHQUFHLEdBQUcsS0FBSyxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxRQUFRLGVBQWUsTUFBTTtFQUNuRixJQUFJLENBQUMsUUFDSixPQUFPO0NBRVQ7Q0FFQSxPQUFPLElBQUk7Q0FDWCxPQUFPLElBQUk7Q0FDWCxPQUFPO0FBQ1I7QUFDQSxTQUFTLGFBQWEsR0FBRyxHQUFHLFFBQVEsUUFBUSxlQUFlLFFBQVE7Q0FLbEUsSUFBSSxTQUFTLE9BQU8sVUFBVSxTQUFTLEtBQUssQ0FBQyxNQUFNLE9BQU8sVUFBVSxTQUFTLEtBQUssQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUU7Q0FFN0gsSUFBSSxPQUFPLEVBQUUsVUFBVSxhQUN0QixXQUFXLEdBQUcsRUFBRSxPQUFPLEVBQUUsT0FBTyxRQUFRLFFBQVEsZUFBZSxNQUFNO0NBR3RFLElBQUksYUFBYSxrQkFBa0IsYUFBYSxnQkFDL0MsV0FBVyxHQUFHLEVBQUUsUUFBUSxFQUFFLFFBQVEsUUFBUSxRQUFRLGVBQWUsTUFBTTtDQUd4RSxXQUFXLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLFFBQVEsUUFBUSxlQUFlLE1BQU07Q0FDdkUsT0FBTztBQUNSO0FBQ0EsU0FBUyxLQUFLLEtBQUssUUFBUTtDQUMxQixNQUFNLE9BQU8sQ0FBQztDQUNkLEtBQUssTUFBTSxPQUFPLEtBQ2pCLElBQUksT0FBTyxLQUFLLEdBQUcsR0FDbEIsS0FBSyxLQUFLLEdBQUc7Q0FHZixPQUFPLEtBQUssT0FBTyxPQUFPLHNCQUFzQixHQUFHLENBQUMsQ0FBQyxRQUFRLFdBQVcsT0FBTyx5QkFBeUIsS0FBSyxNQUFNLENBQUMsQ0FBQyxVQUFVLENBQUM7QUFDakk7QUFDQSxTQUFTLGNBQWMsS0FBSyxLQUFLO0NBQ2hDLE9BQU8sT0FBTyxLQUFLLEdBQUcsS0FBSyxJQUFJLFNBQVM7QUFDekM7QUFDQSxTQUFTLE9BQU8sS0FBSyxLQUFLO0NBQ3pCLE9BQU8sT0FBTyxPQUFPLEtBQUssR0FBRztBQUM5QjtBQUNBLFNBQVMsSUFBSSxVQUFVLE9BQU87Q0FDN0IsT0FBTyxPQUFPLFVBQVUsU0FBUyxNQUFNLEtBQUssTUFBTSxXQUFXLFNBQVM7QUFDdkU7QUFDQSxTQUFTLFVBQVUsS0FBSztDQUN2QixPQUFPLFFBQVEsUUFBUSxPQUFPLFFBQVEsWUFBWSxjQUFjLE9BQU8sT0FBTyxJQUFJLGFBQWEsWUFBWSxjQUFjLE9BQU8sT0FBTyxJQUFJLGFBQWEsWUFBWSxpQkFBaUIsT0FBTyxPQUFPLElBQUksZ0JBQWdCO0FBQ3hOO0FBQ0EsU0FBUyxVQUFVLE1BQU07Q0FDeEIsSUFBSSxLQUFLLE1BQ1IsT0FBTyxLQUFLO0NBRWIsTUFBTSxVQUFVLGlCQUFpQixLQUFLLElBQUksQ0FBQyxDQUFDLE1BQU0sa0RBQWtEO0NBQ3BHLE9BQU8sVUFBVSxRQUFRLEtBQUs7QUFDL0I7QUFDQSxTQUFTLGFBQWEsS0FBSztDQUMxQixJQUFJLE9BQU8sZ0JBQ1YsT0FBTyxPQUFPLGVBQWUsR0FBRztDQUVqQyxJQUFJLElBQUksWUFBWSxjQUFjLEtBQ2pDLE9BQU87Q0FFUixPQUFPLElBQUksWUFBWTtBQUN4QjtBQUNBLFNBQVMsWUFBWSxLQUFLLFVBQVU7Q0FDbkMsSUFBSSxDQUFDLEtBQ0osT0FBTztDQUVSLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxHQUM5QixPQUFPO0NBRVIsT0FBTyxZQUFZLGFBQWEsR0FBRyxHQUFHLFFBQVE7QUFDL0M7QUFFQSxNQUFNLG9CQUFvQjtBQUMxQixNQUFNLGtCQUFrQjtBQUN4QixNQUFNLG1CQUFtQjtBQUN6QixNQUFNLHNCQUFzQjtBQUM1QixNQUFNLG1CQUFtQjtBQUN6QixTQUFTLDBCQUEwQixZQUFZO0NBQzlDLE9BQU8sQ0FBQyxFQUFFLGNBQWMsV0FBVyxzQkFBc0IsQ0FBQyxXQUFXO0FBQ3RFO0FBQ0EsU0FBUyx3QkFBd0IsVUFBVTtDQUMxQyxPQUFPLENBQUMsRUFBRSxZQUFZLFNBQVMsb0JBQW9CLENBQUMsU0FBUztBQUM5RDtBQUNBLFNBQVMsZ0JBQWdCLFFBQVE7Q0FDaEMsT0FBTyxVQUFVLFFBQVEsT0FBTyxXQUFXLFlBQVksQ0FBQyxNQUFNLFFBQVEsTUFBTTtBQUM3RTtBQUNBLFNBQVMsZ0JBQWdCLFFBQVE7Q0FDaEMsT0FBTyxRQUFRLFVBQVUsZ0JBQWdCLE1BQU0sS0FBSyxPQUFPLGlCQUFpQjtBQUM3RTtBQUNBLFNBQVMsd0JBQXdCLFFBQVE7Q0FDeEMsT0FBTyxRQUFRLFVBQVUsZ0JBQWdCLE1BQU0sS0FBSyxPQUFPLHNCQUFzQixPQUFPLG9CQUFvQjtBQUM3RztBQUNBLFNBQVMsc0JBQXNCLFFBQVE7Q0FDdEMsT0FBTyxRQUFRLFVBQVUsZ0JBQWdCLE1BQU0sS0FBSyxPQUFPLG9CQUFvQixPQUFPLG9CQUFvQjtBQUMzRztBQUNBLFNBQVMsa0JBQWtCLFFBQVE7Q0FDbEMsT0FBTyxRQUFRLFVBQVUsZ0JBQWdCLE1BQU0sS0FBSyxPQUFPLGlCQUFpQjtBQUM3RTs7Ozs7Ozs7QUFRQSxNQUFNLGlCQUFpQixPQUFPO0FBQzlCLFNBQVMsWUFBWSxRQUFRO0NBQzVCLE9BQU8sQ0FBQyxFQUFFLFVBQVUsUUFBUSxPQUFPO0FBQ3BDO0FBQ0EsU0FBUyxpQkFBaUIsR0FBRyxHQUFHLGdCQUFnQixDQUFDLEdBQUcsU0FBUyxDQUFDLEdBQUcsU0FBUyxDQUFDLEdBQUc7Q0FDN0UsSUFBSSxPQUFPLE1BQU0sWUFBWSxPQUFPLE1BQU0sWUFBWSxNQUFNLFFBQVEsQ0FBQyxLQUFLLE1BQU0sUUFBUSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUM5SDtDQUVELElBQUksRUFBRSxnQkFBZ0IsRUFBRSxhQUN2QixPQUFPO0NBRVIsSUFBSSxTQUFTLE9BQU87Q0FDcEIsT0FBTyxVQUtOLElBQUksT0FBTyxZQUFZLEdBQ3RCLE9BQU8sT0FBTyxZQUFZO0NBRzVCLE9BQU8sS0FBSyxDQUFDO0NBQ2IsT0FBTyxLQUFLLENBQUM7Q0FDYixNQUFNLHdCQUF3QixDQUFDLEdBQUcsY0FBYyxRQUFRLE1BQU0sTUFBTSxnQkFBZ0IsR0FBRyx5QkFBeUI7Q0FDaEgsU0FBUywwQkFBMEIsR0FBRyxHQUFHO0VBQ3hDLE9BQU8saUJBQWlCLEdBQUcsR0FBRyxDQUFDLEdBQUcsYUFBYSxHQUFHLENBQUMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQztDQUMzRTtDQUNBLElBQUksRUFBRSxTQUFTLFFBQ2Q7TUFBSSxFQUFFLFNBQVMsRUFBRSxNQUNoQixPQUFPO09BQ0QsSUFBSSxJQUFJLE9BQU8sQ0FBQyxLQUFLLHdCQUF3QixDQUFDLEdBQUc7R0FDdkQsSUFBSSxXQUFXO0dBQ2YsS0FBSyxNQUFNLFVBQVUsR0FDcEIsSUFBSSxDQUFDLEVBQUUsSUFBSSxNQUFNLEdBQUc7SUFDbkIsSUFBSSxNQUFNO0lBQ1YsS0FBSyxNQUFNLFVBQVUsR0FFcEIsSUFEZ0IsT0FBTyxRQUFRLFFBQVEscUJBQ25DLE1BQVksTUFDZixNQUFNO0lBR1IsSUFBSSxRQUFRLE9BQU87S0FDbEIsV0FBVztLQUNYO0lBQ0Q7R0FDRDtHQUdELE9BQU8sSUFBSTtHQUNYLE9BQU8sSUFBSTtHQUNYLE9BQU87RUFDUixPQUFPLElBQUksSUFBSSxPQUFPLENBQUMsS0FBSywwQkFBMEIsQ0FBQyxHQUFHO0dBQ3pELElBQUksV0FBVztHQUNmLEtBQUssTUFBTSxVQUFVLEdBQ3BCLElBQUksQ0FBQyxFQUFFLElBQUksT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLE9BQU8sSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLEdBQUcscUJBQXFCLEdBQUc7SUFDckYsSUFBSSxNQUFNO0lBQ1YsS0FBSyxNQUFNLFVBQVUsR0FBRztLQUN2QixNQUFNLGFBQWEsT0FBTyxPQUFPLElBQUksT0FBTyxJQUFJLHFCQUFxQjtLQUNyRSxJQUFJLGVBQWU7S0FDbkIsSUFBSSxlQUFlLE1BQ2xCLGVBQWUsT0FBTyxPQUFPLElBQUksT0FBTyxJQUFJLHFCQUFxQjtLQUVsRSxJQUFJLGlCQUFpQixNQUNwQixNQUFNO0lBRVI7SUFDQSxJQUFJLFFBQVEsT0FBTztLQUNsQixXQUFXO0tBQ1g7SUFDRDtHQUNEO0dBR0QsT0FBTyxJQUFJO0dBQ1gsT0FBTyxJQUFJO0dBQ1gsT0FBTztFQUNSOztDQUVELE1BQU0sWUFBWSxFQUFFLGVBQWUsQ0FBQztDQUNwQyxLQUFLLE1BQU0sVUFBVSxHQUFHO0VBQ3ZCLE1BQU0sUUFBUSxVQUFVLEtBQUs7RUFDN0IsSUFBSSxNQUFNLFFBQVEsQ0FBQyxPQUFPLFFBQVEsTUFBTSxPQUFPLHFCQUFxQixHQUNuRSxPQUFPO0NBRVQ7Q0FDQSxJQUFJLENBQUMsVUFBVSxLQUFLLENBQUMsQ0FBQyxNQUNyQixPQUFPO0NBRVIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEdBRzFHO01BQUksQ0FBQyxPQUZZLE9BQU8sUUFBUSxDQUVwQixHQURLLE9BQU8sUUFBUSxDQUNWLEdBQVUscUJBQXFCLEdBQ3BELE9BQU87Q0FDUjtDQUdELE9BQU8sSUFBSTtDQUNYLE9BQU8sSUFBSTtDQUNYLE9BQU87QUFDUjs7OztBQUlBLFNBQVMsb0JBQW9CLFFBQVEsS0FBSztDQUV6QyxJQUR3QixDQUFDLFVBQVUsT0FBTyxXQUFXLFlBQVksV0FBVyxPQUFPLFdBRWxGLE9BQU87Q0FFUixPQUFPLE9BQU8sT0FBTyxRQUFRLEdBQUcsS0FBSyxvQkFBb0IsT0FBTyxlQUFlLE1BQU0sR0FBRyxHQUFHO0FBQzVGO0FBQ0EsU0FBUyxpQkFBaUIsR0FBRztDQUM1QixPQUFPLFNBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQyxLQUFLLEVBQUUsYUFBYSxTQUFTLEVBQUUsYUFBYSxRQUFRLEVBQUUsYUFBYTtBQUN6SDtBQUNBLFNBQVMsZUFBZSxRQUFRLFFBQVEsZ0JBQWdCLENBQUMsR0FBRztDQUMzRCxNQUFNLHdCQUF3QixjQUFjLFFBQVEsTUFBTSxNQUFNLGNBQWM7Q0FJOUUsTUFBTSw2QkFBNkIsaUNBQWlCLElBQUksUUFBUSxPQUFPLFFBQVEsV0FBVztFQUN6RixJQUFJLENBQUMsaUJBQWlCLE1BQU0sR0FDM0I7RUFFRCxPQUFPLE9BQU8sS0FBSyxNQUFNLENBQUMsQ0FBQyxPQUFPLFFBQVE7R0FDekMsSUFBSSxPQUFPLFFBQVEsUUFBUSxPQUFPLE9BQU8sU0FBUyxVQUFVO0lBQzNELElBQUksZUFBZSxJQUFJLE9BQU8sSUFBSSxHQUNqQyxPQUFPLE9BQU8sT0FBTyxNQUFNLE9BQU8sTUFBTSxxQkFBcUI7SUFFOUQsZUFBZSxJQUFJLE9BQU8sTUFBTSxJQUFJO0dBQ3JDO0dBQ0EsTUFBTSxTQUFTLFVBQVUsUUFBUSxvQkFBb0IsUUFBUSxHQUFHLEtBQUssT0FBTyxPQUFPLE1BQU0sT0FBTyxNQUFNLENBQUMsR0FBRyx1QkFBdUIsMEJBQTBCLGNBQWMsQ0FBQyxDQUFDO0dBTTNLLGVBQWUsT0FBTyxPQUFPLElBQUk7R0FDakMsT0FBTztFQUNSLENBQUM7Q0FDRjtDQUNBLE9BQU8sMEJBQTBCLENBQUMsQ0FBQyxRQUFRLE1BQU07QUFDbEQ7QUFDQSxTQUFTLGFBQWEsR0FBRyxHQUFHO0NBQzNCLElBQUksS0FBSyxRQUFRLEtBQUssUUFBUSxFQUFFLGdCQUFnQixFQUFFLGFBQ2pEO0NBRUQsT0FBTztBQUNSO0FBQ0EsU0FBUyxvQkFBb0IsR0FBRyxHQUFHO0NBQ2xDLElBQUksWUFBWTtDQUNoQixJQUFJLFlBQVk7Q0FDaEIsSUFBSSxFQUFFLGFBQWEsWUFBWSxhQUFhLFdBQVc7RUFDdEQsSUFBSSxFQUFFLGFBQWEsZ0JBQWdCLEVBQUUsYUFBYSxjQUNqRDtFQUVELElBQUk7R0FDSCxZQUFZLElBQUksU0FBUyxDQUFDO0dBQzFCLFlBQVksSUFBSSxTQUFTLENBQUM7RUFDM0IsUUFBUTtHQUNQO0VBQ0Q7Q0FDRDtDQUVBLElBQUksVUFBVSxlQUFlLFVBQVUsWUFDdEMsT0FBTztDQUdSLEtBQUssSUFBSSxJQUFJLEdBQUcsSUFBSSxVQUFVLFlBQVksS0FDekMsSUFBSSxVQUFVLFNBQVMsQ0FBQyxNQUFNLFVBQVUsU0FBUyxDQUFDLEdBQ2pELE9BQU87Q0FHVCxPQUFPO0FBQ1I7QUFDQSxTQUFTLG9CQUFvQixHQUFHLEdBQUcsZ0JBQWdCLENBQUMsR0FBRztDQUN0RCxJQUFJLENBQUMsTUFBTSxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDLEdBQ3hDO0NBR0QsTUFBTSxRQUFRLE9BQU8sS0FBSyxDQUFDO0NBQzNCLE1BQU0sUUFBUSxPQUFPLEtBQUssQ0FBQztDQUUzQixPQUFPLE9BQU8sR0FBRyxHQURhLGNBQWMsUUFBUSxNQUFNLE1BQU0sbUJBQzVDLEdBQXVCLElBQUksS0FBSyxPQUFPLE9BQU8sS0FBSztBQUN4RTtBQUNBLFNBQVMsb0JBQW9CLGtCQUFrQixXQUFXLFdBQVcsU0FBUyxVQUFVO0NBQ3ZGLE1BQU0sY0FBYyxZQUFZLFNBQVMsU0FBUyxPQUFPO0NBQ3pELElBQUksQ0FBQyxpQkFBaUIsU0FBUyxDQUFDLENBQUMsU0FBUyxnQkFBZ0IsR0FDekQsT0FBTyxHQUFHLFlBQVksaUVBQWlFLGlCQUFpQixpQkFBaUIsU0FBUztDQUVuSSxPQUFPO0FBQ1I7QUFDQSxTQUFTLFVBQVUsTUFBTSxPQUFPO0NBQy9CLE9BQU8sR0FBRyxNQUFNLEdBQUcsT0FBTyxVQUFVLElBQUksS0FBSztBQUM5QztBQUNBLFNBQVMsY0FBYyxRQUFRO0NBQzlCLE9BQU8sQ0FBQyxHQUFHLE9BQU8sS0FBSyxNQUFNLEdBQUcsR0FBRyxPQUFPLHNCQUFzQixNQUFNLENBQUMsQ0FBQyxRQUFRLE1BQU0sT0FBTyx5QkFBeUIsUUFBUSxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUM7QUFDOUk7QUFDQSxTQUFTLGdCQUFnQixRQUFRLFFBQVEsZUFBZTtDQUN2RCxJQUFJLFdBQVc7Q0FDZixNQUFNLDhCQUE4QixpQ0FBaUIsSUFBSSxRQUFRLE9BQU8sUUFBUSxXQUFXO0VBQzFGLElBQUksTUFBTSxRQUFRLE1BQU0sR0FDdkI7T0FBSSxNQUFNLFFBQVEsTUFBTSxLQUFLLE9BQU8sV0FBVyxPQUFPLFFBRXJELE9BQU8sT0FBTyxLQUFLLEtBQUssTUFBTSwyQkFBMkIsY0FBYyxDQUFDLENBQUMsT0FBTyxJQUFJLEdBQUcsQ0FBQztFQUN6RixPQUNNLElBQUksa0JBQWtCLE1BQzVCLE9BQU87T0FDRCxJQUFJLFNBQVMsTUFBTSxLQUFLLFNBQVMsTUFBTSxHQUFHO0dBQ2hELElBQUksT0FBTyxRQUFRLFFBQVE7SUFDMUIsR0FBRztJQUNIO0lBQ0E7R0FDRCxDQUFDLEdBRUEsT0FBTztHQUVSLE1BQU0sVUFBVSxDQUFDO0dBQ2pCLGVBQWUsSUFBSSxRQUFRLE9BQU87R0FFbEMsSUFBSSxPQUFPLE9BQU8sZ0JBQWdCLGNBQWMsT0FBTyxPQUFPLFlBQVksU0FBUyxVQUNsRixPQUFPLGVBQWUsU0FBUyxlQUFlO0lBQzdDLFlBQVk7SUFDWixPQUFPLE9BQU87R0FDZixDQUFDO0dBRUYsS0FBSyxNQUFNLE9BQU8sY0FBYyxNQUFNLEdBQ3JDLElBQUksb0JBQW9CLFFBQVEsR0FBRyxHQUNsQyxRQUFRLE9BQU8sZUFBZSxJQUFJLE9BQU8sSUFBSSxJQUFJLGVBQWUsSUFBSSxPQUFPLElBQUksSUFBSSwyQkFBMkIsY0FBYyxDQUFDLENBQUMsT0FBTyxNQUFNLE9BQU8sSUFBSTtRQUV0SixJQUFJLENBQUMsZUFBZSxJQUFJLE9BQU8sSUFBSSxHQUFHO0lBQ3JDLFlBQVk7SUFDWixJQUFJLFNBQVMsT0FBTyxJQUFJLEdBQ3ZCLFlBQVksY0FBYyxPQUFPLElBQUksQ0FBQyxDQUFDO0lBRXhDLDJCQUEyQixjQUFjLENBQUMsQ0FBQyxPQUFPLE1BQU0sT0FBTyxJQUFJO0dBQ3BFO0dBR0YsSUFBSSxjQUFjLE9BQU8sQ0FBQyxDQUFDLFNBQVMsR0FDbkMsT0FBTztFQUVUO0VBQ0EsT0FBTztDQUNSO0NBQ0EsT0FBTztFQUNOLFFBQVEsMkJBQTJCLENBQUMsQ0FBQyxRQUFRLE1BQU07RUFDbkQ7Q0FDRDtBQUNEOzs7O0FBSUEsU0FBUyxpQkFBaUIsS0FBSztDQUM5QixPQUFPLENBQUMsQ0FBQyxRQUFRLE9BQU8sUUFBUSxZQUFZLE9BQU8sUUFBUSxlQUFlLElBQUksZ0JBQWdCLE9BQU8sSUFBSSxZQUFZLENBQUMsYUFBYTtBQUNwSTtBQUVBLElBQUksQ0FBQyxPQUFPLE9BQU8sWUFBWSxlQUFlLEdBQUc7Q0FDaEQsTUFBTSw4QkFBYyxJQUFJLFFBQVE7Q0FDaEMsTUFBTSxXQUFXLE9BQU8sT0FBTyxJQUFJO0NBQ25DLE1BQU0sd0JBQXdCLENBQUM7Q0FDL0IsTUFBTSxxQkFBcUIsT0FBTyxPQUFPLElBQUk7Q0FDN0MsT0FBTyxlQUFlLFlBQVksaUJBQWlCLEVBQUUsV0FBVyxZQUFZLENBQUM7Q0FDN0UsT0FBTyxlQUFlLFlBQVksc0JBQXNCO0VBQ3ZELGNBQWM7RUFDZCxZQUFZO0dBQ1gsT0FBTyxZQUFZLElBQUksV0FBVyxjQUFjO0dBQ2hEO0dBQ0E7RUFDRDtDQUNELENBQUM7Q0FDRCxPQUFPLGVBQWUsWUFBWSw0QkFBNEIsRUFBRSxXQUFXLG1CQUFtQixDQUFDO0FBQ2hHO0FBQ0EsU0FBUyxTQUFTLFFBQVE7Q0FDekIsT0FBTyxXQUFXLGdCQUFnQixDQUFDLElBQUksTUFBTTtBQUM5QztBQUNBLFNBQVMsU0FBUyxPQUFPLFFBQVE7Q0FDaEMsTUFBTSxNQUFNLFdBQVc7Q0FDdkIsTUFBTSxVQUFVLElBQUksSUFBSSxNQUFNLEtBQUssQ0FBQztDQUVwQyxNQUFNLFVBQVUsT0FBTyxpQkFBaUIsU0FBUztFQUNoRCxHQUFHLE9BQU8sMEJBQTBCLE9BQU87RUFDM0MsR0FBRyxPQUFPLDBCQUEwQixLQUFLO0NBQzFDLENBQUM7Q0FDRCxJQUFJLElBQUksUUFBUSxPQUFPO0FBQ3hCO0FBRUEsSUFBTSxvQkFBTixNQUF3QjtDQUV2QixXQUFXLE9BQU8sSUFBSSx3QkFBd0I7Q0FDOUMsWUFBWSxRQUFRLFVBQVUsT0FBTztFQUNwQyxLQUFLLFNBQVM7RUFDZCxLQUFLLFVBQVU7Q0FDaEI7Q0FDQSxrQkFBa0IsUUFBUTtFQUN6QixPQUFPO0dBQ04sR0FBRyxTQUFTLFVBQVUsV0FBVyxjQUFjO0dBQy9DO0dBQ0EsT0FBTyxLQUFLO0dBQ1osZUFBZSx5QkFBeUI7R0FDeEMsT0FBTztJQUNOLEdBQUcsZ0JBQWdCO0lBQ25CO0lBQ0E7SUFDQTtJQUNBO0dBQ0Q7RUFDRDtDQUNEO0FBQ0Q7QUFLQSxrQkFBa0IsVUFBVSxPQUFPLElBQUksY0FBYyxLQUFLLFNBQVMsU0FBUztDQUUzRSxNQUFNLFNBQVMsVUFBVSxNQUFNLFFBQVEsT0FBTyxFQUFFLEtBQUssS0FBSyxDQUFDO0NBQzNELElBQUksT0FBTyxVQUFVLFFBQVEsVUFDNUIsT0FBTztDQUVSLE9BQU8sR0FBRyxLQUFLLFNBQVMsRUFBRTtBQUMzQjtBQUNBLElBQU0sbUJBQU4sY0FBK0Isa0JBQWtCO0NBQ2hELFlBQVksUUFBUSxVQUFVLE9BQU87RUFDcEMsSUFBSSxDQUFDLElBQUksVUFBVSxNQUFNLEdBQ3hCLE1BQU0sSUFBSSxNQUFNLDBCQUEwQjtFQUUzQyxNQUFNLFFBQVEsT0FBTztDQUN0QjtDQUNBLGdCQUFnQixPQUFPO0VBQ3RCLE1BQU0sU0FBUyxJQUFJLFVBQVUsS0FBSyxLQUFLLE1BQU0sU0FBUyxLQUFLLE1BQU07RUFDakUsT0FBTyxLQUFLLFVBQVUsQ0FBQyxTQUFTO0NBQ2pDO0NBQ0EsV0FBVztFQUNWLE9BQU8sU0FBUyxLQUFLLFVBQVUsUUFBUSxHQUFHO0NBQzNDO0NBQ0Esa0JBQWtCO0VBQ2pCLE9BQU87Q0FDUjtBQUNEO0FBQ0EsSUFBTSxXQUFOLGNBQXVCLGtCQUFrQjtDQUN4QyxnQkFBZ0IsT0FBTztFQUN0QixPQUFPLFNBQVM7Q0FDakI7Q0FDQSxXQUFXO0VBQ1YsT0FBTztDQUNSO0NBQ0Esc0JBQXNCO0VBQ3JCLE9BQU87Q0FDUjtBQUNEO0FBQ0EsSUFBTSxtQkFBTixjQUErQixrQkFBa0I7Q0FDaEQsWUFBWSxRQUFRLFVBQVUsT0FBTztFQUNwQyxNQUFNLFFBQVEsT0FBTztDQUN0QjtDQUNBLGFBQWEsS0FBSztFQUNqQixJQUFJLE9BQU8sZ0JBQ1YsT0FBTyxPQUFPLGVBQWUsR0FBRztFQUVqQyxJQUFJLElBQUksWUFBWSxjQUFjLEtBQ2pDLE9BQU87RUFFUixPQUFPLElBQUksWUFBWTtDQUN4QjtDQUNBLFlBQVksS0FBSyxVQUFVO0VBQzFCLElBQUksQ0FBQyxLQUNKLE9BQU87RUFFUixJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsR0FDOUIsT0FBTztFQUVSLE9BQU8sS0FBSyxZQUFZLEtBQUssYUFBYSxHQUFHLEdBQUcsUUFBUTtDQUN6RDtDQUNBLGNBQWMsS0FBSztFQUNsQixPQUFPLENBQUMsR0FBRyxPQUFPLEtBQUssR0FBRyxHQUFHLEdBQUcsT0FBTyxzQkFBc0IsR0FBRyxDQUFDLENBQUMsUUFBUSxNQUFNLE9BQU8seUJBQXlCLEtBQUssQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDO0NBQ3JJO0NBQ0EsZ0JBQWdCLE9BQU8sZUFBZTtFQUNyQyxJQUFJLE9BQU8sS0FBSyxXQUFXLFVBQzFCLE1BQU0sSUFBSSxVQUFVLGlDQUFpQyxLQUFLLFNBQVMsRUFBRSxTQUFTLE9BQU8sS0FBSyxPQUFPLEdBQUc7RUFFckcsSUFBSSxTQUFTO0VBQ2IsTUFBTSxhQUFhLEtBQUssY0FBYyxLQUFLLE1BQU07RUFDakQsS0FBSyxNQUFNLFlBQVksWUFBWTtHQUNsQyxJQUFJLENBQUMsS0FBSyxZQUFZLE9BQU8sUUFBUSxHQUFHO0lBQ3ZDLFNBQVM7SUFDVDtHQUNEO0dBQ0EsTUFBTSxRQUFRLEtBQUssT0FBTztHQUMxQixNQUFNLGFBQWEsTUFBTTtHQUN6QixJQUFJLENBQUMsT0FBTyxPQUFPLFlBQVksYUFBYSxHQUFHO0lBQzlDLFNBQVM7SUFDVDtHQUNEO0VBQ0Q7RUFDQSxPQUFPLEtBQUssVUFBVSxDQUFDLFNBQVM7Q0FDakM7Q0FDQSxXQUFXO0VBQ1YsT0FBTyxTQUFTLEtBQUssVUFBVSxRQUFRLEdBQUc7Q0FDM0M7Q0FDQSxrQkFBa0I7RUFDakIsT0FBTztDQUNSO0FBQ0Q7QUFDQSxJQUFNLGtCQUFOLGNBQThCLGtCQUFrQjtDQUMvQyxZQUFZLFFBQVEsVUFBVSxPQUFPO0VBQ3BDLE1BQU0sUUFBUSxPQUFPO0NBQ3RCO0NBQ0EsZ0JBQWdCLE9BQU8sZUFBZTtFQUNyQyxJQUFJLENBQUMsTUFBTSxRQUFRLEtBQUssTUFBTSxHQUM3QixNQUFNLElBQUksVUFBVSxnQ0FBZ0MsS0FBSyxTQUFTLEVBQUUsU0FBUyxPQUFPLEtBQUssT0FBTyxHQUFHO0VBRXBHLE1BQU0sU0FBUyxLQUFLLE9BQU8sV0FBVyxLQUFLLE1BQU0sUUFBUSxLQUFLLEtBQUssS0FBSyxPQUFPLE9BQU8sU0FBUyxNQUFNLE1BQU0sWUFBWSxPQUFPLE1BQU0sU0FBUyxhQUFhLENBQUMsQ0FBQztFQUM1SixPQUFPLEtBQUssVUFBVSxDQUFDLFNBQVM7Q0FDakM7Q0FDQSxXQUFXO0VBQ1YsT0FBTyxRQUFRLEtBQUssVUFBVSxRQUFRLEdBQUc7Q0FDMUM7Q0FDQSxrQkFBa0I7RUFDakIsT0FBTztDQUNSO0FBQ0Q7QUFDQSxJQUFNLE1BQU4sY0FBa0Isa0JBQWtCO0NBQ25DLFlBQVksUUFBUTtFQUNuQixJQUFJLE9BQU8sV0FBVyxhQUNyQixNQUFNLElBQUksVUFBVSwyR0FBZ0g7RUFFckksTUFBTSxNQUFNO0NBQ2I7Q0FDQSxVQUFVLE1BQU07RUFDZixJQUFJLEtBQUssTUFDUixPQUFPLEtBQUs7RUFHYixNQUFNLFVBRG1CLFNBQVMsVUFBVSxTQUNYLEtBQUssSUFBSSxDQUFDLENBQUMsTUFBTSxrREFBa0Q7RUFDcEcsT0FBTyxVQUFVLFFBQVEsS0FBSztDQUMvQjtDQUNBLGdCQUFnQixPQUFPO0VBQ3RCLElBQUksS0FBSyxXQUFXLFFBQ25CLE9BQU8sT0FBTyxTQUFTLFlBQVksaUJBQWlCO0VBRXJELElBQUksS0FBSyxXQUFXLFFBQ25CLE9BQU8sT0FBTyxTQUFTLFlBQVksaUJBQWlCO0VBRXJELElBQUksS0FBSyxXQUFXLFVBQ25CLE9BQU8sT0FBTyxTQUFTLGNBQWMsT0FBTyxVQUFVO0VBRXZELElBQUksS0FBSyxXQUFXLFNBQ25CLE9BQU8sT0FBTyxTQUFTLGFBQWEsaUJBQWlCO0VBRXRELElBQUksS0FBSyxXQUFXLFFBQ25CLE9BQU8sT0FBTyxTQUFTLFlBQVksaUJBQWlCO0VBRXJELElBQUksS0FBSyxXQUFXLFFBQ25CLE9BQU8sT0FBTyxTQUFTLFlBQVksaUJBQWlCO0VBRXJELElBQUksS0FBSyxXQUFXLFFBQ25CLE9BQU8sT0FBTyxTQUFTO0VBRXhCLE9BQU8saUJBQWlCLEtBQUs7Q0FDOUI7Q0FDQSxXQUFXO0VBQ1YsT0FBTztDQUNSO0NBQ0Esa0JBQWtCO0VBQ2pCLElBQUksS0FBSyxXQUFXLFFBQ25CLE9BQU87RUFFUixJQUFJLEtBQUssV0FBVyxRQUNuQixPQUFPO0VBRVIsSUFBSSxLQUFLLFdBQVcsVUFDbkIsT0FBTztFQUVSLElBQUksS0FBSyxXQUFXLFFBQ25CLE9BQU87RUFFUixJQUFJLEtBQUssV0FBVyxTQUNuQixPQUFPO0VBRVIsT0FBTyxLQUFLLFVBQVUsS0FBSyxNQUFNO0NBQ2xDO0NBQ0Esc0JBQXNCO0VBQ3JCLE9BQU8sT0FBTyxLQUFLLFVBQVUsS0FBSyxNQUFNLEVBQUU7Q0FDM0M7QUFDRDtBQUNBLElBQU0saUJBQU4sY0FBNkIsa0JBQWtCO0NBQzlDLFlBQVksUUFBUSxVQUFVLE9BQU87RUFDcEMsSUFBSSxDQUFDLElBQUksVUFBVSxNQUFNLEtBQUssQ0FBQyxJQUFJLFVBQVUsTUFBTSxHQUNsRCxNQUFNLElBQUksTUFBTSxzQ0FBc0M7RUFFdkQsTUFBTSxJQUFJLE9BQU8sTUFBTSxHQUFHLE9BQU87Q0FDbEM7Q0FDQSxnQkFBZ0IsT0FBTztFQUN0QixNQUFNLFNBQVMsSUFBSSxVQUFVLEtBQUssS0FBSyxLQUFLLE9BQU8sS0FBSyxLQUFLO0VBQzdELE9BQU8sS0FBSyxVQUFVLENBQUMsU0FBUztDQUNqQztDQUNBLFdBQVc7RUFDVixPQUFPLFNBQVMsS0FBSyxVQUFVLFFBQVEsR0FBRztDQUMzQztDQUNBLGtCQUFrQjtFQUNqQixPQUFPO0NBQ1I7QUFDRDtBQUNBLElBQU0sVUFBTixjQUFzQixrQkFBa0I7Q0FDdkM7Q0FDQSxZQUFZLFFBQVEsWUFBWSxHQUFHLFVBQVUsT0FBTztFQUNuRCxJQUFJLENBQUMsSUFBSSxVQUFVLE1BQU0sR0FDeEIsTUFBTSxJQUFJLE1BQU0sMEJBQTBCO0VBRTNDLElBQUksQ0FBQyxJQUFJLFVBQVUsU0FBUyxHQUMzQixNQUFNLElBQUksTUFBTSwyQkFBMkI7RUFFNUMsTUFBTSxNQUFNO0VBQ1osS0FBSyxVQUFVO0VBQ2YsS0FBSyxZQUFZO0NBQ2xCO0NBQ0EsZ0JBQWdCLE9BQU87RUFDdEIsSUFBSSxDQUFDLElBQUksVUFBVSxLQUFLLEdBQ3ZCLE9BQU87RUFFUixJQUFJLFNBQVM7RUFDYixJQUFJLFVBQVUsT0FBTyxxQkFBcUIsS0FBSyxXQUFXLE9BQU8sbUJBQ2hFLFNBQVM7T0FDSCxJQUFJLFVBQVUsT0FBTyxxQkFBcUIsS0FBSyxXQUFXLE9BQU8sbUJBQ3ZFLFNBQVM7T0FFVCxTQUFTLEtBQUssSUFBSSxLQUFLLFNBQVMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxLQUFLLFlBQVk7RUFFbEUsT0FBTyxLQUFLLFVBQVUsQ0FBQyxTQUFTO0NBQ2pDO0NBQ0EsV0FBVztFQUNWLE9BQU8sU0FBUyxLQUFLLFVBQVUsUUFBUSxHQUFHO0NBQzNDO0NBQ0Esa0JBQWtCO0VBQ2pCLE9BQU87Q0FDUjtDQUNBLHNCQUFzQjtFQUNyQixPQUFPO0dBQ04sS0FBSyxTQUFTO0dBQ2QsS0FBSztHQUNMLElBQUksVUFBVSxTQUFTLEtBQUssU0FBUyxFQUFFO0VBQ3hDLENBQUMsQ0FBQyxLQUFLLEdBQUc7Q0FDWDtBQUNEO0FBQ0EsSUFBTSxpQkFBTixjQUE2QixrQkFBa0I7Q0FDOUM7Q0FDQSxZQUFZLFFBQVEsVUFBVSxPQUFPO0VBQ3BDLElBQUksQ0FBQyxpQkFBaUIsTUFBTSxHQUMzQixNQUFNLElBQUksVUFBVSx1REFBdUQ7RUFFNUUsTUFBTSxRQUFRLE9BQU87Q0FDdEI7Q0FDQSxnQkFBZ0IsT0FBTztFQUN0QixNQUFNLFNBQVMsS0FBSyxPQUFPLFlBQVksQ0FBQyxTQUFTLEtBQUs7RUFFdEQsSUFBSSxrQkFBa0IsU0FDckIsTUFBTSxJQUFJLFVBQVUsa0VBQWtFO0VBRXZGLEtBQUssU0FBUztFQUNkLE1BQU0sT0FBTyxDQUFDLEtBQUssT0FBTyxVQUFVLEtBQUssT0FBTyxPQUFPLFdBQVc7RUFDbEUsT0FBTyxLQUFLLFVBQVUsQ0FBQyxPQUFPO0NBQy9CO0NBQ0EsV0FBVztFQUNWLE9BQU8sU0FBUyxLQUFLLFVBQVUsUUFBUSxHQUFHO0NBQzNDO0NBQ0Esa0JBQWtCO0VBQ2pCLE9BQU87Q0FDUjtDQUNBLHNCQUFzQjtFQUNyQixNQUFNLEVBQUUsVUFBVSxLQUFLLGtCQUFrQjtFQUV6QyxLQURlLEtBQUssUUFBUSxVQUFVLENBQUMsRUFDbkMsQ0FBTyxTQUFTLEdBQ25CLE9BQU8sR0FBRyxLQUFLLFNBQVMsRUFBRSxHQUFHLE1BQU0sVUFBVSxLQUFLLFFBQVEsUUFBVyxFQUFFLHFCQUFxQixNQUFNLENBQUM7RUFFcEcsT0FBTyxLQUFLLFNBQVM7Q0FDdEI7QUFDRDtBQUNBLE1BQU0sMEJBQTBCLE1BQU0sVUFBVTtDQUMvQyxNQUFNLFVBQVUsS0FBSyxRQUFRLGtCQUFrQixJQUFJLFNBQVMsQ0FBQztDQUM3RCxNQUFNLFVBQVUsS0FBSyxRQUFRLFFBQVEsYUFBYSxJQUFJLElBQUksUUFBUSxDQUFDO0NBQ25FLE1BQU0sVUFBVSxLQUFLLFFBQVEscUJBQXFCLGFBQWEsSUFBSSxpQkFBaUIsUUFBUSxDQUFDO0NBQzdGLE1BQU0sVUFBVSxLQUFLLFFBQVEscUJBQXFCLGFBQWEsSUFBSSxpQkFBaUIsUUFBUSxDQUFDO0NBQzdGLE1BQU0sVUFBVSxLQUFLLFFBQVEsb0JBQW9CLGFBQWEsSUFBSSxnQkFBZ0IsUUFBUSxDQUFDO0NBQzNGLE1BQU0sVUFBVSxLQUFLLFFBQVEsbUJBQW1CLGFBQWEsSUFBSSxlQUFlLFFBQVEsQ0FBQztDQUN6RixNQUFNLFVBQVUsS0FBSyxRQUFRLFlBQVksVUFBVSxjQUFjLElBQUksUUFBUSxVQUFVLFNBQVMsQ0FBQztDQUNqRyxNQUFNLFVBQVUsS0FBSyxRQUFRLG1CQUFtQixhQUFhLElBQUksZUFBZSxRQUFRLENBQUM7Q0FFekYsS0FBSyxPQUFPLE1BQU07RUFDakIsbUJBQW1CLGFBQWEsSUFBSSxpQkFBaUIsVUFBVSxJQUFJO0VBQ25FLG1CQUFtQixhQUFhLElBQUksaUJBQWlCLFVBQVUsSUFBSTtFQUNuRSxrQkFBa0IsYUFBYSxJQUFJLGdCQUFnQixVQUFVLElBQUk7RUFDakUsaUJBQWlCLGFBQWEsSUFBSSxlQUFlLFVBQVUsSUFBSTtFQUMvRCxVQUFVLFVBQVUsY0FBYyxJQUFJLFFBQVEsVUFBVSxXQUFXLElBQUk7RUFDdkUsaUJBQWlCLGFBQWEsSUFBSSxlQUFlLFVBQVUsSUFBSTtDQUNoRTtBQUNEO0FBRUEsU0FBUyx1QkFBdUIsTUFBTSxXQUFXLFNBQVM7Q0FDekQsTUFBTSxPQUFPLEtBQUssS0FBSyxXQUFXLE1BQU0sSUFBSSxVQUFVO0NBQ3RELE1BQU0sTUFBTSxLQUFLLEtBQUssV0FBVyxRQUFRLElBQUksU0FBUztDQUN0RCxNQUFNLE9BQU8sR0FBRyxLQUFLLEtBQUssV0FBVyxPQUFPLEVBQUUsR0FBRyxVQUFVLGFBQWEsR0FBRztDQUMzRSxNQUFNLGNBQWMsS0FBSyxLQUFLLFdBQVcsU0FBUztDQUVsRCxPQUFPLFNBQVMsS0FBSyxVQURMLGNBQWMsSUFBSSxnQkFBZ0IsR0FDWCxHQUFHLE1BQU07QUFDakQ7QUFDQSxTQUFTLGtCQUFrQixPQUFPLFNBQVMsV0FBVyxPQUFPLFFBQVE7Q0FDcEUsTUFBTSxPQUFPO0NBRWIsSUFBSSxRQUFRLG1CQUFtQixTQUFTO0VBRXZDLFVBQVUsUUFBUSxjQUFjO0dBQy9CLElBQUksQ0FBQyxLQUFLLFVBQ1Q7R0FFRCxNQUFNLFFBQVEsS0FBSyxTQUFTLFFBQVEsT0FBTztHQUMzQyxJQUFJLFVBQVUsSUFDYixLQUFLLFNBQVMsT0FBTyxPQUFPLENBQUM7RUFFL0IsQ0FBQztFQUVELElBQUksQ0FBQyxLQUFLLFVBQ1QsS0FBSyxXQUFXLENBQUM7RUFJbEIsSUFBSSxRQUNILFVBQVUsUUFBUSxLQUFLLE9BQU8sUUFBUTtHQUNyQyxnQkFBZ0IsTUFBTSxHQUFHO0VBQzFCLENBQUM7RUFFRixLQUFLLFNBQVMsS0FBSyxPQUFPO0VBQzFCLElBQUksV0FBVztFQUNmLEtBQUssZUFBZSxDQUFDO0VBQ3JCLEtBQUssV0FBVyxXQUFXO0dBQzFCLElBQUksQ0FBQyxVQUFVO0lBRWQsTUFBTSxTQURZLFdBQVcsbUJBQW1CLHdCQUF3QixNQUFNLEtBQUssSUFDckUsQ0FBVSxNQUFNLEtBQUs7SUFDbkMsUUFBUSxLQUFLO0tBQ1oseUJBQXlCLFVBQVU7S0FDbkM7S0FDQTtLQUNBO0lBQ0QsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO0dBQ1g7RUFDRCxDQUFDO0VBQ0QsT0FBTztHQUNOLEtBQUssYUFBYSxZQUFZO0lBQzdCLFdBQVc7SUFDWCxPQUFPLFFBQVEsS0FBSyxhQUFhLFVBQVU7R0FDNUM7R0FDQSxNQUFNLFlBQVk7SUFDakIsV0FBVztJQUNYLE9BQU8sUUFBUSxNQUFNLFVBQVU7R0FDaEM7R0FDQSxRQUFRLFdBQVc7SUFDbEIsV0FBVztJQUNYLE9BQU8sUUFBUSxRQUFRLFNBQVM7R0FDakM7SUFDQyxPQUFPLGNBQWM7RUFDdkI7Q0FDRDtDQUNBLE9BQU87QUFDUjtBQUNBLFNBQVMsZ0JBQWdCLE1BQU0sS0FBSztDQUNuQyxLQUFLLFdBQVcsRUFBRSxPQUFPLE9BQU87Q0FDaEMsS0FBSyxPQUFPLFFBQVE7Q0FDcEIsS0FBSyxPQUFPLFdBQVcsQ0FBQztDQUN4QixLQUFLLE9BQU8sT0FBTyxLQUFLLGFBQWEsR0FBRyxDQUFDO0FBQzFDOztBQUVBLFNBQVMsY0FBYyxPQUFPLE1BQU0sSUFBSTtDQUN2QyxPQUFPLFNBQVMsR0FBRyxNQUFNO0VBRXhCLElBQUksU0FBUyxZQUNaLE1BQU0sS0FBSyxNQUFNLFNBQVMsSUFBSTtFQUUvQixJQUFJLENBQUMsTUFBTSxLQUFLLE1BQU0sTUFBTSxHQUczQixJQUFJO0dBQ0gsT0FBTyxHQUFHLE1BQU0sTUFBTSxJQUFJO0VBQzNCLFVBQVUsQ0FBQztFQUVaLE1BQU0sT0FBTyxNQUFNLEtBQUssTUFBTSxhQUFhO0VBQzNDLElBQUksQ0FBQyxNQUNKLE1BQU0sSUFBSSxNQUFNLDhDQUE4QztFQUUvRCxJQUFJO0dBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSxNQUFNLElBQUk7R0FDbEMsSUFBSSxVQUFVLE9BQU8sV0FBVyxZQUFZLE9BQU8sT0FBTyxTQUFTLFlBQ2xFLE9BQU8sT0FBTyxLQUFLLE9BQU8sUUFBUTtJQUNqQyxnQkFBZ0IsTUFBTSxHQUFHO0dBQzFCLENBQUM7R0FFRixPQUFPO0VBQ1IsU0FBUyxLQUFLO0dBQ2IsZ0JBQWdCLE1BQU0sR0FBRztFQUMxQjtDQUNEO0FBQ0Q7QUFHQSxNQUFNLGtCQUFrQixNQUFNLFVBQVU7Q0FDdkMsTUFBTSxFQUFFLG1CQUFtQjtDQUMzQixNQUFNLGdCQUFnQix5QkFBeUI7Q0FDL0MsU0FBUyxJQUFJLE1BQU0sSUFBSTtFQUN0QixNQUFNLGFBQWEsTUFBTTtHQUN4QixNQUFNLGNBQWMsY0FBYyxPQUFPLEdBQUcsRUFBRTtHQUM5QyxNQUFNLFVBQVUsS0FBSyxVQUFVLFdBQVcsR0FBRyxXQUFXO0dBQ3hELE1BQU0sVUFBVSxXQUFXLHFCQUFxQixDQUFDLFVBQVUsR0FBRyxXQUFXO0VBQzFFO0VBQ0EsSUFBSSxNQUFNLFFBQVEsSUFBSSxHQUNyQixLQUFLLFNBQVMsTUFBTSxVQUFVLENBQUMsQ0FBQztPQUVoQyxVQUFVLElBQUk7Q0FFaEI7Q0FDQTtFQUNDO0VBQ0E7RUFDQTtDQUNELENBQUMsQ0FBQyxTQUFTLE1BQU07RUFDaEIsTUFBTSxnQkFBZ0IsS0FBSyxVQUFVLFdBQVcsSUFBSSxXQUFXO0dBQzlELE9BQU8sU0FBUyxHQUFHLE1BQU07SUFDeEIsTUFBTSxVQUFVLE1BQU0sS0FBSyxNQUFNLFNBQVM7SUFDMUMsTUFBTSxTQUFTLE1BQU0sS0FBSyxNQUFNLFFBQVE7SUFDeEMsTUFBTSxRQUFRLE1BQU0sS0FBSyxNQUFNLFFBQVE7SUFDdkMsSUFBSSxZQUFZLFdBQ2YsTUFBTSxLQUFLLE1BQU0sZ0JBQWdCO0tBQ2hDLE1BQU07SUFDUCxDQUFDO1NBQ0ssSUFBSSxZQUFZLGNBQWMsT0FBTyxXQUFXLFlBQ3RELElBQUksQ0FBQyxPQUFPO0tBQ1gsTUFBTSxVQUFVLE1BQU0sS0FBSyxNQUFNLFNBQVMsS0FBSztLQUUvQyxNQUFNLElBQUksZUFBZSxTQUFTLEVBRGxCLFVBQVUsTUFDUSxHQUFPLE1BQU0sS0FBSyxNQUFNLE1BQU0sQ0FBQztJQUNsRSxPQUNDO0lBR0YsT0FBTyxNQUFNLE1BQU0sSUFBSTtHQUN4QjtFQUNELENBQUM7Q0FDRixDQUFDO0NBRUQsSUFBSSxZQUFZLFNBQVMsTUFBTTtFQUM5QixNQUFNLEtBQUssTUFBTSxlQUFlLElBQUk7RUFDcEMsT0FBTztDQUNSLENBQUM7Q0FDRCxJQUFJLFdBQVcsU0FBUyxVQUFVO0VBQ2pDLE1BQU0sU0FBUyxNQUFNLEtBQUssTUFBTSxRQUFRO0VBQ3hDLE1BQU0sUUFBUSxPQUFPLFFBQVEsVUFBVSxDQUFDLEdBQUcsZUFBZSxnQkFBZ0IsQ0FBQztFQUMzRSxPQUFPLEtBQUssT0FBTyxPQUFPLDJDQUEyQywrQ0FBK0MsVUFBVSxNQUFNO0NBQ3JJLENBQUM7Q0FDRCxJQUFJLGlCQUFpQixTQUFTLFVBQVU7RUFDdkMsTUFBTSxNQUFNLE1BQU0sS0FBSyxNQUFNLFFBQVE7RUFDckMsTUFBTSxRQUFRLE9BQU8sS0FBSyxVQUFVO0dBQ25DLEdBQUc7R0FDSDtHQUNBO0dBQ0E7R0FDQTtFQUNELEdBQUcsSUFBSTtFQUNQLE9BQU8sS0FBSyxPQUFPLE9BQU8sNkNBQTZDLGlEQUFpRCxVQUFVLEdBQUc7Q0FDdEksQ0FBQztDQUNELElBQUksUUFBUSxTQUFTLFVBQVU7RUFDOUIsTUFBTSxTQUFTLEtBQUs7RUFDcEIsTUFBTSxPQUFPLE9BQU8sR0FBRyxRQUFRLFFBQVE7RUFDdkMsSUFBSSxtQkFBbUI7RUFDdkIsSUFBSSxDQUFDLE1BUUo7T0FQMEIsT0FBTyxRQUFRLFVBQVU7SUFDbEQsR0FBRztJQUNIO0lBQ0E7SUFDQTtJQUNBO0dBQ0QsR0FBRyxJQUNDLEdBQ0gsbUJBQW1CO1FBR25CLElBRG9CLE9BQU8sUUFBUSxVQUFVLENBQUMsR0FBRyxlQUFlLGdCQUFnQixDQUM1RSxHQUNILG1CQUFtQjtFQUVyQjtFQUVELE9BQU8sS0FBSyxPQUFPLE1BQU0sb0JBQW9CLGdCQUFnQixHQUFHLDJEQUEyRCxVQUFVLE1BQU07Q0FDNUksQ0FBQztDQUNELElBQUksaUJBQWlCLFNBQVMsVUFBVTtFQUN2QyxNQUFNLFNBQVMsS0FBSztFQUNwQixNQUFNLE9BQU8sT0FBTyxRQUFRLFVBQVU7R0FDckMsR0FBRztHQUNIO0dBQ0E7RUFDRCxDQUFDO0VBQ0QsTUFBTSxRQUFRLE1BQU0sS0FBSyxNQUFNLFFBQVE7RUFDdkMsTUFBTSxFQUFFLFFBQVEsY0FBYyxhQUFhLGdCQUFnQixRQUFRLFVBQVUsYUFBYTtFQUMxRixJQUFJLFFBQVEsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPO0dBQ3JDLE1BQU0sTUFBTSxNQUFNLFdBQVcsTUFBTTtJQUNsQztJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7R0FDRCxDQUFDO0dBQ0QsTUFBTSxVQUFVLGFBQWEsSUFBSSxNQUFNLEdBQUcsSUFBSSxLQUFLLFNBQVMsWUFBWSxhQUFhLElBQUksYUFBYSxhQUFhO0dBQ25ILE1BQU0sSUFBSSxlQUFlLFNBQVM7SUFDakMsVUFBVTtJQUNWO0lBQ0EsUUFBUTtHQUNULENBQUM7RUFDRjtDQUNELENBQUM7Q0FDRCxJQUFJLFdBQVcsU0FBUyxVQUFVO0VBQ2pDLE1BQU0sU0FBUyxLQUFLO0VBQ3BCLElBQUksT0FBTyxXQUFXLFVBQ3JCLE1BQU0sSUFBSSxVQUFVLG1EQUFtRCxPQUFPLFFBQVE7RUFFdkYsT0FBTyxLQUFLLE9BQU8sT0FBTyxhQUFhLFdBQVcsT0FBTyxTQUFTLFFBQVEsSUFBSSxPQUFPLE1BQU0sUUFBUSxHQUFHLG9DQUFvQyx3Q0FBd0MsVUFBVSxNQUFNO0NBQ25NLENBQUM7Q0FDRCxJQUFJLGFBQWEsU0FBUyxNQUFNO0VBQy9CLE1BQU0sU0FBUyxLQUFLO0VBQ3BCLElBQUksT0FBTyxTQUFTLGVBQWUsa0JBQWtCLE1BQU07R0FDMUQsSUFBSSxFQUFFLGdCQUFnQixPQUNyQixNQUFNLElBQUksVUFBVSw0REFBNEQsT0FBTyxNQUFNO0dBRTlGLE9BQU8sS0FBSyxPQUFPLE9BQU8sU0FBUyxJQUFJLEdBQUcsOENBQThDLGtEQUFrRCxNQUFNLE1BQU07RUFDdko7RUFDQSxJQUFJLE9BQU8saUJBQWlCLGVBQWUsa0JBQWtCLGNBQWM7R0FDMUUsWUFBWSxNQUFNLGNBQWMsQ0FBQyxRQUFRLENBQUM7R0FFMUMsTUFBTSxvQkFEUSxNQUFNLEtBQUssTUFBTSxRQUNMLElBQVEsT0FBTyxNQUFNLFFBQVEsTUFBTSxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksR0FBRyxPQUFPLE1BQU0sR0FBRztHQUM3RixPQUFPLEtBQUssT0FBTyxPQUFPLFNBQVMsSUFBSSxHQUFHLGFBQWEsT0FBTyxNQUFNLGdCQUFnQixLQUFLLElBQUksYUFBYSxPQUFPLE1BQU0sb0JBQW9CLEtBQUssSUFBSSxtQkFBbUIsT0FBTyxLQUFLO0VBQ3BMO0VBRUEsSUFBSSxPQUFPLFdBQVcsWUFBWSxPQUFPLFNBQVMsVUFDakQsT0FBTyxLQUFLLE9BQU8sT0FBTyxTQUFTLElBQUksR0FBRyxzQ0FBc0MsMENBQTBDLE1BQU0sTUFBTTtFQUd2SSxJQUFJLFVBQVUsUUFBUSxPQUFPLFdBQVcsVUFDdkMsTUFBTSxLQUFLLE1BQU0sVUFBVSxNQUFNLEtBQUssTUFBTSxDQUFDO0VBRTlDLE9BQU8sS0FBSyxRQUFRLElBQUk7Q0FDekIsQ0FBQztDQUNELElBQUksa0JBQWtCLFNBQVMsVUFBVTtFQUN4QyxNQUFNLE1BQU0sTUFBTSxLQUFLLE1BQU0sUUFBUTtFQUNyQyxNQUFNLFFBQVEsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLFdBQVcsU0FBUztHQUNqRCxPQUFPLE9BQU8sTUFBTSxVQUFVLGFBQWE7RUFDNUMsQ0FBQztFQUNELEtBQUssT0FBTyxVQUFVLElBQUksbURBQW1ELHVEQUF1RCxRQUFRO0NBQzdJLENBQUM7Q0FDRCxJQUFJLGNBQWMsV0FBVztFQUM1QixNQUFNLE1BQU0sTUFBTSxLQUFLLE1BQU0sUUFBUTtFQUNyQyxLQUFLLE9BQU8sUUFBUSxHQUFHLEdBQUcsaUNBQWlDLHFDQUFxQyxNQUFNLEdBQUc7Q0FDMUcsQ0FBQztDQUNELElBQUksYUFBYSxXQUFXO0VBQzNCLE1BQU0sTUFBTSxNQUFNLEtBQUssTUFBTSxRQUFRO0VBQ3JDLEtBQUssT0FBTyxDQUFDLEtBQUssZ0NBQWdDLG9DQUFvQyxPQUFPLEdBQUc7Q0FDakcsQ0FBQztDQUNELElBQUksbUJBQW1CLFNBQVMsVUFBVTtFQUN6QyxNQUFNLFNBQVMsS0FBSztFQUNwQixZQUFZLFFBQVEsVUFBVSxDQUFDLFVBQVUsUUFBUSxDQUFDO0VBQ2xELFlBQVksVUFBVSxZQUFZLENBQUMsVUFBVSxRQUFRLENBQUM7RUFDdEQsT0FBTyxLQUFLLE9BQU8sU0FBUyxVQUFVLFlBQVksT0FBTyxzQkFBc0IsWUFBWSxZQUFZLE9BQU8sMEJBQTBCLFlBQVksVUFBVSxRQUFRLEtBQUs7Q0FDNUssQ0FBQztDQUNELElBQUksMEJBQTBCLFNBQVMsVUFBVTtFQUNoRCxNQUFNLFNBQVMsS0FBSztFQUNwQixZQUFZLFFBQVEsVUFBVSxDQUFDLFVBQVUsUUFBUSxDQUFDO0VBQ2xELFlBQVksVUFBVSxZQUFZLENBQUMsVUFBVSxRQUFRLENBQUM7RUFDdEQsT0FBTyxLQUFLLE9BQU8sVUFBVSxVQUFVLFlBQVksT0FBTyxrQ0FBa0MsWUFBWSxZQUFZLE9BQU8sc0NBQXNDLFlBQVksVUFBVSxRQUFRLEtBQUs7Q0FDck0sQ0FBQztDQUNELElBQUksZ0JBQWdCLFNBQVMsVUFBVTtFQUN0QyxNQUFNLFNBQVMsS0FBSztFQUNwQixZQUFZLFFBQVEsVUFBVSxDQUFDLFVBQVUsUUFBUSxDQUFDO0VBQ2xELFlBQVksVUFBVSxZQUFZLENBQUMsVUFBVSxRQUFRLENBQUM7RUFDdEQsT0FBTyxLQUFLLE9BQU8sU0FBUyxVQUFVLFlBQVksT0FBTyxtQkFBbUIsWUFBWSxZQUFZLE9BQU8sdUJBQXVCLFlBQVksVUFBVSxRQUFRLEtBQUs7Q0FDdEssQ0FBQztDQUNELElBQUksdUJBQXVCLFNBQVMsVUFBVTtFQUM3QyxNQUFNLFNBQVMsS0FBSztFQUNwQixZQUFZLFFBQVEsVUFBVSxDQUFDLFVBQVUsUUFBUSxDQUFDO0VBQ2xELFlBQVksVUFBVSxZQUFZLENBQUMsVUFBVSxRQUFRLENBQUM7RUFDdEQsT0FBTyxLQUFLLE9BQU8sVUFBVSxVQUFVLFlBQVksT0FBTywrQkFBK0IsWUFBWSxZQUFZLE9BQU8sbUNBQW1DLFlBQVksVUFBVSxRQUFRLEtBQUs7Q0FDL0wsQ0FBQztDQUNELElBQUksV0FBVyxXQUFXO0VBQ3pCLE1BQU0sTUFBTSxNQUFNLEtBQUssTUFBTSxRQUFRO0VBQ3JDLEtBQUssT0FBTyxPQUFPLE1BQU0sR0FBRyxHQUFHLDhCQUE4QixrQ0FBa0MsS0FBWSxHQUFHO0NBQy9HLENBQUM7Q0FDRCxJQUFJLGlCQUFpQixXQUFXO0VBQy9CLE1BQU0sTUFBTSxNQUFNLEtBQUssTUFBTSxRQUFRO0VBQ3JDLEtBQUssT0FBTyxXQUFjLEtBQUssb0NBQW9DLHdDQUF3QyxRQUFXLEdBQUc7Q0FDMUgsQ0FBQztDQUNELElBQUksWUFBWSxXQUFXO0VBQzFCLE1BQU0sTUFBTSxNQUFNLEtBQUssTUFBTSxRQUFRO0VBQ3JDLEtBQUssT0FBTyxRQUFRLE1BQU0sK0JBQStCLG1DQUFtQyxNQUFNLEdBQUc7Q0FDdEcsQ0FBQztDQUNELElBQUksZ0JBQWdCLFdBQVc7RUFDOUIsTUFBTSxNQUFNLE1BQU0sS0FBSyxNQUFNLFFBQVE7RUFDckMsS0FBSyxPQUFPLE9BQU8sTUFBTSxrQ0FBa0Msc0NBQXNDLE1BQU0sR0FBRztDQUMzRyxDQUFDO0NBQ0QsSUFBSSxlQUFlLFdBQVc7RUFDN0IsTUFBTSxNQUFNLE1BQU0sS0FBSyxNQUFNLFFBQVE7RUFDckMsS0FBSyxPQUFPLE9BQU8sUUFBUSxhQUFhLGtDQUFrQyxvQ0FBb0MsR0FBRztDQUNsSCxDQUFDO0NBQ0QsSUFBSSxjQUFjLFNBQVMsVUFBVTtFQUNwQyxNQUFNLFNBQVMsT0FBTyxLQUFLO0VBQzNCLE1BQU0sUUFBUSxhQUFhO0VBQzNCLE9BQU8sS0FBSyxPQUFPLE9BQU8seUNBQXlDLDZDQUE2QyxVQUFVLE1BQU07Q0FDakksQ0FBQztDQUNELElBQUksa0JBQWtCLFNBQVMsS0FBSztFQUNuQyxPQUFPLEtBQUssV0FBVyxHQUFHO0NBQzNCLENBQUM7Q0FDRCxJQUFJLGdCQUFnQixTQUFTLFFBQVE7RUFDcEMsT0FBTyxLQUFLLEtBQUssT0FBTyxNQUFNO0NBQy9CLENBQUM7Q0FFRCxJQUFJLGtCQUFrQixTQUFTLEdBQUcsTUFBTTtFQUN2QyxJQUFJLE1BQU0sUUFBUSxLQUFLLEVBQUUsR0FDeEIsS0FBSyxLQUFLLEtBQUssRUFBRSxDQUFDLEtBQUssUUFBUSxPQUFPLEdBQUcsQ0FBQyxDQUFDLFFBQVEsYUFBYSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRztFQUVsRixNQUFNLFNBQVMsS0FBSztFQUNwQixNQUFNLENBQUMsY0FBYyxZQUFZO0VBQ2pDLE1BQU0saUJBQWlCO0dBRXRCLElBRGUsT0FBTyxPQUFPLFFBQVEsWUFDakMsR0FDSCxPQUFPO0lBQ04sT0FBTyxPQUFPO0lBQ2QsUUFBUTtHQUNUO0dBRUQsT0FBTyxNQUFNLFlBQVksUUFBUSxZQUFZO0VBQzlDO0VBQ0EsTUFBTSxFQUFFLE9BQU8sV0FBVyxTQUFTO0VBQ25DLE1BQU0sT0FBTyxXQUFXLEtBQUssV0FBVyxLQUFLLE9BQU8sVUFBVSxPQUFPLGFBQWE7RUFDbEYsTUFBTSxjQUFjLEtBQUssV0FBVyxJQUFJLEtBQUssZUFBZSxNQUFNLFdBQVcsUUFBUTtFQUNyRixPQUFPLEtBQUssT0FBTyxNQUFNLHNDQUFzQyxhQUFhLEdBQUcsZUFBZSwwQ0FBMEMsYUFBYSxHQUFHLGVBQWUsVUFBVSxTQUFTLFFBQVEsTUFBUztDQUM1TSxDQUFDO0NBQ0QsSUFBSSxlQUFlLFNBQVMsVUFBVSxZQUFZLEdBQUc7RUFDcEQsTUFBTSxXQUFXLEtBQUs7RUFDdEIsSUFBSSxPQUFPO0VBQ1gsSUFBSSxlQUFlO0VBQ25CLElBQUksZUFBZTtFQUNuQixJQUFJLGFBQWEsT0FBTyxxQkFBcUIsYUFBYSxPQUFPLG1CQUNoRSxPQUFPO09BQ0QsSUFBSSxhQUFhLE9BQU8scUJBQXFCLGFBQWEsT0FBTyxtQkFDdkUsT0FBTztPQUNEO0dBQ04sZUFBZSxNQUFNLENBQUMsWUFBWTtHQUNsQyxlQUFlLEtBQUssSUFBSSxXQUFXLFFBQVE7R0FDM0MsT0FBTyxlQUFlO0VBQ3ZCO0VBQ0EsT0FBTyxLQUFLLE9BQU8sTUFBTSxrRUFBa0UsYUFBYSxpQkFBaUIsZ0JBQWdCLHNFQUFzRSxhQUFhLGlCQUFpQixnQkFBZ0IsVUFBVSxVQUFVLEtBQUs7Q0FDdlIsQ0FBQztDQUNELFNBQVMsYUFBYSxXQUFXO0VBQ2hDLElBQUksQ0FBQyxlQUFlLFVBQVUsSUFBSSxHQUNqQyxNQUFNLElBQUksVUFBVSxHQUFHLE1BQU0sUUFBUSxVQUFVLElBQUksRUFBRSxrQ0FBa0M7Q0FFekY7Q0FDQSxTQUFTLE9BQU8sV0FBVztFQUMxQixhQUFhLFNBQVM7RUFDdEIsT0FBTyxVQUFVO0NBQ2xCO0NBQ0EsSUFBSSxDQUFDLHlCQUF5QixpQkFBaUIsR0FBRyxTQUFTLFFBQVE7RUFDbEUsTUFBTSxNQUFNLE9BQU8sSUFBSTtFQUN2QixNQUFNLFVBQVUsSUFBSSxZQUFZO0VBQ2hDLE1BQU0sWUFBWSxJQUFJLEtBQUssTUFBTTtFQUNqQyxPQUFPLEtBQUssT0FBTyxjQUFjLFFBQVEsYUFBYSxRQUFRLHVDQUF1QyxVQUFVLFNBQVMsYUFBYSxRQUFRLGtDQUFrQyxRQUFRLFdBQVcsS0FBSztDQUN4TSxDQUFDO0NBQ0QsSUFBSSx3QkFBd0IsV0FBVztFQUN0QyxNQUFNLE1BQU0sT0FBTyxJQUFJO0VBQ3ZCLE1BQU0sVUFBVSxJQUFJLFlBQVk7RUFDaEMsTUFBTSxZQUFZLElBQUksS0FBSyxNQUFNO0VBQ2pDLE9BQU8sS0FBSyxPQUFPLGNBQWMsR0FBRyxhQUFhLFFBQVEsK0JBQStCLFVBQVUsU0FBUyxhQUFhLFFBQVEsMEJBQTBCLEdBQUcsV0FBVyxLQUFLO0NBQzlLLENBQUM7Q0FDRCxJQUFJLENBQUMsb0JBQW9CLFlBQVksR0FBRyxXQUFXO0VBQ2xELE1BQU0sTUFBTSxPQUFPLElBQUk7RUFDdkIsTUFBTSxVQUFVLElBQUksWUFBWTtFQUNoQyxNQUFNLFlBQVksSUFBSSxLQUFLLE1BQU07RUFDakMsTUFBTSxTQUFTLFlBQVk7RUFDM0IsTUFBTSxRQUFRLE1BQU0sS0FBSyxNQUFNLFFBQVE7RUFDdkMsSUFBSSxNQUFNLE1BQU0sV0FBVyxNQUFNO0dBQ2hDO0dBQ0EsYUFBYSxRQUFRO0dBQ3JCLGFBQWEsUUFBUSxzREFBc0QsVUFBVTtHQUNyRjtHQUNBO0VBQ0QsQ0FBQztFQUNELElBQUksVUFBVSxPQUNiLE1BQU0sWUFBWSxLQUFLLEdBQUc7RUFFM0IsSUFBSSxVQUFVLFNBQVMsQ0FBQyxVQUFVLENBQUMsT0FDbEMsTUFBTSxJQUFJLGVBQWUsR0FBRztDQUU5QixDQUFDO0NBR0QsU0FBUyxvQkFBb0IsR0FBRyxHQUFHO0VBQ2xDLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE9BQU8sT0FBTyxNQUFNLE9BQU8sT0FBTyxFQUFFLElBQUksQ0FBQyxHQUFHLGVBQWUsZ0JBQWdCLENBQUMsQ0FBQztDQUNoSDtDQUNBLElBQUksQ0FBQyx3QkFBd0IsZ0JBQWdCLEdBQUcsU0FBUyxHQUFHLE1BQU07RUFDakUsTUFBTSxNQUFNLE9BQU8sSUFBSTtFQUN2QixNQUFNLFVBQVUsSUFBSSxZQUFZO0VBQ2hDLE1BQU0sT0FBTyxJQUFJLEtBQUssTUFBTSxNQUFNLFlBQVksb0JBQW9CLFNBQVMsSUFBSSxDQUFDO0VBQ2hGLE1BQU0sUUFBUSxNQUFNLEtBQUssTUFBTSxRQUFRO0VBQ3ZDLE1BQU0sTUFBTSxNQUFNLFdBQVcsTUFBTTtHQUNsQztHQUNBLGFBQWEsUUFBUTtHQUNyQixhQUFhLFFBQVE7R0FDckI7RUFDRCxDQUFDO0VBQ0QsSUFBSSxRQUFRLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FDOUIsTUFBTSxJQUFJLGVBQWUsWUFBWSxLQUFLLEtBQUssSUFBSSxDQUFDO0NBRXRELENBQUM7Q0FDRCxJQUFJLG1DQUFtQyxTQUFTLEdBQUcsTUFBTTtFQUN4RCxNQUFNLE1BQU0sT0FBTyxJQUFJO0VBQ3ZCLE1BQU0sVUFBVSxJQUFJLFlBQVk7RUFDaEMsTUFBTSxZQUFZLElBQUksS0FBSyxNQUFNO0VBRWpDLE1BQU0sT0FEa0IsSUFBSSxLQUFLLE1BQU0sTUFBTSxZQUFZLG9CQUFvQixTQUFTLElBQUksQ0FDN0UsS0FBbUIsY0FBYztFQUM5QyxNQUFNLFFBQVEsTUFBTSxLQUFLLE1BQU0sUUFBUTtFQUN2QyxNQUFNLE1BQU0sTUFBTSxXQUFXLE1BQU07R0FDbEM7R0FDQSxhQUFhLFFBQVE7R0FDckIsYUFBYSxRQUFRO0dBQ3JCO0VBQ0QsQ0FBQztFQUNELElBQUksUUFBUSxTQUFTLENBQUMsUUFBUSxDQUFDLE9BQzlCLE1BQU0sSUFBSSxlQUFlLFlBQVksS0FBSyxLQUFLLElBQUksQ0FBQztDQUV0RCxDQUFDO0NBQ0QsSUFBSSwyQkFBMkIsU0FBUyxPQUFPLEdBQUcsTUFBTTtFQUN2RCxNQUFNLE1BQU0sT0FBTyxJQUFJO0VBQ3ZCLE1BQU0sVUFBVSxJQUFJLFlBQVk7RUFDaEMsTUFBTSxVQUFVLElBQUksS0FBSyxNQUFNLFFBQVE7RUFDdkMsTUFBTSxZQUFZLElBQUksS0FBSyxNQUFNO0VBQ2pDLE1BQU0sV0FBVyxTQUFTO0VBQzFCLEtBQUssT0FBTyxXQUFXLG9CQUFvQixTQUFTLElBQUksR0FBRyxZQUFZLFFBQVEsS0FBSyxFQUFFLElBQUksUUFBUSx3Q0FBd0MsV0FBVyxLQUFLLHFCQUFxQixVQUFVLFdBQVcsWUFBWSxRQUFRLEtBQUssRUFBRSxJQUFJLFFBQVEsNkNBQTZDLE1BQU0sU0FBUyxRQUFRO0NBQ2hULENBQUM7Q0FDRCxJQUFJLDRCQUE0QixTQUFTLEdBQUcsTUFBTTtFQUNqRCxNQUFNLE1BQU0sT0FBTyxJQUFJO0VBQ3ZCLE1BQU0sVUFBVSxJQUFJLFlBQVk7RUFDaEMsTUFBTSxXQUFXLElBQUksS0FBSyxNQUFNLEdBQUcsRUFBRTtFQUNyQyxLQUFLLE9BQU8sWUFBWSxvQkFBb0IsVUFBVSxJQUFJLEdBQUcsa0JBQWtCLFFBQVEseUNBQXlDLGtCQUFrQixRQUFRLDZDQUE2QyxNQUFNLFFBQVE7Q0FDdE4sQ0FBQzs7OztDQUlELFNBQVMsNEJBQTRCLFdBQVcsVUFBVSx5QkFBeUI7RUFDbEYsTUFBTSw0QkFBNEIsVUFBVSxLQUFLO0VBQ2pELE1BQU0sMkJBQTJCLFNBQVMsS0FBSztFQUMvQyxJQUFJLDBCQUEwQixXQUFXLEdBQ3hDLE9BQU8sQ0FBQztFQUVULElBQUkseUJBQXlCLFdBQVcsR0FDdkMsT0FBTztFQUVSLE9BQU8sMEJBQTBCLEtBQUsseUJBQXlCO0NBQ2hFO0NBQ0EsSUFBSSxDQUFDLHdCQUF3QixHQUFHLFNBQVMsV0FBVywwQkFBMEIsTUFBTTtFQUNuRixNQUFNLFlBQVksT0FBTyxJQUFJO0VBQzdCLElBQUksQ0FBQyxlQUFlLFNBQVMsR0FDNUIsTUFBTSxJQUFJLFVBQVUsR0FBRyxNQUFNLFFBQVEsU0FBUyxFQUFFLGlDQUFpQztFQUVsRixLQUFLLE9BQU8sNEJBQTRCLFdBQVcsV0FBVyx1QkFBdUIsR0FBRyxhQUFhLFVBQVUsWUFBWSxFQUFFLGdDQUFnQyxVQUFVLFlBQVksRUFBRSxJQUFJLGFBQWEsVUFBVSxZQUFZLEVBQUUsb0NBQW9DLFVBQVUsWUFBWSxFQUFFLElBQUksV0FBVyxTQUFTO0NBQ25ULENBQUM7Q0FDRCxJQUFJLENBQUMsdUJBQXVCLEdBQUcsU0FBUyxXQUFXLDBCQUEwQixNQUFNO0VBQ2xGLE1BQU0sWUFBWSxPQUFPLElBQUk7RUFDN0IsSUFBSSxDQUFDLGVBQWUsU0FBUyxHQUM1QixNQUFNLElBQUksVUFBVSxHQUFHLE1BQU0sUUFBUSxTQUFTLEVBQUUsaUNBQWlDO0VBRWxGLEtBQUssT0FBTyw0QkFBNEIsV0FBVyxXQUFXLHVCQUF1QixHQUFHLGFBQWEsVUFBVSxZQUFZLEVBQUUsK0JBQStCLFVBQVUsWUFBWSxFQUFFLElBQUksYUFBYSxVQUFVLFlBQVksRUFBRSxtQ0FBbUMsVUFBVSxZQUFZLEVBQUUsSUFBSSxXQUFXLFNBQVM7Q0FDalQsQ0FBQztDQUNELElBQUksQ0FBQyxXQUFXLGNBQWMsR0FBRyxTQUFTLFVBQVU7RUFDbkQsSUFBSSxPQUFPLGFBQWEsWUFBWSxPQUFPLGFBQWEsZUFBZSxvQkFBb0IsUUFFMUYsT0FBTyxLQUFLLE9BQU8sYUFBYSxLQUFLLE9BQU8sUUFBUTtFQUVyRCxNQUFNLE1BQU0sS0FBSztFQUNqQixNQUFNLFVBQVUsTUFBTSxLQUFLLE1BQU0sU0FBUztFQUMxQyxNQUFNLFFBQVEsTUFBTSxLQUFLLE1BQU0sUUFBUTtFQUN2QyxJQUFJLFNBQVM7RUFDYixJQUFJLFlBQVksV0FDZixTQUFTO09BQ0gsSUFBSSxZQUFZLGNBQWMsT0FBTyxRQUFRLFlBQ25ELElBQUksQ0FBQyxPQUFPO0dBQ1gsTUFBTSxVQUFVLE1BQU0sS0FBSyxNQUFNLFNBQVMsS0FBSztHQUUvQyxNQUFNLElBQUksZUFBZSxTQUFTLEVBRGxCLFVBQVUsTUFDUSxHQUFPLE1BQU0sS0FBSyxNQUFNLE1BQU0sQ0FBQztFQUNsRSxPQUNDO09BRUs7R0FDTixJQUFJLFVBQVU7R0FDZCxJQUFJO0lBQ0gsSUFBSTtHQUNMLFNBQVMsS0FBSztJQUNiLFVBQVU7SUFDVixTQUFTO0dBQ1Y7R0FDQSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU87SUFDdkIsTUFBTSxVQUFVLE1BQU0sS0FBSyxNQUFNLFNBQVMsS0FBSztJQUUvQyxNQUFNLElBQUksZUFBZSxTQUFTLEVBRGxCLFVBQVUsTUFDUSxHQUFPLE1BQU0sS0FBSyxNQUFNLE1BQU0sQ0FBQztHQUNsRTtFQUNEO0VBQ0EsSUFBSSxPQUFPLGFBQWEsWUFBWTtHQUNuQyxNQUFNLE9BQU8sU0FBUyxRQUFRLFNBQVMsVUFBVSxZQUFZO0dBQzdELE9BQU8sS0FBSyxPQUFPLFVBQVUsa0JBQWtCLFVBQVUsb0NBQW9DLFFBQVEsd0NBQXdDLFFBQVEsVUFBVSxNQUFNO0VBQ3RLO0VBQ0EsSUFBSSxRQUFRLFFBQVEsR0FBRztHQUN0QixNQUFNLFFBQVEsT0FBTyxRQUFRLFVBQVUsQ0FBQyxHQUFHLGVBQWUsZ0JBQWdCLENBQUM7R0FDM0UsT0FBTyxLQUFLLE9BQU8sT0FBTyx3Q0FBd0MsNENBQTRDLFVBQVUsTUFBTTtFQUMvSDtFQUNBLElBQUksT0FBTyxhQUFhLFlBQVkscUJBQXFCLFlBQVksT0FBTyxTQUFTLG9CQUFvQixZQUFZO0dBQ3BILE1BQU0sVUFBVTtHQUNoQixPQUFPLEtBQUssT0FBTyxVQUFVLFFBQVEsZ0JBQWdCLE1BQU0sR0FBRyw4Q0FBOEMsa0RBQWtELFNBQVMsTUFBTTtFQUM5SztFQUNBLE1BQU0sUUFBUSxPQUFPLFFBQVEsVUFBVSxDQUFDLEdBQUcsZUFBZSxnQkFBZ0IsQ0FBQztFQUMzRSxPQUFPLEtBQUssT0FBTyxPQUFPLDJDQUEyQywrQ0FBK0MsVUFBVSxNQUFNO0NBQ3JJLENBQUM7Q0FDRCxDQUFDO0VBQ0EsTUFBTTtFQUNOLFlBQVksUUFBUSxJQUFJLEtBQUssZUFBZSxTQUFTLEtBQUssSUFBSSxLQUFLLGVBQWUsTUFBTSxFQUFFLFdBQVcsU0FBUyxXQUFXO0VBQ3pILFFBQVE7Q0FDVCxHQUFHO0VBQ0YsTUFBTSxDQUFDLGtCQUFrQixVQUFVO0VBQ25DLFlBQVksUUFBUSxJQUFJLEtBQUssTUFBTSxTQUFTLEtBQUssSUFBSSxLQUFLLFFBQVEsTUFBTSxFQUFFLFdBQVcsU0FBUyxPQUFPO0VBQ3JHLFFBQVE7Q0FDVCxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxXQUFXLGFBQWE7RUFDM0MsSUFBSSxNQUFNLFdBQVc7R0FDcEIsTUFBTSxNQUFNLE9BQU8sSUFBSTtHQUN2QixNQUFNLFVBQVUsSUFBSSxZQUFZO0dBQ2hDLE1BQU0sT0FBTyxVQUFVLEdBQUc7R0FDMUIsS0FBSyxPQUFPLE1BQU0sYUFBYSxRQUFRLHVCQUF1QixPQUFPLGlCQUFpQixhQUFhLFFBQVEsMkJBQTJCLFVBQVUsTUFBTSxDQUFDLE1BQU0sS0FBSztFQUNuSyxDQUFDO0NBQ0YsQ0FBQztDQUNELENBQUM7RUFDQSxNQUFNO0VBQ04sWUFBWSxLQUFLLFVBQVUsSUFBSSxLQUFLLGVBQWUsUUFBUSxHQUFHLEVBQUUsV0FBVyxTQUFTLGNBQWMsRUFBRSxJQUFJLEdBQUcsQ0FBQyxNQUFNO0VBQ2xILFFBQVE7Q0FDVCxHQUFHO0VBQ0YsTUFBTSxDQUFDLHVCQUF1QixlQUFlO0VBQzdDLFlBQVksS0FBSyxVQUFVLElBQUksS0FBSyxRQUFRLFFBQVEsR0FBRyxFQUFFLFdBQVcsU0FBUyxVQUFVLElBQUksRUFBRSxHQUFHLENBQUMsTUFBTTtFQUN2RyxRQUFRO0NBQ1QsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLE1BQU0sV0FBVyxhQUFhO0VBQzNDLElBQUksTUFBTSxTQUFTLE9BQU87R0FDekIsTUFBTSxNQUFNLE9BQU8sSUFBSTtHQUN2QixNQUFNLFVBQVUsSUFBSSxZQUFZO0dBQ2hDLE1BQU0sT0FBTyxVQUFVLEtBQUssS0FBSztHQUNqQyxLQUFLLE9BQU8sTUFBTSxhQUFhLFFBQVEsdUJBQXVCLE9BQU8sR0FBRyxNQUFNLFNBQVMsYUFBYSxRQUFRLDJCQUEyQixPQUFPLEdBQUcsTUFBTSxTQUFTLDRCQUE0QixTQUFTLDRCQUE0QixRQUFRLEtBQUs7RUFDL08sQ0FBQztDQUNGLENBQUM7Q0FDRCxDQUFDO0VBQ0EsTUFBTTtFQUNOLFlBQVksS0FBSyxVQUFVLElBQUksS0FBSyxlQUFlLE1BQU0sRUFBRSxNQUFNLE9BQU8sYUFBYSxTQUFTLGVBQWUsT0FBTyxPQUFPLE1BQU0sQ0FBQztFQUNsSSxRQUFRO0NBQ1QsR0FBRztFQUNGLE1BQU0sQ0FBQyxzQkFBc0IsY0FBYztFQUMzQyxZQUFZLEtBQUssVUFBVSxJQUFJLEtBQUssUUFBUSxNQUFNLEVBQUUsTUFBTSxPQUFPLGFBQWEsU0FBUyxZQUFZLE9BQU8sT0FBTyxNQUFNLENBQUM7RUFDeEgsUUFBUTtDQUNULENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxNQUFNLFdBQVcsYUFBYTtFQUMzQyxJQUFJLE1BQU0sU0FBUyxPQUFPO0dBQ3pCLE1BQU0sTUFBTSxPQUFPLElBQUk7R0FDdkIsTUFBTSxPQUFPLFVBQVUsS0FBSyxLQUFLO0dBQ2pDLE1BQU0sUUFBUSxNQUFNLEtBQUssTUFBTSxRQUFRO0dBQ3ZDLElBQUksUUFBUSxTQUFTLENBQUMsUUFBUSxDQUFDLE9BQU87SUFDckMsTUFBTSxVQUFVLElBQUksWUFBWTtJQUNoQyxNQUFNLE1BQU0sTUFBTSxXQUFXLE1BQU07S0FDbEM7S0FDQSxhQUFhLFFBQVEsT0FBTyxPQUFPO0tBQ25DLGFBQWEsUUFBUSxXQUFXLE9BQU87S0FDdkM7SUFDRCxDQUFDO0lBQ0QsTUFBTSxVQUFVLFdBQVcsV0FBVyxJQUFJLEtBQUssVUFBVSxJQUFJLEtBQUs7SUFDbEUsTUFBTSxJQUFJLGVBQWUsY0FBYyxLQUFLLFNBQVMsS0FBSyxLQUFLLENBQUM7R0FDakU7RUFDRCxDQUFDO0NBQ0YsQ0FBQztDQUNELENBQUM7RUFDQSxNQUFNO0VBQ04sWUFBWSxLQUFLLFVBQVU7R0FDMUIsTUFBTSxTQUFTLElBQUksS0FBSyxlQUFlLEdBQUcsRUFBRTtHQUM1QyxPQUFPLFFBQVEsVUFBVSxPQUFPLFNBQVMsZUFBZSxPQUFPLE9BQU8sT0FBTyxLQUFLLENBQUM7RUFDcEY7RUFDQSxRQUFRO0NBQ1QsR0FBRztFQUNGLE1BQU07RUFDTixZQUFZLEtBQUssVUFBVTtHQUMxQixNQUFNLFNBQVMsSUFBSSxLQUFLLFFBQVEsR0FBRyxFQUFFO0dBQ3JDLE9BQU8sUUFBUSxVQUFVLE9BQU8sU0FBUyxZQUFZLE9BQU8sT0FBTyxPQUFPLEtBQUssQ0FBQztFQUNqRjtFQUNBLFFBQVE7Q0FDVCxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxXQUFXLGFBQWE7RUFDM0MsSUFBSSxNQUFNLFNBQVMsT0FBTztHQUN6QixNQUFNLE1BQU0sT0FBTyxJQUFJO0dBRXZCLE1BQU0sVUFEVSxXQUFXLFdBQVcsSUFBSSxLQUFLLFVBQVUsSUFBSSxLQUFLLGVBQ25ELENBQVEsR0FBRyxFQUFFO0dBQzVCLE1BQU0sVUFBVSxJQUFJLFlBQVk7R0FDaEMsS0FBSyxPQUFPLFVBQVUsS0FBSyxLQUFLLEdBQUcsa0JBQWtCLFFBQVEsWUFBWSxPQUFPLFVBQVUsa0JBQWtCLFFBQVEsZ0JBQWdCLE9BQU8sVUFBVSxPQUFPLFFBQVEsS0FBSztFQUMxSyxDQUFDO0NBQ0YsQ0FBQztDQUNELENBQUM7RUFDQSxNQUFNO0VBQ04sWUFBWSxLQUFLLE9BQU8sVUFBVTtHQUNqQyxNQUFNLFNBQVMsSUFBSSxLQUFLLGVBQWUsUUFBUTtHQUMvQyxPQUFPLFVBQVUsT0FBTyxTQUFTLGVBQWUsT0FBTyxPQUFPLE9BQU8sS0FBSztFQUMzRTtFQUNBLFFBQVE7Q0FDVCxHQUFHO0VBQ0YsTUFBTTtFQUNOLFlBQVksS0FBSyxPQUFPLFVBQVU7R0FDakMsTUFBTSxTQUFTLElBQUksS0FBSyxRQUFRLFFBQVE7R0FDeEMsT0FBTyxVQUFVLE9BQU8sU0FBUyxZQUFZLE9BQU8sT0FBTyxPQUFPLEtBQUs7RUFDeEU7RUFDQSxRQUFRO0NBQ1QsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLE1BQU0sV0FBVyxhQUFhO0VBQzNDLElBQUksTUFBTSxTQUFTLFNBQVMsT0FBTztHQUNsQyxNQUFNLE1BQU0sT0FBTyxJQUFJO0dBQ3ZCLE1BQU0sVUFBVSxJQUFJLFlBQVk7R0FFaEMsTUFBTSxVQURVLFdBQVcsV0FBVyxJQUFJLEtBQUssVUFBVSxJQUFJLEtBQUssZUFDbkQsQ0FBUSxVQUFVO0dBQ2pDLE1BQU0sY0FBYyxHQUFHLFFBQVEsT0FBTyxFQUFFO0dBQ3hDLEtBQUssT0FBTyxVQUFVLEtBQUssU0FBUyxLQUFLLEdBQUcsWUFBWSxZQUFZLElBQUksUUFBUSxZQUFZLE9BQU8sVUFBVSxZQUFZLFlBQVksSUFBSSxRQUFRLGdCQUFnQixPQUFPLFVBQVUsT0FBTyxRQUFRLEtBQUs7RUFDdk0sQ0FBQztDQUNGLENBQUM7Q0FFRCxJQUFJLGVBQWUsU0FBUyxTQUFTO0VBQ3BDLEtBQUssTUFBTSxPQUFPLFNBQ2pCLE1BQU0sS0FBSyxNQUFNLEtBQUssUUFBUSxJQUFJO0VBRW5DLE9BQU87Q0FDUixDQUFDO0NBQ0QsTUFBTSxZQUFZLEtBQUssVUFBVSxXQUFXLFlBQVksU0FBUyxzQkFBc0I7RUFDdEYsTUFBTSx3QkFBUSxJQUFJLE1BQU0sVUFBVTtFQUNsQyxNQUFNLEtBQUssTUFBTSxXQUFXLFVBQVU7RUFDdEMsTUFBTSxLQUFLLE1BQU0sU0FBUyxLQUFLO0VBQy9CLE1BQU0sT0FBTyxNQUFNLEtBQUssTUFBTSxhQUFhO0VBQzNDLE1BQU0sTUFBTSxNQUFNLEtBQUssTUFBTSxRQUFRO0VBQ3JDLElBQUksTUFBTSxLQUFLLE1BQU0sTUFBTSxHQUMxQixNQUFNLElBQUksWUFBWSw4REFBOEQ7RUFFckYsSUFBSSxPQUFPLEtBQUssU0FBUyxZQUN4QixNQUFNLElBQUksVUFBVSxxRUFBcUUsT0FBTyxJQUFJLEdBQUc7RUFFeEcsTUFBTSxRQUFRLElBQUksTUFBTSxNQUFNLEVBQUUsTUFBTSxRQUFRLEtBQUssYUFBYTtHQUMvRCxNQUFNLFNBQVMsUUFBUSxJQUFJLFFBQVEsS0FBSyxRQUFRO0dBQ2hELElBQUksT0FBTyxXQUFXLFlBQ3JCLE9BQU8sa0JBQWtCLEtBQUssWUFBWSxRQUFRO0dBRW5ELFFBQVEsR0FBRyxTQUFTO0lBQ25CLE1BQU0sS0FBSyxNQUFNLFNBQVMsR0FBRztJQUM3QixNQUFNLFVBQVUsUUFBUSxRQUFRLEdBQUcsQ0FBQyxDQUFDLE1BQU0sVUFBVTtLQUNwRCxNQUFNLEtBQUssTUFBTSxVQUFVLEtBQUs7S0FDaEMsT0FBTyxPQUFPLEtBQUssTUFBTSxHQUFHLElBQUk7SUFDakMsSUFBSSxRQUFRO0tBQ1gsTUFBTSxTQUFTLElBQUksZUFBZSxxQkFBcUIsTUFBTSxRQUFRLEdBQUcsRUFBRSx5QkFBeUIsRUFBRSxVQUFVLE1BQU0sQ0FBQztLQUN0SCxPQUFPLFFBQVE7S0FDZixNQUFNO0lBQ1AsQ0FBQyxDQUFDLENBQUMsT0FBTyxRQUFRO0tBQ2pCLElBQUksUUFBUSxHQUFHLEtBQUssTUFBTSxPQUN6QixJQUFJLFFBQVEsTUFBTSxNQUFNLFFBQVEsTUFBTSxTQUFTLElBQUksT0FBTztLQUUzRCxNQUFNO0lBQ1AsQ0FBQztJQUNELE9BQU8sa0JBQWtCLE1BQU0sU0FBUyx1QkFBdUIsT0FBTyxNQUFNLENBQUMsQ0FBQyxLQUFLLE1BQU0sR0FBRyxPQUFPLE1BQU0sS0FBSyxNQUFNLE1BQU0sQ0FBQztHQUM1SDtFQUNELEVBQUUsQ0FBQztFQUNILE9BQU87Q0FDUixDQUFDO0NBQ0QsTUFBTSxZQUFZLEtBQUssVUFBVSxXQUFXLFdBQVcsU0FBUyxxQkFBcUI7RUFDcEYsTUFBTSx3QkFBUSxJQUFJLE1BQU0sU0FBUztFQUNqQyxNQUFNLEtBQUssTUFBTSxXQUFXLFNBQVM7RUFDckMsTUFBTSxLQUFLLE1BQU0sU0FBUyxLQUFLO0VBQy9CLE1BQU0sT0FBTyxNQUFNLEtBQUssTUFBTSxhQUFhO0VBQzNDLE1BQU0sTUFBTSxNQUFNLEtBQUssTUFBTSxRQUFRO0VBQ3JDLE1BQU0sVUFBVSxPQUFPLFFBQVEsYUFBYSxJQUFJLElBQUk7RUFDcEQsSUFBSSxNQUFNLEtBQUssTUFBTSxNQUFNLEdBQzFCLE1BQU0sSUFBSSxZQUFZLDZEQUE2RDtFQUVwRixJQUFJLE9BQU8sU0FBUyxTQUFTLFlBQzVCLE1BQU0sSUFBSSxVQUFVLG9FQUFvRSxPQUFPLFFBQVEsR0FBRztFQUUzRyxNQUFNLFFBQVEsSUFBSSxNQUFNLE1BQU0sRUFBRSxNQUFNLFFBQVEsS0FBSyxhQUFhO0dBQy9ELE1BQU0sU0FBUyxRQUFRLElBQUksUUFBUSxLQUFLLFFBQVE7R0FDaEQsSUFBSSxPQUFPLFdBQVcsWUFDckIsT0FBTyxrQkFBa0IsS0FBSyxZQUFZLFFBQVE7R0FFbkQsUUFBUSxHQUFHLFNBQVM7SUFDbkIsTUFBTSxLQUFLLE1BQU0sU0FBUyxHQUFHO0lBQzdCLE1BQU0sVUFBVSxRQUFRLFFBQVEsT0FBTyxDQUFDLENBQUMsTUFBTSxVQUFVO0tBTXhELE1BQU0sSUFMYSxlQUFlLHFCQUFxQixNQUFNLFFBQVEsS0FBSyxFQUFFLHlCQUF5QjtNQUNwRyxVQUFVO01BQ1YsMEJBQVUsSUFBSSxNQUFNLGtCQUFrQjtNQUN0QyxRQUFRO0tBQ1QsQ0FDTTtJQUNQLElBQUksUUFBUTtLQUNYLE1BQU0sS0FBSyxNQUFNLFVBQVUsR0FBRztLQUM5QixPQUFPLE9BQU8sS0FBSyxNQUFNLEdBQUcsSUFBSTtJQUNqQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFFBQVE7S0FDakIsSUFBSSxRQUFRLEdBQUcsS0FBSyxNQUFNLE9BQ3pCLElBQUksUUFBUSxNQUFNLE1BQU0sUUFBUSxNQUFNLFNBQVMsSUFBSSxPQUFPO0tBRTNELE1BQU07SUFDUCxDQUFDO0lBQ0QsT0FBTyxrQkFBa0IsTUFBTSxTQUFTLHVCQUF1QixPQUFPLE1BQU0sQ0FBQyxDQUFDLEtBQUssTUFBTSxHQUFHLE9BQU8sTUFBTSxLQUFLLE1BQU0sTUFBTSxDQUFDO0dBQzVIO0VBQ0QsRUFBRSxDQUFDO0VBQ0gsT0FBTztDQUNSLENBQUM7QUFDRjtBQUNBLFNBQVMsWUFBWSxLQUFLLEtBQUssZ0JBQWdCO0NBQzlDLElBQUksSUFBSSxLQUFLLE1BQU0sUUFDbEIsT0FBT0EsRUFBRSxLQUFLLG9CQUFvQixJQUFJLEtBQUssTUFBTSxLQUFLLFNBQVMsTUFBTTtFQUNwRSxJQUFJLGFBQWFBLEVBQUUsS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLFlBQVksRUFBRSxXQUFXO0VBQzVFLElBQUksZ0JBQ0gsY0FBYyxLQUFLLGdCQUFnQixTQUFTLEVBQUUscUJBQXFCLEtBQUssQ0FBQztPQUV6RSxjQUFjLFVBQVUsT0FBTyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxLQUFLLFNBQVMsT0FBTyxNQUFNLENBQUMsQ0FBQyxLQUFLLElBQUk7RUFFcEYsY0FBYztFQUNkLE9BQU87Q0FDUixDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksR0FBRztDQUVoQixPQUFPQSxFQUFFLEtBQUssd0JBQXdCQSxFQUFFLEtBQUssSUFBSSxLQUFLLE1BQU0sTUFBTSxFQUFFLEdBQUc7Q0FDdkUsT0FBTztBQUNSO0FBQ0EsU0FBUyxjQUFjLEtBQUssU0FBUyxLQUFLLGtCQUFrQjtDQUMzRCxJQUFJLFFBQVEsUUFDWCxPQUFPQSxFQUFFLEtBQUssb0JBQW9CLFFBQVEsS0FBSyxZQUFZLE1BQU07RUFDaEUsSUFBSSxhQUFhQSxFQUFFLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxZQUFZLEVBQUUsa0JBQWtCO0VBQ25GLElBQUksa0JBQ0gsY0FBYyxLQUFLLGtCQUFrQixXQUFXLE9BQU8sRUFBRSxxQkFBcUIsS0FBSyxDQUFDO09BRXBGLGNBQWMsVUFBVSxVQUFVLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEtBQUssU0FBUyxPQUFPLE1BQU0sQ0FBQyxDQUFDLEtBQUssSUFBSTtFQUV2RixjQUFjO0VBQ2QsT0FBTztDQUNSLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxHQUFHO0NBRWhCLE9BQU9BLEVBQUUsS0FBSyx3QkFBd0JBLEVBQUUsS0FBSyxJQUFJLEtBQUssTUFBTSxNQUFNLEVBQUUsR0FBRztDQUN2RSxPQUFPO0FBQ1I7QUFFQSxTQUFTLGdCQUFnQixXQUFXLFFBQVE7Q0FDM0MsTUFBTSxNQUFNLFVBQVU7Q0FDdEIsTUFBTSxRQUFRQyxjQUFLLEtBQUssV0FBVyxRQUFRO0NBQzNDLE1BQU0sVUFBVUEsY0FBSyxLQUFLLFdBQVcsU0FBUyxLQUFLO0NBQ25ELE1BQU0sZ0JBQWdCQSxjQUFLLEtBQUssV0FBVyxTQUFTO0NBQ3BELE1BQU0sWUFBWTtFQUNqQixHQUFHLGdCQUFnQjtFQUNuQjtFQUNBO0VBQ0E7RUFDQTtDQUNEO0NBQ0EsSUFBSSxPQUFPQSxjQUFLLEtBQUssV0FBVyxhQUFhO0NBQzdDLE1BQU0sa0JBQWtCLE1BQU0sZ0JBQWdCO0NBQzlDLElBQUksTUFBTSxTQUFTLFFBQ2xCLE9BQU87Q0FFUixNQUFNLGVBQWU7RUFDcEIsR0FBRyxTQUFTLE1BQU07RUFDbEI7RUFDQSxlQUFlLHlCQUF5QjtFQUN4QztFQUNBLE9BQU87RUFDUDtFQUNBO0VBQ0Esa0JBQWtCLENBQUM7RUFDbkIsTUFBTUEsY0FBSyxLQUFLLFdBQVcsTUFBTTtFQUNqQyxNQUFNQSxjQUFLLEtBQUssV0FBVyxNQUFNO0VBQ2pDO0NBQ0Q7Q0FDQSxPQUFPLE9BQU8sY0FBYyxFQUFFLEtBQUssQ0FBQztDQUNwQyxPQUFPO0VBQ04sT0FBTztFQUNQO0VBQ0E7RUFDQTtDQUNEO0FBQ0Q7QUFDQSxJQUFNLGtCQUFOLGNBQThCLE1BQU07Q0FDbkMsWUFBWSxTQUFTLFFBQVEsVUFBVSwwQkFBMEI7RUFDaEUsTUFBTSxPQUFPO0VBQ2IsS0FBSyxTQUFTO0VBQ2QsS0FBSyxXQUFXO0VBQ2hCLEtBQUssMkJBQTJCO0NBQ2pDO0FBQ0Q7QUFDQSxTQUFTLGlCQUFpQixHQUFHLFFBQVEsVUFBVTtDQUM5QyxRQUFRLEdBQUcsVUFBVTtFQUNwQixPQUFPLFFBQVEsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLHFCQUFxQixxQkFBcUI7R0FDNUUsU0FBUyw0QkFBNEIsR0FBRyxNQUFNO0lBQzdDLE1BQU0sRUFBRSxPQUFPLE9BQU8sS0FBSyxrQkFBa0IsZ0JBQWdCLE1BQU0sTUFBTTtJQUN6RSxNQUFNLFNBQVMsZ0JBQWdCLEtBQUssT0FBTyxLQUFLLEdBQUcsSUFBSTtJQUN2RCxJQUFJLFVBQVUsT0FBTyxXQUFXLFlBQVksT0FBTyxPQUFPLFNBQVMsWUFFbEUsT0FBTyxPQUFTLE1BQU0sRUFBRSxNQUFNLFNBQVMsUUFBUSxVQUFVLFdBQVc7S0FDbkUsSUFBSSxRQUFRLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FFOUIsTUFBTSxJQUFJLGlCQURZLGdCQUFnQixHQUFHLGNBQWMsTUFBTSxNQUFNLFFBQVEsR0FDbkMsUUFBUSxVQUFVO01BQ3pELGVBQWU7TUFDZjtLQUNELENBQUM7SUFFSCxDQUFDO0lBRUYsTUFBTSxFQUFFLE1BQU0sU0FBUyxRQUFRLFVBQVUsU0FBUztJQUNsRCxJQUFJLFFBQVEsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUU5QixNQUFNLElBQUksaUJBRFksZ0JBQWdCLEdBQUcsY0FBYyxNQUFNLE1BQU0sUUFBUSxHQUNuQyxRQUFRLFVBQVU7S0FDekQsZUFBZTtLQUNmO0lBQ0QsQ0FBQztHQUVIO0dBQ0EsTUFBTSxjQUFjLGNBQWMsT0FBTyxxQkFBcUIsMkJBQTJCO0dBQ3pGLE1BQU0sVUFBVSxXQUFXLHFCQUFxQixDQUFDLFVBQVUscUJBQXFCLFdBQVc7R0FDM0YsTUFBTSxVQUFVLEVBQUUsVUFBVSxXQUFXLHFCQUFxQixXQUFXO0dBSXZFLElBQUksZ0JBQWdCLDBCQUEwQjtJQUM3QyxNQUFNLGNBQWMsRUFBRSxVQUFVLFVBQVU7SUFDMUMsT0FBTyxlQUFlLGFBQWEsNEJBQTRCLEVBQUUsT0FBTyxLQUFLLENBQUM7R0FDL0U7R0FDQSxNQUFNLHNCQUFzQixrQkFBa0I7SUFDN0MsWUFBWSxVQUFVLE9BQU8sR0FBRyxRQUFRO0tBQ3ZDLE1BQU0sUUFBUSxPQUFPO0lBQ3RCO0lBQ0EsZ0JBQWdCLE9BQU87S0FDdEIsTUFBTSxFQUFFLFNBQVMsZ0JBQWdCLEtBQUssS0FBSyxrQkFBa0IsTUFBTSxHQUFHLE9BQU8sR0FBRyxLQUFLLE1BQU07S0FDM0YsT0FBTyxLQUFLLFVBQVUsQ0FBQyxPQUFPO0lBQy9CO0lBQ0EsV0FBVztLQUNWLE9BQU8sR0FBRyxLQUFLLFVBQVUsU0FBUyxLQUFLO0lBQ3hDO0lBQ0Esa0JBQWtCO0tBQ2pCLE9BQU87SUFDUjtJQUNBLHNCQUFzQjtLQUNyQixPQUFPLEdBQUcsS0FBSyxTQUFTLEVBQUUsR0FBRyxLQUFLLE9BQU8sS0FBSyxTQUFTLFVBQVUsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRTtJQUNwRjtHQUNEO0dBQ0EsTUFBTSxpQkFBaUIsR0FBRyxXQUFXLElBQUksY0FBYyxPQUFPLEdBQUcsTUFBTTtHQUN2RSxPQUFPLGVBQWUsUUFBUSxxQkFBcUI7SUFDbEQsY0FBYztJQUNkLFlBQVk7SUFDWixPQUFPO0lBQ1AsVUFBVTtHQUNYLENBQUM7R0FDRCxPQUFPLGVBQWUsT0FBTyxLQUFLLHFCQUFxQjtJQUN0RCxjQUFjO0lBQ2QsWUFBWTtJQUNaLFFBQVEsR0FBRyxXQUFXLElBQUksY0FBYyxNQUFNLEdBQUcsTUFBTTtJQUN2RCxVQUFVO0dBQ1gsQ0FBQztHQUdELE9BQU8sZUFBZSxXQUFXLDZCQUE2QixxQkFBcUI7SUFDbEYsY0FBYztJQUNkLFlBQVk7SUFDWixPQUFPO0lBQ1AsVUFBVTtHQUNYLENBQUM7RUFDRixDQUFDO0NBQ0Y7QUFDRDtBQUNBLE1BQU0sY0FBYyxNQUFNLFVBQVU7Q0FDbkMsTUFBTSxVQUFVLEtBQUssUUFBUSxXQUFXLFFBQVEsWUFBWTtFQUMzRCxJQUFJLGlCQUFpQixNQUFNLFFBQVEsT0FBTyxDQUFDO0NBQzVDLENBQUM7QUFDRiJ9
|