{ "version": 3, "sources": ["../../../node_modules/react/cjs/react.production.min.js", "../../../node_modules/react/index.js", "../../../node_modules/scheduler/cjs/scheduler.production.min.js", "../../../node_modules/scheduler/index.js", "../../../node_modules/react-dom/cjs/react-dom.production.min.js", "../../../node_modules/react-dom/index.js", "../../../node_modules/react-dom/client.js", "../../../node_modules/react-router/dist/development/chunk-62JRHF6Z.mjs", "../../../node_modules/react-router/dist/development/dom-export.mjs", "../../../node_modules/react-router/dist/development/index.mjs", "../../../node_modules/react-router-dom/dist/index.mjs", "../../../node_modules/@tanstack/query-core/src/subscribable.ts", "../../../node_modules/@tanstack/query-core/src/utils.ts", "../../../node_modules/@tanstack/query-core/src/focusManager.ts", "../../../node_modules/@tanstack/query-core/src/onlineManager.ts", "../../../node_modules/@tanstack/query-core/src/retryer.ts", "../../../node_modules/@tanstack/query-core/src/notifyManager.ts", "../../../node_modules/@tanstack/query-core/src/removable.ts", "../../../node_modules/@tanstack/query-core/src/query.ts", "../../../node_modules/@tanstack/query-core/src/queryCache.ts", "../../../node_modules/@tanstack/query-core/src/mutation.ts", "../../../node_modules/@tanstack/query-core/src/mutationCache.ts", "../../../node_modules/@tanstack/query-core/src/infiniteQueryBehavior.ts", "../../../node_modules/@tanstack/query-core/src/queryClient.ts", "../../../node_modules/@tanstack/query-core/src/queryObserver.ts", "../../../node_modules/@tanstack/query-core/src/infiniteQueryObserver.ts", "../../../node_modules/@tanstack/query-core/src/mutationObserver.ts", "../../../node_modules/@tanstack/query-core/build/modern/types.js", "../../../node_modules/@tanstack/query-core/src/index.ts", "../../../node_modules/@tanstack/react-query/build/modern/types.js", "../../../node_modules/react/cjs/react-jsx-runtime.production.min.js", "../../../node_modules/react/jsx-runtime.js", "../../../node_modules/@tanstack/react-query/src/QueryClientProvider.tsx", "../../../node_modules/@tanstack/react-query/src/isRestoring.ts", "../../../node_modules/@tanstack/react-query/src/QueryErrorResetBoundary.tsx", "../../../node_modules/@tanstack/react-query/src/utils.ts", "../../../node_modules/@tanstack/react-query/src/errorBoundaryUtils.ts", "../../../node_modules/@tanstack/react-query/src/suspense.ts", "../../../node_modules/@tanstack/react-query/src/useBaseQuery.ts", "../../../node_modules/@tanstack/react-query/src/useQuery.ts", "../../../node_modules/@tanstack/react-query/src/useMutation.ts", "../../../node_modules/@tanstack/react-query/src/useInfiniteQuery.ts", "../../../node_modules/@tanstack/react-query/src/index.ts", "../../javascript/api/queryClient.ts", "../../../node_modules/@fullstory/snippet/dist/index.esm.js", "../../../node_modules/@fullstory/browser/dist/index.esm.js", "../../../node_modules/aws-rum-web/dist/es/plugins/utils/constant.js", "../../../node_modules/aws-rum-web/dist/es/plugins/InternalPlugin.js", "../../../node_modules/aws-rum-web/dist/es/utils/InternalLogger.js", "../../../node_modules/aws-rum-web/dist/es/plugins/PluginManager.js", "../../../node_modules/aws-rum-web/dist/es/plugins/event-plugins/DomEventPlugin.js", "../../../node_modules/aws-rum-web/dist/es/plugins/utils/js-error-utils.js", "../../../node_modules/aws-rum-web/dist/es/plugins/event-plugins/JsErrorPlugin.js", "../../../node_modules/aws-rum-web/dist/es/utils/cookies-utils.js", "../../../node_modules/uuid/dist/stringify.js", "../../../node_modules/uuid/dist/rng.js", "../../../node_modules/uuid/dist/v4.js", "../../../node_modules/uuid/dist/index.js", "../../../node_modules/ua-parser-js/src/ua-parser.js", "../../../node_modules/aws-rum-web/dist/es/utils/constants.js", "../../../node_modules/aws-rum-web/dist/es/sessions/SessionManager.js", "../../../node_modules/shimmer/index.js", "../../../node_modules/aws-rum-web/dist/es/plugins/MonkeyPatched.js", "../../../node_modules/aws-rum-web/dist/es/sessions/VirtualPageLoadTimer.js", "../../../node_modules/aws-rum-web/dist/es/sessions/PageManager.js", "../../../node_modules/aws-rum-web/dist/es/event-bus/EventBus.js", "../../../node_modules/aws-rum-web/dist/es/event-cache/EventCache.js", "../../../node_modules/@smithy/util-hex-encoding/dist-es/index.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/abort.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/auth/auth.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/auth/HttpApiKeyAuth.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/auth/HttpAuthScheme.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/auth/HttpAuthSchemeProvider.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/auth/HttpSigner.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/auth/IdentityProviderConfig.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/auth/index.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/blob/blob-payload-input-types.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/checksum.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/client.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/command.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/connection/config.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/connection/manager.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/connection/pool.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/connection/index.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/crypto.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/encode.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/endpoint.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/endpoints/EndpointRuleObject.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/endpoints/ErrorRuleObject.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/endpoints/RuleSetObject.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/endpoints/shared.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/endpoints/TreeRuleObject.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/endpoints/index.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/eventStream.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/extensions/checksum.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/extensions/defaultClientConfiguration.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/extensions/defaultExtensionConfiguration.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/extensions/index.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/feature-ids.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/http.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/http/httpHandlerInitialization.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/identity/apiKeyIdentity.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/identity/awsCredentialIdentity.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/identity/identity.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/identity/tokenIdentity.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/identity/index.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/logger.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/middleware.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/pagination.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/profile.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/response.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/retry.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/serde.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/shapes.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/signature.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/stream.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/streaming-payload/streaming-blob-common-types.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/streaming-payload/streaming-blob-payload-input-types.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/streaming-payload/streaming-blob-payload-output-types.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/transfer.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/transform/client-payload-blob-type-narrow.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/transform/no-undefined.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/transform/type-transform.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/uri.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/util.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/waiter.js", "../../../node_modules/@smithy/util-middleware/node_modules/@smithy/types/dist-es/index.js", "../../../node_modules/@smithy/util-middleware/dist-es/getSmithyContext.js", "../../../node_modules/@smithy/util-middleware/dist-es/normalizeProvider.js", "../../../node_modules/@smithy/util-middleware/dist-es/index.js", "../../../node_modules/@smithy/util-uri-escape/dist-es/escape-uri.js", "../../../node_modules/@smithy/util-uri-escape/dist-es/escape-uri-path.js", "../../../node_modules/@smithy/util-uri-escape/dist-es/index.js", "../../../node_modules/@smithy/util-utf8/dist-es/fromUtf8.browser.js", "../../../node_modules/@smithy/util-utf8/dist-es/toUint8Array.js", "../../../node_modules/@smithy/util-utf8/dist-es/toUtf8.browser.js", "../../../node_modules/@smithy/util-utf8/dist-es/index.js", "../../../node_modules/@smithy/signature-v4/dist-es/constants.js", "../../../node_modules/@smithy/signature-v4/dist-es/credentialDerivation.js", "../../../node_modules/@smithy/signature-v4/dist-es/getCanonicalHeaders.js", "../../../node_modules/@smithy/signature-v4/dist-es/getCanonicalQuery.js", "../../../node_modules/@smithy/is-array-buffer/dist-es/index.js", "../../../node_modules/@smithy/signature-v4/dist-es/getPayloadHash.js", "../../../node_modules/@smithy/signature-v4/dist-es/HeaderFormatter.js", "../../../node_modules/@smithy/signature-v4/dist-es/headerUtil.js", "../../../node_modules/@smithy/protocol-http/dist-es/extensions/httpExtensionConfiguration.js", "../../../node_modules/@smithy/protocol-http/dist-es/extensions/index.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/abort.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/auth/auth.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/auth/HttpApiKeyAuth.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/auth/HttpAuthScheme.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/auth/HttpAuthSchemeProvider.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/auth/HttpSigner.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/auth/IdentityProviderConfig.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/auth/index.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/blob/blob-payload-input-types.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/checksum.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/client.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/command.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/connection/config.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/connection/manager.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/connection/pool.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/connection/index.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/crypto.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/encode.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/endpoint.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/endpoints/EndpointRuleObject.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/endpoints/ErrorRuleObject.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/endpoints/RuleSetObject.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/endpoints/shared.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/endpoints/TreeRuleObject.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/endpoints/index.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/eventStream.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/extensions/checksum.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/extensions/defaultClientConfiguration.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/extensions/defaultExtensionConfiguration.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/extensions/index.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/feature-ids.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/http.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/http/httpHandlerInitialization.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/identity/apiKeyIdentity.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/identity/awsCredentialIdentity.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/identity/identity.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/identity/tokenIdentity.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/identity/index.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/logger.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/middleware.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/pagination.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/profile.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/response.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/retry.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/serde.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/shapes.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/signature.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/stream.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/streaming-payload/streaming-blob-common-types.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/streaming-payload/streaming-blob-payload-input-types.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/streaming-payload/streaming-blob-payload-output-types.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/transfer.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/transform/client-payload-blob-type-narrow.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/transform/no-undefined.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/transform/type-transform.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/uri.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/util.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/waiter.js", "../../../node_modules/@smithy/protocol-http/node_modules/@smithy/types/dist-es/index.js", "../../../node_modules/@smithy/protocol-http/dist-es/Field.js", "../../../node_modules/@smithy/protocol-http/dist-es/Fields.js", "../../../node_modules/@smithy/protocol-http/dist-es/httpHandler.js", "../../../node_modules/@smithy/protocol-http/dist-es/httpRequest.js", "../../../node_modules/@smithy/protocol-http/dist-es/httpResponse.js", "../../../node_modules/@smithy/protocol-http/dist-es/isValidHostname.js", "../../../node_modules/@smithy/protocol-http/dist-es/types.js", "../../../node_modules/@smithy/protocol-http/dist-es/index.js", "../../../node_modules/@smithy/signature-v4/dist-es/moveHeadersToQuery.js", "../../../node_modules/@smithy/signature-v4/dist-es/prepareRequest.js", "../../../node_modules/@smithy/signature-v4/dist-es/utilDate.js", "../../../node_modules/@smithy/signature-v4/dist-es/SignatureV4.js", "../../../node_modules/@smithy/signature-v4/dist-es/index.js", "../../../node_modules/@aws-crypto/sha256-js/node_modules/tslib/tslib.es6.js", "../../../node_modules/@aws-crypto/sha256-js/src/constants.ts", "../../../node_modules/@aws-crypto/sha256-js/src/RawSha256.ts", "../../../node_modules/@aws-sdk/util-utf8-browser/dist-cjs/pureJs.js", "../../../node_modules/@aws-sdk/util-utf8-browser/dist-cjs/whatwgEncodingApi.js", "../../../node_modules/@aws-sdk/util-utf8-browser/dist-cjs/index.js", "../../../node_modules/@aws-crypto/util/src/convertToBuffer.ts", "../../../node_modules/@aws-crypto/util/src/isEmptyData.ts", "../../../node_modules/@aws-crypto/util/src/numToUint8.ts", "../../../node_modules/@aws-crypto/util/src/uint32ArrayFrom.ts", "../../../node_modules/@aws-crypto/util/src/index.ts", "../../../node_modules/@aws-crypto/sha256-js/src/jsSha256.ts", "../../../node_modules/@aws-crypto/sha256-js/src/index.ts", "../../../node_modules/aws-rum-web/dist/es/dispatch/DataPlaneClient.js", "../../../node_modules/@aws-sdk/util-uri-escape/dist-es/escape-uri.js", "../../../node_modules/@aws-sdk/util-uri-escape/dist-es/escape-uri-path.js", "../../../node_modules/@aws-sdk/util-uri-escape/dist-es/index.js", "../../../node_modules/@aws-sdk/querystring-builder/dist-es/index.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/BeaconHttpHandler.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/request-timeout.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/FetchHttpHandler.js", "../../../node_modules/aws-rum-web/dist/es/utils/random.js", "../../../node_modules/aws-rum-web/dist/es/plugins/utils/http-utils.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/RetryHttpHandler.js", "../../../node_modules/@smithy/querystring-builder/dist-es/index.js", "../../../node_modules/@smithy/fetch-http-handler/dist-es/create-request.js", "../../../node_modules/@smithy/fetch-http-handler/dist-es/request-timeout.js", "../../../node_modules/@smithy/fetch-http-handler/dist-es/fetch-http-handler.js", "../../../node_modules/@smithy/util-base64/dist-es/constants.browser.js", "../../../node_modules/@smithy/util-base64/dist-es/fromBase64.browser.js", "../../../node_modules/@smithy/util-base64/dist-es/toBase64.browser.js", "../../../node_modules/@smithy/util-base64/dist-es/index.js", "../../../node_modules/@smithy/fetch-http-handler/dist-es/stream-collector.js", "../../../node_modules/@smithy/fetch-http-handler/dist-es/index.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/utils.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/StsClient.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/CognitoIdentityClient.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/Authentication.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/BasicAuthentication.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/EnhancedAuthentication.js", "../../../node_modules/aws-rum-web/dist/es/dispatch/Dispatch.js", "../../../node_modules/aws-rum-web/dist/es/utils/common-utils.js", "../../../node_modules/aws-rum-web/dist/es/plugins/utils/performance-utils.js", "../../../node_modules/aws-rum-web/dist/es/plugins/event-plugins/NavigationPlugin.js", "../../../node_modules/aws-rum-web/dist/es/plugins/event-plugins/ResourcePlugin.js", "../../../node_modules/web-vitals/dist/web-vitals.attribution.js", "../../../node_modules/aws-rum-web/dist/es/plugins/event-plugins/WebVitalsPlugin.js", "../../../node_modules/aws-rum-web/dist/es/errors/XhrError.js", "../../../node_modules/aws-rum-web/dist/es/plugins/event-plugins/XhrPlugin.js", "../../../node_modules/aws-rum-web/dist/es/plugins/event-plugins/FetchPlugin.js", "../../../node_modules/aws-rum-web/dist/es/plugins/event-plugins/PageViewPlugin.js", "../../../node_modules/aws-rum-web/dist/es/orchestration/Orchestration.js", "../../../node_modules/aws-rum-web/dist/es/index.js", "../../../node_modules/@mui/utils/esm/chainPropTypes/chainPropTypes.js", "../../../node_modules/@mui/utils/esm/chainPropTypes/index.js", "../../../node_modules/@babel/runtime/helpers/esm/extends.js", "../../../node_modules/@mui/utils/esm/deepmerge.js", "../../../node_modules/prop-types/lib/ReactPropTypesSecret.js", "../../../node_modules/prop-types/factoryWithThrowingShims.js", "../../../node_modules/prop-types/index.js", "../../../node_modules/@mui/utils/esm/formatMuiErrorMessage.js", "../../../node_modules/react-is/cjs/react-is.production.min.js", "../../../node_modules/react-is/index.js", "../../../node_modules/@mui/utils/esm/capitalize/capitalize.js", "../../../node_modules/@mui/utils/esm/capitalize/index.js", "../../../node_modules/@mui/utils/esm/createChainedFunction.js", "../../../node_modules/@mui/utils/esm/debounce/debounce.js", "../../../node_modules/@mui/utils/esm/debounce/index.js", "../../../node_modules/@mui/utils/esm/isMuiElement.js", "../../../node_modules/@mui/utils/esm/ownerDocument/ownerDocument.js", "../../../node_modules/@mui/utils/esm/ownerDocument/index.js", "../../../node_modules/@mui/utils/esm/ownerWindow/ownerWindow.js", "../../../node_modules/@mui/utils/esm/ownerWindow/index.js", "../../../node_modules/@mui/utils/esm/setRef.js", "../../../node_modules/@mui/utils/esm/useEnhancedEffect/useEnhancedEffect.js", "../../../node_modules/@mui/utils/esm/useEnhancedEffect/index.js", "../../../node_modules/@mui/utils/esm/useId/useId.js", "../../../node_modules/@mui/utils/esm/useId/index.js", "../../../node_modules/@mui/utils/esm/useControlled/useControlled.js", "../../../node_modules/@mui/utils/esm/useControlled/index.js", "../../../node_modules/@mui/utils/esm/useEventCallback/useEventCallback.js", "../../../node_modules/@mui/utils/esm/useEventCallback/index.js", "../../../node_modules/@mui/utils/esm/useForkRef/useForkRef.js", "../../../node_modules/@mui/utils/esm/useForkRef/index.js", "../../../node_modules/@mui/utils/esm/useIsFocusVisible.js", "../../../node_modules/@mui/utils/esm/getScrollbarSize.js", "../../../node_modules/@mui/utils/esm/scrollLeft.js", "../../../node_modules/@mui/utils/esm/usePreviousProps.js", "../../../node_modules/@mui/utils/esm/visuallyHidden.js", "../../../node_modules/@mui/utils/esm/integerPropType.js", "../../../node_modules/@mui/utils/esm/resolveProps.js", "../../../node_modules/@mui/utils/esm/composeClasses/composeClasses.js", "../../../node_modules/@mui/utils/esm/composeClasses/index.js", "../../../node_modules/@mui/utils/esm/ClassNameGenerator/ClassNameGenerator.js", "../../../node_modules/@mui/utils/esm/ClassNameGenerator/index.js", "../../../node_modules/@mui/utils/esm/generateUtilityClass/generateUtilityClass.js", "../../../node_modules/@mui/utils/esm/generateUtilityClass/index.js", "../../../node_modules/@mui/utils/esm/generateUtilityClasses/generateUtilityClasses.js", "../../../node_modules/@mui/utils/esm/generateUtilityClasses/index.js", "../../../node_modules/@mui/utils/esm/index.js", "../../../node_modules/@mui/material/styles/identifier.js", "../../../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js", "../../../node_modules/@emotion/memoize/dist/emotion-memoize.esm.js", "../../../node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js", "../../../node_modules/@emotion/sheet/dist/emotion-sheet.browser.esm.js", "../../../node_modules/stylis/src/Enum.js", "../../../node_modules/stylis/src/Utility.js", "../../../node_modules/stylis/src/Tokenizer.js", "../../../node_modules/stylis/src/Parser.js", "../../../node_modules/stylis/src/Prefixer.js", "../../../node_modules/stylis/src/Serializer.js", "../../../node_modules/stylis/src/Middleware.js", "../../../node_modules/stylis/index.js", "../../../node_modules/@emotion/weak-memoize/dist/emotion-weak-memoize.esm.js", "../../../node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js", "../../../node_modules/hoist-non-react-statics/node_modules/react-is/cjs/react-is.production.min.js", "../../../node_modules/hoist-non-react-statics/node_modules/react-is/index.js", "../../../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js", "../../../node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js", "../../../node_modules/@emotion/hash/dist/emotion-hash.esm.js", "../../../node_modules/@emotion/unitless/dist/emotion-unitless.esm.js", "../../../node_modules/@emotion/serialize/dist/emotion-serialize.browser.esm.js", "../../../node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js", "../../../node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js", "../../../node_modules/@emotion/react/dist/emotion-react.browser.esm.js", "../../../node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js", "../../../node_modules/@emotion/styled/dist/emotion-styled.browser.esm.js", "../../../node_modules/@mui/styled-engine/GlobalStyles/GlobalStyles.js", "../../../node_modules/@mui/styled-engine/GlobalStyles/index.js", "../../../node_modules/@mui/styled-engine/index.js", "../../../node_modules/@mui/system/esm/createTheme/createBreakpoints.js", "../../../node_modules/@mui/system/esm/createTheme/shape.js", "../../../node_modules/@mui/system/esm/merge.js", "../../../node_modules/@mui/system/esm/breakpoints.js", "../../../node_modules/@mui/system/esm/style.js", "../../../node_modules/@mui/system/esm/memoize.js", "../../../node_modules/@mui/system/esm/spacing.js", "../../../node_modules/@mui/system/esm/createTheme/createSpacing.js", "../../../node_modules/@mui/system/esm/compose.js", "../../../node_modules/@mui/system/esm/borders.js", "../../../node_modules/@mui/system/esm/cssGrid.js", "../../../node_modules/@mui/system/esm/palette.js", "../../../node_modules/@mui/system/esm/sizing.js", "../../../node_modules/@mui/system/esm/styleFunctionSx/defaultSxConfig.js", "../../../node_modules/@mui/system/esm/styleFunctionSx/styleFunctionSx.js", "../../../node_modules/@mui/system/esm/createTheme/createTheme.js", "../../../node_modules/@mui/system/esm/createTheme/index.js", "../../../node_modules/@mui/system/esm/useThemeWithoutDefault.js", "../../../node_modules/@mui/system/esm/useTheme.js", "../../../node_modules/@mui/system/esm/GlobalStyles/GlobalStyles.js", "../../../node_modules/@mui/system/esm/GlobalStyles/index.js", "../../../node_modules/@mui/system/esm/flexbox.js", "../../../node_modules/@mui/system/esm/positions.js", "../../../node_modules/@mui/system/esm/typography.js", "../../../node_modules/@mui/system/esm/styleFunctionSx/extendSxProp.js", "../../../node_modules/@mui/system/esm/styleFunctionSx/index.js", "../../../node_modules/clsx/dist/clsx.m.js", "../../../node_modules/@mui/system/esm/createBox.js", "../../../node_modules/@mui/system/esm/propsToClassKey.js", "../../../node_modules/@mui/system/esm/createStyled.js", "../../../node_modules/@mui/system/esm/styled.js", "../../../node_modules/@mui/system/esm/useThemeProps/getThemeProps.js", "../../../node_modules/@mui/system/esm/useThemeProps/useThemeProps.js", "../../../node_modules/@mui/system/esm/useThemeProps/index.js", "../../../node_modules/@mui/system/esm/colorManipulator.js", "../../../node_modules/@mui/private-theming/useTheme/ThemeContext.js", "../../../node_modules/@mui/private-theming/useTheme/useTheme.js", "../../../node_modules/@mui/private-theming/useTheme/index.js", "../../../node_modules/@mui/private-theming/ThemeProvider/nested.js", "../../../node_modules/@mui/private-theming/ThemeProvider/ThemeProvider.js", "../../../node_modules/@mui/private-theming/ThemeProvider/index.js", "../../../node_modules/@mui/private-theming/index.js", "../../../node_modules/@mui/system/esm/ThemeProvider/ThemeProvider.js", "../../../node_modules/@mui/system/esm/ThemeProvider/index.js", "../../../node_modules/@mui/system/esm/cssVars/getInitColorSchemeScript.js", "../../../node_modules/@mui/system/esm/cssVars/useCurrentColorScheme.js", "../../../node_modules/@mui/system/esm/cssVars/createCssVarsProvider.js", "../../../node_modules/@mui/system/esm/cssVars/createGetCssVar.js", "../../../node_modules/@mui/system/esm/cssVars/cssVarsParser.js", "../../../node_modules/@mui/system/esm/cssVars/prepareCssVars.js", "../../../node_modules/@mui/system/esm/Container/createContainer.js", "../../../node_modules/@mui/system/esm/Container/containerClasses.js", "../../../node_modules/@mui/system/esm/Container/index.js", "../../../node_modules/@mui/system/esm/Unstable_Grid/GridProps.js", "../../../node_modules/@mui/system/esm/Unstable_Grid/gridClasses.js", "../../../node_modules/@mui/system/esm/Unstable_Grid/index.js", "../../../node_modules/@mui/system/esm/Stack/createStack.js", "../../../node_modules/@mui/system/esm/Stack/StackProps.js", "../../../node_modules/@mui/system/esm/Stack/stackClasses.js", "../../../node_modules/@mui/system/esm/Stack/index.js", "../../../node_modules/@mui/system/esm/index.js", "../../../node_modules/@mui/material/generateUtilityClass/index.js", "../../../node_modules/@mui/material/styles/createMixins.js", "../../../node_modules/@mui/material/colors/common.js", "../../../node_modules/@mui/material/colors/grey.js", "../../../node_modules/@mui/material/colors/purple.js", "../../../node_modules/@mui/material/colors/red.js", "../../../node_modules/@mui/material/colors/orange.js", "../../../node_modules/@mui/material/colors/blue.js", "../../../node_modules/@mui/material/colors/lightBlue.js", "../../../node_modules/@mui/material/colors/green.js", "../../../node_modules/@mui/material/styles/createPalette.js", "../../../node_modules/@mui/material/styles/createTypography.js", "../../../node_modules/@mui/material/styles/shadows.js", "../../../node_modules/@mui/material/styles/createTransitions.js", "../../../node_modules/@mui/material/styles/zIndex.js", "../../../node_modules/@mui/material/styles/createTheme.js", "../../../node_modules/@mui/material/styles/cssUtils.js", "../../../node_modules/@mui/material/styles/defaultTheme.js", "../../../node_modules/@mui/material/styles/useTheme.js", "../../../node_modules/@mui/material/styles/useThemeProps.js", "../../../node_modules/@mui/material/styles/styled.js", "../../../node_modules/@mui/material/styles/ThemeProvider.js", "../../../node_modules/@mui/material/styles/shouldSkipGeneratingVar.js", "../../../node_modules/@mui/material/styles/getOverlayAlpha.js", "../../../node_modules/@mui/material/styles/experimental_extendTheme.js", "../../../node_modules/@mui/material/styles/excludeVariablesFromRoot.js", "../../../node_modules/@mui/material/styles/CssVarsProvider.js", "../../../node_modules/@mui/material/styles/index.js", "../../../node_modules/@mui/material/colors/index.js", "../../../node_modules/@mui/material/utils/capitalize.js", "../../../node_modules/@mui/material/utils/createChainedFunction.js", "../../../node_modules/@mui/base/utils/isHostComponent.js", "../../../node_modules/@mui/base/utils/appendOwnerState.js", "../../../node_modules/@mui/base/utils/ClassNameConfigurator.js", "../../../node_modules/@mui/base/utils/extractEventHandlers.js", "../../../node_modules/@mui/base/utils/resolveComponentProps.js", "../../../node_modules/@mui/base/utils/omitEventHandlers.js", "../../../node_modules/@mui/base/utils/mergeSlotProps.js", "../../../node_modules/@mui/base/utils/useSlotProps.js", "../../../node_modules/@mui/base/utils/PolymorphicComponent.js", "../../../node_modules/@mui/base/utils/types.js", "../../../node_modules/@mui/base/utils/index.js", "../../../node_modules/@mui/base/composeClasses/index.js", "../../../node_modules/@mui/base/useBadge/useBadge.js", "../../../node_modules/@mui/base/useBadge/useBadge.types.js", "../../../node_modules/@mui/base/useBadge/index.js", "../../../node_modules/@mui/base/generateUtilityClasses/index.js", "../../../node_modules/@mui/base/generateUtilityClass/index.js", "../../../node_modules/@mui/base/Badge/badgeClasses.js", "../../../node_modules/@mui/base/Badge/Badge.types.js", "../../../node_modules/@mui/base/Badge/index.js", "../../../node_modules/@mui/base/Button/buttonClasses.js", "../../../node_modules/@mui/base/useButton/useButton.types.js", "../../../node_modules/@mui/base/useButton/index.js", "../../../node_modules/@mui/base/Button/Button.types.js", "../../../node_modules/@mui/base/Button/index.js", "../../../node_modules/@mui/base/ClickAwayListener/ClickAwayListener.js", "../../../node_modules/@mui/base/ClickAwayListener/index.js", "../../../node_modules/@mui/base/FocusTrap/FocusTrap.js", "../../../node_modules/@mui/base/FocusTrap/FocusTrap.types.js", "../../../node_modules/@mui/base/FocusTrap/index.js", "../../../node_modules/@mui/base/FormControl/formControlClasses.js", "../../../node_modules/@mui/base/FormControl/index.js", "../../../node_modules/@mui/base/Input/inputClasses.js", "../../../node_modules/@mui/base/useInput/useInput.types.js", "../../../node_modules/@mui/base/useInput/index.js", "../../../node_modules/@mui/base/Input/Input.types.js", "../../../node_modules/@mui/base/Input/index.js", "../../../node_modules/@mui/base/Menu/menuClasses.js", "../../../node_modules/@mui/base/useMenu/useMenu.types.js", "../../../node_modules/@mui/base/useMenu/MenuProvider.js", "../../../node_modules/@mui/base/useMenu/index.js", "../../../node_modules/@popperjs/core/lib/enums.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js", "../../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js", "../../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js", "../../../node_modules/@popperjs/core/lib/utils/getBasePlacement.js", "../../../node_modules/@popperjs/core/lib/utils/math.js", "../../../node_modules/@popperjs/core/lib/utils/userAgent.js", "../../../node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/contains.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js", "../../../node_modules/@popperjs/core/lib/dom-utils/isTableElement.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getParentNode.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js", "../../../node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js", "../../../node_modules/@popperjs/core/lib/utils/within.js", "../../../node_modules/@popperjs/core/lib/utils/getFreshSideObject.js", "../../../node_modules/@popperjs/core/lib/utils/mergePaddingObject.js", "../../../node_modules/@popperjs/core/lib/utils/expandToHashMap.js", "../../../node_modules/@popperjs/core/lib/modifiers/arrow.js", "../../../node_modules/@popperjs/core/lib/utils/getVariation.js", "../../../node_modules/@popperjs/core/lib/modifiers/computeStyles.js", "../../../node_modules/@popperjs/core/lib/modifiers/eventListeners.js", "../../../node_modules/@popperjs/core/lib/utils/getOppositePlacement.js", "../../../node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js", "../../../node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js", "../../../node_modules/@popperjs/core/lib/utils/rectToClientRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js", "../../../node_modules/@popperjs/core/lib/utils/computeOffsets.js", "../../../node_modules/@popperjs/core/lib/utils/detectOverflow.js", "../../../node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js", "../../../node_modules/@popperjs/core/lib/modifiers/flip.js", "../../../node_modules/@popperjs/core/lib/modifiers/hide.js", "../../../node_modules/@popperjs/core/lib/modifiers/offset.js", "../../../node_modules/@popperjs/core/lib/modifiers/popperOffsets.js", "../../../node_modules/@popperjs/core/lib/utils/getAltAxis.js", "../../../node_modules/@popperjs/core/lib/modifiers/preventOverflow.js", "../../../node_modules/@popperjs/core/lib/modifiers/index.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js", "../../../node_modules/@popperjs/core/lib/utils/orderModifiers.js", "../../../node_modules/@popperjs/core/lib/utils/debounce.js", "../../../node_modules/@popperjs/core/lib/utils/mergeByName.js", "../../../node_modules/@popperjs/core/lib/createPopper.js", "../../../node_modules/@popperjs/core/lib/popper.js", "../../../node_modules/@popperjs/core/lib/index.js", "../../../node_modules/@mui/base/Portal/Portal.js", "../../../node_modules/@mui/base/Portal/Portal.types.js", "../../../node_modules/@mui/base/Portal/index.js", "../../../node_modules/@mui/base/Popper/popperClasses.js", "../../../node_modules/@mui/base/Popper/Popper.js", "../../../node_modules/@mui/base/Popper/index.js", "../../../node_modules/@mui/base/Menu/Menu.types.js", "../../../node_modules/@mui/base/Menu/index.js", "../../../node_modules/@mui/base/MenuItem/menuItemClasses.js", "../../../node_modules/@mui/base/useMenuItem/useMenuItem.types.js", "../../../node_modules/@mui/base/useMenuItem/index.js", "../../../node_modules/@mui/base/MenuItem/MenuItem.types.js", "../../../node_modules/@mui/base/MenuItem/index.js", "../../../node_modules/@mui/base/Modal/ModalManager.js", "../../../node_modules/@mui/base/Modal/modalClasses.js", "../../../node_modules/@mui/base/Modal/Modal.js", "../../../node_modules/@mui/base/Modal/Modal.types.js", "../../../node_modules/@mui/base/Modal/index.js", "../../../node_modules/@mui/base/OptionGroup/optionGroupClasses.js", "../../../node_modules/@mui/base/OptionGroup/OptionGroup.types.js", "../../../node_modules/@mui/base/OptionGroup/index.js", "../../../node_modules/@mui/base/Option/optionClasses.js", "../../../node_modules/@mui/base/useOption/useOption.types.js", "../../../node_modules/@mui/base/useOption/index.js", "../../../node_modules/@mui/base/Option/Option.types.js", "../../../node_modules/@mui/base/Option/index.js", "../../../node_modules/@mui/base/useSelect/useSelect.types.js", "../../../node_modules/@mui/base/useSelect/SelectProvider.js", "../../../node_modules/@mui/base/useSelect/index.js", "../../../node_modules/@mui/base/Select/selectClasses.js", "../../../node_modules/@mui/base/Select/Select.types.js", "../../../node_modules/@mui/base/Select/index.js", "../../../node_modules/@mui/base/Slider/sliderClasses.js", "../../../node_modules/@mui/base/useSlider/useSlider.js", "../../../node_modules/@mui/base/useSlider/useSlider.types.js", "../../../node_modules/@mui/base/useSlider/index.js", "../../../node_modules/@mui/base/Slider/Slider.types.js", "../../../node_modules/@mui/base/Slider/index.js", "../../../node_modules/@mui/base/Snackbar/snackbarClasses.js", "../../../node_modules/@mui/base/useSnackbar/useSnackbar.js", "../../../node_modules/@mui/base/useSnackbar/useSnackbar.types.js", "../../../node_modules/@mui/base/useSnackbar/index.js", "../../../node_modules/@mui/base/Snackbar/Snackbar.types.js", "../../../node_modules/@mui/base/Snackbar/index.js", "../../../node_modules/@mui/base/useSwitch/useSwitch.types.js", "../../../node_modules/@mui/base/useSwitch/index.js", "../../../node_modules/@mui/base/Switch/switchClasses.js", "../../../node_modules/@mui/base/Switch/Switch.types.js", "../../../node_modules/@mui/base/Switch/index.js", "../../../node_modules/@mui/base/TablePagination/tablePaginationClasses.js", "../../../node_modules/@mui/base/TablePagination/TablePagination.types.js", "../../../node_modules/@mui/base/TablePagination/TablePaginationActions.types.js", "../../../node_modules/@mui/base/TablePagination/common.types.js", "../../../node_modules/@mui/base/TablePagination/index.js", "../../../node_modules/@mui/base/TabPanel/tabPanelClasses.js", "../../../node_modules/@mui/base/Tabs/tabsClasses.js", "../../../node_modules/@mui/base/useTabs/useTabs.js", "../../../node_modules/@mui/base/useTabs/useTabs.types.js", "../../../node_modules/@mui/base/Tabs/TabsContext.js", "../../../node_modules/@mui/base/useTabs/TabsProvider.js", "../../../node_modules/@mui/base/useTabs/index.js", "../../../node_modules/@mui/base/Tabs/Tabs.types.js", "../../../node_modules/@mui/base/Tabs/index.js", "../../../node_modules/@mui/base/TabPanel/TabPanel.types.js", "../../../node_modules/@mui/base/TabPanel/index.js", "../../../node_modules/@mui/base/TabsList/tabsListClasses.js", "../../../node_modules/@mui/base/useTabsList/useTabsList.types.js", "../../../node_modules/@mui/base/useTabsList/TabsListProvider.js", "../../../node_modules/@mui/base/useTabsList/index.js", "../../../node_modules/@mui/base/TabsList/TabsList.types.js", "../../../node_modules/@mui/base/TabsList/index.js", "../../../node_modules/@mui/base/Tab/tabClasses.js", "../../../node_modules/@mui/base/useTab/useTab.types.js", "../../../node_modules/@mui/base/useTab/index.js", "../../../node_modules/@mui/base/Tab/Tab.types.js", "../../../node_modules/@mui/base/Tab/index.js", "../../../node_modules/@mui/base/TextareaAutosize/TextareaAutosize.js", "../../../node_modules/@mui/base/TextareaAutosize/TextareaAutosize.types.js", "../../../node_modules/@mui/base/TextareaAutosize/index.js", "../../../node_modules/@mui/base/useAutocomplete/useAutocomplete.js", "../../../node_modules/@mui/base/useAutocomplete/index.js", "../../../node_modules/@mui/base/useTabPanel/useTabPanel.types.js", "../../../node_modules/@mui/base/useTabPanel/index.js", "../../../node_modules/@mui/base/index.js", "../../../node_modules/@mui/material/SvgIcon/svgIconClasses.js", "../../../node_modules/@mui/material/SvgIcon/SvgIcon.js", "../../../node_modules/@mui/material/SvgIcon/index.js", "../../../node_modules/@mui/material/utils/createSvgIcon.js", "../../../node_modules/@mui/material/utils/debounce.js", "../../../node_modules/@mui/material/utils/isMuiElement.js", "../../../node_modules/@mui/material/utils/ownerDocument.js", "../../../node_modules/@mui/material/utils/ownerWindow.js", "../../../node_modules/@mui/material/utils/useEnhancedEffect.js", "../../../node_modules/@mui/material/utils/useId.js", "../../../node_modules/@mui/material/utils/useControlled.js", "../../../node_modules/@mui/material/utils/useEventCallback.js", "../../../node_modules/@mui/material/utils/useForkRef.js", "../../../node_modules/@mui/material/utils/useIsFocusVisible.js", "../../../node_modules/@mui/material/utils/index.js", "../../../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js", "../../../node_modules/@babel/runtime/helpers/esm/inheritsLoose.js", "../../../node_modules/dom-helpers/esm/hasClass.js", "../../../node_modules/dom-helpers/esm/addClass.js", "../../../node_modules/dom-helpers/esm/removeClass.js", "../../../node_modules/react-transition-group/esm/config.js", "../../../node_modules/react-transition-group/esm/TransitionGroupContext.js", "../../../node_modules/react-transition-group/esm/utils/reflow.js", "../../../node_modules/react-transition-group/esm/Transition.js", "../../../node_modules/react-transition-group/esm/CSSTransition.js", "../../../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js", "../../../node_modules/react-transition-group/esm/utils/ChildMapping.js", "../../../node_modules/react-transition-group/esm/TransitionGroup.js", "../../../node_modules/react-transition-group/esm/index.js", "../../../node_modules/@mui/material/transitions/utils.js", "../../../node_modules/@mui/material/Collapse/collapseClasses.js", "../../../node_modules/@mui/material/Collapse/Collapse.js", "../../../node_modules/@mui/material/Collapse/index.js", "../../../node_modules/@mui/material/Paper/paperClasses.js", "../../../node_modules/@mui/material/Paper/Paper.js", "../../../node_modules/@mui/material/Paper/index.js", "../../../node_modules/@mui/material/Accordion/accordionClasses.js", "../../../node_modules/@mui/material/Accordion/index.js", "../../../node_modules/@mui/material/AccordionActions/accordionActionsClasses.js", "../../../node_modules/@mui/material/AccordionActions/index.js", "../../../node_modules/@mui/material/AccordionDetails/accordionDetailsClasses.js", "../../../node_modules/@mui/material/AccordionDetails/index.js", "../../../node_modules/@mui/material/ButtonBase/Ripple.js", "../../../node_modules/@mui/material/ButtonBase/touchRippleClasses.js", "../../../node_modules/@mui/material/ButtonBase/TouchRipple.js", "../../../node_modules/@mui/material/ButtonBase/buttonBaseClasses.js", "../../../node_modules/@mui/material/ButtonBase/ButtonBase.js", "../../../node_modules/@mui/material/ButtonBase/index.js", "../../../node_modules/@mui/material/AccordionSummary/accordionSummaryClasses.js", "../../../node_modules/@mui/material/AccordionSummary/index.js", "../../../node_modules/@mui/material/Alert/alertClasses.js", "../../../node_modules/@mui/material/IconButton/iconButtonClasses.js", "../../../node_modules/@mui/material/IconButton/IconButton.js", "../../../node_modules/@mui/material/IconButton/index.js", "../../../node_modules/@mui/material/internal/svg-icons/SuccessOutlined.js", "../../../node_modules/@mui/material/internal/svg-icons/ReportProblemOutlined.js", "../../../node_modules/@mui/material/internal/svg-icons/ErrorOutline.js", "../../../node_modules/@mui/material/internal/svg-icons/InfoOutlined.js", "../../../node_modules/@mui/material/internal/svg-icons/Close.js", "../../../node_modules/@mui/material/Alert/Alert.js", "../../../node_modules/@mui/material/Alert/index.js", "../../../node_modules/@mui/material/Typography/typographyClasses.js", "../../../node_modules/@mui/material/Typography/Typography.js", "../../../node_modules/@mui/material/Typography/index.js", "../../../node_modules/@mui/material/AlertTitle/alertTitleClasses.js", "../../../node_modules/@mui/material/AlertTitle/index.js", "../../../node_modules/@mui/material/AppBar/appBarClasses.js", "../../../node_modules/@mui/material/AppBar/index.js", "../../../node_modules/@mui/material/Popper/Popper.js", "../../../node_modules/@mui/material/Popper/index.js", "../../../node_modules/@mui/material/ListSubheader/listSubheaderClasses.js", "../../../node_modules/@mui/material/ListSubheader/ListSubheader.js", "../../../node_modules/@mui/material/ListSubheader/index.js", "../../../node_modules/@mui/material/internal/svg-icons/Cancel.js", "../../../node_modules/@mui/material/Chip/chipClasses.js", "../../../node_modules/@mui/material/Chip/Chip.js", "../../../node_modules/@mui/material/Chip/index.js", "../../../node_modules/@mui/material/FormControl/formControlState.js", "../../../node_modules/@mui/material/FormControl/FormControlContext.js", "../../../node_modules/@mui/material/FormControl/useFormControl.js", "../../../node_modules/@mui/material/GlobalStyles/GlobalStyles.js", "../../../node_modules/@mui/material/GlobalStyles/index.js", "../../../node_modules/@mui/material/InputBase/utils.js", "../../../node_modules/@mui/material/InputBase/inputBaseClasses.js", "../../../node_modules/@mui/material/InputBase/InputBase.js", "../../../node_modules/@mui/material/InputBase/index.js", "../../../node_modules/@mui/material/Input/inputClasses.js", "../../../node_modules/@mui/material/OutlinedInput/outlinedInputClasses.js", "../../../node_modules/@mui/material/FilledInput/filledInputClasses.js", "../../../node_modules/@mui/material/internal/svg-icons/ArrowDropDown.js", "../../../node_modules/@mui/material/Autocomplete/autocompleteClasses.js", "../../../node_modules/@mui/material/Autocomplete/Autocomplete.js", "../../../node_modules/@mui/material/Autocomplete/index.js", "../../../node_modules/@mui/material/Avatar/avatarClasses.js", "../../../node_modules/@mui/material/Avatar/index.js", "../../../node_modules/@mui/material/AvatarGroup/avatarGroupClasses.js", "../../../node_modules/@mui/material/AvatarGroup/index.js", "../../../node_modules/@mui/material/Fade/Fade.js", "../../../node_modules/@mui/material/Fade/index.js", "../../../node_modules/@mui/material/Backdrop/backdropClasses.js", "../../../node_modules/@mui/material/Backdrop/Backdrop.js", "../../../node_modules/@mui/material/Backdrop/index.js", "../../../node_modules/@mui/material/Badge/badgeClasses.js", "../../../node_modules/@mui/material/Badge/Badge.js", "../../../node_modules/@mui/material/Badge/index.js", "../../../node_modules/@mui/material/BottomNavigation/bottomNavigationClasses.js", "../../../node_modules/@mui/material/BottomNavigation/index.js", "../../../node_modules/@mui/material/BottomNavigationAction/bottomNavigationActionClasses.js", "../../../node_modules/@mui/material/BottomNavigationAction/index.js", "../../../node_modules/@mui/material/className/index.js", "../../../node_modules/@mui/material/Box/Box.js", "../../../node_modules/@mui/material/Box/index.js", "../../../node_modules/@mui/material/Breadcrumbs/breadcrumbsClasses.js", "../../../node_modules/@mui/material/Breadcrumbs/index.js", "../../../node_modules/@mui/material/Button/buttonClasses.js", "../../../node_modules/@mui/material/ButtonGroup/ButtonGroupContext.js", "../../../node_modules/@mui/material/Button/Button.js", "../../../node_modules/@mui/material/Button/index.js", "../../../node_modules/@mui/material/ButtonGroup/buttonGroupClasses.js", "../../../node_modules/@mui/material/ButtonGroup/index.js", "../../../node_modules/@mui/material/Card/cardClasses.js", "../../../node_modules/@mui/material/Card/Card.js", "../../../node_modules/@mui/material/Card/index.js", "../../../node_modules/@mui/material/CardActionArea/cardActionAreaClasses.js", "../../../node_modules/@mui/material/CardActionArea/index.js", "../../../node_modules/@mui/material/CardActions/cardActionsClasses.js", "../../../node_modules/@mui/material/CardActions/index.js", "../../../node_modules/@mui/material/CardContent/cardContentClasses.js", "../../../node_modules/@mui/material/CardContent/index.js", "../../../node_modules/@mui/material/CardHeader/cardHeaderClasses.js", "../../../node_modules/@mui/material/CardHeader/index.js", "../../../node_modules/@mui/material/CardMedia/cardMediaClasses.js", "../../../node_modules/@mui/material/CardMedia/index.js", "../../../node_modules/@mui/material/internal/switchBaseClasses.js", "../../../node_modules/@mui/material/internal/SwitchBase.js", "../../../node_modules/@mui/material/internal/svg-icons/CheckBoxOutlineBlank.js", "../../../node_modules/@mui/material/internal/svg-icons/CheckBox.js", "../../../node_modules/@mui/material/internal/svg-icons/IndeterminateCheckBox.js", "../../../node_modules/@mui/material/Checkbox/checkboxClasses.js", "../../../node_modules/@mui/material/Checkbox/Checkbox.js", "../../../node_modules/@mui/material/Checkbox/index.js", "../../../node_modules/@mui/material/CircularProgress/circularProgressClasses.js", "../../../node_modules/@mui/material/CircularProgress/CircularProgress.js", "../../../node_modules/@mui/material/CircularProgress/index.js", "../../../node_modules/@mui/material/ClickAwayListener/index.js", "../../../node_modules/@mui/material/Container/Container.js", "../../../node_modules/@mui/material/Container/containerClasses.js", "../../../node_modules/@mui/material/Container/index.js", "../../../node_modules/@mui/material/CssBaseline/index.js", "../../../node_modules/@mui/material/darkScrollbar/index.js", "../../../node_modules/@mui/material/Modal/Modal.js", "../../../node_modules/@mui/material/Modal/index.js", "../../../node_modules/@mui/material/Dialog/dialogClasses.js", "../../../node_modules/@mui/material/Dialog/DialogContext.js", "../../../node_modules/@mui/material/Dialog/Dialog.js", "../../../node_modules/@mui/material/Dialog/index.js", "../../../node_modules/@mui/material/DialogActions/dialogActionsClasses.js", "../../../node_modules/@mui/material/DialogActions/DialogActions.js", "../../../node_modules/@mui/material/DialogActions/index.js", "../../../node_modules/@mui/material/DialogContent/dialogContentClasses.js", "../../../node_modules/@mui/material/DialogTitle/dialogTitleClasses.js", "../../../node_modules/@mui/material/DialogContent/DialogContent.js", "../../../node_modules/@mui/material/DialogContent/index.js", "../../../node_modules/@mui/material/DialogContentText/dialogContentTextClasses.js", "../../../node_modules/@mui/material/DialogContentText/index.js", "../../../node_modules/@mui/material/DialogTitle/DialogTitle.js", "../../../node_modules/@mui/material/DialogTitle/index.js", "../../../node_modules/@mui/material/Divider/dividerClasses.js", "../../../node_modules/@mui/material/Divider/Divider.js", "../../../node_modules/@mui/material/Divider/index.js", "../../../node_modules/@mui/material/Slide/Slide.js", "../../../node_modules/@mui/material/Slide/index.js", "../../../node_modules/@mui/material/Drawer/drawerClasses.js", "../../../node_modules/@mui/material/Drawer/Drawer.js", "../../../node_modules/@mui/material/Drawer/index.js", "../../../node_modules/@mui/material/Fab/fabClasses.js", "../../../node_modules/@mui/material/Fab/Fab.js", "../../../node_modules/@mui/material/Fab/index.js", "../../../node_modules/@mui/material/FilledInput/FilledInput.js", "../../../node_modules/@mui/material/FilledInput/index.js", "../../../node_modules/@mui/material/FormControl/formControlClasses.js", "../../../node_modules/@mui/material/FormControl/FormControl.js", "../../../node_modules/@mui/material/FormControl/index.js", "../../../node_modules/@mui/material/FormControlLabel/formControlLabelClasses.js", "../../../node_modules/@mui/material/FormControlLabel/FormControlLabel.js", "../../../node_modules/@mui/material/FormControlLabel/index.js", "../../../node_modules/@mui/material/FormGroup/formGroupClasses.js", "../../../node_modules/@mui/material/FormGroup/FormGroup.js", "../../../node_modules/@mui/material/FormGroup/index.js", "../../../node_modules/@mui/material/FormHelperText/formHelperTextClasses.js", "../../../node_modules/@mui/material/FormHelperText/FormHelperText.js", "../../../node_modules/@mui/material/FormHelperText/index.js", "../../../node_modules/@mui/material/FormLabel/formLabelClasses.js", "../../../node_modules/@mui/material/FormLabel/FormLabel.js", "../../../node_modules/@mui/material/FormLabel/index.js", "../../../node_modules/@mui/material/Grid/gridClasses.js", "../../../node_modules/@mui/material/Grid/index.js", "../../../node_modules/@mui/material/Unstable_Grid2/Grid2Props.js", "../../../node_modules/@mui/material/Unstable_Grid2/grid2Classes.js", "../../../node_modules/@mui/material/Unstable_Grid2/index.js", "../../../node_modules/@mui/material/Grow/Grow.js", "../../../node_modules/@mui/material/Grow/index.js", "../../../node_modules/@mui/material/useMediaQuery/useMediaQuery.js", "../../../node_modules/@mui/material/useMediaQuery/index.js", "../../../node_modules/@mui/material/Hidden/index.js", "../../../node_modules/@mui/material/Icon/iconClasses.js", "../../../node_modules/@mui/material/Icon/index.js", "../../../node_modules/@mui/material/ImageList/imageListClasses.js", "../../../node_modules/@mui/material/ImageList/index.js", "../../../node_modules/@mui/material/ImageListItem/imageListItemClasses.js", "../../../node_modules/@mui/material/ImageListItem/index.js", "../../../node_modules/@mui/material/ImageListItemBar/imageListItemBarClasses.js", "../../../node_modules/@mui/material/ImageListItemBar/index.js", "../../../node_modules/@mui/material/Input/Input.js", "../../../node_modules/@mui/material/Input/index.js", "../../../node_modules/@mui/material/InputAdornment/inputAdornmentClasses.js", "../../../node_modules/@mui/material/InputAdornment/InputAdornment.js", "../../../node_modules/@mui/material/InputAdornment/index.js", "../../../node_modules/@mui/material/InputLabel/inputLabelClasses.js", "../../../node_modules/@mui/material/InputLabel/InputLabel.js", "../../../node_modules/@mui/material/InputLabel/index.js", "../../../node_modules/@mui/material/LinearProgress/linearProgressClasses.js", "../../../node_modules/@mui/material/LinearProgress/LinearProgress.js", "../../../node_modules/@mui/material/LinearProgress/index.js", "../../../node_modules/@mui/material/Link/linkClasses.js", "../../../node_modules/@mui/material/Link/getTextDecoration.js", "../../../node_modules/@mui/material/Link/Link.js", "../../../node_modules/@mui/material/Link/index.js", "../../../node_modules/@mui/material/List/ListContext.js", "../../../node_modules/@mui/material/List/listClasses.js", "../../../node_modules/@mui/material/List/List.js", "../../../node_modules/@mui/material/List/index.js", "../../../node_modules/@mui/material/ListItem/listItemClasses.js", "../../../node_modules/@mui/material/ListItemButton/listItemButtonClasses.js", "../../../node_modules/@mui/material/ListItemButton/index.js", "../../../node_modules/@mui/material/ListItemSecondaryAction/listItemSecondaryActionClasses.js", "../../../node_modules/@mui/material/ListItemSecondaryAction/ListItemSecondaryAction.js", "../../../node_modules/@mui/material/ListItemSecondaryAction/index.js", "../../../node_modules/@mui/material/ListItem/ListItem.js", "../../../node_modules/@mui/material/ListItem/index.js", "../../../node_modules/@mui/material/ListItemAvatar/listItemAvatarClasses.js", "../../../node_modules/@mui/material/ListItemAvatar/index.js", "../../../node_modules/@mui/material/ListItemIcon/listItemIconClasses.js", "../../../node_modules/@mui/material/ListItemIcon/ListItemIcon.js", "../../../node_modules/@mui/material/ListItemIcon/index.js", "../../../node_modules/@mui/material/ListItemText/listItemTextClasses.js", "../../../node_modules/@mui/material/ListItemText/ListItemText.js", "../../../node_modules/@mui/material/ListItemText/index.js", "../../../node_modules/@mui/material/utils/getScrollbarSize.js", "../../../node_modules/@mui/material/MenuList/MenuList.js", "../../../node_modules/@mui/material/MenuList/index.js", "../../../node_modules/@mui/material/Popover/popoverClasses.js", "../../../node_modules/@mui/material/Popover/Popover.js", "../../../node_modules/@mui/material/Popover/index.js", "../../../node_modules/@mui/material/Menu/menuClasses.js", "../../../node_modules/@mui/material/Menu/Menu.js", "../../../node_modules/@mui/material/Menu/index.js", "../../../node_modules/@mui/material/MenuItem/menuItemClasses.js", "../../../node_modules/@mui/material/MenuItem/MenuItem.js", "../../../node_modules/@mui/material/MenuItem/index.js", "../../../node_modules/@mui/material/MobileStepper/mobileStepperClasses.js", "../../../node_modules/@mui/material/MobileStepper/index.js", "../../../node_modules/@mui/material/NativeSelect/nativeSelectClasses.js", "../../../node_modules/@mui/material/NativeSelect/NativeSelectInput.js", "../../../node_modules/@mui/material/NativeSelect/index.js", "../../../node_modules/@mui/material/NoSsr/index.js", "../../../node_modules/@mui/material/OutlinedInput/NotchedOutline.js", "../../../node_modules/@mui/material/OutlinedInput/OutlinedInput.js", "../../../node_modules/@mui/material/OutlinedInput/index.js", "../../../node_modules/@mui/material/Pagination/paginationClasses.js", "../../../node_modules/@mui/material/usePagination/usePagination.js", "../../../node_modules/@mui/material/usePagination/index.js", "../../../node_modules/@mui/material/PaginationItem/paginationItemClasses.js", "../../../node_modules/@mui/material/internal/svg-icons/FirstPage.js", "../../../node_modules/@mui/material/internal/svg-icons/LastPage.js", "../../../node_modules/@mui/material/internal/svg-icons/NavigateBefore.js", "../../../node_modules/@mui/material/internal/svg-icons/NavigateNext.js", "../../../node_modules/@mui/material/PaginationItem/PaginationItem.js", "../../../node_modules/@mui/material/PaginationItem/index.js", "../../../node_modules/@mui/material/Pagination/Pagination.js", "../../../node_modules/@mui/material/Pagination/index.js", "../../../node_modules/@mui/material/Portal/index.js", "../../../node_modules/@mui/material/internal/svg-icons/RadioButtonUnchecked.js", "../../../node_modules/@mui/material/internal/svg-icons/RadioButtonChecked.js", "../../../node_modules/@mui/material/Radio/RadioButtonIcon.js", "../../../node_modules/@mui/material/RadioGroup/RadioGroupContext.js", "../../../node_modules/@mui/material/RadioGroup/useRadioGroup.js", "../../../node_modules/@mui/material/Radio/radioClasses.js", "../../../node_modules/@mui/material/Radio/Radio.js", "../../../node_modules/@mui/material/Radio/index.js", "../../../node_modules/@mui/material/RadioGroup/RadioGroup.js", "../../../node_modules/@mui/material/RadioGroup/index.js", "../../../node_modules/@mui/material/Rating/ratingClasses.js", "../../../node_modules/@mui/material/Rating/index.js", "../../../node_modules/@mui/material/ScopedCssBaseline/scopedCssBaselineClasses.js", "../../../node_modules/@mui/material/ScopedCssBaseline/index.js", "../../../node_modules/@mui/material/Select/selectClasses.js", "../../../node_modules/@mui/material/Select/SelectInput.js", "../../../node_modules/@mui/material/Select/Select.js", "../../../node_modules/@mui/material/Select/index.js", "../../../node_modules/@mui/material/Skeleton/skeletonClasses.js", "../../../node_modules/@mui/material/Skeleton/Skeleton.js", "../../../node_modules/@mui/material/Skeleton/index.js", "../../../node_modules/@mui/material/Slider/sliderClasses.js", "../../../node_modules/@mui/material/Slider/SliderValueLabel.js", "../../../node_modules/@mui/material/Slider/Slider.js", "../../../node_modules/@mui/material/Slider/index.js", "../../../node_modules/@mui/material/SnackbarContent/snackbarContentClasses.js", "../../../node_modules/@mui/material/SnackbarContent/SnackbarContent.js", "../../../node_modules/@mui/material/SnackbarContent/index.js", "../../../node_modules/@mui/material/Snackbar/snackbarClasses.js", "../../../node_modules/@mui/material/Snackbar/Snackbar.js", "../../../node_modules/@mui/material/Snackbar/index.js", "../../../node_modules/@mui/material/Zoom/index.js", "../../../node_modules/@mui/material/SpeedDial/speedDialClasses.js", "../../../node_modules/@mui/material/SpeedDial/index.js", "../../../node_modules/@mui/material/Tooltip/tooltipClasses.js", "../../../node_modules/@mui/material/Tooltip/Tooltip.js", "../../../node_modules/@mui/material/Tooltip/index.js", "../../../node_modules/@mui/material/SpeedDialAction/speedDialActionClasses.js", "../../../node_modules/@mui/material/SpeedDialAction/index.js", "../../../node_modules/@mui/material/SpeedDialIcon/speedDialIconClasses.js", "../../../node_modules/@mui/material/SpeedDialIcon/index.js", "../../../node_modules/@mui/material/Stack/Stack.js", "../../../node_modules/@mui/material/Stack/index.js", "../../../node_modules/@mui/material/Stepper/StepperContext.js", "../../../node_modules/@mui/material/Step/StepContext.js", "../../../node_modules/@mui/material/Step/stepClasses.js", "../../../node_modules/@mui/material/Step/index.js", "../../../node_modules/@mui/material/StepIcon/stepIconClasses.js", "../../../node_modules/@mui/material/StepIcon/index.js", "../../../node_modules/@mui/material/StepLabel/stepLabelClasses.js", "../../../node_modules/@mui/material/StepLabel/index.js", "../../../node_modules/@mui/material/StepButton/stepButtonClasses.js", "../../../node_modules/@mui/material/StepButton/index.js", "../../../node_modules/@mui/material/StepConnector/stepConnectorClasses.js", "../../../node_modules/@mui/material/StepConnector/index.js", "../../../node_modules/@mui/material/StepContent/stepContentClasses.js", "../../../node_modules/@mui/material/StepContent/index.js", "../../../node_modules/@mui/material/Stepper/stepperClasses.js", "../../../node_modules/@mui/material/Stepper/index.js", "../../../node_modules/@mui/material/SwipeableDrawer/index.js", "../../../node_modules/@mui/material/Switch/switchClasses.js", "../../../node_modules/@mui/material/Switch/index.js", "../../../node_modules/@mui/material/Tab/tabClasses.js", "../../../node_modules/@mui/material/Tab/Tab.js", "../../../node_modules/@mui/material/Tab/index.js", "../../../node_modules/@mui/material/Table/TableContext.js", "../../../node_modules/@mui/material/Table/tableClasses.js", "../../../node_modules/@mui/material/Table/Table.js", "../../../node_modules/@mui/material/Table/index.js", "../../../node_modules/@mui/material/Table/Tablelvl2Context.js", "../../../node_modules/@mui/material/TableBody/tableBodyClasses.js", "../../../node_modules/@mui/material/TableBody/TableBody.js", "../../../node_modules/@mui/material/TableBody/index.js", "../../../node_modules/@mui/material/TableCell/tableCellClasses.js", "../../../node_modules/@mui/material/TableCell/TableCell.js", "../../../node_modules/@mui/material/TableCell/index.js", "../../../node_modules/@mui/material/TableContainer/tableContainerClasses.js", "../../../node_modules/@mui/material/TableContainer/TableContainer.js", "../../../node_modules/@mui/material/TableContainer/index.js", "../../../node_modules/@mui/material/TableFooter/tableFooterClasses.js", "../../../node_modules/@mui/material/TableFooter/index.js", "../../../node_modules/@mui/material/TableHead/tableHeadClasses.js", "../../../node_modules/@mui/material/TableHead/TableHead.js", "../../../node_modules/@mui/material/TableHead/index.js", "../../../node_modules/@mui/material/Toolbar/toolbarClasses.js", "../../../node_modules/@mui/material/Toolbar/index.js", "../../../node_modules/@mui/material/internal/svg-icons/KeyboardArrowLeft.js", "../../../node_modules/@mui/material/internal/svg-icons/KeyboardArrowRight.js", "../../../node_modules/@mui/material/TablePagination/tablePaginationClasses.js", "../../../node_modules/@mui/material/TablePagination/index.js", "../../../node_modules/@mui/material/TableRow/tableRowClasses.js", "../../../node_modules/@mui/material/TableRow/TableRow.js", "../../../node_modules/@mui/material/TableRow/index.js", "../../../node_modules/@mui/material/TableSortLabel/tableSortLabelClasses.js", "../../../node_modules/@mui/material/TableSortLabel/index.js", "../../../node_modules/@mui/material/utils/scrollLeft.js", "../../../node_modules/@mui/material/internal/animate.js", "../../../node_modules/@mui/material/Tabs/ScrollbarSize.js", "../../../node_modules/@mui/material/TabScrollButton/tabScrollButtonClasses.js", "../../../node_modules/@mui/material/TabScrollButton/TabScrollButton.js", "../../../node_modules/@mui/material/TabScrollButton/index.js", "../../../node_modules/@mui/material/Tabs/tabsClasses.js", "../../../node_modules/@mui/material/Tabs/Tabs.js", "../../../node_modules/@mui/material/Tabs/index.js", "../../../node_modules/@mui/material/TextField/textFieldClasses.js", "../../../node_modules/@mui/material/TextField/TextField.js", "../../../node_modules/@mui/material/TextField/index.js", "../../../node_modules/@mui/material/TextareaAutosize/index.js", "../../../node_modules/@mui/material/ToggleButton/toggleButtonClasses.js", "../../../node_modules/@mui/material/ToggleButton/index.js", "../../../node_modules/@mui/material/ToggleButtonGroup/toggleButtonGroupClasses.js", "../../../node_modules/@mui/material/ToggleButtonGroup/index.js", "../../../node_modules/@mui/material/useScrollTrigger/index.js", "../../../node_modules/@mui/material/index.js", "../../javascript/components/theme/fonts.ts", "../../javascript/components/theme/tokens/colors.ts", "../../../node_modules/dayjs/dayjs.min.js", "../../../node_modules/dayjs/plugin/weekOfYear.js", "../../../node_modules/dayjs/plugin/customParseFormat.js", "../../../node_modules/dayjs/plugin/localizedFormat.js", "../../../node_modules/dayjs/plugin/isBetween.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/warning.js", "../../../node_modules/@mui/x-date-pickers/AdapterDayjs/AdapterDayjs.js", "../../../node_modules/@mui/x-date-pickers/AdapterDayjs/index.js", "../../../node_modules/@mui/x-date-pickers/LocalizationProvider/LocalizationProvider.js", "../../../node_modules/@mui/x-date-pickers/LocalizationProvider/index.js", "../../javascript/utils/sessionExpiration.ts", "../../javascript/contexts/GlobalAlertContext.tsx", "../../javascript/utils/cloudwatchRum.ts", "../../javascript/utils/fetchHelpers.ts", "../../javascript/utils/featureFlags.ts", "../../javascript/api/userEvents.ts", "../../javascript/components/agent_prototype/planningAnalytics.ts", "../../javascript/utils/urlHelpers.ts", "../../../node_modules/shared/src/utils/mergeClasses.ts", "../../../node_modules/shared/src/utils/toKebabCase.ts", "../../../node_modules/shared/src/utils/toCamelCase.ts", "../../../node_modules/shared/src/utils/toPascalCase.ts", "../../../node_modules/lucide-react/src/defaultAttributes.ts", "../../../node_modules/shared/src/utils/hasA11yProp.ts", "../../../node_modules/lucide-react/src/context.ts", "../../../node_modules/lucide-react/src/Icon.ts", "../../../node_modules/lucide-react/src/createLucideIcon.ts", "../../../node_modules/lucide-react/src/icons/arrow-left.ts", "../../../node_modules/lucide-react/src/icons/arrow-right.ts", "../../../node_modules/lucide-react/src/icons/arrow-up-down.ts", "../../../node_modules/lucide-react/src/icons/arrow-up.ts", "../../../node_modules/lucide-react/src/icons/badge-check.ts", "../../../node_modules/lucide-react/src/icons/bell.ts", "../../../node_modules/lucide-react/src/icons/blocks.ts", "../../../node_modules/lucide-react/src/icons/book-open.ts", "../../../node_modules/lucide-react/src/icons/brain.ts", "../../../node_modules/lucide-react/src/icons/calendar.ts", "../../../node_modules/lucide-react/src/icons/check.ts", "../../../node_modules/lucide-react/src/icons/chevron-down.ts", "../../../node_modules/lucide-react/src/icons/chevron-left.ts", "../../../node_modules/lucide-react/src/icons/chevron-right.ts", "../../../node_modules/lucide-react/src/icons/chevron-up.ts", "../../../node_modules/lucide-react/src/icons/circle-alert.ts", "../../../node_modules/lucide-react/src/icons/circle-check.ts", "../../../node_modules/lucide-react/src/icons/circle-check-big.ts", "../../../node_modules/lucide-react/src/icons/circle-dollar-sign.ts", "../../../node_modules/lucide-react/src/icons/circle-minus.ts", "../../../node_modules/lucide-react/src/icons/circle-pause.ts", "../../../node_modules/lucide-react/src/icons/circle-question-mark.ts", "../../../node_modules/lucide-react/src/icons/circle-stop.ts", "../../../node_modules/lucide-react/src/icons/clipboard-copy.ts", "../../../node_modules/lucide-react/src/icons/clock-3.ts", "../../../node_modules/lucide-react/src/icons/copy.ts", "../../../node_modules/lucide-react/src/icons/download.ts", "../../../node_modules/lucide-react/src/icons/dot.ts", "../../../node_modules/lucide-react/src/icons/ellipsis-vertical.ts", "../../../node_modules/lucide-react/src/icons/ellipsis.ts", "../../../node_modules/lucide-react/src/icons/expand.ts", "../../../node_modules/lucide-react/src/icons/external-link.ts", "../../../node_modules/lucide-react/src/icons/eye-off.ts", "../../../node_modules/lucide-react/src/icons/eye.ts", "../../../node_modules/lucide-react/src/icons/file-output.ts", "../../../node_modules/lucide-react/src/icons/file-plus-corner.ts", "../../../node_modules/lucide-react/src/icons/file-search.ts", "../../../node_modules/lucide-react/src/icons/file-text.ts", "../../../node_modules/lucide-react/src/icons/file-up.ts", "../../../node_modules/lucide-react/src/icons/file.ts", "../../../node_modules/lucide-react/src/icons/folder-input.ts", "../../../node_modules/lucide-react/src/icons/folder-open.ts", "../../../node_modules/lucide-react/src/icons/folder-plus.ts", "../../../node_modules/lucide-react/src/icons/folders.ts", "../../../node_modules/lucide-react/src/icons/folder.ts", "../../../node_modules/lucide-react/src/icons/fullscreen.ts", "../../../node_modules/lucide-react/src/icons/gavel.ts", "../../../node_modules/lucide-react/src/icons/hammer.ts", "../../../node_modules/lucide-react/src/icons/hand.ts", "../../../node_modules/lucide-react/src/icons/hard-drive.ts", "../../../node_modules/lucide-react/src/icons/hash.ts", "../../../node_modules/lucide-react/src/icons/highlighter.ts", "../../../node_modules/lucide-react/src/icons/history.ts", "../../../node_modules/lucide-react/src/icons/info.ts", "../../../node_modules/lucide-react/src/icons/landmark.ts", "../../../node_modules/lucide-react/src/icons/lightbulb.ts", "../../../node_modules/lucide-react/src/icons/link-2.ts", "../../../node_modules/lucide-react/src/icons/link.ts", "../../../node_modules/lucide-react/src/icons/list-checks.ts", "../../../node_modules/lucide-react/src/icons/list.ts", "../../../node_modules/lucide-react/src/icons/loader.ts", "../../../node_modules/lucide-react/src/icons/lock.ts", "../../../node_modules/lucide-react/src/icons/log-out.ts", "../../../node_modules/lucide-react/src/icons/mail.ts", "../../../node_modules/lucide-react/src/icons/message-square-plus.ts", "../../../node_modules/lucide-react/src/icons/message-square.ts", "../../../node_modules/lucide-react/src/icons/messages-square.ts", "../../../node_modules/lucide-react/src/icons/minimize-2.ts", "../../../node_modules/lucide-react/src/icons/minus.ts", "../../../node_modules/lucide-react/src/icons/move-right.ts", "../../../node_modules/lucide-react/src/icons/paperclip.ts", "../../../node_modules/lucide-react/src/icons/pen-line.ts", "../../../node_modules/lucide-react/src/icons/pencil.ts", "../../../node_modules/lucide-react/src/icons/pin-off.ts", "../../../node_modules/lucide-react/src/icons/pin.ts", "../../../node_modules/lucide-react/src/icons/play.ts", "../../../node_modules/lucide-react/src/icons/plus.ts", "../../../node_modules/lucide-react/src/icons/quote.ts", "../../../node_modules/lucide-react/src/icons/receipt-text.ts", "../../../node_modules/lucide-react/src/icons/refresh-cw.ts", "../../../node_modules/lucide-react/src/icons/rss.ts", "../../../node_modules/lucide-react/src/icons/scale.ts", "../../../node_modules/lucide-react/src/icons/scissors.ts", "../../../node_modules/lucide-react/src/icons/scroll-text.ts", "../../../node_modules/lucide-react/src/icons/search-check.ts", "../../../node_modules/lucide-react/src/icons/search-x.ts", "../../../node_modules/lucide-react/src/icons/search.ts", "../../../node_modules/lucide-react/src/icons/share-2.ts", "../../../node_modules/lucide-react/src/icons/shield-check.ts", "../../../node_modules/lucide-react/src/icons/shrink.ts", "../../../node_modules/lucide-react/src/icons/shuffle.ts", "../../../node_modules/lucide-react/src/icons/signal-high.ts", "../../../node_modules/lucide-react/src/icons/signal-low.ts", "../../../node_modules/lucide-react/src/icons/signal-medium.ts", "../../../node_modules/lucide-react/src/icons/signal.ts", "../../../node_modules/lucide-react/src/icons/signal-zero.ts", "../../../node_modules/lucide-react/src/icons/sliders-horizontal.ts", "../../../node_modules/lucide-react/src/icons/split.ts", "../../../node_modules/lucide-react/src/icons/square-plus.ts", "../../../node_modules/lucide-react/src/icons/square.ts", "../../../node_modules/lucide-react/src/icons/star.ts", "../../../node_modules/lucide-react/src/icons/sticky-note.ts", "../../../node_modules/lucide-react/src/icons/terminal.ts", "../../../node_modules/lucide-react/src/icons/thumbs-down.ts", "../../../node_modules/lucide-react/src/icons/thumbs-up.ts", "../../../node_modules/lucide-react/src/icons/trash-2.ts", "../../../node_modules/lucide-react/src/icons/triangle-alert.ts", "../../../node_modules/lucide-react/src/icons/unplug.ts", "../../../node_modules/lucide-react/src/icons/user-search.ts", "../../../node_modules/lucide-react/src/icons/user.ts", "../../../node_modules/lucide-react/src/icons/users.ts", "../../../node_modules/lucide-react/src/icons/x.ts", "../../../node_modules/lucide-react/dist/esm/lucide-react.mjs", "../../javascript/components/theme/tokens/iconSize.ts", "../../javascript/components/icons/Icon.tsx", "../../javascript/components/icons/renderLucideOrNode.tsx", "../../javascript/components/icons/index.ts", "../../javascript/components/atoms/BIQIconButton.tsx", "../../javascript/utils/styled.ts", "../../javascript/components/molecules/EntryBlock.tsx", "../../javascript/components/theme/tokens/layout.ts", "../../javascript/components/layouts/EntryLayout.tsx", "../../javascript/components/molecules/UseCaseBlock.tsx", "../../javascript/components/atoms/BIQChip.tsx", "../../javascript/components/atoms/UsecaseCard.tsx", "../../javascript/components/agent_prototype/planningSubmitSx.ts", "../../javascript/components/atoms/BIQButton.tsx", "../../javascript/components/theme/tokens/spacing.ts", "../../javascript/components/agent_prototype/conversationDrafts.ts", "../../javascript/components/agent_prototype/constants.ts", "../../javascript/utils/creditBilling.ts", "../../javascript/components/agent_prototype/modelConfig.ts", "../../../node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js", "../../../node_modules/use-sync-external-store/shim/index.js", "../../../node_modules/@tiptap/core/dist/rolldown-runtime-D7D4PA-g.js", "../../../node_modules/orderedmap/dist/index.js", "../../../node_modules/prosemirror-model/dist/index.js", "../../../node_modules/prosemirror-transform/dist/index.js", "../../../node_modules/@tiptap/pm/dist/transform/index.js", "../../../node_modules/prosemirror-state/dist/index.js", "../../../node_modules/prosemirror-commands/dist/index.js", "../../../node_modules/@tiptap/pm/dist/commands/index.js", "../../../node_modules/@tiptap/pm/dist/state/index.js", "../../../node_modules/@tiptap/pm/dist/model/index.js", "../../../node_modules/prosemirror-schema-list/dist/index.js", "../../../node_modules/@tiptap/pm/dist/schema-list/index.js", "../../../node_modules/prosemirror-view/dist/index.js", "../../../node_modules/@tiptap/pm/dist/view/index.js", "../../../node_modules/w3c-keyname/index.js", "../../../node_modules/prosemirror-keymap/dist/index.js", "../../../node_modules/@tiptap/pm/dist/keymap/index.js", "../../../node_modules/@tiptap/core/src/helpers/createChainableState.ts", "../../../node_modules/@tiptap/core/src/CommandManager.ts", "../../../node_modules/@tiptap/core/src/commands/blur.ts", "../../../node_modules/@tiptap/core/src/commands/clearContent.ts", "../../../node_modules/@tiptap/core/src/commands/clearNodes.ts", "../../../node_modules/@tiptap/core/src/commands/command.ts", "../../../node_modules/@tiptap/core/src/commands/createParagraphNear.ts", "../../../node_modules/@tiptap/core/src/commands/cut.ts", "../../../node_modules/@tiptap/core/src/commands/deleteCurrentNode.ts", "../../../node_modules/@tiptap/core/src/helpers/getNodeType.ts", "../../../node_modules/@tiptap/core/src/commands/deleteNode.ts", "../../../node_modules/@tiptap/core/src/commands/deleteRange.ts", "../../../node_modules/@tiptap/core/src/commands/deleteSelection.ts", "../../../node_modules/@tiptap/core/src/commands/enter.ts", "../../../node_modules/@tiptap/core/src/commands/exitCode.ts", "../../../node_modules/@tiptap/core/src/utilities/isRegExp.ts", "../../../node_modules/@tiptap/core/src/utilities/objectIncludes.ts", "../../../node_modules/@tiptap/core/src/helpers/getMarkRange.ts", "../../../node_modules/@tiptap/core/src/helpers/getMarkType.ts", "../../../node_modules/@tiptap/core/src/commands/extendMarkRange.ts", "../../../node_modules/@tiptap/core/src/commands/first.ts", "../../../node_modules/@tiptap/core/src/helpers/isTextSelection.ts", "../../../node_modules/@tiptap/core/src/utilities/minMax.ts", "../../../node_modules/@tiptap/core/src/helpers/resolveFocusPosition.ts", "../../../node_modules/@tiptap/core/src/utilities/isAndroid.ts", "../../../node_modules/@tiptap/core/src/utilities/isiOS.ts", "../../../node_modules/@tiptap/core/src/utilities/isSafari.ts", "../../../node_modules/@tiptap/core/src/commands/focus.ts", "../../../node_modules/@tiptap/core/src/commands/forEach.ts", "../../../node_modules/@tiptap/core/src/commands/insertContent.ts", "../../../node_modules/@tiptap/core/src/utilities/elementFromString.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorContent.ts", "../../../node_modules/@tiptap/core/src/helpers/createNodeFromContent.ts", "../../../node_modules/@tiptap/core/src/helpers/isFragment.ts", "../../../node_modules/@tiptap/core/src/helpers/selectionToInsertionEnd.ts", "../../../node_modules/@tiptap/core/src/commands/insertContentAt.ts", "../../../node_modules/@tiptap/core/src/helpers/defaultBlockAt.ts", "../../../node_modules/@tiptap/core/src/commands/insertDefaultBlock.ts", "../../../node_modules/@tiptap/core/src/commands/join.ts", "../../../node_modules/@tiptap/core/src/commands/joinItemBackward.ts", "../../../node_modules/@tiptap/core/src/commands/joinItemForward.ts", "../../../node_modules/@tiptap/core/src/commands/joinTextblockBackward.ts", "../../../node_modules/@tiptap/core/src/commands/joinTextblockForward.ts", "../../../node_modules/@tiptap/core/src/utilities/isMacOS.ts", "../../../node_modules/@tiptap/core/src/commands/keyboardShortcut.ts", "../../../node_modules/@tiptap/core/src/helpers/isNodeActive.ts", "../../../node_modules/@tiptap/core/src/commands/lift.ts", "../../../node_modules/@tiptap/core/src/commands/liftEmptyBlock.ts", "../../../node_modules/@tiptap/core/src/commands/liftListItem.ts", "../../../node_modules/@tiptap/core/src/commands/newlineInCode.ts", "../../../node_modules/@tiptap/core/src/helpers/getSchemaTypeNameByName.ts", "../../../node_modules/@tiptap/core/src/utilities/deleteProps.ts", "../../../node_modules/@tiptap/core/src/commands/resetAttributes.ts", "../../../node_modules/@tiptap/core/src/commands/scrollIntoView.ts", "../../../node_modules/@tiptap/core/src/commands/selectAll.ts", "../../../node_modules/@tiptap/core/src/commands/selectNodeBackward.ts", "../../../node_modules/@tiptap/core/src/commands/selectNodeForward.ts", "../../../node_modules/@tiptap/core/src/commands/selectParentNode.ts", "../../../node_modules/@tiptap/core/src/commands/selectTextblockEnd.ts", "../../../node_modules/@tiptap/core/src/commands/selectTextblockStart.ts", "../../../node_modules/@tiptap/core/src/helpers/createDocument.ts", "../../../node_modules/@tiptap/core/src/commands/setContent.ts", "../../../node_modules/@tiptap/core/src/helpers/getMarkAttributes.ts", "../../../node_modules/@tiptap/core/src/helpers/combineTransactionSteps.ts", "../../../node_modules/@tiptap/core/src/helpers/findChildren.ts", "../../../node_modules/@tiptap/core/src/helpers/findChildrenInRange.ts", "../../../node_modules/@tiptap/core/src/helpers/findParentNodeClosestToPos.ts", "../../../node_modules/@tiptap/core/src/helpers/findParentNode.ts", "../../../node_modules/@tiptap/core/src/helpers/getExtensionField.ts", "../../../node_modules/@tiptap/core/src/helpers/flattenExtensions.ts", "../../../node_modules/@tiptap/core/src/helpers/getHTMLFromFragment.ts", "../../../node_modules/@tiptap/core/src/utilities/isFunction.ts", "../../../node_modules/@tiptap/core/src/utilities/callOrReturn.ts", "../../../node_modules/@tiptap/core/src/utilities/isEmptyObject.ts", "../../../node_modules/@tiptap/core/src/helpers/splitExtensions.ts", "../../../node_modules/@tiptap/core/src/helpers/getAttributesFromExtensions.ts", "../../../node_modules/@tiptap/core/src/utilities/mergeAttributes.ts", "../../../node_modules/@tiptap/core/src/helpers/getRenderedAttributes.ts", "../../../node_modules/@tiptap/core/src/utilities/fromString.ts", "../../../node_modules/@tiptap/core/src/helpers/injectExtensionAttributesToParseRule.ts", "../../../node_modules/@tiptap/core/src/helpers/getSchemaByResolvedExtensions.ts", "../../../node_modules/@tiptap/core/src/utilities/findDuplicates.ts", "../../../node_modules/@tiptap/core/src/helpers/sortExtensions.ts", "../../../node_modules/@tiptap/core/src/helpers/resolveExtensions.ts", "../../../node_modules/@tiptap/core/src/helpers/getSchema.ts", "../../../node_modules/@tiptap/core/src/helpers/generateHTML.ts", "../../../node_modules/@tiptap/core/src/helpers/generateJSON.ts", "../../../node_modules/@tiptap/core/src/helpers/getTextBetween.ts", "../../../node_modules/@tiptap/core/src/helpers/getText.ts", "../../../node_modules/@tiptap/core/src/helpers/getTextSerializersFromSchema.ts", "../../../node_modules/@tiptap/core/src/helpers/generateText.ts", "../../../node_modules/@tiptap/core/src/helpers/getNodeAttributes.ts", "../../../node_modules/@tiptap/core/src/helpers/getAttributes.ts", "../../../node_modules/@tiptap/core/src/utilities/removeDuplicates.ts", "../../../node_modules/@tiptap/core/src/helpers/getChangedRanges.ts", "../../../node_modules/@tiptap/core/src/helpers/getDebugJSON.ts", "../../../node_modules/@tiptap/core/src/helpers/getMarksBetween.ts", "../../../node_modules/@tiptap/core/src/helpers/getNodeAtPosition.ts", "../../../node_modules/@tiptap/core/src/helpers/getPreviousBlockSibling.ts", "../../../node_modules/@tiptap/core/src/helpers/getSchemaTypeByName.ts", "../../../node_modules/@tiptap/core/src/helpers/getSplittedAttributes.ts", "../../../node_modules/@tiptap/core/src/helpers/getTextContentFromNodes.ts", "../../../node_modules/@tiptap/core/src/helpers/isMarkActive.ts", "../../../node_modules/@tiptap/core/src/helpers/isActive.ts", "../../../node_modules/@tiptap/core/src/helpers/isAtEndOfNode.ts", "../../../node_modules/@tiptap/core/src/helpers/isAtStartOfNode.ts", "../../../node_modules/@tiptap/core/src/helpers/isExtensionRulesEnabled.ts", "../../../node_modules/@tiptap/core/src/helpers/isList.ts", "../../../node_modules/@tiptap/core/src/helpers/isNodeEmpty.ts", "../../../node_modules/@tiptap/core/src/helpers/isNodeSelection.ts", "../../../node_modules/@tiptap/core/src/helpers/isNodeViewSelected.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorAddMarkStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorAddNodeMarkStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorAttrStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorCellSelection.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorDocAttrStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorFragment.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorNodeSelection.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorRemoveMarkStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorRemoveNodeMarkStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorReplaceAroundStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorReplaceStep.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorSlice.ts", "../../../node_modules/@tiptap/core/src/helpers/isProseMirrorStepResult.ts", "../../../node_modules/@tiptap/core/src/helpers/MappablePosition.ts", "../../../node_modules/@tiptap/core/src/helpers/posToDOMRect.ts", "../../../node_modules/@tiptap/core/src/helpers/rewriteUnknownContent.ts", "../../../node_modules/@tiptap/core/src/commands/setMark.ts", "../../../node_modules/@tiptap/core/src/commands/setMeta.ts", "../../../node_modules/@tiptap/core/src/commands/setNode.ts", "../../../node_modules/@tiptap/core/src/commands/setNodeSelection.ts", "../../../node_modules/@tiptap/core/src/commands/setTextDirection.ts", "../../../node_modules/@tiptap/core/src/commands/setTextSelection.ts", "../../../node_modules/@tiptap/core/src/commands/sinkListItem.ts", "../../../node_modules/@tiptap/core/src/commands/splitBlock.ts", "../../../node_modules/@tiptap/core/src/commands/splitListItem.ts", "../../../node_modules/@tiptap/core/src/commands/toggleList.ts", "../../../node_modules/@tiptap/core/src/commands/toggleMark.ts", "../../../node_modules/@tiptap/core/src/commands/toggleNode.ts", "../../../node_modules/@tiptap/core/src/commands/toggleWrap.ts", "../../../node_modules/@tiptap/core/src/commands/undoInputRule.ts", "../../../node_modules/@tiptap/core/src/commands/unsetAllMarks.ts", "../../../node_modules/@tiptap/core/src/commands/unsetMark.ts", "../../../node_modules/@tiptap/core/src/commands/unsetTextDirection.ts", "../../../node_modules/@tiptap/core/src/commands/updateAttributes.ts", "../../../node_modules/@tiptap/core/src/decorations/constants.ts", "../../../node_modules/@tiptap/core/src/commands/updateDecorations.ts", "../../../node_modules/@tiptap/core/src/commands/wrapIn.ts", "../../../node_modules/@tiptap/core/src/commands/wrapInList.ts", "../../../node_modules/@tiptap/core/src/commands/index.ts", "../../../node_modules/@tiptap/core/src/decorations/decorationApplyScope.ts", "../../../node_modules/@tiptap/core/src/EventEmitter.ts", "../../../node_modules/@tiptap/core/src/utilities/isDev.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/decorationsToPMDecorations.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/buildDecorationSet.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/rangeOwnsPosition.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/filterOutOfRangeDecorations.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/widgetKeyOf.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/findDuplicateWidgetKeys.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/isAttrStep.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/hasResolvableChangedRange.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/getRebuildRanges.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/mapDecorationSet.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/mapDecorations.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/mergeDecorationSets.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/unionWidgetKeys.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/validateDecorationSpec.ts", "../../../node_modules/@tiptap/core/src/decorations/helpers/shouldRecomputeDecoration.ts", "../../../node_modules/@tiptap/core/src/decorations/DecorationManager.ts", "../../../node_modules/@tiptap/core/src/utilities/attrsEqual.ts", "../../../node_modules/@tiptap/core/src/utilities/canInsertNode.ts", "../../../node_modules/@tiptap/core/src/utilities/createStyleTag.ts", "../../../node_modules/@tiptap/core/src/utilities/escapeForRegEx.ts", "../../../node_modules/@tiptap/core/src/utilities/getStyleProperty.ts", "../../../node_modules/@tiptap/core/src/utilities/htmlEntities.ts", "../../../node_modules/@tiptap/core/src/utilities/isFirefox.ts", "../../../node_modules/@tiptap/core/src/utilities/isNumber.ts", "../../../node_modules/@tiptap/core/src/utilities/isPlainObject.ts", "../../../node_modules/@tiptap/core/src/utilities/isString.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/tokenizeAttributes.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/parseAttributes.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/serializeAttributes.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/createAtomBlockMarkdownSpec.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/createBlockMarkdownSpec.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/parseShortcodeAttributes.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/createInlineMarkdownSpec.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/parseIndentedBlocks.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/renderNestedMarkdownContent.ts", "../../../node_modules/@tiptap/core/src/utilities/markdown/index.ts", "../../../node_modules/@tiptap/core/src/utilities/marksEqual.ts", "../../../node_modules/@tiptap/core/src/utilities/mergeDeep.ts", "../../../node_modules/@tiptap/core/src/MarkView.ts", "../../../node_modules/@tiptap/core/src/InputRule.ts", "../../../node_modules/@tiptap/core/src/Extendable.ts", "../../../node_modules/@tiptap/core/src/Mark.ts", "../../../node_modules/@tiptap/core/src/PasteRule.ts", "../../../node_modules/@tiptap/core/src/ExtensionManager.ts", "../../../node_modules/@tiptap/core/src/Extension.ts", "../../../node_modules/@tiptap/core/src/extensions/clipboardTextSerializer.ts", "../../../node_modules/@tiptap/core/src/extensions/commands.ts", "../../../node_modules/@tiptap/core/src/extensions/delete.ts", "../../../node_modules/@tiptap/core/src/extensions/drop.ts", "../../../node_modules/@tiptap/core/src/extensions/editable.ts", "../../../node_modules/@tiptap/core/src/extensions/focusEvents.ts", "../../../node_modules/@tiptap/core/src/extensions/keymap.ts", "../../../node_modules/@tiptap/core/src/extensions/paste.ts", "../../../node_modules/@tiptap/core/src/extensions/tabindex.ts", "../../../node_modules/@tiptap/core/src/extensions/textDirection.ts", "../../../node_modules/@tiptap/core/src/extensions/index.ts", "../../../node_modules/@tiptap/core/src/helpers/warnOnDuplicatedProseMirrorModel.ts", "../../../node_modules/@tiptap/core/src/NodePos.ts", "../../../node_modules/@tiptap/core/src/style.ts", "../../../node_modules/@tiptap/core/src/Editor.ts", "../../../node_modules/@tiptap/core/src/decorations/Decoration.ts", "../../../node_modules/@tiptap/core/src/decorations/createWidgetDecoration.ts", "../../../node_modules/@tiptap/core/src/inputRules/markInputRule.ts", "../../../node_modules/@tiptap/core/src/inputRules/nodeInputRule.ts", "../../../node_modules/@tiptap/core/src/inputRules/textblockTypeInputRule.ts", "../../../node_modules/@tiptap/core/src/inputRules/textInputRule.ts", "../../../node_modules/@tiptap/core/src/inputRules/wrappingInputRule.ts", "../../../node_modules/@tiptap/core/src/jsx-runtime.ts", "../../../node_modules/@tiptap/core/src/lib/ResizableNodeView.ts", "../../../node_modules/@tiptap/core/src/Node.ts", "../../../node_modules/@tiptap/core/src/NodeView.ts", "../../../node_modules/@tiptap/core/src/pasteRules/markPasteRule.ts", "../../../node_modules/@tiptap/core/src/pasteRules/nodePasteRule.ts", "../../../node_modules/@tiptap/core/src/pasteRules/textPasteRule.ts", "../../../node_modules/@tiptap/core/src/Tracker.ts", "../../../node_modules/src/utils.ts", "../../../node_modules/src/equals.ts", "../../../node_modules/src/comparator.ts", "../../../node_modules/src/index.ts", "../../../node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.js", "../../../node_modules/use-sync-external-store/shim/with-selector.js", "../../../node_modules/@tiptap/react/src/Context.tsx", "../../../node_modules/@tiptap/react/src/EditorContent.tsx", "../../../node_modules/@tiptap/react/src/useEditor.ts", "../../../node_modules/@tiptap/react/src/useEditorState.ts", "../../../node_modules/@tiptap/react/src/useReactNodeView.ts", "../../../node_modules/@tiptap/react/src/NodeViewContent.tsx", "../../../node_modules/@tiptap/react/src/NodeViewWrapper.tsx", "../../../node_modules/@tiptap/react/src/ReactMarkViewRenderer.tsx", "../../../node_modules/@tiptap/react/src/ReactRenderer.tsx", "../../../node_modules/@tiptap/react/src/ReactNodeViewRenderer.tsx", "../../../node_modules/@tiptap/react/src/Tiptap.tsx", "../../../node_modules/@tiptap/react/src/index.ts", "../../../node_modules/@tiptap/core/src/jsx-runtime.ts", "../../../node_modules/@tiptap/core/jsx-runtime/index.js", "../../../node_modules/@tiptap/extension-blockquote/src/blockquote.tsx", "../../../node_modules/@tiptap/extension-blockquote/src/index.ts", "../../../node_modules/@tiptap/extension-bold/src/bold.tsx", "../../../node_modules/@tiptap/extension-bold/src/index.ts", "../../../node_modules/@tiptap/extension-code/src/code.ts", "../../../node_modules/@tiptap/extension-code/src/index.ts", "../../../node_modules/@tiptap/extension-code-block/src/code-block.ts", "../../../node_modules/@tiptap/extension-code-block/src/index.ts", "../../../node_modules/@tiptap/extension-document/src/document.ts", "../../../node_modules/@tiptap/extension-document/src/index.ts", "../../../node_modules/@tiptap/extension-hard-break/src/hard-break.ts", "../../../node_modules/@tiptap/extension-hard-break/src/index.ts", "../../../node_modules/@tiptap/extension-heading/src/heading.ts", "../../../node_modules/@tiptap/extension-heading/src/index.ts", "../../../node_modules/@tiptap/extension-horizontal-rule/src/horizontal-rule.ts", "../../../node_modules/@tiptap/extension-horizontal-rule/src/index.ts", "../../../node_modules/@tiptap/extension-italic/src/italic.ts", "../../../node_modules/@tiptap/extension-italic/src/index.ts", "../../../node_modules/linkifyjs/dist/linkify.mjs", "../../../node_modules/@tiptap/extension-link/src/link.ts", "../../../node_modules/@tiptap/extension-link/src/helpers/autolink.ts", "../../../node_modules/@tiptap/extension-link/src/helpers/whitespace.ts", "../../../node_modules/@tiptap/extension-link/src/helpers/clickHandler.ts", "../../../node_modules/@tiptap/extension-link/src/helpers/pasteHandler.ts", "../../../node_modules/@tiptap/extension-link/src/index.ts", "../../../node_modules/@tiptap/extension-list/src/bullet-list/bullet-list.ts", "../../../node_modules/@tiptap/extension-list/src/item/list-item.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/list-keymap.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/index.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/findListItemPos.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/getNextListDepth.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/handleBackspace.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListBefore.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListItemBefore.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/listItemHasSubList.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/handleDelete.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/nextListIsDeeper.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/nextListIsHigher.ts", "../../../node_modules/@tiptap/extension-list/src/keymap/listHelpers/hasListItemAfter.ts", "../../../node_modules/@tiptap/extension-list/src/kit/index.ts", "../../../node_modules/@tiptap/extension-list/src/ordered-list/ordered-list.ts", "../../../node_modules/@tiptap/extension-list/src/ordered-list/utils.ts", "../../../node_modules/@tiptap/extension-list/src/task-item/task-item.ts", "../../../node_modules/@tiptap/extension-list/src/task-list/task-list.ts", "../../../node_modules/@tiptap/extension-paragraph/src/paragraph.ts", "../../../node_modules/@tiptap/extension-paragraph/src/index.ts", "../../../node_modules/@tiptap/extension-strike/src/strike.ts", "../../../node_modules/@tiptap/extension-strike/src/index.ts", "../../../node_modules/@tiptap/extension-text/src/text.ts", "../../../node_modules/@tiptap/extension-text/src/index.ts", "../../../node_modules/@tiptap/extension-underline/src/underline.ts", "../../../node_modules/@tiptap/extension-underline/src/index.ts", "../../../node_modules/prosemirror-dropcursor/dist/index.js", "../../../node_modules/@tiptap/pm/dist/dropcursor/index.js", "../../../node_modules/prosemirror-gapcursor/dist/index.js", "../../../node_modules/@tiptap/pm/dist/gapcursor/index.js", "../../../node_modules/rope-sequence/dist/index.js", "../../../node_modules/prosemirror-history/dist/index.js", "../../../node_modules/@tiptap/pm/dist/history/index.js", "../../../node_modules/@tiptap/extensions/src/character-count/character-count.ts", "../../../node_modules/@tiptap/extensions/src/drop-cursor/drop-cursor.ts", "../../../node_modules/@tiptap/extensions/src/focus/focus.ts", "../../../node_modules/@tiptap/extensions/src/gap-cursor/gap-cursor.ts", "../../../node_modules/@tiptap/extensions/src/placeholder/placeholder.ts", "../../../node_modules/@tiptap/extensions/src/selection/selection.ts", "../../../node_modules/@tiptap/extensions/src/trailing-node/trailing-node.ts", "../../../node_modules/@tiptap/extensions/src/undo-redo/undo-redo.ts", "../../../node_modules/@tiptap/starter-kit/src/starter-kit.ts", "../../../node_modules/@tiptap/starter-kit/src/index.ts", "../../../node_modules/marked/src/defaults.ts", "../../../node_modules/marked/src/rules.ts", "../../../node_modules/marked/src/helpers.ts", "../../../node_modules/marked/src/Tokenizer.ts", "../../../node_modules/marked/src/Lexer.ts", "../../../node_modules/marked/src/Renderer.ts", "../../../node_modules/marked/src/TextRenderer.ts", "../../../node_modules/marked/src/Parser.ts", "../../../node_modules/marked/src/Hooks.ts", "../../../node_modules/marked/src/Instance.ts", "../../../node_modules/marked/src/marked.ts", "../../../node_modules/@tiptap/markdown/src/Extension.ts", "../../../node_modules/@tiptap/markdown/src/MarkdownManager.ts", "../../../node_modules/@tiptap/markdown/src/utils.ts", "../../../node_modules/@tiptap/extension-placeholder/src/index.ts", "../../javascript/utils/clerkErrorCopy.ts", "../../javascript/components/agent_prototype/AgentPrototypeInput.tsx", "../../javascript/components/atoms/DialogDefaultActions.tsx", "../../javascript/components/atoms/DialogDisclaimer.tsx", "../../javascript/utils/constants.ts", "../../javascript/utils/canRequestJudge.ts", "../../javascript/components/agent_prototype/DataCoverageModal.tsx", "../../javascript/components/atoms/BIQInputField.tsx", "../../javascript/api/judgeRequests.ts", "../../javascript/components/molecules/RequestJudgeModal.tsx", "../../javascript/contexts/ClientMatterContext.tsx", "../../javascript/components/agent_prototype/examplePrompts.ts", "../../javascript/components/agent_prototype/AgentPrototypeContext.tsx", "../../javascript/utils/transcriptScrollAnchor.ts", "../../javascript/components/agent_prototype/openFreshClerkTab.ts", "../../javascript/components/agent_prototype/pendingClerkDraft.ts", "../../javascript/components/agent_prototype/planningModePreference.ts", "../../javascript/components/agent_prototype/AgentPrototypeWelcome.tsx", "../../javascript/components/Home.tsx", "../../javascript/api/agentPrototype.ts", "../../javascript/components/agent_prototype/nextSteps.ts", "../../javascript/hooks/useAgentNextSteps.ts", "../../javascript/components/atoms/AnimatedEllipsis.tsx", "../../javascript/components/agent_prototype/AgentPrototypeThinking.tsx", "../../javascript/components/agent_prototype/planCompletion.ts", "../../javascript/components/atoms/BenchAlert.tsx", "../../javascript/components/molecules/MatterCodeAutocomplete.tsx", "../../../node_modules/@lukemorales/query-key-factory/src/internals/assert-schema-keys.ts", "../../../node_modules/@lukemorales/query-key-factory/src/internals/omit-prototype.ts", "../../../node_modules/@lukemorales/query-key-factory/src/create-query-keys.ts", "../../../node_modules/@lukemorales/query-key-factory/src/create-query-key-store.ts", "../../../node_modules/@lukemorales/query-key-factory/src/create-mutation-keys.ts", "../../../node_modules/@lukemorales/query-key-factory/src/merge-query-keys.ts", "../../../node_modules/zod/v4/core/util.js", "../../../node_modules/zod/v4/core/core.js", "../../../node_modules/zod/v4/core/errors.js", "../../../node_modules/zod/v4/core/parse.js", "../../../node_modules/zod/v4/core/regexes.js", "../../../node_modules/zod/v4/core/checks.js", "../../../node_modules/zod/v4/core/doc.js", "../../../node_modules/zod/v4/core/versions.js", "../../../node_modules/zod/v4/core/schemas.js", "../../../node_modules/zod/v4/core/memoizer.js", "../../../node_modules/zod/v4/locales/ar.js", "../../../node_modules/zod/v4/locales/az.js", "../../../node_modules/zod/v4/locales/be.js", "../../../node_modules/zod/v4/locales/bg.js", "../../../node_modules/zod/v4/locales/bn.js", "../../../node_modules/zod/v4/locales/ca.js", "../../../node_modules/zod/v4/locales/ckb.js", "../../../node_modules/zod/v4/locales/cs.js", "../../../node_modules/zod/v4/locales/da.js", "../../../node_modules/zod/v4/locales/de.js", "../../../node_modules/zod/v4/locales/el.js", "../../../node_modules/zod/v4/locales/en.js", "../../../node_modules/zod/v4/locales/eo.js", "../../../node_modules/zod/v4/locales/es.js", "../../../node_modules/zod/v4/locales/fa.js", "../../../node_modules/zod/v4/locales/fi.js", "../../../node_modules/zod/v4/locales/fr.js", "../../../node_modules/zod/v4/locales/fr-CA.js", "../../../node_modules/zod/v4/locales/gu.js", "../../../node_modules/zod/v4/locales/he.js", "../../../node_modules/zod/v4/locales/hi.js", "../../../node_modules/zod/v4/locales/hr.js", "../../../node_modules/zod/v4/locales/hu.js", "../../../node_modules/zod/v4/locales/hy.js", "../../../node_modules/zod/v4/locales/id.js", "../../../node_modules/zod/v4/locales/is.js", "../../../node_modules/zod/v4/locales/it.js", "../../../node_modules/zod/v4/locales/ja.js", "../../../node_modules/zod/v4/locales/ka.js", "../../../node_modules/zod/v4/locales/km.js", "../../../node_modules/zod/v4/locales/kh.js", "../../../node_modules/zod/v4/locales/kn.js", "../../../node_modules/zod/v4/locales/ko.js", "../../../node_modules/zod/v4/locales/lt.js", "../../../node_modules/zod/v4/locales/mk.js", "../../../node_modules/zod/v4/locales/ms.js", "../../../node_modules/zod/v4/locales/ne.js", "../../../node_modules/zod/v4/locales/nl.js", "../../../node_modules/zod/v4/locales/nn.js", "../../../node_modules/zod/v4/locales/no.js", "../../../node_modules/zod/v4/locales/ota.js", "../../../node_modules/zod/v4/locales/ps.js", "../../../node_modules/zod/v4/locales/pl.js", "../../../node_modules/zod/v4/locales/pt.js", "../../../node_modules/zod/v4/locales/pt-BR.js", "../../../node_modules/zod/v4/locales/ro.js", "../../../node_modules/zod/v4/locales/ru.js", "../../../node_modules/zod/v4/locales/sk.js", "../../../node_modules/zod/v4/locales/sl.js", "../../../node_modules/zod/v4/locales/sv.js", "../../../node_modules/zod/v4/locales/ta.js", "../../../node_modules/zod/v4/locales/tg.js", "../../../node_modules/zod/v4/locales/th.js", "../../../node_modules/zod/v4/locales/tk.js", "../../../node_modules/zod/v4/locales/tr.js", "../../../node_modules/zod/v4/locales/uk.js", "../../../node_modules/zod/v4/locales/ua.js", "../../../node_modules/zod/v4/locales/ur.js", "../../../node_modules/zod/v4/locales/uz.js", "../../../node_modules/zod/v4/locales/vi.js", "../../../node_modules/zod/v4/locales/zh-CN.js", "../../../node_modules/zod/v4/locales/zh-TW.js", "../../../node_modules/zod/v4/locales/yo.js", "../../../node_modules/zod/v4/locales/index.js", "../../../node_modules/zod/v4/core/registries.js", "../../../node_modules/zod/v4/core/compile.js", "../../../node_modules/zod/v4/core/api.js", "../../../node_modules/zod/v4/core/to-json-schema.js", "../../../node_modules/zod/v4/core/json-schema-processors.js", "../../../node_modules/zod/v4/core/json-schema-generator.js", "../../../node_modules/zod/v4/core/json-schema.js", "../../../node_modules/zod/v4/core/index.js", "../../../node_modules/zod/v4/classic/checks.js", "../../../node_modules/zod/v4/classic/errors.js", "../../../node_modules/zod/v4/classic/parse.js", "../../../node_modules/zod/v4/classic/schemas.js", "../../../node_modules/zod/v4/classic/compat.js", "../../../node_modules/zod/v4/classic/iso.js", "../../../node_modules/zod/v4/classic/from-json-schema.js", "../../../node_modules/zod/v4/core/visit.js", "../../../node_modules/zod/v4/classic/deep-partial.js", "../../../node_modules/zod/v4/classic/in-out.js", "../../../node_modules/zod/v4/classic/coerce.js", "../../../node_modules/zod/v4/classic/external.js", "../../../node_modules/zod/index.js", "../../javascript/api/queries/transcriptScrollTargets.types.ts", "../../javascript/api/queries/transcripts.types.ts", "../../javascript/api/queries/transcripts.ts", "../../javascript/components/types/queryImprovement.ts", "../../javascript/api/queries/queryImprovement.types.ts", "../../javascript/api/queries/queryImprovement.ts", "../../javascript/api/queries/benchOpinions.types.ts", "../../javascript/api/queries/benchOpinions.ts", "../../javascript/api/queries/judges.types.ts", "../../javascript/api/queries/judges.ts", "../../javascript/api/queries/folders.types.ts", "../../javascript/api/queries/folders.ts", "../../javascript/api/queries/index.ts", "../../javascript/api/queries/caseHistory.ts", "../../javascript/dev/sampleOverviews.ts", "../../javascript/dev/injectOverviews.ts", "../../javascript/api/documents.ts", "../../javascript/api/folders.ts", "../../javascript/hooks/useSaveToFolder.ts", "../../javascript/components/theme/mixins/noSelectedRowFillSx.ts", "../../../node_modules/@seznam/compose-react-refs/composeRefs.ts", "../../javascript/components/atoms/GhostTextField.tsx", "../../javascript/components/molecules/CreateFolderModal.tsx", "../../javascript/components/molecules/addToFoldersAction.ts", "../../javascript/components/molecules/SaveToFolderPopover.tsx", "../../../node_modules/framer-motion/dist/es/context/LayoutGroupContext.mjs", "../../../node_modules/framer-motion/src/utils/use-constant.ts", "../../../node_modules/framer-motion/src/utils/is-browser.ts", "../../../node_modules/framer-motion/src/utils/use-isomorphic-effect.ts", "../../../node_modules/framer-motion/src/context/PresenceContext.ts", "../../../node_modules/motion-utils/src/array.ts", "../../../node_modules/motion-utils/src/clamp.ts", "../../../node_modules/motion-utils/src/errors.ts", "../../../node_modules/motion-utils/src/global-config.ts", "../../../node_modules/motion-utils/src/is-numerical-string.ts", "../../../node_modules/motion-utils/src/is-object.ts", "../../../node_modules/motion-utils/src/is-zero-value-string.ts", "../../../node_modules/motion-utils/src/memo.ts", "../../../node_modules/motion-utils/src/noop.ts", "../../../node_modules/motion-utils/src/pipe.ts", "../../../node_modules/motion-utils/src/progress.ts", "../../../node_modules/motion-utils/src/subscription-manager.ts", "../../../node_modules/motion-utils/src/time-conversion.ts", "../../../node_modules/motion-utils/src/velocity-per-second.ts", "../../../node_modules/motion-utils/src/easing/cubic-bezier.ts", "../../../node_modules/motion-utils/src/easing/modifiers/mirror.ts", "../../../node_modules/motion-utils/src/easing/modifiers/reverse.ts", "../../../node_modules/motion-utils/src/easing/back.ts", "../../../node_modules/motion-utils/src/easing/anticipate.ts", "../../../node_modules/motion-utils/src/easing/circ.ts", "../../../node_modules/motion-utils/src/easing/ease.ts", "../../../node_modules/motion-utils/src/easing/utils/is-easing-array.ts", "../../../node_modules/motion-utils/src/easing/utils/is-bezier-definition.ts", "../../../node_modules/motion-utils/src/easing/utils/map.ts", "../../../node_modules/motion-utils/dist/es/index.mjs", "../../../node_modules/motion-dom/src/frameloop/order.ts", "../../../node_modules/motion-dom/src/stats/buffer.ts", "../../../node_modules/motion-dom/src/frameloop/render-step.ts", "../../../node_modules/motion-dom/src/frameloop/batcher.ts", "../../../node_modules/motion-dom/src/frameloop/frame.ts", "../../../node_modules/motion-dom/src/frameloop/sync-time.ts", "../../../node_modules/motion-dom/src/stats/animation-count.ts", "../../../node_modules/motion-dom/src/animation/utils/is-css-variable.ts", "../../../node_modules/motion-dom/src/value/types/numbers/index.ts", "../../../node_modules/motion-dom/src/value/types/utils/sanitize.ts", "../../../node_modules/motion-dom/src/value/types/utils/float-regex.ts", "../../../node_modules/motion-dom/src/value/types/utils/is-nullish.ts", "../../../node_modules/motion-dom/src/value/types/utils/single-color-regex.ts", "../../../node_modules/motion-dom/src/value/types/color/utils.ts", "../../../node_modules/motion-dom/src/value/types/color/rgba.ts", "../../../node_modules/motion-dom/src/value/types/color/hex.ts", "../../../node_modules/motion-dom/src/value/types/numbers/units.ts", "../../../node_modules/motion-dom/src/value/types/color/hsla.ts", "../../../node_modules/motion-dom/src/value/types/color/index.ts", "../../../node_modules/motion-dom/src/value/types/utils/color-regex.ts", "../../../node_modules/motion-dom/src/value/types/complex/index.ts", "../../../node_modules/motion-dom/src/value/types/color/hsla-to-rgba.ts", "../../../node_modules/motion-dom/src/utils/mix/immediate.ts", "../../../node_modules/motion-dom/src/utils/mix/number.ts", "../../../node_modules/motion-dom/src/utils/mix/color.ts", "../../../node_modules/motion-dom/src/utils/mix/visibility.ts", "../../../node_modules/motion-dom/src/utils/mix/complex.ts", "../../../node_modules/motion-dom/src/utils/mix/index.ts", "../../../node_modules/motion-dom/src/animation/drivers/frame.ts", "../../../node_modules/motion-dom/src/animation/waapi/utils/linear.ts", "../../../node_modules/motion-dom/src/animation/generators/utils/calc-duration.ts", "../../../node_modules/motion-dom/src/animation/generators/utils/create-generator-easing.ts", "../../../node_modules/motion-dom/src/animation/generators/spring.ts", "../../../node_modules/motion-dom/src/animation/generators/utils/velocity.ts", "../../../node_modules/motion-dom/src/animation/generators/inertia.ts", "../../../node_modules/motion-dom/src/utils/interpolate.ts", "../../../node_modules/motion-dom/src/animation/keyframes/offsets/fill.ts", "../../../node_modules/motion-dom/src/animation/keyframes/offsets/default.ts", "../../../node_modules/motion-dom/src/animation/keyframes/offsets/time.ts", "../../../node_modules/motion-dom/src/animation/generators/keyframes.ts", "../../../node_modules/motion-dom/src/animation/keyframes/get-final.ts", "../../../node_modules/motion-dom/src/animation/utils/replace-transition-type.ts", "../../../node_modules/motion-dom/src/animation/utils/WithPromise.ts", "../../../node_modules/motion-dom/src/animation/JSAnimation.ts", "../../../node_modules/motion-dom/src/animation/keyframes/utils/fill-wildcards.ts", "../../../node_modules/motion-dom/src/render/dom/parse-transform.ts", "../../../node_modules/motion-dom/src/render/utils/keys-transform.ts", "../../../node_modules/motion-dom/src/animation/keyframes/utils/unit-conversion.ts", "../../../node_modules/motion-dom/src/animation/keyframes/KeyframesResolver.ts", "../../../node_modules/motion-dom/src/render/dom/is-css-var.ts", "../../../node_modules/motion-dom/src/render/dom/style-set.ts", "../../../node_modules/motion-dom/src/utils/supports/flags.ts", "../../../node_modules/motion-dom/src/utils/supports/memo.ts", "../../../node_modules/motion-dom/src/utils/supports/scroll-timeline.ts", "../../../node_modules/motion-dom/src/utils/supports/linear-easing.ts", "../../../node_modules/motion-dom/src/animation/waapi/easing/cubic-bezier.ts", "../../../node_modules/motion-dom/src/animation/waapi/easing/supported.ts", "../../../node_modules/motion-dom/src/animation/waapi/easing/map-easing.ts", "../../../node_modules/motion-dom/src/animation/waapi/start-waapi-animation.ts", "../../../node_modules/motion-dom/src/animation/generators/utils/is-generator.ts", "../../../node_modules/motion-dom/src/animation/waapi/utils/apply-generator.ts", "../../../node_modules/motion-dom/src/animation/NativeAnimation.ts", "../../../node_modules/motion-dom/src/animation/waapi/utils/unsupported-easing.ts", "../../../node_modules/motion-dom/src/animation/NativeAnimationExtended.ts", "../../../node_modules/motion-dom/src/animation/utils/is-animatable.ts", "../../../node_modules/motion-dom/src/animation/utils/can-animate.ts", "../../../node_modules/motion-dom/src/animation/utils/make-animation-instant.ts", "../../../node_modules/motion-dom/src/animation/waapi/utils/accelerated-values.ts", "../../../node_modules/motion-dom/src/animation/waapi/utils/is-browser-color.ts", "../../../node_modules/motion-dom/src/animation/waapi/supports/waapi.ts", "../../../node_modules/motion-dom/src/animation/AsyncMotionValueAnimation.ts", "../../../node_modules/motion-dom/src/animation/utils/calc-child-stagger.ts", "../../../node_modules/motion-dom/src/animation/utils/css-variables-conversion.ts", "../../../node_modules/motion-dom/src/animation/utils/default-transitions.ts", "../../../node_modules/motion-dom/src/animation/utils/resolve-transition.ts", "../../../node_modules/motion-dom/src/animation/utils/get-value-transition.ts", "../../../node_modules/motion-dom/src/animation/utils/is-transition-defined.ts", "../../../node_modules/motion-dom/src/animation/interfaces/motion-value.ts", "../../../node_modules/motion-dom/src/render/utils/resolve-variants.ts", "../../../node_modules/motion-dom/src/render/utils/resolve-dynamic-variants.ts", "../../../node_modules/motion-dom/src/render/utils/keys-position.ts", "../../../node_modules/motion-dom/src/value/index.ts", "../../../node_modules/motion-dom/src/render/utils/is-keyframes-target.ts", "../../../node_modules/motion-dom/src/render/utils/setters.ts", "../../../node_modules/motion-dom/src/value/utils/is-motion-value.ts", "../../../node_modules/motion-dom/src/value/will-change/is.ts", "../../../node_modules/motion-dom/src/value/will-change/add-will-change.ts", "../../../node_modules/motion-dom/src/render/dom/utils/camel-to-dash.ts", "../../../node_modules/motion-dom/src/animation/optimized-appear/data-id.ts", "../../../node_modules/motion-dom/src/animation/optimized-appear/get-appear-id.ts", "../../../node_modules/motion-dom/src/animation/interfaces/visual-element-target.ts", "../../../node_modules/motion-dom/src/animation/interfaces/visual-element-variant.ts", "../../../node_modules/motion-dom/src/animation/interfaces/visual-element.ts", "../../../node_modules/motion-dom/src/value/types/auto.ts", "../../../node_modules/motion-dom/src/value/types/test.ts", "../../../node_modules/motion-dom/src/value/types/dimensions.ts", "../../../node_modules/motion-dom/src/animation/keyframes/utils/is-none.ts", "../../../node_modules/motion-dom/src/value/types/complex/filter.ts", "../../../node_modules/motion-dom/src/value/types/complex/mask.ts", "../../../node_modules/motion-dom/src/value/types/int.ts", "../../../node_modules/motion-dom/src/value/types/maps/transform.ts", "../../../node_modules/motion-dom/src/value/types/maps/number.ts", "../../../node_modules/motion-dom/src/value/types/maps/defaults.ts", "../../../node_modules/motion-dom/src/value/types/utils/animatable-none.ts", "../../../node_modules/motion-dom/src/animation/keyframes/utils/make-none-animatable.ts", "../../../node_modules/motion-dom/src/animation/keyframes/DOMKeyframesResolver.ts", "../../../node_modules/motion-dom/src/utils/resolve-elements.ts", "../../../node_modules/motion-dom/src/value/types/utils/get-as-type.ts", "../../../node_modules/motion-dom/src/utils/is-html-element.ts", "../../../node_modules/motion-dom/src/frameloop/microtask.ts", "../../../node_modules/motion-dom/src/gestures/drag/state/is-active.ts", "../../../node_modules/motion-dom/src/gestures/drag/state/set-active.ts", "../../../node_modules/motion-dom/src/gestures/utils/setup.ts", "../../../node_modules/motion-dom/src/gestures/hover.ts", "../../../node_modules/motion-dom/src/gestures/utils/is-node-or-child.ts", "../../../node_modules/motion-dom/src/gestures/utils/is-primary-pointer.ts", "../../../node_modules/motion-dom/src/gestures/press/utils/is-keyboard-accessible.ts", "../../../node_modules/motion-dom/src/gestures/press/utils/state.ts", "../../../node_modules/motion-dom/src/gestures/press/utils/keyboard.ts", "../../../node_modules/motion-dom/src/gestures/press/index.ts", "../../../node_modules/motion-dom/src/utils/is-svg-element.ts", "../../../node_modules/motion-dom/src/resize/handle-element.ts", "../../../node_modules/motion-dom/src/resize/handle-window.ts", "../../../node_modules/motion-dom/src/resize/index.ts", "../../../node_modules/motion-dom/src/utils/is-svg-svg-element.ts", "../../../node_modules/motion-dom/src/value/types/utils/find.ts", "../../../node_modules/motion-dom/src/projection/geometry/models.ts", "../../../node_modules/motion-dom/src/render/store.ts", "../../../node_modules/motion-dom/src/render/utils/is-animation-controls.ts", "../../../node_modules/motion-dom/src/render/utils/is-variant-label.ts", "../../../node_modules/motion-dom/src/render/utils/variant-props.ts", "../../../node_modules/motion-dom/src/render/utils/is-controlling-variants.ts", "../../../node_modules/motion-dom/src/render/utils/motion-values.ts", "../../../node_modules/motion-dom/src/render/utils/reduced-motion/state.ts", "../../../node_modules/motion-dom/src/render/utils/reduced-motion/index.ts", "../../../node_modules/motion-dom/src/render/VisualElement.ts", "../../../node_modules/motion-dom/src/render/dom/DOMVisualElement.ts", "../../../node_modules/motion-dom/src/render/Feature.ts", "../../../node_modules/motion-dom/src/projection/geometry/conversion.ts", "../../../node_modules/motion-dom/src/projection/utils/has-transform.ts", "../../../node_modules/motion-dom/src/projection/geometry/delta-apply.ts", "../../../node_modules/motion-dom/src/projection/utils/measure.ts", "../../../node_modules/motion-dom/src/render/html/utils/build-transform.ts", "../../../node_modules/motion-dom/src/render/html/utils/build-styles.ts", "../../../node_modules/motion-dom/src/render/html/utils/render.ts", "../../../node_modules/motion-dom/src/projection/styles/scale-border-radius.ts", "../../../node_modules/motion-dom/src/projection/styles/scale-box-shadow.ts", "../../../node_modules/motion-dom/src/projection/styles/scale-correction.ts", "../../../node_modules/motion-dom/src/render/utils/is-forced-motion-value.ts", "../../../node_modules/motion-dom/src/render/html/utils/scrape-motion-values.ts", "../../../node_modules/motion-dom/src/render/html/HTMLVisualElement.ts", "../../../node_modules/motion-dom/src/render/svg/utils/path.ts", "../../../node_modules/motion-dom/src/render/svg/utils/build-attrs.ts", "../../../node_modules/motion-dom/src/render/svg/utils/camel-case-attrs.ts", "../../../node_modules/motion-dom/src/render/svg/utils/is-svg-tag.ts", "../../../node_modules/motion-dom/src/render/svg/utils/render.ts", "../../../node_modules/motion-dom/src/render/svg/utils/scrape-motion-values.ts", "../../../node_modules/motion-dom/src/render/svg/SVGVisualElement.ts", "../../../node_modules/motion-dom/src/render/utils/get-variant-context.ts", "../../../node_modules/motion-dom/src/render/utils/shallow-compare.ts", "../../../node_modules/motion-dom/src/render/utils/animation-state.ts", "../../../node_modules/motion-dom/src/projection/geometry/copy.ts", "../../../node_modules/motion-dom/src/projection/geometry/delta-calc.ts", "../../../node_modules/motion-dom/src/projection/geometry/delta-remove.ts", "../../../node_modules/motion-dom/src/projection/geometry/utils.ts", "../../../node_modules/motion-dom/src/projection/utils/each-axis.ts", "../../../node_modules/motion-dom/src/projection/styles/transform.ts", "../../../node_modules/motion-dom/src/projection/animation/mix-values.ts", "../../../node_modules/motion-dom/src/animation/animate/single-value.ts", "../../../node_modules/motion-dom/src/events/add-dom-event.ts", "../../../node_modules/motion-dom/src/projection/utils/compare-by-depth.ts", "../../../node_modules/motion-dom/src/projection/utils/flat-tree.ts", "../../../node_modules/motion-dom/src/utils/delay.ts", "../../../node_modules/motion-dom/src/value/utils/resolve-motion-value.ts", "../../../node_modules/motion-dom/src/projection/shared/stack.ts", "../../../node_modules/motion-dom/src/projection/node/state.ts", "../../../node_modules/motion-dom/src/projection/node/create-projection-node.ts", "../../../node_modules/motion-dom/src/projection/node/DocumentProjectionNode.ts", "../../../node_modules/motion-dom/src/projection/node/HTMLProjectionNode.ts", "../../../node_modules/motion-dom/dist/es/index.mjs", "../../../node_modules/framer-motion/src/context/MotionConfigContext.tsx", "../../../node_modules/framer-motion/src/utils/use-composed-ref.ts", "../../../node_modules/framer-motion/src/components/AnimatePresence/PopChild.tsx", "../../../node_modules/framer-motion/src/components/AnimatePresence/PresenceChild.tsx", "../../../node_modules/framer-motion/src/components/AnimatePresence/use-presence.ts", "../../../node_modules/framer-motion/src/components/AnimatePresence/utils.ts", "../../../node_modules/framer-motion/src/components/AnimatePresence/index.tsx", "../../../node_modules/framer-motion/src/context/LazyContext.ts", "../../../node_modules/framer-motion/src/motion/features/definitions.ts", "../../../node_modules/framer-motion/src/motion/features/load-features.ts", "../../../node_modules/framer-motion/src/motion/utils/valid-prop.ts", "../../../node_modules/framer-motion/src/render/dom/utils/filter-props.ts", "../../../node_modules/framer-motion/src/components/MotionConfig/index.tsx", "../../../node_modules/framer-motion/src/context/MotionContext/index.ts", "../../../node_modules/framer-motion/src/context/MotionContext/utils.ts", "../../../node_modules/framer-motion/src/context/MotionContext/create.ts", "../../../node_modules/framer-motion/src/render/html/utils/create-render-state.ts", "../../../node_modules/framer-motion/src/render/html/use-props.ts", "../../../node_modules/framer-motion/src/render/svg/utils/create-render-state.ts", "../../../node_modules/framer-motion/src/render/svg/use-props.ts", "../../../node_modules/framer-motion/src/render/svg/lowercase-elements.ts", "../../../node_modules/framer-motion/src/render/dom/utils/is-svg-component.ts", "../../../node_modules/framer-motion/src/render/dom/use-render.ts", "../../../node_modules/framer-motion/src/motion/utils/use-visual-state.ts", "../../../node_modules/framer-motion/src/render/html/use-html-visual-state.ts", "../../../node_modules/framer-motion/src/render/svg/use-svg-visual-state.ts", "../../../node_modules/framer-motion/src/motion/utils/symbol.ts", "../../../node_modules/framer-motion/src/motion/utils/use-motion-ref.ts", "../../../node_modules/framer-motion/src/utils/is-ref-object.ts", "../../../node_modules/framer-motion/src/motion/utils/use-visual-element.ts", "../../../node_modules/framer-motion/src/motion/index.tsx", "../../../node_modules/framer-motion/src/render/components/create-proxy.ts", "../../../node_modules/framer-motion/src/render/dom/create-visual-element.ts", "../../../node_modules/framer-motion/src/motion/features/animation/index.ts", "../../../node_modules/framer-motion/src/motion/features/animation/exit.ts", "../../../node_modules/framer-motion/src/motion/features/animations.ts", "../../../node_modules/framer-motion/src/events/event-info.ts", "../../../node_modules/framer-motion/src/events/add-pointer-event.ts", "../../../node_modules/framer-motion/src/utils/get-context-window.ts", "../../../node_modules/framer-motion/src/utils/distance.ts", "../../../node_modules/framer-motion/src/gestures/pan/PanSession.ts", "../../../node_modules/framer-motion/src/gestures/drag/utils/constraints.ts", "../../../node_modules/framer-motion/src/gestures/drag/VisualElementDragControls.ts", "../../../node_modules/framer-motion/src/gestures/drag/index.ts", "../../../node_modules/framer-motion/src/gestures/pan/index.ts", "../../../node_modules/framer-motion/src/motion/features/layout/MeasureLayout.tsx", "../../../node_modules/framer-motion/src/motion/features/drag.ts", "../../../node_modules/framer-motion/src/gestures/hover.ts", "../../../node_modules/framer-motion/src/gestures/focus.ts", "../../../node_modules/framer-motion/src/gestures/press.ts", "../../../node_modules/framer-motion/src/motion/features/viewport/observers.ts", "../../../node_modules/framer-motion/src/motion/features/viewport/index.ts", "../../../node_modules/framer-motion/src/motion/features/gestures.ts", "../../../node_modules/framer-motion/src/motion/features/layout.ts", "../../../node_modules/framer-motion/src/render/components/motion/feature-bundle.ts", "../../../node_modules/framer-motion/src/render/components/motion/proxy.ts", "../../../node_modules/framer-motion/src/utils/reduced-motion/use-reduced-motion.ts", "../../../node_modules/framer-motion/dist/es/index.mjs", "../../../node_modules/motion/dist/es/react.mjs", "../../javascript/components/theme/tokens/motion.ts", "../../javascript/components/atoms/FolderChipRow.tsx", "../../javascript/utils/clerkPushNotifications.ts", "../../javascript/api/queries/agentPrototype.ts", "../../javascript/hooks/useAgentPrototypeStream.ts", "../../javascript/utils/clerkAnalytics.ts", "../../javascript/utils/clerkClarifyingQuestion.ts", "../../javascript/contexts/CreditAgentSpeedBumpContext.tsx", "../../javascript/hooks/useAgentPrototypeSession.ts", "../../javascript/components/agent_prototype/AgentPrototypePlanningCard.tsx", "../../javascript/components/molecules/OverflowTooltip.tsx", "../../javascript/components/molecules/ClarifyingQuestionCard.tsx", "../../javascript/components/agent_prototype/AgentQuestionControls.tsx", "../../javascript/components/agent_prototype/AgentPrototypePlanningQuestion.tsx", "../../javascript/components/AppShell/useSidepanelResize.ts", "../../javascript/components/AppShell/useAutoFullscreenOnNarrow.ts", "../../javascript/components/AppShell/EffectiveRailWidthContext.tsx", "../../javascript/components/SideNav/resolveSidenavLayout.ts", "../../javascript/components/SideNav/useExpandableSideNavOverlay.ts", "../../javascript/components/SideNav/useSidenavLayout.ts", "../../javascript/components/AppShell/AppShell.tsx", "../../javascript/components/AppShell/useReaderPanelState.ts", "../../javascript/components/AppShell/index.ts", "../../javascript/components/agent_prototype/ClerkDisabledBanner.tsx", "../../javascript/components/agent_prototype/ClerkDisabledBannerSlot.tsx", "../../javascript/components/agent_prototype/AgentPrototypeClarifyingQuestion.tsx", "../../javascript/components/agent_prototype/docket_connect/DocketConnectApprovalDialog.tsx", "../../javascript/components/agent_prototype/docket_connect/DocketConnectRequestSurface.tsx", "../../javascript/components/atoms/SafeSpan.tsx", "../../javascript/utils/formatTranscriptDisplayTitle.ts", "../../javascript/hooks/useTranscriptDisplayTitle.ts", "../../../node_modules/lodash/lodash.js", "../../javascript/utils/load_intercom.js", "../../javascript/contexts/TimeEntryContext.tsx", "../../javascript/components/molecules/TimeTrackingButton.tsx", "../../javascript/utils/needsTimeTracker.ts", "../../javascript/components/AppShell/TopBarRight.tsx", "../../javascript/components/Reader/TranscriptHeaderLeft.tsx", "../../javascript/components/Reader/TranscriptHeaderRight.tsx", "../../javascript/components/layouts/ReaderLayout.tsx", "../../javascript/components/Reader/ReaderTopBar.tsx", "../../javascript/components/atoms/BIQTabs.tsx", "../../javascript/components/Reader/ReaderTabs.tsx", "../../javascript/components/Reader/transcript_body/StickySpeakerLabel.tsx", "../../javascript/components/Reader/SectionHeader.tsx", "../../javascript/components/Reader/SearchResultsBar.tsx", "../../javascript/components/Reader/SearchWithinTranscript.tsx", "../../javascript/utils/decorateContentWithHighlights.ts", "../../javascript/components/atoms/AISummaryUnavailable.tsx", "../../javascript/components/molecules/case_history_tab/CaseHistoryEntry.tsx", "../../javascript/utils/convertDateToMMDDYYYY.ts", "../../javascript/components/molecules/case_history_tab/CaseHistoryTab.tsx", "../../javascript/api/emailTranscript.ts", "../../javascript/components/molecules/email_transcript_modal/CommaSeparatedEmailsWithTagsInputField.tsx", "../../javascript/components/atoms/SmartQuotesTextField.tsx", "../../../node_modules/validator/lib/util/assertString.js", "../../../node_modules/validator/lib/toDate.js", "../../../node_modules/validator/lib/util/nullUndefinedCheck.js", "../../../node_modules/validator/lib/alpha.js", "../../../node_modules/validator/lib/isFloat.js", "../../../node_modules/validator/lib/toFloat.js", "../../../node_modules/validator/lib/toInt.js", "../../../node_modules/validator/lib/toBoolean.js", "../../../node_modules/validator/lib/equals.js", "../../../node_modules/validator/lib/util/toString.js", "../../../node_modules/validator/lib/util/merge.js", "../../../node_modules/validator/lib/contains.js", "../../../node_modules/validator/lib/matches.js", "../../../node_modules/validator/lib/util/checkHost.js", "../../../node_modules/validator/lib/isByteLength.js", "../../../node_modules/validator/lib/isFQDN.js", "../../../node_modules/validator/lib/isIP.js", "../../../node_modules/validator/lib/isEmail.js", "../../../node_modules/validator/lib/util/includesString.js", "../../../node_modules/validator/lib/isURL.js", "../../../node_modules/validator/lib/isMACAddress.js", "../../../node_modules/validator/lib/isIPRange.js", "../../../node_modules/validator/lib/isDate.js", "../../../node_modules/validator/lib/isTime.js", "../../../node_modules/validator/lib/util/includesArray.js", "../../../node_modules/validator/lib/isBoolean.js", "../../../node_modules/validator/lib/isLocale.js", "../../../node_modules/validator/lib/isAbaRouting.js", "../../../node_modules/validator/lib/isAlpha.js", "../../../node_modules/validator/lib/isAlphanumeric.js", "../../../node_modules/validator/lib/isNumeric.js", "../../../node_modules/validator/lib/isPassportNumber.js", "../../../node_modules/validator/lib/isInt.js", "../../../node_modules/validator/lib/isPort.js", "../../../node_modules/validator/lib/isLowercase.js", "../../../node_modules/validator/lib/isUppercase.js", "../../../node_modules/validator/lib/isIMEI.js", "../../../node_modules/validator/lib/isAscii.js", "../../../node_modules/validator/lib/isFullWidth.js", "../../../node_modules/validator/lib/isHalfWidth.js", "../../../node_modules/validator/lib/isVariableWidth.js", "../../../node_modules/validator/lib/isMultibyte.js", "../../../node_modules/validator/lib/util/multilineRegex.js", "../../../node_modules/validator/lib/isSemVer.js", "../../../node_modules/validator/lib/isSurrogatePair.js", "../../../node_modules/validator/lib/isDecimal.js", "../../../node_modules/validator/lib/isHexadecimal.js", "../../../node_modules/validator/lib/isOctal.js", "../../../node_modules/validator/lib/isDivisibleBy.js", "../../../node_modules/validator/lib/isHexColor.js", "../../../node_modules/validator/lib/isRgbColor.js", "../../../node_modules/validator/lib/isHSL.js", "../../../node_modules/validator/lib/isISRC.js", "../../../node_modules/validator/lib/isIBAN.js", "../../../node_modules/validator/lib/isISO31661Alpha2.js", "../../../node_modules/validator/lib/isBIC.js", "../../../node_modules/validator/lib/isMD5.js", "../../../node_modules/validator/lib/isHash.js", "../../../node_modules/validator/lib/isBase64.js", "../../../node_modules/validator/lib/isJWT.js", "../../../node_modules/validator/lib/isJSON.js", "../../../node_modules/validator/lib/isEmpty.js", "../../../node_modules/validator/lib/isLength.js", "../../../node_modules/validator/lib/isULID.js", "../../../node_modules/validator/lib/isUUID.js", "../../../node_modules/validator/lib/isMongoId.js", "../../../node_modules/validator/lib/isAfter.js", "../../../node_modules/validator/lib/isBefore.js", "../../../node_modules/validator/lib/isIn.js", "../../../node_modules/validator/lib/isLuhnNumber.js", "../../../node_modules/validator/lib/isCreditCard.js", "../../../node_modules/validator/lib/isIdentityCard.js", "../../../node_modules/validator/lib/isEAN.js", "../../../node_modules/validator/lib/isISIN.js", "../../../node_modules/validator/lib/isISBN.js", "../../../node_modules/validator/lib/isISSN.js", "../../../node_modules/validator/lib/util/algorithms.js", "../../../node_modules/validator/lib/isTaxID.js", "../../../node_modules/validator/lib/isMobilePhone.js", "../../../node_modules/validator/lib/isEthereumAddress.js", "../../../node_modules/validator/lib/isCurrency.js", "../../../node_modules/validator/lib/isBtcAddress.js", "../../../node_modules/validator/lib/isISO6346.js", "../../../node_modules/validator/lib/isISO6391.js", "../../../node_modules/validator/lib/isISO8601.js", "../../../node_modules/validator/lib/isRFC3339.js", "../../../node_modules/validator/lib/isISO15924.js", "../../../node_modules/validator/lib/isISO31661Alpha3.js", "../../../node_modules/validator/lib/isISO31661Numeric.js", "../../../node_modules/validator/lib/isISO4217.js", "../../../node_modules/validator/lib/isBase32.js", "../../../node_modules/validator/lib/isBase58.js", "../../../node_modules/validator/lib/isDataURI.js", "../../../node_modules/validator/lib/isMagnetURI.js", "../../../node_modules/validator/lib/rtrim.js", "../../../node_modules/validator/lib/ltrim.js", "../../../node_modules/validator/lib/trim.js", "../../../node_modules/validator/lib/isMailtoURI.js", "../../../node_modules/validator/lib/isMimeType.js", "../../../node_modules/validator/lib/isLatLong.js", "../../../node_modules/validator/lib/isPostalCode.js", "../../../node_modules/validator/lib/escape.js", "../../../node_modules/validator/lib/unescape.js", "../../../node_modules/validator/lib/blacklist.js", "../../../node_modules/validator/lib/stripLow.js", "../../../node_modules/validator/lib/whitelist.js", "../../../node_modules/validator/lib/isWhitelisted.js", "../../../node_modules/validator/lib/normalizeEmail.js", "../../../node_modules/validator/lib/isSlug.js", "../../../node_modules/validator/lib/isLicensePlate.js", "../../../node_modules/validator/lib/isStrongPassword.js", "../../../node_modules/validator/lib/isVAT.js", "../../../node_modules/validator/index.js", "../../javascript/components/molecules/email_transcript_modal/EmailTranscriptModal.tsx", "../../javascript/components/molecules/BenchOpinionsModal.tsx", "../../javascript/components/atoms/StarToggle.tsx", "../../javascript/components/molecules/FloatingTimeTracker.tsx", "../../javascript/components/Reader/transcript_body/helpers.ts", "../../javascript/utils/enrichedTranscriptAnchors.ts", "../../javascript/components/Reader/transcript_body/folderHighlighting.ts", "../../javascript/components/Reader/transcript_body/Annotation.tsx", "../../javascript/components/Reader/transcript_body/ExaminationSection.tsx", "../../javascript/components/Reader/transcript_body/MetadataRow.tsx", "../../javascript/components/Reader/transcript_body/HeadingCaption.tsx", "../../javascript/components/Reader/transcript_body/PageMarker.tsx", "../../javascript/components/Reader/transcript_body/StickyHeaderBand.tsx", "../../javascript/components/Reader/transcript_body/Turn.tsx", "../../javascript/components/Reader/transcript_body/TranscriptBody.tsx", "../../javascript/components/Reader/transcript_body/index.ts", "../../javascript/components/molecules/DocumentReader.tsx", "../../javascript/hooks/useReaderScrollTracking.ts", "../../javascript/utils/getSelectionOffsets.ts", "../../javascript/utils/benchOpinionAiNotice.ts", "../../javascript/utils/highlightRangeUtils.ts", "../../javascript/hooks/useHighlightNavigation.ts", "../../javascript/components/highlights/HighlightActionsPopover.tsx", "../../javascript/utils/formatNoteDate.ts", "../../javascript/utils/transcriptCitationOutput.ts", "../../javascript/components/theme/tokens/shadows.ts", "../../javascript/components/theme/tokens/zIndex.ts", "../../javascript/components/theme/tokens/radii.ts", "../../javascript/components/theme/tokens/index.ts", "../../javascript/components/Reader/citations/CitationText.tsx", "../../javascript/components/Reader/citations/citationCopyOptions.ts", "../../javascript/components/Reader/citations/CitationCopyPopover.tsx", "../../javascript/components/Reader/citations/CitationSelectionSummary.tsx", "../../javascript/components/Reader/citations/NoteCitationDetails.tsx", "../../javascript/components/Reader/citations/HighlightCitationText.tsx", "../../javascript/components/Reader/citations/index.ts", "../../javascript/components/highlights/NotePopover.tsx", "../../javascript/components/highlights/TextSelectionToolbar.tsx", "../../javascript/utils/flattenNoteEntries.ts", "../../javascript/components/atoms/ExcerptBox.tsx", "../../javascript/components/atoms/NoteSnippet.tsx", "../../javascript/components/highlights/NoteItem.tsx", "../../javascript/components/highlights/NotesPanel.tsx", "../../javascript/utils/temporaryHighlight.ts", "../../javascript/components/atoms/NotesBadgeIcon.tsx", "../../javascript/utils/waitForScrollIdle.ts", "../../javascript/components/highlights/HighlightIndicator.tsx", "../../javascript/components/highlights/NoteMarginIndicators.tsx", "../../javascript/utils/highlightPopoverAnchor.ts", "../../javascript/utils/transcriptCitationSelection.ts", "../../javascript/utils/writeRichClipboard.ts", "../../javascript/utils/pdfSourceTarget.ts", "../../javascript/components/Reader/TranscriptProcessingAlert.tsx", "../../javascript/utils/useInterval.ts", "../../javascript/components/molecules/in_transcript_search_drawer/SearchInProgress.tsx", "webpack://pdf.js/src/shared/util.js", "webpack://pdf.js/src/shared/math_clamp.js", "webpack://pdf.js/src/display/page_viewport.js", "webpack://pdf.js/src/display/xfa_text.js", "webpack://pdf.js/src/display/xfa_layer.js", "webpack://pdf.js/src/display/display_utils.js", "webpack://pdf.js/src/display/editor/toolbar.js", "webpack://pdf.js/src/shared/internal_evt.js", "webpack://pdf.js/src/display/editor/tools.js", "webpack://pdf.js/src/display/editor/alt_text.js", "webpack://pdf.js/src/display/editor/comment.js", "webpack://pdf.js/src/display/touch_manager.js", "webpack://pdf.js/src/display/editor/editor.js", "webpack://pdf.js/src/shared/murmurhash3.js", "webpack://pdf.js/src/display/annotation_storage.js", "webpack://pdf.js/src/display/canvas_dependency_tracker.js", "webpack://pdf.js/src/display/font_loader.js", "webpack://pdf.js/src/shared/obj_bin_transform_utils.js", "webpack://pdf.js/src/display/obj_bin_transform_display.js", "webpack://pdf.js/src/display/api_utils.js", "webpack://pdf.js/src/shared/message_handler.js", "webpack://pdf.js/src/display/binary_data_factory.js", "webpack://pdf.js/src/display/canvas_factory.js", "webpack://pdf.js/src/display/filter_factory.js", "webpack://pdf.js/src/display/node_utils.js", "webpack://pdf.js/src/shared/image_utils.js", "webpack://pdf.js/src/display/webgpu.js", "webpack://pdf.js/src/display/pattern_helper.js", "webpack://pdf.js/src/display/canvas.js", "webpack://pdf.js/src/shared/base_pdf_stream.js", "webpack://pdf.js/src/display/content_disposition.js", "webpack://pdf.js/src/display/network_utils.js", "webpack://pdf.js/src/display/fetch_stream.js", "webpack://pdf.js/src/display/transport_stream.js", "webpack://pdf.js/src/display/network.js", "webpack://pdf.js/src/display/node_stream.js", "webpack://pdf.js/src/display/network_stream.js", "webpack://pdf.js/src/display/worker_options.js", "webpack://pdf.js/src/display/metadata.js", "webpack://pdf.js/src/display/optional_content_config.js", "webpack://pdf.js/src/display/pages_mapper.js", "webpack://pdf.js/src/display/pdf_objects.js", "webpack://pdf.js/src/display/text_layer.js", "webpack://pdf.js/src/display/api.js", "webpack://pdf.js/src/display/editor/color_picker.js", "webpack://pdf.js/src/shared/scripting_utils.js", "webpack://pdf.js/src/display/svg_factory.js", "webpack://pdf.js/src/display/annotation_layer.js", "webpack://pdf.js/src/display/editor/freetext.js", "webpack://pdf.js/src/display/editor/drawers/outline.js", "webpack://pdf.js/src/display/editor/drawers/freedraw.js", "webpack://pdf.js/src/display/editor/drawers/highlight.js", "webpack://pdf.js/src/display/editor/highlight.js", "webpack://pdf.js/src/display/editor/draw.js", "webpack://pdf.js/src/display/editor/drawers/inkdraw.js", "webpack://pdf.js/src/display/editor/ink.js", "webpack://pdf.js/src/display/editor/drawers/contour.js", "webpack://pdf.js/src/display/editor/drawers/signaturedraw.js", "webpack://pdf.js/src/display/editor/signature.js", "webpack://pdf.js/src/display/editor/stamp.js", "webpack://pdf.js/src/display/editor/annotation_editor_layer.js", "webpack://pdf.js/src/display/draw_layer.js", "webpack://pdf.js/src/display/text_layer_images.js", "webpack://pdf.js/src/pdf.js", "webpack://pdf.js/web/pdfjs.js", "webpack://pdf.js/web/pdf_find_utils.js", "webpack://pdf.js/web/ui_utils.js", "webpack://pdf.js/web/internal_evt.js", "webpack://pdf.js/web/pdf_find_controller.js", "webpack://pdf.js/web/pdf_link_service.js", "webpack://pdf.js/web/annotation_layer_builder.js", "webpack://pdf.js/web/base_download_manager.js", "webpack://pdf.js/web/download_manager.js", "webpack://pdf.js/web/event_utils.js", "webpack://pdf.js/node_modules/@fluent/bundle/esm/types.js", "webpack://pdf.js/node_modules/@fluent/bundle/esm/resolver.js", "webpack://pdf.js/node_modules/@fluent/bundle/esm/scope.js", "webpack://pdf.js/node_modules/@fluent/bundle/esm/builtins.js", "webpack://pdf.js/node_modules/@fluent/bundle/esm/memoizer.js", "webpack://pdf.js/node_modules/@fluent/bundle/esm/bundle.js", "webpack://pdf.js/node_modules/@fluent/bundle/esm/resource.js", "webpack://pdf.js/node_modules/@fluent/bundle/esm/index.js", "webpack://pdf.js/node_modules/@fluent/dom/esm/overlay.js", "webpack://pdf.js/node_modules/cached-iterable/src/cached_iterable.mjs", "webpack://pdf.js/node_modules/cached-iterable/src/cached_sync_iterable.mjs", "webpack://pdf.js/node_modules/cached-iterable/src/cached_async_iterable.mjs", "webpack://pdf.js/node_modules/cached-iterable/src/index.mjs", "webpack://pdf.js/node_modules/@fluent/dom/esm/localization.js", "webpack://pdf.js/node_modules/@fluent/dom/esm/dom_localization.js", "webpack://pdf.js/node_modules/@fluent/dom/esm/index.js", "webpack://pdf.js/web/l10n.js", "webpack://pdf.js/web/genericl10n.js", "webpack://pdf.js/web/pdf_history.js", "webpack://pdf.js/web/annotation_editor_layer_builder.js", "webpack://pdf.js/web/app_options.js", "webpack://pdf.js/web/autolinker.js", "webpack://pdf.js/web/renderable_view.js", "webpack://pdf.js/web/base_pdf_page_view.js", "webpack://pdf.js/web/draw_layer_builder.js", "webpack://pdf.js/web/pdf_page_detail_view.js", "webpack://pdf.js/web/struct_tree_layer_builder.js", "webpack://pdf.js/web/text_accessibility.js", "webpack://pdf.js/web/text_highlighter.js", "webpack://pdf.js/web/text_layer_builder.js", "webpack://pdf.js/web/xfa_layer_builder.js", "webpack://pdf.js/web/pdf_page_view.js", "webpack://pdf.js/web/generic_scripting.js", "webpack://pdf.js/web/pdf_scripting_manager.js", "webpack://pdf.js/web/pdf_scripting_manager.component.js", "webpack://pdf.js/web/pdf_rendering_queue.js", "webpack://pdf.js/web/pdf_viewer.js", "webpack://pdf.js/web/pdf_single_page_viewer.js", "webpack://pdf.js/web/pdf_viewer.component.js", "../../javascript/components/Reader/pdf/pdfPageLabelResolver.ts", "../../javascript/components/Reader/pdf/pdfCitationLocator.ts", "../../javascript/components/Reader/pdf/PdfCitationHighlightLayer.ts", "../../javascript/components/Reader/pdf/AuthenticatedPdfRangeTransport.ts", "../../javascript/components/Reader/pdf/OfficialSourcePdfViewer.tsx", "../../javascript/components/Reader/pdf/SourceCitationPopover.tsx", "../../javascript/components/Reader/pdf/OfficialSourcePdfOverlay.tsx", "../../javascript/components/molecules/TranscriptReader.tsx", "../../javascript/utils/getTopBarHeight.ts", "../../javascript/components/molecules/in_transcript_search_drawer/InTranscriptSearchPanel.tsx", "../../javascript/components/Reader/ReaderLeftPanel.tsx", "../../javascript/utils/sanitizeSearchResultHighlight.ts", "../../javascript/components/Reader/PassageSnippetList.tsx", "../../javascript/components/Reader/SearchWithinPanel.tsx", "../../../node_modules/file-saver/src/FileSaver.js", "../../javascript/components/atoms/Excerpt.tsx", "../../javascript/components/atoms/SearchCard.tsx", "../../javascript/components/atoms/BooleanSearchTips.tsx", "../../javascript/components/molecules/ValidatedTipsSearchCard.tsx", "../../javascript/utils/makeSelectorListMatcher.ts", "../../javascript/hooks/useSearchTipsFocus.ts", "../../javascript/utils/booleanSearchValidation.ts", "../../javascript/utils/useBooleanSearchValidation.ts", "../../javascript/components/molecules/in_transcript_search_drawer/SearchWithinDocumentPanel.tsx", "../../javascript/utils/injectHighlightSpans.ts", "../../javascript/components/molecules/TranscriptReaderWithDrawers.tsx", "../../javascript/components/Reader/SidepanelTranscriptReader.tsx", "../../javascript/components/Reader/index.ts", "../../javascript/components/atoms/ActiveMatterButton.tsx", "../../javascript/utils/creditMatterLaunch.ts", "../../javascript/components/agent_prototype/docket_connect/DocketConnectLimitNotice.tsx", "../../javascript/components/agent_prototype/docket_connect/DocketConnectRetrievalStatus.tsx", "../../javascript/components/agent_prototype/citations/types.ts", "../../javascript/components/agent_prototype/citations/citationLinks.ts", "../../javascript/components/agent_prototype/AgentPrototypeLayout.tsx", "../../javascript/components/agent_prototype/AgentPrototypeNextSteps.tsx", "../../javascript/components/atoms/icons/LogoMark.tsx", "../../javascript/components/atoms/Citation.tsx", "../../../node_modules/devlop/lib/default.js", "../../../node_modules/comma-separated-tokens/index.js", "../../../node_modules/estree-util-is-identifier-name/lib/index.js", "../../../node_modules/estree-util-is-identifier-name/index.js", "../../../node_modules/hast-util-whitespace/lib/index.js", "../../../node_modules/hast-util-whitespace/index.js", "../../../node_modules/property-information/lib/util/schema.js", "../../../node_modules/property-information/lib/util/merge.js", "../../../node_modules/property-information/lib/normalize.js", "../../../node_modules/property-information/lib/util/info.js", "../../../node_modules/property-information/lib/util/types.js", "../../../node_modules/property-information/lib/util/defined-info.js", "../../../node_modules/property-information/lib/util/create.js", "../../../node_modules/property-information/lib/aria.js", "../../../node_modules/property-information/lib/util/case-sensitive-transform.js", "../../../node_modules/property-information/lib/util/case-insensitive-transform.js", "../../../node_modules/property-information/lib/html.js", "../../../node_modules/property-information/lib/svg.js", "../../../node_modules/property-information/lib/xlink.js", "../../../node_modules/property-information/lib/xmlns.js", "../../../node_modules/property-information/lib/xml.js", "../../../node_modules/property-information/lib/hast-to-react.js", "../../../node_modules/property-information/lib/find.js", "../../../node_modules/property-information/index.js", "../../../node_modules/space-separated-tokens/index.js", "../../../node_modules/inline-style-parser/index.js", "../../../node_modules/style-to-object/src/index.ts", "../../../node_modules/style-to-js/src/utilities.ts", "../../../node_modules/style-to-js/src/index.ts", "../../../node_modules/unist-util-position/lib/index.js", "../../../node_modules/unist-util-position/index.js", "../../../node_modules/unist-util-stringify-position/lib/index.js", "../../../node_modules/unist-util-stringify-position/index.js", "../../../node_modules/vfile-message/lib/index.js", "../../../node_modules/vfile-message/index.js", "../../../node_modules/hast-util-to-jsx-runtime/lib/index.js", "../../../node_modules/hast-util-to-jsx-runtime/index.js", "../../../node_modules/html-url-attributes/lib/index.js", "../../../node_modules/html-url-attributes/index.js", "../../../node_modules/mdast-util-to-string/lib/index.js", "../../../node_modules/mdast-util-to-string/index.js", "../../../node_modules/decode-named-character-reference/index.dom.js", "../../../node_modules/micromark-util-chunked/index.js", "../../../node_modules/micromark-util-combine-extensions/index.js", "../../../node_modules/micromark-util-decode-numeric-character-reference/index.js", "../../../node_modules/micromark-util-normalize-identifier/index.js", "../../../node_modules/micromark-util-character/index.js", "../../../node_modules/micromark-util-sanitize-uri/index.js", "../../../node_modules/micromark-factory-space/index.js", "../../../node_modules/micromark/lib/initialize/content.js", "../../../node_modules/micromark/lib/initialize/document.js", "../../../node_modules/micromark-util-classify-character/index.js", "../../../node_modules/micromark-util-resolve-all/index.js", "../../../node_modules/micromark-core-commonmark/lib/attention.js", "../../../node_modules/micromark-core-commonmark/lib/autolink.js", "../../../node_modules/micromark-core-commonmark/lib/blank-line.js", "../../../node_modules/micromark-core-commonmark/lib/block-quote.js", "../../../node_modules/micromark-core-commonmark/lib/character-escape.js", "../../../node_modules/micromark-core-commonmark/lib/character-reference.js", "../../../node_modules/micromark-core-commonmark/lib/code-fenced.js", "../../../node_modules/micromark-core-commonmark/lib/code-indented.js", "../../../node_modules/micromark-core-commonmark/lib/code-text.js", "../../../node_modules/micromark-util-subtokenize/lib/splice-buffer.js", "../../../node_modules/micromark-util-subtokenize/index.js", "../../../node_modules/micromark-core-commonmark/lib/content.js", "../../../node_modules/micromark-factory-destination/index.js", "../../../node_modules/micromark-factory-label/index.js", "../../../node_modules/micromark-factory-title/index.js", "../../../node_modules/micromark-factory-whitespace/index.js", "../../../node_modules/micromark-core-commonmark/lib/definition.js", "../../../node_modules/micromark-core-commonmark/lib/hard-break-escape.js", "../../../node_modules/micromark-core-commonmark/lib/heading-atx.js", "../../../node_modules/micromark-util-html-tag-name/index.js", "../../../node_modules/micromark-core-commonmark/lib/html-flow.js", "../../../node_modules/micromark-core-commonmark/lib/html-text.js", "../../../node_modules/micromark-core-commonmark/lib/label-end.js", "../../../node_modules/micromark-core-commonmark/lib/label-start-image.js", "../../../node_modules/micromark-core-commonmark/lib/label-start-link.js", "../../../node_modules/micromark-core-commonmark/lib/line-ending.js", "../../../node_modules/micromark-core-commonmark/lib/thematic-break.js", "../../../node_modules/micromark-core-commonmark/lib/list.js", "../../../node_modules/micromark-core-commonmark/lib/setext-underline.js", "../../../node_modules/micromark-core-commonmark/index.js", "../../../node_modules/micromark/lib/initialize/flow.js", "../../../node_modules/micromark/lib/initialize/text.js", "../../../node_modules/micromark/lib/constructs.js", "../../../node_modules/micromark/lib/create-tokenizer.js", "../../../node_modules/micromark/lib/parse.js", "../../../node_modules/micromark/lib/postprocess.js", "../../../node_modules/micromark/lib/preprocess.js", "../../../node_modules/micromark/index.js", "../../../node_modules/micromark-util-decode-string/index.js", "../../../node_modules/mdast-util-from-markdown/lib/index.js", "../../../node_modules/mdast-util-from-markdown/index.js", "../../../node_modules/remark-parse/lib/index.js", "../../../node_modules/remark-parse/index.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/blockquote.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/break.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/code.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/delete.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/emphasis.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/footnote-reference.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/heading.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/html.js", "../../../node_modules/mdast-util-to-hast/lib/revert.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/image-reference.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/image.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/inline-code.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/link-reference.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/link.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/list-item.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/list.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/paragraph.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/root.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/strong.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/table.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/table-row.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/table-cell.js", "../../../node_modules/trim-lines/index.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/text.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/thematic-break.js", "../../../node_modules/mdast-util-to-hast/lib/handlers/index.js", "../../../node_modules/@ungap/structured-clone/esm/types.js", "../../../node_modules/@ungap/structured-clone/esm/deserialize.js", "../../../node_modules/@ungap/structured-clone/esm/serialize.js", "../../../node_modules/@ungap/structured-clone/esm/index.js", "../../../node_modules/mdast-util-to-hast/lib/footer.js", "../../../node_modules/unist-util-is/lib/index.js", "../../../node_modules/unist-util-is/index.js", "../../../node_modules/unist-util-visit-parents/lib/color.js", "../../../node_modules/unist-util-visit-parents/lib/index.js", "../../../node_modules/unist-util-visit-parents/index.js", "../../../node_modules/unist-util-visit/lib/index.js", "../../../node_modules/unist-util-visit/index.js", "../../../node_modules/mdast-util-to-hast/lib/state.js", "../../../node_modules/mdast-util-to-hast/lib/index.js", "../../../node_modules/mdast-util-to-hast/index.js", "../../../node_modules/remark-rehype/lib/index.js", "../../../node_modules/remark-rehype/index.js", "../../../node_modules/bail/index.js", "../../../node_modules/extend/index.js", "../../../node_modules/is-plain-obj/index.js", "../../../node_modules/trough/lib/index.js", "../../../node_modules/trough/index.js", "../../../node_modules/vfile/lib/minpath.browser.js", "../../../node_modules/vfile/lib/minproc.browser.js", "../../../node_modules/vfile/lib/minurl.shared.js", "../../../node_modules/vfile/lib/minurl.browser.js", "../../../node_modules/vfile/lib/index.js", "../../../node_modules/vfile/index.js", "../../../node_modules/unified/lib/callable-instance.js", "../../../node_modules/unified/lib/index.js", "../../../node_modules/unified/index.js", "../../../node_modules/react-markdown/lib/index.js", "../../../node_modules/react-markdown/index.js", "../../../node_modules/ccount/index.js", "../../../node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp/index.js", "../../../node_modules/mdast-util-find-and-replace/lib/index.js", "../../../node_modules/mdast-util-find-and-replace/index.js", "../../../node_modules/mdast-util-gfm-autolink-literal/lib/index.js", "../../../node_modules/mdast-util-gfm-autolink-literal/index.js", "../../../node_modules/mdast-util-gfm-footnote/lib/index.js", "../../../node_modules/mdast-util-gfm-footnote/index.js", "../../../node_modules/mdast-util-gfm-strikethrough/lib/index.js", "../../../node_modules/mdast-util-gfm-strikethrough/index.js", "../../../node_modules/markdown-table/index.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/blockquote.js", "../../../node_modules/mdast-util-to-markdown/lib/util/pattern-in-scope.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/break.js", "../../../node_modules/longest-streak/index.js", "../../../node_modules/mdast-util-to-markdown/lib/util/format-code-as-indented.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-fence.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/code.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-quote.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/definition.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-emphasis.js", "../../../node_modules/mdast-util-to-markdown/lib/util/encode-character-reference.js", "../../../node_modules/mdast-util-to-markdown/lib/util/encode-info.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/emphasis.js", "../../../node_modules/mdast-util-to-markdown/lib/util/format-heading-as-setext.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/heading.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/html.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/image.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/image-reference.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/inline-code.js", "../../../node_modules/mdast-util-to-markdown/lib/util/format-link-as-autolink.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/link.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/link-reference.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-bullet.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-bullet-other.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-bullet-ordered.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-rule.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/list.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-list-item-indent.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/list-item.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/paragraph.js", "../../../node_modules/mdast-util-phrasing/lib/index.js", "../../../node_modules/mdast-util-phrasing/index.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/root.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-strong.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/strong.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/text.js", "../../../node_modules/mdast-util-to-markdown/lib/util/check-rule-repetition.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/thematic-break.js", "../../../node_modules/mdast-util-to-markdown/lib/handle/index.js", "../../../node_modules/mdast-util-to-markdown/index.js", "../../../node_modules/mdast-util-gfm-table/lib/index.js", "../../../node_modules/mdast-util-gfm-table/index.js", "../../../node_modules/mdast-util-gfm-task-list-item/lib/index.js", "../../../node_modules/mdast-util-gfm-task-list-item/index.js", "../../../node_modules/mdast-util-gfm/lib/index.js", "../../../node_modules/mdast-util-gfm/index.js", "../../../node_modules/micromark-extension-gfm-autolink-literal/lib/syntax.js", "../../../node_modules/micromark-extension-gfm-autolink-literal/index.js", "../../../node_modules/micromark-extension-gfm-footnote/lib/syntax.js", "../../../node_modules/micromark-extension-gfm-footnote/index.js", "../../../node_modules/micromark-extension-gfm-strikethrough/lib/syntax.js", "../../../node_modules/micromark-extension-gfm-strikethrough/index.js", "../../../node_modules/micromark-extension-gfm-table/lib/edit-map.js", "../../../node_modules/micromark-extension-gfm-table/lib/infer.js", "../../../node_modules/micromark-extension-gfm-table/lib/syntax.js", "../../../node_modules/micromark-extension-gfm-table/index.js", "../../../node_modules/micromark-extension-gfm-task-list-item/lib/syntax.js", "../../../node_modules/micromark-extension-gfm-task-list-item/index.js", "../../../node_modules/micromark-extension-gfm/index.js", "../../../node_modules/remark-gfm/lib/index.js", "../../../node_modules/remark-gfm/index.js", "../../javascript/components/agent_prototype/AgentPrototypeDownloadCard.tsx", "../../javascript/components/agent_prototype/MessageTimestamp.tsx", "../../javascript/components/agent_prototype/MessageActions.tsx", "../../javascript/components/agent_prototype/UserMessageActions.tsx", "../../javascript/hooks/useHighlightOverlay.ts", "../../javascript/hooks/useStableValue.ts", "../../javascript/components/agent_prototype/citations/AgentSourcesSection.tsx", "../../javascript/components/agent_prototype/citations/citationControlText.ts", "../../javascript/components/agent_prototype/citations/collapseDocumentCitationBlocks.ts", "../../javascript/components/agent_prototype/AgentPrototypeMessage.tsx", "../../javascript/dev/sampleClerkSession.ts", "../../javascript/dev/injectClerkSession.ts", "../../javascript/utils/stripMarkdown.ts", "../../javascript/components/agent_prototype/BranchOriginDivider.tsx", "../../javascript/components/agent_prototype/AgentPrototypeChat.tsx", "../../javascript/api/judges.ts", "../../javascript/components/contexts/SearchFilterControlContext.tsx", "../../javascript/components/contexts/BooleanSearchBarControlContext.tsx", "../../javascript/utils/searchPrefill.ts", "../../javascript/hooks/useCarriedQueryPrefill.ts", "../../javascript/components/agent_prototype/lockedClerkExamples.ts", "../../javascript/components/agent_prototype/LockedClerkFooter.tsx", "../../javascript/components/agent_prototype/AgentPrototypeConversation.tsx", "../../javascript/components/molecules/EmptyState.tsx", "../../javascript/components/SideNav/Recents/RenameSessionDialog.tsx", "../../javascript/components/SideNav/Recents/SessionActionsMenu.tsx", "../../javascript/utils/useContinuousScrollHook.ts", "../../javascript/components/agent_prototype/AgentPrototypeHistory.tsx", "../../javascript/components/agent_prototype/AgentPrototypeShareResolver.tsx", "../../javascript/components/agent_prototype/RedirectToAgent.tsx", "../../javascript/components/agent_prototype/LockedClerkLanding.tsx", "../../javascript/components/agent_prototype/LockedClerkExampleSession.tsx", "../../javascript/components/organisms/NoTranscriptResults.tsx", "../../javascript/components/organisms/formatResultCountLabel.ts", "../../../node_modules/react-side-effect/lib/index.js", "../../../node_modules/react-fast-compare/index.js", "../../../node_modules/object-assign/index.js", "../../../node_modules/react-helmet/es/Helmet.js", "../../javascript/components/atoms/WindowTitle.tsx", "../../javascript/components/atoms/StyledPagination.tsx", "../../javascript/components/atoms/MotionTag.tsx", "../../javascript/components/atoms/MotionTags.tsx", "../../javascript/components/atoms/CitationText.tsx", "../../javascript/components/atoms/TranscriptOverview.tsx", "../../javascript/components/molecules/QueryResultCard.tsx", "../../javascript/api/queries/autoCorrections.types.ts", "../../javascript/api/queryAutoCorrections.ts", "../../javascript/components/atoms/ExpandableTruncatedText.tsx", "../../javascript/utils/identifyBooleanTerms.ts", "../../javascript/components/atoms/ScrollableContent.tsx", "../../javascript/utils/areUrlParamsTheSame.ts", "../../javascript/components/atoms/FeatureDisabledByAdmin.tsx", "../../javascript/utils/queryCorrectionUtils.ts", "../../javascript/utils/autoCorrectionExecution.ts", "../../javascript/vendor/@mui/material/useAutocomplete.js", "../../javascript/vendor/@mui/material/Autocomplete.jsx", "../../../node_modules/humanparser/index.js", "../../javascript/utils/nameParser.ts", "../../javascript/components/atoms/FilterButton.tsx", "../../javascript/components/atoms/JudgeAutocomplete.tsx", "../../../node_modules/@mui/x-date-pickers/locales/utils/getPickersLocalization.js", "../../../node_modules/@mui/x-date-pickers/locales/enUS.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useUtils.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/views.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/date-utils.js", "../../../node_modules/@mui/x-date-pickers/node_modules/clsx/dist/clsx.mjs", "../../../node_modules/@mui/x-date-pickers/internals/components/pickersToolbarClasses.js", "../../../node_modules/@mui/x-date-pickers/internals/components/PickersToolbar.js", "../../../node_modules/@mui/x-date-pickers/DatePicker/datePickerToolbarClasses.js", "../../../node_modules/@mui/x-date-pickers/DatePicker/DatePickerToolbar.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/slots-migration.js", "../../../node_modules/@mui/x-date-pickers/DatePicker/shared.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/isHostComponent.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/appendOwnerState.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/extractEventHandlers.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/resolveComponentProps.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/omitEventHandlers.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/mergeSlotProps.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/useSlotProps.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/PolymorphicComponent.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/types.js", "../../../node_modules/@mui/x-date-pickers/node_modules/@mui/base/utils/index.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/validation/validateDate.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/useIsDateDisabled.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/time-utils.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/getDefaultReferenceDate.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/valueManagers.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/useCalendarState.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/pickersFadeTransitionGroupClasses.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/PickersFadeTransitionGroup.js", "../../../node_modules/@mui/x-date-pickers/internals/constants/dimensions.js", "../../../node_modules/@mui/x-date-pickers/PickersDay/pickersDayClasses.js", "../../../node_modules/@mui/x-date-pickers/PickersDay/PickersDay.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/pickersSlideTransitionClasses.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/PickersSlideTransition.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/dayCalendarClasses.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/DayCalendar.js", "../../../node_modules/@mui/x-date-pickers/MonthCalendar/pickersMonthClasses.js", "../../../node_modules/@mui/x-date-pickers/MonthCalendar/PickersMonth.js", "../../../node_modules/@mui/x-date-pickers/MonthCalendar/monthCalendarClasses.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useValueWithTimezone.js", "../../../node_modules/@mui/x-date-pickers/MonthCalendar/MonthCalendar.js", "../../../node_modules/@mui/x-date-pickers/MonthCalendar/index.js", "../../../node_modules/@mui/x-date-pickers/YearCalendar/pickersYearClasses.js", "../../../node_modules/@mui/x-date-pickers/YearCalendar/PickersYear.js", "../../../node_modules/@mui/x-date-pickers/YearCalendar/yearCalendarClasses.js", "../../../node_modules/@mui/x-date-pickers/YearCalendar/YearCalendar.js", "../../../node_modules/@mui/x-date-pickers/YearCalendar/index.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useViews.js", "../../../node_modules/@mui/x-date-pickers/PickersCalendarHeader/pickersCalendarHeaderClasses.js", "../../../node_modules/@mui/x-date-pickers/icons/index.js", "../../../node_modules/@mui/x-date-pickers/internals/components/PickersArrowSwitcher/pickersArrowSwitcherClasses.js", "../../../node_modules/@mui/x-date-pickers/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js", "../../../node_modules/@mui/x-date-pickers/internals/components/PickersArrowSwitcher/index.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/date-helpers-hooks.js", "../../../node_modules/@mui/x-date-pickers/PickersCalendarHeader/PickersCalendarHeader.js", "../../../node_modules/@mui/x-date-pickers/PickersCalendarHeader/index.js", "../../../node_modules/@mui/x-date-pickers/internals/components/PickerViewRoot/PickerViewRoot.js", "../../../node_modules/@mui/x-date-pickers/internals/components/PickerViewRoot/index.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useDefaultReduceAnimations.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/dateCalendarClasses.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/DateCalendar.js", "../../../node_modules/@mui/x-date-pickers/DateCalendar/index.js", "../../../node_modules/@mui/x-date-pickers/dateViewRenderers/dateViewRenderers.js", "../../../node_modules/@mui/x-date-pickers/dateViewRenderers/index.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useOpenState.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useValidation.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/usePicker/usePickerValue.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/usePicker/usePickerViews.js", "../../../node_modules/@mui/x-date-pickers/internals/utils/utils.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useIsLandscape.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/usePicker/usePickerLayoutProps.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/usePicker/usePicker.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/usePicker/index.js", "../../../node_modules/@mui/x-date-pickers/PickersLayout/pickersLayoutClasses.js", "../../../node_modules/@mui/x-date-pickers/PickersActionBar/PickersActionBar.js", "../../../node_modules/@mui/x-date-pickers/PickersActionBar/index.js", "../../../node_modules/@mui/x-date-pickers/PickersShortcuts/PickersShortcuts.js", "../../../node_modules/@mui/x-date-pickers/PickersShortcuts/index.js", "../../../node_modules/@mui/x-date-pickers/PickersLayout/usePickerLayout.js", "../../../node_modules/@mui/x-date-pickers/PickersLayout/PickersLayout.js", "../../../node_modules/@mui/x-date-pickers/PickersLayout/index.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useStaticPicker/useStaticPicker.js", "../../../node_modules/@mui/x-date-pickers/internals/hooks/useStaticPicker/index.js", "../../../node_modules/@mui/x-date-pickers/internals/index.js", "../../../node_modules/@mui/x-date-pickers/StaticDatePicker/StaticDatePicker.js", "../../../node_modules/@mui/x-date-pickers/StaticDatePicker/index.js", "../../javascript/utils/dateValidation.ts", "../../javascript/components/atoms/DateFilterChip.tsx", "../../javascript/components/atoms/CaseNumberFilterChip.tsx", "../../javascript/components/molecules/AppliedFilters.tsx", "../../javascript/utils/overviewCitations.ts", "../../javascript/components/molecules/LockedSearchMatterModal.tsx", "../../javascript/components/organisms/QueryResultsPage.tsx", "../../javascript/utils/activityHistory.ts", "../../javascript/utils/transformQueryToFilters.ts", "../../javascript/components/atoms/FilterTooltip.tsx", "../../javascript/components/molecules/activity_history/ActivityHistoryItem.tsx", "../../javascript/components/organisms/ActivityHistoryPage.tsx", "../../javascript/utils/handleSignOut.ts", "../../javascript/components/molecules/TimeTrackingModal.tsx", "../../javascript/components/Alerts.tsx", "../../javascript/components/molecules/TermsOfServiceModal.tsx", "../../javascript/components/auth/AuthComponents.tsx", "../../javascript/components/auth/authApi.ts", "../../javascript/components/auth/LoginPages.tsx", "../../javascript/components/auth/SignupPage.tsx", "../../javascript/components/auth/authNavigation.ts", "../../javascript/components/auth/PasswordPages.tsx", "../../javascript/components/auth/ConfirmationPages.tsx", "../../javascript/components/auth/InvitationPage.tsx", "../../javascript/api/mcpOAuth.ts", "../../javascript/components/auth/TermsOfService.tsx", "../../javascript/components/auth/ProfileSetup.tsx", "../../javascript/components/theme/palette.ts", "../../javascript/components/theme/typography.ts", "../../javascript/components/atoms/checkbox/CheckboxIcons.tsx", "../../javascript/components/theme/mixins/focusRing.ts", "../../javascript/components/theme/components.ts", "../../javascript/components/theme/borders.ts", "../../javascript/components/theme/index.ts", "../../javascript/components/highlights/HighlightStyles.tsx", "../../javascript/components/organisms/UnifiedHistoryPage.tsx", "../../javascript/utils/entrySourceFromSearch.ts", "../../javascript/components/organisms/StarredPage.tsx", "../../javascript/components/molecules/folders/StickyFolderPageHeader.tsx", "../../javascript/components/molecules/folders/DeleteFolderDialog.tsx", "../../javascript/components/molecules/folders/useFolderForm.ts", "../../javascript/components/molecules/folders/EditFolderModal.tsx", "../../javascript/components/molecules/folders/stickyFolderTableHeadSx.ts", "../../javascript/components/molecules/folders/StickyFolderTableCard.tsx", "../../javascript/utils/formatFolderDateTime.ts", "../../javascript/components/molecules/folders/FolderTable.tsx", "../../javascript/components/molecules/folders/FoldersEmptyState.tsx", "../../javascript/components/organisms/FoldersPage.tsx", "../../javascript/components/molecules/folders/FolderDetailHeader.tsx", "../../javascript/components/molecules/folders/FolderDetailErrorAlert.tsx", "../../javascript/components/molecules/folders/FolderDetailEmptyState.tsx", "../../javascript/components/molecules/folders/FolderDetailToolbar.tsx", "../../javascript/components/molecules/folders/FolderItemRowActions.tsx", "../../javascript/utils/formatTranscriptDateForDisplay.ts", "../../javascript/components/molecules/folders/FolderItemRow.tsx", "../../javascript/components/molecules/folders/FolderItemsTable.tsx", "../../javascript/components/organisms/FolderDetailPage.tsx", "../../javascript/components/organisms/NotesPage.tsx", "../../javascript/components/PageViewTracker.tsx", "../../javascript/components/molecules/SessionExpiredModal.tsx", "webpack://ls/webpack/universalModuleDefinition", "webpack://ls/webpack/bootstrap", "webpack://ls/webpack/runtime/define%20property%20getters", "webpack://ls/webpack/runtime/hasOwnProperty%20shorthand", "webpack://ls/src/helpers.ts", "webpack://ls/src/ls.ts", "../../javascript/utils/localStorageWithExpiry.ts", "../../javascript/utils/localStorageCleanup.ts", "../../javascript/components/contexts/TopBarProvider.tsx", "../../javascript/components/SideNav/NavItem.tsx", "../../javascript/components/SideNav/HomeLogoButton.tsx", "../../javascript/components/SideNav/useSideNavModel.ts", "../../javascript/components/SideNav/SideNav.tsx", "../../javascript/components/SideNav/Recents/StatusIcon.tsx", "../../javascript/components/SideNav/Recents/CollapsedStatusRollup.tsx", "../../javascript/components/SideNav/NavMenuRow.tsx", "../../javascript/components/SideNav/Recents/WorkingPulse.tsx", "../../javascript/components/SideNav/Recents/StatusIndicator.tsx", "../../javascript/components/SideNav/Recents/SessionItem.tsx", "../../javascript/components/SideNav/Recents/ShowMoreButton.tsx", "../../javascript/components/SideNav/Recents/RecentsList.tsx", "../../javascript/components/SideNav/AccountMenu/accountMenuParts.tsx", "../../javascript/components/SideNav/AccountMenu/AccountMenu.tsx", "../../javascript/components/SideNav/UserProfileFooter.tsx", "../../javascript/components/SideNav/ExpandableSideNav.tsx", "../../javascript/components/SideNav/RecentSessionsContainer.tsx", "../../javascript/components/SideNav/ExpandableSideNavContainer.tsx", "../../javascript/components/SideNav/usePinnedSidenavPreference.ts", "../../javascript/components/AppShell/OmnibarSearchTrigger.tsx", "../../javascript/components/AppShell/TopBarLeft.tsx", "../../javascript/components/molecules/QueryImprovementCard.tsx", "../../javascript/components/molecules/QueryImprovementSection.tsx", "../../javascript/components/organisms/QueryImprovementsPanel.tsx", "../../javascript/api/queryImprovement.ts", "../../javascript/components/organisms/SearchOverlay.tsx", "../../javascript/utils/browserExtensionErrors.ts", "../../javascript/components/atoms/QueryImprovementChip.tsx", "../../javascript/components/atoms/TopBarStatusChip.tsx", "../../javascript/components/molecules/ClientMatterModal.tsx", "../../javascript/components/molecules/CreditAgentSpeedBumpModal.tsx", "../../javascript/utils/needsClientMatter.ts", "../../javascript/components/molecules/CreditMatterLaunchHandler.tsx", "../../javascript/components/mcp/McpClientIcon.tsx", "../../javascript/components/mcp/McpOauthConsentPage.tsx", "../../javascript/api/mcpConnections.ts", "../../javascript/components/settings/ConnectedAppsConnectionCard.tsx", "../../javascript/components/settings/ConnectedAppsDialogs.tsx", "../../javascript/components/settings/ConnectedAppsPage.tsx", "../../javascript/components/index.tsx", "../../javascript/application.js"], "sourcesContent": ["/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var l=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),p=Symbol.for(\"react.fragment\"),q=Symbol.for(\"react.strict_mode\"),r=Symbol.for(\"react.profiler\"),t=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),v=Symbol.for(\"react.forward_ref\"),w=Symbol.for(\"react.suspense\"),x=Symbol.for(\"react.memo\"),y=Symbol.for(\"react.lazy\"),z=Symbol.iterator;function A(a){if(null===a||\"object\"!==typeof a)return null;a=z&&a[z]||a[\"@@iterator\"];return\"function\"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if(\"object\"!==typeof a&&\"function\"!==typeof a&&null!=a)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,a,b,\"setState\")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,\"forceUpdate\")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=\"\"+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1>>1,e=a[d];if(0>>1;dg(C,c))ng(x,C)?(a[d]=x,a[n]=c,d=n):(a[d]=C,a[m]=c,d=m);else if(ng(x,c))a[d]=x,a[n]=c,d=n;else break a}}return b}\nfunction g(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}if(\"object\"===typeof performance&&\"function\"===typeof performance.now){var l=performance;exports.unstable_now=function(){return l.now()}}else{var p=Date,q=p.now();exports.unstable_now=function(){return p.now()-q}}var r=[],t=[],u=1,v=null,y=3,z=!1,A=!1,B=!1,D=\"function\"===typeof setTimeout?setTimeout:null,E=\"function\"===typeof clearTimeout?clearTimeout:null,F=\"undefined\"!==typeof setImmediate?setImmediate:null;\n\"undefined\"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function G(a){for(var b=h(t);null!==b;){if(null===b.callback)k(t);else if(b.startTime<=a)k(t),b.sortIndex=b.expirationTime,f(r,b);else break;b=h(t)}}function H(a){B=!1;G(a);if(!A)if(null!==h(r))A=!0,I(J);else{var b=h(t);null!==b&&K(H,b.startTime-a)}}\nfunction J(a,b){A=!1;B&&(B=!1,E(L),L=-1);z=!0;var c=y;try{G(b);for(v=h(r);null!==v&&(!(v.expirationTime>b)||a&&!M());){var d=v.callback;if(\"function\"===typeof d){v.callback=null;y=v.priorityLevel;var e=d(v.expirationTime<=b);b=exports.unstable_now();\"function\"===typeof e?v.callback=e:v===h(r)&&k(r);G(b)}else k(r);v=h(r)}if(null!==v)var w=!0;else{var m=h(t);null!==m&&K(H,m.startTime-b);w=!1}return w}finally{v=null,y=c,z=!1}}var N=!1,O=null,L=-1,P=5,Q=-1;\nfunction M(){return exports.unstable_now()-Qa||125d?(a.sortIndex=c,f(t,a),null===h(r)&&a===h(t)&&(B?(E(L),L=-1):B=!0,K(H,c-d))):(a.sortIndex=e,f(r,a),A||z||(A=!0,I(J)));return a};\nexports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}};\n", "'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/scheduler.production.min.js');\n} else {\n module.exports = require('./cjs/scheduler.development.js');\n}\n", "/**\n * @license React\n * react-dom.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\n'use strict';var aa=require(\"react\"),ca=require(\"scheduler\");function p(a){for(var b=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+a,c=1;cb}return!1}function v(a,b,c,d,e,f,g){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f;this.removeEmptyString=g}var z={};\n\"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style\".split(\" \").forEach(function(a){z[a]=new v(a,0,!1,a,null,!1,!1)});[[\"acceptCharset\",\"accept-charset\"],[\"className\",\"class\"],[\"htmlFor\",\"for\"],[\"httpEquiv\",\"http-equiv\"]].forEach(function(a){var b=a[0];z[b]=new v(b,1,!1,a[1],null,!1,!1)});[\"contentEditable\",\"draggable\",\"spellCheck\",\"value\"].forEach(function(a){z[a]=new v(a,2,!1,a.toLowerCase(),null,!1,!1)});\n[\"autoReverse\",\"externalResourcesRequired\",\"focusable\",\"preserveAlpha\"].forEach(function(a){z[a]=new v(a,2,!1,a,null,!1,!1)});\"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope\".split(\" \").forEach(function(a){z[a]=new v(a,3,!1,a.toLowerCase(),null,!1,!1)});\n[\"checked\",\"multiple\",\"muted\",\"selected\"].forEach(function(a){z[a]=new v(a,3,!0,a,null,!1,!1)});[\"capture\",\"download\"].forEach(function(a){z[a]=new v(a,4,!1,a,null,!1,!1)});[\"cols\",\"rows\",\"size\",\"span\"].forEach(function(a){z[a]=new v(a,6,!1,a,null,!1,!1)});[\"rowSpan\",\"start\"].forEach(function(a){z[a]=new v(a,5,!1,a.toLowerCase(),null,!1,!1)});var ra=/[\\-:]([a-z])/g;function sa(a){return a[1].toUpperCase()}\n\"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height\".split(\" \").forEach(function(a){var b=a.replace(ra,\nsa);z[b]=new v(b,1,!1,a,null,!1,!1)});\"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type\".split(\" \").forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,\"http://www.w3.org/1999/xlink\",!1,!1)});[\"xml:base\",\"xml:lang\",\"xml:space\"].forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,\"http://www.w3.org/XML/1998/namespace\",!1,!1)});[\"tabIndex\",\"crossOrigin\"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!1,!1)});\nz.xlinkHref=new v(\"xlinkHref\",1,!1,\"xlink:href\",\"http://www.w3.org/1999/xlink\",!0,!1);[\"src\",\"href\",\"action\",\"formAction\"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!0,!0)});\nfunction ta(a,b,c,d){var e=z.hasOwnProperty(b)?z[b]:null;if(null!==e?0!==e.type:d||!(2h||e[g]!==f[h]){var k=\"\\n\"+e[g].replace(\" at new \",\" at \");a.displayName&&k.includes(\"\")&&(k=k.replace(\"\",a.displayName));return k}while(1<=g&&0<=h)}break}}}finally{Na=!1,Error.prepareStackTrace=c}return(a=a?a.displayName||a.name:\"\")?Ma(a):\"\"}\nfunction Pa(a){switch(a.tag){case 5:return Ma(a.type);case 16:return Ma(\"Lazy\");case 13:return Ma(\"Suspense\");case 19:return Ma(\"SuspenseList\");case 0:case 2:case 15:return a=Oa(a.type,!1),a;case 11:return a=Oa(a.type.render,!1),a;case 1:return a=Oa(a.type,!0),a;default:return\"\"}}\nfunction Qa(a){if(null==a)return null;if(\"function\"===typeof a)return a.displayName||a.name||null;if(\"string\"===typeof a)return a;switch(a){case ya:return\"Fragment\";case wa:return\"Portal\";case Aa:return\"Profiler\";case za:return\"StrictMode\";case Ea:return\"Suspense\";case Fa:return\"SuspenseList\"}if(\"object\"===typeof a)switch(a.$$typeof){case Ca:return(a.displayName||\"Context\")+\".Consumer\";case Ba:return(a._context.displayName||\"Context\")+\".Provider\";case Da:var b=a.render;a=a.displayName;a||(a=b.displayName||\nb.name||\"\",a=\"\"!==a?\"ForwardRef(\"+a+\")\":\"ForwardRef\");return a;case Ga:return b=a.displayName||null,null!==b?b:Qa(a.type)||\"Memo\";case Ha:b=a._payload;a=a._init;try{return Qa(a(b))}catch(c){}}return null}\nfunction Ra(a){var b=a.type;switch(a.tag){case 24:return\"Cache\";case 9:return(b.displayName||\"Context\")+\".Consumer\";case 10:return(b._context.displayName||\"Context\")+\".Provider\";case 18:return\"DehydratedFragment\";case 11:return a=b.render,a=a.displayName||a.name||\"\",b.displayName||(\"\"!==a?\"ForwardRef(\"+a+\")\":\"ForwardRef\");case 7:return\"Fragment\";case 5:return b;case 4:return\"Portal\";case 3:return\"Root\";case 6:return\"Text\";case 16:return Qa(b);case 8:return b===za?\"StrictMode\":\"Mode\";case 22:return\"Offscreen\";\ncase 12:return\"Profiler\";case 21:return\"Scope\";case 13:return\"Suspense\";case 19:return\"SuspenseList\";case 25:return\"TracingMarker\";case 1:case 0:case 17:case 2:case 14:case 15:if(\"function\"===typeof b)return b.displayName||b.name||null;if(\"string\"===typeof b)return b}return null}function Sa(a){switch(typeof a){case \"boolean\":case \"number\":case \"string\":case \"undefined\":return a;case \"object\":return a;default:return\"\"}}\nfunction Ta(a){var b=a.type;return(a=a.nodeName)&&\"input\"===a.toLowerCase()&&(\"checkbox\"===b||\"radio\"===b)}\nfunction Ua(a){var b=Ta(a)?\"checked\":\"value\",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=\"\"+a[b];if(!a.hasOwnProperty(b)&&\"undefined\"!==typeof c&&\"function\"===typeof c.get&&\"function\"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=\"\"+a;f.call(this,a)}});Object.defineProperty(a,b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=\"\"+a},stopTracking:function(){a._valueTracker=\nnull;delete a[b]}}}}function Va(a){a._valueTracker||(a._valueTracker=Ua(a))}function Wa(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d=\"\";a&&(d=Ta(a)?a.checked?\"true\":\"false\":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Xa(a){a=a||(\"undefined\"!==typeof document?document:void 0);if(\"undefined\"===typeof a)return null;try{return a.activeElement||a.body}catch(b){return a.body}}\nfunction Ya(a,b){var c=b.checked;return A({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function Za(a,b){var c=null==b.defaultValue?\"\":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=Sa(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:\"checkbox\"===b.type||\"radio\"===b.type?null!=b.checked:null!=b.value}}function ab(a,b){b=b.checked;null!=b&&ta(a,\"checked\",b,!1)}\nfunction bb(a,b){ab(a,b);var c=Sa(b.value),d=b.type;if(null!=c)if(\"number\"===d){if(0===c&&\"\"===a.value||a.value!=c)a.value=\"\"+c}else a.value!==\"\"+c&&(a.value=\"\"+c);else if(\"submit\"===d||\"reset\"===d){a.removeAttribute(\"value\");return}b.hasOwnProperty(\"value\")?cb(a,b.type,c):b.hasOwnProperty(\"defaultValue\")&&cb(a,b.type,Sa(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}\nfunction db(a,b,c){if(b.hasOwnProperty(\"value\")||b.hasOwnProperty(\"defaultValue\")){var d=b.type;if(!(\"submit\"!==d&&\"reset\"!==d||void 0!==b.value&&null!==b.value))return;b=\"\"+a._wrapperState.initialValue;c||b===a.value||(a.value=b);a.defaultValue=b}c=a.name;\"\"!==c&&(a.name=\"\");a.defaultChecked=!!a._wrapperState.initialChecked;\"\"!==c&&(a.name=c)}\nfunction cb(a,b,c){if(\"number\"!==b||Xa(a.ownerDocument)!==a)null==c?a.defaultValue=\"\"+a._wrapperState.initialValue:a.defaultValue!==\"\"+c&&(a.defaultValue=\"\"+c)}var eb=Array.isArray;\nfunction fb(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e\"+b.valueOf().toString()+\"\";for(b=mb.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}});\nfunction ob(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b}\nvar pb={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,\nzoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},qb=[\"Webkit\",\"ms\",\"Moz\",\"O\"];Object.keys(pb).forEach(function(a){qb.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);pb[b]=pb[a]})});function rb(a,b,c){return null==b||\"boolean\"===typeof b||\"\"===b?\"\":c||\"number\"!==typeof b||0===b||pb.hasOwnProperty(a)&&pb[a]?(\"\"+b).trim():b+\"px\"}\nfunction sb(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf(\"--\"),e=rb(c,b[c],d);\"float\"===c&&(c=\"cssFloat\");d?a.setProperty(c,e):a[c]=e}}var tb=A({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});\nfunction ub(a,b){if(b){if(tb[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(p(137,a));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(p(60));if(\"object\"!==typeof b.dangerouslySetInnerHTML||!(\"__html\"in b.dangerouslySetInnerHTML))throw Error(p(61));}if(null!=b.style&&\"object\"!==typeof b.style)throw Error(p(62));}}\nfunction vb(a,b){if(-1===a.indexOf(\"-\"))return\"string\"===typeof b.is;switch(a){case \"annotation-xml\":case \"color-profile\":case \"font-face\":case \"font-face-src\":case \"font-face-uri\":case \"font-face-format\":case \"font-face-name\":case \"missing-glyph\":return!1;default:return!0}}var wb=null;function xb(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode:a}var yb=null,zb=null,Ab=null;\nfunction Bb(a){if(a=Cb(a)){if(\"function\"!==typeof yb)throw Error(p(280));var b=a.stateNode;b&&(b=Db(b),yb(a.stateNode,a.type,b))}}function Eb(a){zb?Ab?Ab.push(a):Ab=[a]:zb=a}function Fb(){if(zb){var a=zb,b=Ab;Ab=zb=null;Bb(a);if(b)for(a=0;a>>=0;return 0===a?32:31-(pc(a)/qc|0)|0}var rc=64,sc=4194304;\nfunction tc(a){switch(a&-a){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return a&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;\ndefault:return a}}function uc(a,b){var c=a.pendingLanes;if(0===c)return 0;var d=0,e=a.suspendedLanes,f=a.pingedLanes,g=c&268435455;if(0!==g){var h=g&~e;0!==h?d=tc(h):(f&=g,0!==f&&(d=tc(f)))}else g=c&~e,0!==g?d=tc(g):0!==f&&(d=tc(f));if(0===d)return 0;if(0!==b&&b!==d&&0===(b&e)&&(e=d&-d,f=b&-b,e>=f||16===e&&0!==(f&4194240)))return b;0!==(d&4)&&(d|=c&16);b=a.entangledLanes;if(0!==b)for(a=a.entanglements,b&=d;0c;c++)b.push(a);return b}\nfunction Ac(a,b,c){a.pendingLanes|=b;536870912!==b&&(a.suspendedLanes=0,a.pingedLanes=0);a=a.eventTimes;b=31-oc(b);a[b]=c}function Bc(a,b){var c=a.pendingLanes&~b;a.pendingLanes=b;a.suspendedLanes=0;a.pingedLanes=0;a.expiredLanes&=b;a.mutableReadLanes&=b;a.entangledLanes&=b;b=a.entanglements;var d=a.eventTimes;for(a=a.expirationTimes;0=be),ee=String.fromCharCode(32),fe=!1;\nfunction ge(a,b){switch(a){case \"keyup\":return-1!==$d.indexOf(b.keyCode);case \"keydown\":return 229!==b.keyCode;case \"keypress\":case \"mousedown\":case \"focusout\":return!0;default:return!1}}function he(a){a=a.detail;return\"object\"===typeof a&&\"data\"in a?a.data:null}var ie=!1;function je(a,b){switch(a){case \"compositionend\":return he(b);case \"keypress\":if(32!==b.which)return null;fe=!0;return ee;case \"textInput\":return a=b.data,a===ee&&fe?null:a;default:return null}}\nfunction ke(a,b){if(ie)return\"compositionend\"===a||!ae&&ge(a,b)?(a=nd(),md=ld=kd=null,ie=!1,a):null;switch(a){case \"paste\":return null;case \"keypress\":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=Je(c)}}function Le(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?Le(a,b.parentNode):\"contains\"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}\nfunction Me(){for(var a=window,b=Xa();b instanceof a.HTMLIFrameElement;){try{var c=\"string\"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=Xa(a.document)}return b}function Ne(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&(\"input\"===b&&(\"text\"===a.type||\"search\"===a.type||\"tel\"===a.type||\"url\"===a.type||\"password\"===a.type)||\"textarea\"===b||\"true\"===a.contentEditable)}\nfunction Oe(a){var b=Me(),c=a.focusedElem,d=a.selectionRange;if(b!==c&&c&&c.ownerDocument&&Le(c.ownerDocument.documentElement,c)){if(null!==d&&Ne(c))if(b=d.start,a=d.end,void 0===a&&(a=b),\"selectionStart\"in c)c.selectionStart=b,c.selectionEnd=Math.min(a,c.value.length);else if(a=(b=c.ownerDocument||document)&&b.defaultView||window,a.getSelection){a=a.getSelection();var e=c.textContent.length,f=Math.min(d.start,e);d=void 0===d.end?f:Math.min(d.end,e);!a.extend&&f>d&&(e=d,d=f,f=e);e=Ke(c,f);var g=Ke(c,\nd);e&&g&&(1!==a.rangeCount||a.anchorNode!==e.node||a.anchorOffset!==e.offset||a.focusNode!==g.node||a.focusOffset!==g.offset)&&(b=b.createRange(),b.setStart(e.node,e.offset),a.removeAllRanges(),f>d?(a.addRange(b),a.extend(g.node,g.offset)):(b.setEnd(g.node,g.offset),a.addRange(b)))}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop});\"function\"===typeof c.focus&&c.focus();for(c=0;c=document.documentMode,Qe=null,Re=null,Se=null,Te=!1;\nfunction Ue(a,b,c){var d=c.window===c?c.document:9===c.nodeType?c:c.ownerDocument;Te||null==Qe||Qe!==Xa(d)||(d=Qe,\"selectionStart\"in d&&Ne(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),Se&&Ie(Se,d)||(Se=d,d=oe(Re,\"onSelect\"),0Tf||(a.current=Sf[Tf],Sf[Tf]=null,Tf--)}function G(a,b){Tf++;Sf[Tf]=a.current;a.current=b}var Vf={},H=Uf(Vf),Wf=Uf(!1),Xf=Vf;function Yf(a,b){var c=a.type.contextTypes;if(!c)return Vf;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}\nfunction Zf(a){a=a.childContextTypes;return null!==a&&void 0!==a}function $f(){E(Wf);E(H)}function ag(a,b,c){if(H.current!==Vf)throw Error(p(168));G(H,b);G(Wf,c)}function bg(a,b,c){var d=a.stateNode;b=b.childContextTypes;if(\"function\"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in b))throw Error(p(108,Ra(a)||\"Unknown\",e));return A({},c,d)}\nfunction cg(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Vf;Xf=H.current;G(H,a);G(Wf,Wf.current);return!0}function dg(a,b,c){var d=a.stateNode;if(!d)throw Error(p(169));c?(a=bg(a,b,Xf),d.__reactInternalMemoizedMergedChildContext=a,E(Wf),E(H),G(H,a)):E(Wf);G(Wf,c)}var eg=null,fg=!1,gg=!1;function hg(a){null===eg?eg=[a]:eg.push(a)}function ig(a){fg=!0;hg(a)}\nfunction jg(){if(!gg&&null!==eg){gg=!0;var a=0,b=C;try{var c=eg;for(C=1;a>=g;e-=g;rg=1<<32-oc(b)+e|c<w?(x=u,u=null):x=u.sibling;var n=r(e,u,h[w],k);if(null===n){null===u&&(u=x);break}a&&u&&null===n.alternate&&b(e,u);g=f(n,g,w);null===m?l=n:m.sibling=n;m=n;u=x}if(w===h.length)return c(e,u),I&&tg(e,w),l;if(null===u){for(;ww?(x=m,m=null):x=m.sibling;var t=r(e,m,n.value,k);if(null===t){null===m&&(m=x);break}a&&m&&null===t.alternate&&b(e,m);g=f(t,g,w);null===u?l=t:u.sibling=t;u=t;m=x}if(n.done)return c(e,\nm),I&&tg(e,w),l;if(null===m){for(;!n.done;w++,n=h.next())n=q(e,n.value,k),null!==n&&(g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);I&&tg(e,w);return l}for(m=d(e,m);!n.done;w++,n=h.next())n=y(m,e,w,n.value,k),null!==n&&(a&&null!==n.alternate&&m.delete(null===n.key?w:n.key),g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);a&&m.forEach(function(a){return b(e,a)});I&&tg(e,w);return l}function J(a,d,f,h){\"object\"===typeof f&&null!==f&&f.type===ya&&null===f.key&&(f=f.props.children);if(\"object\"===typeof f&&null!==f){switch(f.$$typeof){case va:a:{for(var k=\nf.key,l=d;null!==l;){if(l.key===k){k=f.type;if(k===ya){if(7===l.tag){c(a,l.sibling);d=e(l,f.props.children);d.return=a;a=d;break a}}else if(l.elementType===k||\"object\"===typeof k&&null!==k&&k.$$typeof===Ha&&uh(k)===l.type){c(a,l.sibling);d=e(l,f.props);d.ref=sh(a,l,f);d.return=a;a=d;break a}c(a,l);break}else b(a,l);l=l.sibling}f.type===ya?(d=Ah(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=yh(f.type,f.key,f.props,null,a.mode,h),h.ref=sh(a,d,f),h.return=a,a=h)}return g(a);case wa:a:{for(l=f.key;null!==\nd;){if(d.key===l)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=zh(f,a.mode,h);d.return=a;a=d}return g(a);case Ha:return l=f._init,J(a,d,l(f._payload),h)}if(eb(f))return n(a,d,f,h);if(Ka(f))return t(a,d,f,h);th(a,f)}return\"string\"===typeof f&&\"\"!==f||\"number\"===typeof f?(f=\"\"+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):\n(c(a,d),d=xh(f,a.mode,h),d.return=a,a=d),g(a)):c(a,d)}return J}var Bh=vh(!0),Ch=vh(!1),Dh={},Eh=Uf(Dh),Fh=Uf(Dh),Gh=Uf(Dh);function Hh(a){if(a===Dh)throw Error(p(174));return a}function Ih(a,b){G(Gh,b);G(Fh,a);G(Eh,Dh);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:lb(null,\"\");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=lb(b,a)}E(Eh);G(Eh,b)}function Jh(){E(Eh);E(Fh);E(Gh)}\nfunction Kh(a){Hh(Gh.current);var b=Hh(Eh.current);var c=lb(b,a.type);b!==c&&(G(Fh,a),G(Eh,c))}function Lh(a){Fh.current===a&&(E(Eh),E(Fh))}var M=Uf(0);\nfunction Mh(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||\"$?\"===c.data||\"$!\"===c.data))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.flags&128))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}var Nh=[];\nfunction Oh(){for(var a=0;ac?c:4;a(!0);var d=Qh.transition;Qh.transition={};try{a(!1),b()}finally{C=c,Qh.transition=d}}function Fi(){return di().memoizedState}\nfunction Gi(a,b,c){var d=lh(a);c={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(Hi(a))Ii(b,c);else if(c=Yg(a,b,c,d),null!==c){var e=L();mh(c,a,d,e);Ji(c,b,d)}}\nfunction ri(a,b,c){var d=lh(a),e={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(Hi(a))Ii(b,e);else{var f=a.alternate;if(0===a.lanes&&(null===f||0===f.lanes)&&(f=b.lastRenderedReducer,null!==f))try{var g=b.lastRenderedState,h=f(g,c);e.hasEagerState=!0;e.eagerState=h;if(He(h,g)){var k=b.interleaved;null===k?(e.next=e,Xg(b)):(e.next=k.next,k.next=e);b.interleaved=e;return}}catch(l){}finally{}c=Yg(a,b,e,d);null!==c&&(e=L(),mh(c,a,d,e),Ji(c,b,d))}}\nfunction Hi(a){var b=a.alternate;return a===N||null!==b&&b===N}function Ii(a,b){Th=Sh=!0;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}function Ji(a,b,c){if(0!==(c&4194240)){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;Cc(a,c)}}\nvar ai={readContext:Vg,useCallback:Q,useContext:Q,useEffect:Q,useImperativeHandle:Q,useInsertionEffect:Q,useLayoutEffect:Q,useMemo:Q,useReducer:Q,useRef:Q,useState:Q,useDebugValue:Q,useDeferredValue:Q,useTransition:Q,useMutableSource:Q,useSyncExternalStore:Q,useId:Q,unstable_isNewReconciler:!1},Yh={readContext:Vg,useCallback:function(a,b){ci().memoizedState=[a,void 0===b?null:b];return a},useContext:Vg,useEffect:vi,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return ti(4194308,\n4,yi.bind(null,b,a),c)},useLayoutEffect:function(a,b){return ti(4194308,4,a,b)},useInsertionEffect:function(a,b){return ti(4,2,a,b)},useMemo:function(a,b){var c=ci();b=void 0===b?null:b;a=a();c.memoizedState=[a,b];return a},useReducer:function(a,b,c){var d=ci();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a,lastRenderedState:b};d.queue=a;a=a.dispatch=Gi.bind(null,N,a);return[d.memoizedState,a]},useRef:function(a){var b=\nci();a={current:a};return b.memoizedState=a},useState:qi,useDebugValue:Ai,useDeferredValue:function(a){return ci().memoizedState=a},useTransition:function(){var a=qi(!1),b=a[0];a=Ei.bind(null,a[1]);ci().memoizedState=a;return[b,a]},useMutableSource:function(){},useSyncExternalStore:function(a,b,c){var d=N,e=ci();if(I){if(void 0===c)throw Error(p(407));c=c()}else{c=b();if(null===R)throw Error(p(349));0!==(Rh&30)||ni(d,b,c)}e.memoizedState=c;var f={value:c,getSnapshot:b};e.queue=f;vi(ki.bind(null,d,\nf,a),[a]);d.flags|=2048;li(9,mi.bind(null,d,f,c,b),void 0,null);return c},useId:function(){var a=ci(),b=R.identifierPrefix;if(I){var c=sg;var d=rg;c=(d&~(1<<32-oc(d)-1)).toString(32)+c;b=\":\"+b+\"R\"+c;c=Uh++;0\\x3c/script>\",a=a.removeChild(a.firstChild)):\n\"string\"===typeof d.is?a=g.createElement(c,{is:d.is}):(a=g.createElement(c),\"select\"===c&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,c);a[Of]=b;a[Pf]=d;Aj(a,b,!1,!1);b.stateNode=a;a:{g=vb(c,d);switch(c){case \"dialog\":D(\"cancel\",a);D(\"close\",a);e=d;break;case \"iframe\":case \"object\":case \"embed\":D(\"load\",a);e=d;break;case \"video\":case \"audio\":for(e=0;eHj&&(b.flags|=128,d=!0,Ej(f,!1),b.lanes=4194304)}else{if(!d)if(a=Mh(g),null!==a){if(b.flags|=128,d=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.flags|=4),Ej(f,!0),null===f.tail&&\"hidden\"===f.tailMode&&!g.alternate&&!I)return S(b),null}else 2*B()-f.renderingStartTime>Hj&&1073741824!==c&&(b.flags|=128,d=!0,Ej(f,!1),b.lanes=4194304);f.isBackwards?(g.sibling=b.child,b.child=g):(c=f.last,null!==c?c.sibling=g:b.child=g,f.last=g)}if(null!==f.tail)return b=f.tail,f.rendering=\nb,f.tail=b.sibling,f.renderingStartTime=B(),b.sibling=null,c=M.current,G(M,d?c&1|2:c&1),b;S(b);return null;case 22:case 23:return Ij(),d=null!==b.memoizedState,null!==a&&null!==a.memoizedState!==d&&(b.flags|=8192),d&&0!==(b.mode&1)?0!==(gj&1073741824)&&(S(b),b.subtreeFlags&6&&(b.flags|=8192)):S(b),null;case 24:return null;case 25:return null}throw Error(p(156,b.tag));}\nfunction Jj(a,b){wg(b);switch(b.tag){case 1:return Zf(b.type)&&$f(),a=b.flags,a&65536?(b.flags=a&-65537|128,b):null;case 3:return Jh(),E(Wf),E(H),Oh(),a=b.flags,0!==(a&65536)&&0===(a&128)?(b.flags=a&-65537|128,b):null;case 5:return Lh(b),null;case 13:E(M);a=b.memoizedState;if(null!==a&&null!==a.dehydrated){if(null===b.alternate)throw Error(p(340));Ig()}a=b.flags;return a&65536?(b.flags=a&-65537|128,b):null;case 19:return E(M),null;case 4:return Jh(),null;case 10:return Rg(b.type._context),null;case 22:case 23:return Ij(),\nnull;case 24:return null;default:return null}}var Kj=!1,U=!1,Lj=\"function\"===typeof WeakSet?WeakSet:Set,V=null;function Mj(a,b){var c=a.ref;if(null!==c)if(\"function\"===typeof c)try{c(null)}catch(d){W(a,b,d)}else c.current=null}function Nj(a,b,c){try{c()}catch(d){W(a,b,d)}}var Oj=!1;\nfunction Pj(a,b){Cf=dd;a=Me();if(Ne(a)){if(\"selectionStart\"in a)var c={start:a.selectionStart,end:a.selectionEnd};else a:{c=(c=a.ownerDocument)&&c.defaultView||window;var d=c.getSelection&&c.getSelection();if(d&&0!==d.rangeCount){c=d.anchorNode;var e=d.anchorOffset,f=d.focusNode;d=d.focusOffset;try{c.nodeType,f.nodeType}catch(F){c=null;break a}var g=0,h=-1,k=-1,l=0,m=0,q=a,r=null;b:for(;;){for(var y;;){q!==c||0!==e&&3!==q.nodeType||(h=g+e);q!==f||0!==d&&3!==q.nodeType||(k=g+d);3===q.nodeType&&(g+=\nq.nodeValue.length);if(null===(y=q.firstChild))break;r=q;q=y}for(;;){if(q===a)break b;r===c&&++l===e&&(h=g);r===f&&++m===d&&(k=g);if(null!==(y=q.nextSibling))break;q=r;r=q.parentNode}q=y}c=-1===h||-1===k?null:{start:h,end:k}}else c=null}c=c||{start:0,end:0}}else c=null;Df={focusedElem:a,selectionRange:c};dd=!1;for(V=b;null!==V;)if(b=V,a=b.child,0!==(b.subtreeFlags&1028)&&null!==a)a.return=b,V=a;else for(;null!==V;){b=V;try{var n=b.alternate;if(0!==(b.flags&1024))switch(b.tag){case 0:case 11:case 15:break;\ncase 1:if(null!==n){var t=n.memoizedProps,J=n.memoizedState,x=b.stateNode,w=x.getSnapshotBeforeUpdate(b.elementType===b.type?t:Lg(b.type,t),J);x.__reactInternalSnapshotBeforeUpdate=w}break;case 3:var u=b.stateNode.containerInfo;1===u.nodeType?u.textContent=\"\":9===u.nodeType&&u.documentElement&&u.removeChild(u.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(p(163));}}catch(F){W(b,b.return,F)}a=b.sibling;if(null!==a){a.return=b.return;V=a;break}V=b.return}n=Oj;Oj=!1;return n}\nfunction Qj(a,b,c){var d=b.updateQueue;d=null!==d?d.lastEffect:null;if(null!==d){var e=d=d.next;do{if((e.tag&a)===a){var f=e.destroy;e.destroy=void 0;void 0!==f&&Nj(b,c,f)}e=e.next}while(e!==d)}}function Rj(a,b){b=b.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){var c=b=b.next;do{if((c.tag&a)===a){var d=c.create;c.destroy=d()}c=c.next}while(c!==b)}}function Sj(a){var b=a.ref;if(null!==b){var c=a.stateNode;switch(a.tag){case 5:a=c;break;default:a=c}\"function\"===typeof b?b(a):b.current=a}}\nfunction Tj(a){var b=a.alternate;null!==b&&(a.alternate=null,Tj(b));a.child=null;a.deletions=null;a.sibling=null;5===a.tag&&(b=a.stateNode,null!==b&&(delete b[Of],delete b[Pf],delete b[of],delete b[Qf],delete b[Rf]));a.stateNode=null;a.return=null;a.dependencies=null;a.memoizedProps=null;a.memoizedState=null;a.pendingProps=null;a.stateNode=null;a.updateQueue=null}function Uj(a){return 5===a.tag||3===a.tag||4===a.tag}\nfunction Vj(a){a:for(;;){for(;null===a.sibling;){if(null===a.return||Uj(a.return))return null;a=a.return}a.sibling.return=a.return;for(a=a.sibling;5!==a.tag&&6!==a.tag&&18!==a.tag;){if(a.flags&2)continue a;if(null===a.child||4===a.tag)continue a;else a.child.return=a,a=a.child}if(!(a.flags&2))return a.stateNode}}\nfunction Wj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=Bf));else if(4!==d&&(a=a.child,null!==a))for(Wj(a,b,c),a=a.sibling;null!==a;)Wj(a,b,c),a=a.sibling}\nfunction Xj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?c.insertBefore(a,b):c.appendChild(a);else if(4!==d&&(a=a.child,null!==a))for(Xj(a,b,c),a=a.sibling;null!==a;)Xj(a,b,c),a=a.sibling}var X=null,Yj=!1;function Zj(a,b,c){for(c=c.child;null!==c;)ak(a,b,c),c=c.sibling}\nfunction ak(a,b,c){if(lc&&\"function\"===typeof lc.onCommitFiberUnmount)try{lc.onCommitFiberUnmount(kc,c)}catch(h){}switch(c.tag){case 5:U||Mj(c,b);case 6:var d=X,e=Yj;X=null;Zj(a,b,c);X=d;Yj=e;null!==X&&(Yj?(a=X,c=c.stateNode,8===a.nodeType?a.parentNode.removeChild(c):a.removeChild(c)):X.removeChild(c.stateNode));break;case 18:null!==X&&(Yj?(a=X,c=c.stateNode,8===a.nodeType?Kf(a.parentNode,c):1===a.nodeType&&Kf(a,c),bd(a)):Kf(X,c.stateNode));break;case 4:d=X;e=Yj;X=c.stateNode.containerInfo;Yj=!0;\nZj(a,b,c);X=d;Yj=e;break;case 0:case 11:case 14:case 15:if(!U&&(d=c.updateQueue,null!==d&&(d=d.lastEffect,null!==d))){e=d=d.next;do{var f=e,g=f.destroy;f=f.tag;void 0!==g&&(0!==(f&2)?Nj(c,b,g):0!==(f&4)&&Nj(c,b,g));e=e.next}while(e!==d)}Zj(a,b,c);break;case 1:if(!U&&(Mj(c,b),d=c.stateNode,\"function\"===typeof d.componentWillUnmount))try{d.props=c.memoizedProps,d.state=c.memoizedState,d.componentWillUnmount()}catch(h){W(c,b,h)}Zj(a,b,c);break;case 21:Zj(a,b,c);break;case 22:c.mode&1?(U=(d=U)||null!==\nc.memoizedState,Zj(a,b,c),U=d):Zj(a,b,c);break;default:Zj(a,b,c)}}function bk(a){var b=a.updateQueue;if(null!==b){a.updateQueue=null;var c=a.stateNode;null===c&&(c=a.stateNode=new Lj);b.forEach(function(b){var d=ck.bind(null,a,b);c.has(b)||(c.add(b),b.then(d,d))})}}\nfunction dk(a,b){var c=b.deletions;if(null!==c)for(var d=0;de&&(e=g);d&=~f}d=e;d=B()-d;d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*mk(d/1960))-d;if(10a?16:a;if(null===xk)var d=!1;else{a=xk;xk=null;yk=0;if(0!==(K&6))throw Error(p(331));var e=K;K|=4;for(V=a.current;null!==V;){var f=V,g=f.child;if(0!==(V.flags&16)){var h=f.deletions;if(null!==h){for(var k=0;kB()-gk?Lk(a,0):sk|=c);Ek(a,b)}function Zk(a,b){0===b&&(0===(a.mode&1)?b=1:(b=sc,sc<<=1,0===(sc&130023424)&&(sc=4194304)));var c=L();a=Zg(a,b);null!==a&&(Ac(a,b,c),Ek(a,c))}function vj(a){var b=a.memoizedState,c=0;null!==b&&(c=b.retryLane);Zk(a,c)}\nfunction ck(a,b){var c=0;switch(a.tag){case 13:var d=a.stateNode;var e=a.memoizedState;null!==e&&(c=e.retryLane);break;case 19:d=a.stateNode;break;default:throw Error(p(314));}null!==d&&d.delete(b);Zk(a,c)}var Wk;\nWk=function(a,b,c){if(null!==a)if(a.memoizedProps!==b.pendingProps||Wf.current)Ug=!0;else{if(0===(a.lanes&c)&&0===(b.flags&128))return Ug=!1,zj(a,b,c);Ug=0!==(a.flags&131072)?!0:!1}else Ug=!1,I&&0!==(b.flags&1048576)&&ug(b,ng,b.index);b.lanes=0;switch(b.tag){case 2:var d=b.type;jj(a,b);a=b.pendingProps;var e=Yf(b,H.current);Tg(b,c);e=Xh(null,b,d,a,e,c);var f=bi();b.flags|=1;\"object\"===typeof e&&null!==e&&\"function\"===typeof e.render&&void 0===e.$$typeof?(b.tag=1,b.memoizedState=null,b.updateQueue=\nnull,Zf(d)?(f=!0,cg(b)):f=!1,b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null,ah(b),e.updater=nh,b.stateNode=e,e._reactInternals=b,rh(b,d,a,c),b=kj(null,b,d,!0,f,c)):(b.tag=0,I&&f&&vg(b),Yi(null,b,e,c),b=b.child);return b;case 16:d=b.elementType;a:{jj(a,b);a=b.pendingProps;e=d._init;d=e(d._payload);b.type=d;e=b.tag=$k(d);a=Lg(d,a);switch(e){case 0:b=dj(null,b,d,a,c);break a;case 1:b=ij(null,b,d,a,c);break a;case 11:b=Zi(null,b,d,a,c);break a;case 14:b=aj(null,b,d,Lg(d.type,a),c);break a}throw Error(p(306,\nd,\"\"));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),dj(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),ij(a,b,d,e,c);case 3:a:{lj(b);if(null===a)throw Error(p(387));d=b.pendingProps;f=b.memoizedState;e=f.element;bh(a,b);gh(b,d,null,c);var g=b.memoizedState;d=g.element;if(f.isDehydrated)if(f={element:d,isDehydrated:!1,cache:g.cache,pendingSuspenseBoundaries:g.pendingSuspenseBoundaries,transitions:g.transitions},b.updateQueue.baseState=\nf,b.memoizedState=f,b.flags&256){e=Ki(Error(p(423)),b);b=mj(a,b,d,c,e);break a}else if(d!==e){e=Ki(Error(p(424)),b);b=mj(a,b,d,c,e);break a}else for(yg=Lf(b.stateNode.containerInfo.firstChild),xg=b,I=!0,zg=null,c=Ch(b,null,d,c),b.child=c;c;)c.flags=c.flags&-3|4096,c=c.sibling;else{Ig();if(d===e){b=$i(a,b,c);break a}Yi(a,b,d,c)}b=b.child}return b;case 5:return Kh(b),null===a&&Eg(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:null,g=e.children,Ef(d,e)?g=null:null!==f&&Ef(d,f)&&(b.flags|=32),\nhj(a,b),Yi(a,b,g,c),b.child;case 6:return null===a&&Eg(b),null;case 13:return pj(a,b,c);case 4:return Ih(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=Bh(b,null,d,c):Yi(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),Zi(a,b,d,e,c);case 7:return Yi(a,b,b.pendingProps,c),b.child;case 8:return Yi(a,b,b.pendingProps.children,c),b.child;case 12:return Yi(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;f=b.memoizedProps;\ng=e.value;G(Mg,d._currentValue);d._currentValue=g;if(null!==f)if(He(f.value,g)){if(f.children===e.children&&!Wf.current){b=$i(a,b,c);break a}}else for(f=b.child,null!==f&&(f.return=b);null!==f;){var h=f.dependencies;if(null!==h){g=f.child;for(var k=h.firstContext;null!==k;){if(k.context===d){if(1===f.tag){k=ch(-1,c&-c);k.tag=2;var l=f.updateQueue;if(null!==l){l=l.shared;var m=l.pending;null===m?k.next=k:(k.next=m.next,m.next=k);l.pending=k}}f.lanes|=c;k=f.alternate;null!==k&&(k.lanes|=c);Sg(f.return,\nc,b);h.lanes|=c;break}k=k.next}}else if(10===f.tag)g=f.type===b.type?null:f.child;else if(18===f.tag){g=f.return;if(null===g)throw Error(p(341));g.lanes|=c;h=g.alternate;null!==h&&(h.lanes|=c);Sg(g,c,b);g=f.sibling}else g=f.child;if(null!==g)g.return=f;else for(g=f;null!==g;){if(g===b){g=null;break}f=g.sibling;if(null!==f){f.return=g.return;g=f;break}g=g.return}f=g}Yi(a,b,e.children,c);b=b.child}return b;case 9:return e=b.type,d=b.pendingProps.children,Tg(b,c),e=Vg(e),d=d(e),b.flags|=1,Yi(a,b,d,c),\nb.child;case 14:return d=b.type,e=Lg(d,b.pendingProps),e=Lg(d.type,e),aj(a,b,d,e,c);case 15:return cj(a,b,b.type,b.pendingProps,c);case 17:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),jj(a,b),b.tag=1,Zf(d)?(a=!0,cg(b)):a=!1,Tg(b,c),ph(b,d,e),rh(b,d,e,c),kj(null,b,d,!0,a,c);case 19:return yj(a,b,c);case 22:return ej(a,b,c)}throw Error(p(156,b.tag));};function Gk(a,b){return ac(a,b)}\nfunction al(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.subtreeFlags=this.flags=0;this.deletions=null;this.childLanes=this.lanes=0;this.alternate=null}function Bg(a,b,c,d){return new al(a,b,c,d)}function bj(a){a=a.prototype;return!(!a||!a.isReactComponent)}\nfunction $k(a){if(\"function\"===typeof a)return bj(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===Da)return 11;if(a===Ga)return 14}return 2}\nfunction wh(a,b){var c=a.alternate;null===c?(c=Bg(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.type=a.type,c.flags=0,c.subtreeFlags=0,c.deletions=null);c.flags=a.flags&14680064;c.childLanes=a.childLanes;c.lanes=a.lanes;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue=a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{lanes:b.lanes,firstContext:b.firstContext};\nc.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c}\nfunction yh(a,b,c,d,e,f){var g=2;d=a;if(\"function\"===typeof a)bj(a)&&(g=1);else if(\"string\"===typeof a)g=5;else a:switch(a){case ya:return Ah(c.children,e,f,b);case za:g=8;e|=8;break;case Aa:return a=Bg(12,c,b,e|2),a.elementType=Aa,a.lanes=f,a;case Ea:return a=Bg(13,c,b,e),a.elementType=Ea,a.lanes=f,a;case Fa:return a=Bg(19,c,b,e),a.elementType=Fa,a.lanes=f,a;case Ia:return qj(c,e,f,b);default:if(\"object\"===typeof a&&null!==a)switch(a.$$typeof){case Ba:g=10;break a;case Ca:g=9;break a;case Da:g=11;\nbreak a;case Ga:g=14;break a;case Ha:g=16;d=null;break a}throw Error(p(130,null==a?a:typeof a,\"\"));}b=Bg(g,c,b,e);b.elementType=a;b.type=d;b.lanes=f;return b}function Ah(a,b,c,d){a=Bg(7,a,d,b);a.lanes=c;return a}function qj(a,b,c,d){a=Bg(22,a,d,b);a.elementType=Ia;a.lanes=c;a.stateNode={isHidden:!1};return a}function xh(a,b,c){a=Bg(6,a,null,b);a.lanes=c;return a}\nfunction zh(a,b,c){b=Bg(4,null!==a.children?a.children:[],a.key,b);b.lanes=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}\nfunction bl(a,b,c,d,e){this.tag=b;this.containerInfo=a;this.finishedWork=this.pingCache=this.current=this.pendingChildren=null;this.timeoutHandle=-1;this.callbackNode=this.pendingContext=this.context=null;this.callbackPriority=0;this.eventTimes=zc(0);this.expirationTimes=zc(-1);this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0;this.entanglements=zc(0);this.identifierPrefix=d;this.onRecoverableError=e;this.mutableSourceEagerHydrationData=\nnull}function cl(a,b,c,d,e,f,g,h,k){a=new bl(a,b,c,h,k);1===b?(b=1,!0===f&&(b|=8)):b=0;f=Bg(3,null,null,b);a.current=f;f.stateNode=a;f.memoizedState={element:d,isDehydrated:c,cache:null,transitions:null,pendingSuspenseBoundaries:null};ah(f);return a}function dl(a,b,c){var d=3 {\n throw TypeError(msg);\n};\nvar __accessCheck = (obj, member, msg) => member.has(obj) || __typeError(\"Cannot \" + msg);\nvar __privateGet = (obj, member, getter) => (__accessCheck(obj, member, \"read from private field\"), getter ? getter.call(obj) : member.get(obj));\nvar __privateAdd = (obj, member, value) => member.has(obj) ? __typeError(\"Cannot add the same private member more than once\") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\nvar __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, \"write to private field\"), setter ? setter.call(obj, value) : member.set(obj, value), value);\n\n// lib/router/url.ts\nvar ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|[\\\\/]{2})/i;\nvar PROTOCOL_RELATIVE_URL_REGEX = /^[\\\\/]{2}/;\nfunction normalizeProtocolRelativeUrl(url, protocol) {\n return protocol + url.replace(/\\\\/g, \"/\");\n}\n\n// lib/router/history.ts\nvar Action = /* @__PURE__ */ ((Action2) => {\n Action2[\"Pop\"] = \"POP\";\n Action2[\"Push\"] = \"PUSH\";\n Action2[\"Replace\"] = \"REPLACE\";\n return Action2;\n})(Action || {});\nvar PopStateEventType = \"popstate\";\nfunction isLocation(obj) {\n return typeof obj === \"object\" && obj != null && \"pathname\" in obj && \"search\" in obj && \"hash\" in obj && \"state\" in obj && \"key\" in obj;\n}\nfunction createMemoryHistory(options = {}) {\n let { initialEntries = [\"/\"], initialIndex, v5Compat = false } = options;\n let entries;\n entries = initialEntries.map(\n (entry, index2) => createMemoryLocation(\n entry,\n typeof entry === \"string\" ? null : entry.state,\n index2 === 0 ? \"default\" : void 0,\n typeof entry === \"string\" ? void 0 : entry.mask\n )\n );\n let index = clampIndex(\n initialIndex == null ? entries.length - 1 : initialIndex\n );\n let action = \"POP\" /* Pop */;\n let listener = null;\n function clampIndex(n) {\n return Math.min(Math.max(n, 0), entries.length - 1);\n }\n function getCurrentLocation() {\n return entries[index];\n }\n function createMemoryLocation(to, state = null, key, mask) {\n let location = createLocation(\n entries ? getCurrentLocation().pathname : \"/\",\n to,\n state,\n key,\n mask\n );\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in memory history: ${JSON.stringify(\n to\n )}`\n );\n return location;\n }\n function createHref2(to) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n let history = {\n get index() {\n return index;\n },\n get action() {\n return action;\n },\n get location() {\n return getCurrentLocation();\n },\n createHref: createHref2,\n createURL(to) {\n return new URL(createHref2(to), \"http://localhost\");\n },\n encodeLocation(to) {\n let path = typeof to === \"string\" ? parsePath(to) : to;\n return {\n pathname: path.pathname || \"\",\n search: path.search || \"\",\n hash: path.hash || \"\"\n };\n },\n push(to, state) {\n action = \"PUSH\" /* Push */;\n let nextLocation = isLocation(to) ? to : createMemoryLocation(to, state);\n index += 1;\n entries.splice(index, entries.length, nextLocation);\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 1 });\n }\n },\n replace(to, state) {\n action = \"REPLACE\" /* Replace */;\n let nextLocation = isLocation(to) ? to : createMemoryLocation(to, state);\n entries[index] = nextLocation;\n if (v5Compat && listener) {\n listener({ action, location: nextLocation, delta: 0 });\n }\n },\n go(delta) {\n action = \"POP\" /* Pop */;\n let nextIndex = clampIndex(index + delta);\n let nextLocation = entries[nextIndex];\n index = nextIndex;\n if (listener) {\n listener({ action, location: nextLocation, delta });\n }\n },\n listen(fn) {\n listener = fn;\n return () => {\n listener = null;\n };\n }\n };\n return history;\n}\nfunction createBrowserHistory(options = {}) {\n function createBrowserLocation(window2, globalHistory) {\n let maskedLocation = globalHistory.state?.masked;\n let { pathname, search, hash } = maskedLocation || window2.location;\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n globalHistory.state && globalHistory.state.usr || null,\n globalHistory.state && globalHistory.state.key || \"default\",\n maskedLocation ? {\n pathname: window2.location.pathname,\n search: window2.location.search,\n hash: window2.location.hash\n } : void 0\n );\n }\n function createBrowserHref(window2, to) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n return getUrlBasedHistory(\n createBrowserLocation,\n createBrowserHref,\n null,\n options\n );\n}\nfunction createHashHistory(options = {}) {\n function createHashLocation(window2, globalHistory) {\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\"\n } = parsePath(window2.location.hash.substring(1));\n if (!pathname.startsWith(\"/\") && !pathname.startsWith(\".\")) {\n pathname = \"/\" + pathname;\n }\n return createLocation(\n \"\",\n { pathname, search, hash },\n // state defaults to `null` because `window.history.state` does\n globalHistory.state && globalHistory.state.usr || null,\n globalHistory.state && globalHistory.state.key || \"default\"\n );\n }\n function createHashHref(window2, to) {\n let base = window2.document.querySelector(\"base\");\n let href = \"\";\n if (base && base.getAttribute(\"href\")) {\n let url = window2.location.href;\n let hashIndex = url.indexOf(\"#\");\n href = hashIndex === -1 ? url : url.slice(0, hashIndex);\n }\n return href + \"#\" + (typeof to === \"string\" ? to : createPath(to));\n }\n function validateHashLocation(location, to) {\n warning(\n location.pathname.charAt(0) === \"/\",\n `relative pathnames are not supported in hash history.push(${JSON.stringify(\n to\n )})`\n );\n }\n return getUrlBasedHistory(\n createHashLocation,\n createHashHref,\n validateHashLocation,\n options\n );\n}\nfunction invariant(value, message) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\nfunction warning(cond, message) {\n if (!cond) {\n if (typeof console !== \"undefined\") console.warn(message);\n try {\n throw new Error(message);\n } catch (e) {\n }\n }\n}\nfunction createKey() {\n return Math.random().toString(36).substring(2, 10);\n}\nfunction getHistoryState(location, index) {\n return {\n usr: location.state,\n key: location.key,\n idx: index,\n masked: location.mask ? {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash\n } : void 0\n };\n}\nfunction createLocation(current, to, state = null, key, mask) {\n let location = {\n pathname: typeof current === \"string\" ? current : current.pathname,\n search: \"\",\n hash: \"\",\n ...typeof to === \"string\" ? parsePath(to) : to,\n state,\n // TODO: This could be cleaned up. push/replace should probably just take\n // full Locations now and avoid the need to run through this flow at all\n // But that's a pretty big refactor to the current test suite so going to\n // keep as is for the time being and just let any incoming keys take precedence\n key: to && to.key || key || createKey(),\n mask\n };\n return location;\n}\nfunction createPath({\n pathname = \"/\",\n search = \"\",\n hash = \"\"\n}) {\n if (search && search !== \"?\")\n pathname += search.charAt(0) === \"?\" ? search : \"?\" + search;\n if (hash && hash !== \"#\")\n pathname += hash.charAt(0) === \"#\" ? hash : \"#\" + hash;\n return pathname;\n}\nfunction parsePath(path) {\n let parsedPath = {};\n if (path) {\n let hashIndex = path.indexOf(\"#\");\n if (hashIndex >= 0) {\n parsedPath.hash = path.substring(hashIndex);\n path = path.substring(0, hashIndex);\n }\n let searchIndex = path.indexOf(\"?\");\n if (searchIndex >= 0) {\n parsedPath.search = path.substring(searchIndex);\n path = path.substring(0, searchIndex);\n }\n if (path) {\n parsedPath.pathname = path;\n }\n }\n return parsedPath;\n}\nfunction getUrlBasedHistory(getLocation, createHref2, validateLocation, options = {}) {\n let { window: window2 = document.defaultView, v5Compat = false } = options;\n let globalHistory = window2.history;\n let action = \"POP\" /* Pop */;\n let listener = null;\n let index = getIndex();\n if (index == null) {\n index = 0;\n globalHistory.replaceState({ ...globalHistory.state, idx: index }, \"\");\n }\n function getIndex() {\n let state = globalHistory.state || { idx: null };\n return state.idx;\n }\n function handlePop() {\n action = \"POP\" /* Pop */;\n let nextIndex = getIndex();\n let delta = nextIndex == null ? null : nextIndex - index;\n index = nextIndex;\n if (listener) {\n listener({ action, location: history.location, delta });\n }\n }\n function push(to, state) {\n action = \"PUSH\" /* Push */;\n let location = isLocation(to) ? to : createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n index = getIndex() + 1;\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location.mask || location);\n try {\n globalHistory.pushState(historyState, \"\", url);\n } catch (error) {\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw error;\n }\n window2.location.assign(url);\n }\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 1 });\n }\n }\n function replace2(to, state) {\n action = \"REPLACE\" /* Replace */;\n let location = isLocation(to) ? to : createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n index = getIndex();\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location.mask || location);\n globalHistory.replaceState(historyState, \"\", url);\n if (v5Compat && listener) {\n listener({ action, location: history.location, delta: 0 });\n }\n }\n function createURL(to) {\n return createBrowserURLImpl(window2, to);\n }\n let history = {\n get action() {\n return action;\n },\n get location() {\n return getLocation(window2, globalHistory);\n },\n listen(fn) {\n if (listener) {\n throw new Error(\"A history only accepts one active listener\");\n }\n window2.addEventListener(PopStateEventType, handlePop);\n listener = fn;\n return () => {\n window2.removeEventListener(PopStateEventType, handlePop);\n listener = null;\n };\n },\n createHref(to) {\n return createHref2(window2, to);\n },\n createURL,\n encodeLocation(to) {\n let url = createURL(to);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash\n };\n },\n push,\n replace: replace2,\n go(n) {\n return globalHistory.go(n);\n }\n };\n return history;\n}\nfunction createBrowserURLImpl(windowImpl, to, isAbsolute = false) {\n let base = \"http://localhost\";\n if (windowImpl) {\n base = windowImpl.location.origin !== \"null\" ? windowImpl.location.origin : windowImpl.location.href;\n }\n invariant(base, \"No window.location.(origin|href) available to create URL\");\n let href = typeof to === \"string\" ? to : createPath(to);\n href = href.replace(/ $/, \"%20\");\n if (!isAbsolute && PROTOCOL_RELATIVE_URL_REGEX.test(href)) {\n href = base + href;\n }\n return new URL(href, base);\n}\n\n// lib/router/utils.ts\nfunction createContext(defaultValue) {\n return { defaultValue };\n}\nvar _map;\nvar RouterContextProvider = class {\n /**\n * Create a new `RouterContextProvider` instance\n * @param init An optional initial context map to populate the provider with\n */\n constructor(init) {\n __privateAdd(this, _map, /* @__PURE__ */ new Map());\n if (init) {\n for (let [context, value] of init) {\n this.set(context, value);\n }\n }\n }\n /**\n * Access a value from the context. If no value has been set for the context,\n * it will return the context's `defaultValue` if provided, or throw an error\n * if no `defaultValue` was set.\n * @param context The context to get the value for\n * @returns The value for the context, or the context's `defaultValue` if no\n * value was set\n */\n get(context) {\n if (__privateGet(this, _map).has(context)) {\n return __privateGet(this, _map).get(context);\n }\n if (context.defaultValue !== void 0) {\n return context.defaultValue;\n }\n throw new Error(\"No value found for context\");\n }\n /**\n * Set a value for the context. If the context already has a value set, this\n * will overwrite it.\n *\n * @param context The context to set the value for\n * @param value The value to set for the context\n * @returns {void}\n */\n set(context, value) {\n __privateGet(this, _map).set(context, value);\n }\n};\n_map = new WeakMap();\nvar unsupportedLazyRouteObjectKeys = /* @__PURE__ */ new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"children\"\n]);\nfunction isUnsupportedLazyRouteObjectKey(key) {\n return unsupportedLazyRouteObjectKeys.has(\n key\n );\n}\nvar unsupportedLazyRouteFunctionKeys = /* @__PURE__ */ new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"middleware\",\n \"children\"\n]);\nfunction isUnsupportedLazyRouteFunctionKey(key) {\n return unsupportedLazyRouteFunctionKeys.has(\n key\n );\n}\nfunction isIndexRoute(route) {\n return route.index === true;\n}\nfunction convertRoutesToDataRoutes(routes, mapRouteProperties2, parentPath = [], manifest = {}, allowInPlaceMutations = false) {\n return routes.map((route, index) => {\n let treePath = [...parentPath, String(index)];\n let id = typeof route.id === \"string\" ? route.id : treePath.join(\"-\");\n invariant(\n route.index !== true || !route.children,\n `Cannot specify children on an index route`\n );\n invariant(\n allowInPlaceMutations || !manifest[id],\n `Found a route id collision on id \"${id}\". Route id's must be globally unique within Data Router usages`\n );\n if (isIndexRoute(route)) {\n let indexRoute = {\n ...route,\n id\n };\n manifest[id] = mergeRouteUpdates(\n indexRoute,\n mapRouteProperties2(indexRoute)\n );\n return indexRoute;\n } else {\n let pathOrLayoutRoute = {\n ...route,\n id,\n children: void 0\n };\n manifest[id] = mergeRouteUpdates(\n pathOrLayoutRoute,\n mapRouteProperties2(pathOrLayoutRoute)\n );\n if (route.children) {\n pathOrLayoutRoute.children = convertRoutesToDataRoutes(\n route.children,\n mapRouteProperties2,\n treePath,\n manifest,\n allowInPlaceMutations\n );\n }\n return pathOrLayoutRoute;\n }\n });\n}\nfunction mergeRouteUpdates(route, updates) {\n return Object.assign(route, {\n ...updates,\n ...typeof updates.lazy === \"object\" && updates.lazy != null ? {\n lazy: {\n ...route.lazy,\n ...updates.lazy\n }\n } : {}\n });\n}\nfunction matchRoutes(routes, locationArg, basename = \"/\") {\n return matchRoutesImpl(routes, locationArg, basename, false);\n}\nfunction matchRoutesImpl(routes, locationArg, basename, allowPartial, precomputedBranches) {\n let location = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n let pathname = stripBasename(location.pathname || \"/\", basename);\n if (pathname == null) {\n return null;\n }\n let branches = precomputedBranches ?? flattenAndRankRoutes(routes);\n let matches = null;\n let decoded = decodePath(pathname);\n for (let i = 0; matches == null && i < branches.length; ++i) {\n matches = matchRouteBranch(\n branches[i],\n decoded,\n allowPartial\n );\n }\n return matches;\n}\nfunction convertRouteMatchToUiMatch(match, loaderData) {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id],\n loaderData: loaderData[route.id],\n handle: route.handle\n };\n}\nfunction flattenAndRankRoutes(routes) {\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n return branches;\n}\nfunction flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = \"\", _hasParentOptionalSegments = false) {\n let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath) => {\n let meta = {\n relativePath: relativePath === void 0 ? route.path || \"\" : relativePath,\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route\n };\n if (meta.relativePath.startsWith(\"/\")) {\n if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) {\n return;\n }\n invariant(\n meta.relativePath.startsWith(parentPath),\n `Absolute route path \"${meta.relativePath}\" nested under path \"${parentPath}\" is not valid. An absolute child route path must start with the combined path of all its parent routes.`\n );\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n let path = joinPaths([parentPath, meta.relativePath]);\n let routesMeta = parentsMeta.concat(meta);\n if (route.children && route.children.length > 0) {\n invariant(\n // Our types know better, but runtime JS may not!\n // @ts-expect-error\n route.index !== true,\n `Index routes must not have child routes. Please remove all child routes from route path \"${path}\".`\n );\n flattenRoutes(\n route.children,\n branches,\n routesMeta,\n path,\n hasParentOptionalSegments\n );\n }\n if (route.path == null && !route.index) {\n return;\n }\n branches.push({\n path,\n score: computeScore(path, route.index),\n routesMeta: routesMeta.map((meta2, i) => {\n let [matcher, params] = compilePath(\n meta2.relativePath,\n meta2.caseSensitive,\n i === routesMeta.length - 1\n );\n return {\n ...meta2,\n matcher,\n compiledParams: params\n };\n })\n });\n };\n routes.forEach((route, index) => {\n if (route.path === \"\" || !route.path?.includes(\"?\")) {\n flattenRoute(route, index);\n } else {\n for (let exploded of explodeOptionalSegments(route.path)) {\n flattenRoute(route, index, true, exploded);\n }\n }\n });\n return branches;\n}\nfunction explodeOptionalSegments(path) {\n let segments = path.split(\"/\");\n if (segments.length === 0) return [];\n let [first, ...rest] = segments;\n let isOptional = first.endsWith(\"?\");\n let required = first.replace(/\\?$/, \"\");\n if (rest.length === 0) {\n return isOptional ? [required, \"\"] : [required];\n }\n let restExploded = explodeOptionalSegments(rest.join(\"/\"));\n let result = [];\n result.push(\n ...restExploded.map(\n (subpath) => subpath === \"\" ? required : [required, subpath].join(\"/\")\n )\n );\n if (isOptional) {\n result.push(...restExploded);\n }\n return result.map(\n (exploded) => path.startsWith(\"/\") && exploded === \"\" ? \"/\" : exploded\n );\n}\nfunction rankRouteBranches(branches) {\n branches.sort(\n (a, b) => a.score !== b.score ? b.score - a.score : compareIndexes(\n a.routesMeta.map((meta) => meta.childrenIndex),\n b.routesMeta.map((meta) => meta.childrenIndex)\n )\n );\n}\nvar paramRe = /^:[\\w-]+$/;\nvar dynamicSegmentValue = 3;\nvar indexRouteValue = 2;\nvar emptySegmentValue = 1;\nvar staticSegmentValue = 10;\nvar splatPenalty = -2;\nvar isSplat = (s) => s === \"*\";\nfunction computeScore(path, index) {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n if (index) {\n initialScore += indexRouteValue;\n }\n return segments.filter((s) => !isSplat(s)).reduce(\n (score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === \"\" ? emptySegmentValue : staticSegmentValue),\n initialScore\n );\n}\nfunction compareIndexes(a, b) {\n let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);\n return siblings ? (\n // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1]\n ) : (\n // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0\n );\n}\nfunction matchRouteBranch(branch, pathname, allowPartial = false) {\n let { routesMeta } = branch;\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches = [];\n for (let i = 0; i < routesMeta.length; ++i) {\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname = matchedPathname === \"/\" ? pathname : pathname.slice(matchedPathname.length) || \"/\";\n let pattern = {\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end\n };\n let match = (\n // Use precomputed matcher if it exists\n meta.matcher && meta.compiledParams ? matchPathImpl(\n pattern,\n remainingPathname,\n meta.matcher,\n meta.compiledParams\n ) : matchPath(pattern, remainingPathname)\n );\n let route = meta.route;\n if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) {\n match = matchPath(\n {\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end: false\n },\n remainingPathname\n );\n }\n if (!match) {\n return null;\n }\n Object.assign(matchedParams, match.params);\n matches.push({\n // TODO: Can this as be avoided?\n params: matchedParams,\n pathname: joinPaths([matchedPathname, match.pathname]),\n pathnameBase: normalizePathname(\n joinPaths([matchedPathname, match.pathnameBase])\n ),\n route\n });\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);\n }\n }\n return matches;\n}\nfunction generatePath(originalPath, params = {}) {\n let path = originalPath;\n if (path.endsWith(\"*\") && path !== \"*\" && !path.endsWith(\"/*\")) {\n warning(\n false,\n `Route path \"${path}\" will be treated as if it were \"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must always follow a \\`/\\` in the pattern. To get rid of this warning, please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n path = path.replace(/\\*$/, \"/*\");\n }\n const prefix = path.startsWith(\"/\") ? \"/\" : \"\";\n const stringify2 = (p) => p == null ? \"\" : typeof p === \"string\" ? p : String(p);\n const segments = path.split(/\\/+/).map((segment, index, array) => {\n const isLastSegment = index === array.length - 1;\n if (isLastSegment && segment === \"*\") {\n return stringify2(params[\"*\"]);\n }\n const keyMatch = segment.match(/^:([\\w-]+)(\\??)(.*)/);\n if (keyMatch) {\n const [, key, optional, suffix] = keyMatch;\n let param = params[key];\n invariant(optional === \"?\" || param != null, `Missing \":${key}\" param`);\n return encodeURIComponent(stringify2(param)) + suffix;\n }\n return segment.replace(/\\?$/g, \"\");\n }).filter((segment) => !!segment);\n return prefix + segments.join(\"/\");\n}\nfunction matchPath(pattern, pathname) {\n if (typeof pattern === \"string\") {\n pattern = { path: pattern, caseSensitive: false, end: true };\n }\n let [matcher, compiledParams] = compilePath(\n pattern.path,\n pattern.caseSensitive,\n pattern.end\n );\n return matchPathImpl(pattern, pathname, matcher, compiledParams);\n}\nfunction matchPathImpl(pattern, pathname, matcher, compiledParams) {\n let match = pathname.match(matcher);\n if (!match) return null;\n let matchedPathname = match[0];\n let pathnameBase = matchedPathname.replace(/(.)\\/+$/, \"$1\");\n let captureGroups = match.slice(1);\n let params = compiledParams.reduce(\n (memo2, { paramName, isOptional }, index) => {\n if (paramName === \"*\") {\n let splatValue = captureGroups[index] || \"\";\n pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\\/+$/, \"$1\");\n }\n const value = captureGroups[index];\n if (isOptional && !value) {\n memo2[paramName] = void 0;\n } else {\n memo2[paramName] = (value || \"\").replace(/%2F/g, \"/\");\n }\n return memo2;\n },\n {}\n );\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern\n };\n}\nfunction compilePath(path, caseSensitive = false, end = true) {\n warning(\n path === \"*\" || !path.endsWith(\"*\") || path.endsWith(\"/*\"),\n `Route path \"${path}\" will be treated as if it were \"${path.replace(/\\*$/, \"/*\")}\" because the \\`*\\` character must always follow a \\`/\\` in the pattern. To get rid of this warning, please change the route path to \"${path.replace(/\\*$/, \"/*\")}\".`\n );\n let params = [];\n let regexpSource = \"^\" + path.replace(/\\/*\\*?$/, \"\").replace(/^\\/*/, \"/\").replace(/[\\\\.*+^${}|()[\\]]/g, \"\\\\$&\").replace(\n /\\/:([\\w-]+)(\\?)?/g,\n (match, paramName, isOptional, index, str) => {\n params.push({ paramName, isOptional: isOptional != null });\n if (isOptional) {\n let nextChar = str.charAt(index + match.length);\n if (nextChar && nextChar !== \"/\") {\n return \"/([^\\\\/]*)\";\n }\n return \"(?:/([^\\\\/]*))?\";\n }\n return \"/([^\\\\/]+)\";\n }\n ).replace(/\\/([\\w-]+)\\?(\\/|$)/g, \"(/$1)?$2\");\n if (path.endsWith(\"*\")) {\n params.push({ paramName: \"*\" });\n regexpSource += path === \"*\" || path === \"/*\" ? \"(.*)$\" : \"(?:\\\\/(.+)|\\\\/*)$\";\n } else if (end) {\n regexpSource += \"\\\\/*$\";\n } else if (path !== \"\" && path !== \"/\") {\n regexpSource += \"(?:(?=\\\\/|$))\";\n } else {\n }\n let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : \"i\");\n return [matcher, params];\n}\nfunction decodePath(value) {\n try {\n return value.split(\"/\").map((v) => decodeURIComponent(v).replace(/\\//g, \"%2F\")).join(\"/\");\n } catch (error) {\n warning(\n false,\n `The URL path \"${value}\" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${error}).`\n );\n return value;\n }\n}\nfunction stripBasename(pathname, basename) {\n if (basename === \"/\") return pathname;\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return null;\n }\n let startIndex = basename.endsWith(\"/\") ? basename.length - 1 : basename.length;\n let nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== \"/\") {\n return null;\n }\n return pathname.slice(startIndex) || \"/\";\n}\nfunction prependBasename({\n basename,\n pathname\n}) {\n return pathname === \"/\" ? basename : joinPaths([basename, pathname]);\n}\nvar isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url);\nfunction resolvePath(to, fromPathname = \"/\") {\n let {\n pathname: toPathname,\n search = \"\",\n hash = \"\"\n } = typeof to === \"string\" ? parsePath(to) : to;\n let pathname;\n if (toPathname) {\n toPathname = removeDoubleSlashes(toPathname);\n if (toPathname.startsWith(\"/\")) {\n pathname = resolvePathname(toPathname.substring(1), \"/\");\n } else {\n pathname = resolvePathname(toPathname, fromPathname);\n }\n } else {\n pathname = fromPathname;\n }\n return {\n pathname,\n search: normalizeSearch(search),\n hash: normalizeHash(hash)\n };\n}\nfunction resolvePathname(relativePath, fromPathname) {\n let segments = removeTrailingSlash(fromPathname).split(\"/\");\n let relativeSegments = relativePath.split(\"/\");\n relativeSegments.forEach((segment) => {\n if (segment === \"..\") {\n if (segments.length > 1) segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n return segments.length > 1 ? segments.join(\"/\") : \"/\";\n}\nfunction getInvalidPathError(char, field, dest, path) {\n return `Cannot include a '${char}' character in a manually specified \\`to.${field}\\` field [${JSON.stringify(\n path\n )}]. Please separate it out to the \\`to.${dest}\\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`;\n}\nfunction getPathContributingMatches(matches) {\n return matches.filter(\n (match, index) => index === 0 || match.route.path && match.route.path.length > 0\n );\n}\nfunction getResolveToMatches(matches) {\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches.map(\n (match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase\n );\n}\nfunction resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) {\n let to;\n if (typeof toArg === \"string\") {\n to = parsePath(toArg);\n } else {\n to = { ...toArg };\n invariant(\n !to.pathname || !to.pathname.includes(\"?\"),\n getInvalidPathError(\"?\", \"pathname\", \"search\", to)\n );\n invariant(\n !to.pathname || !to.pathname.includes(\"#\"),\n getInvalidPathError(\"#\", \"pathname\", \"hash\", to)\n );\n invariant(\n !to.search || !to.search.includes(\"#\"),\n getInvalidPathError(\"#\", \"search\", \"hash\", to)\n );\n }\n let isEmptyPath = toArg === \"\" || to.pathname === \"\";\n let toPathname = isEmptyPath ? \"/\" : to.pathname;\n let from;\n if (toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n if (!isPathRelative && toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n to.pathname = toSegments.join(\"/\");\n }\n from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : \"/\";\n }\n let path = resolvePath(to, from);\n let hasExplicitTrailingSlash = toPathname && toPathname !== \"/\" && toPathname.endsWith(\"/\");\n let hasCurrentTrailingSlash = (isEmptyPath || toPathname === \".\") && locationPathname.endsWith(\"/\");\n if (!path.pathname.endsWith(\"/\") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {\n path.pathname += \"/\";\n }\n return path;\n}\nvar removeDoubleSlashes = (path) => path.replace(/[\\\\/]{2,}/g, \"/\");\nvar joinPaths = (paths) => removeDoubleSlashes(paths.join(\"/\"));\nvar removeTrailingSlash = (path) => path.replace(/\\/+$/, \"\");\nvar normalizePathname = (pathname) => removeTrailingSlash(pathname).replace(/^\\/*/, \"/\");\nvar normalizeSearch = (search) => !search || search === \"?\" ? \"\" : search.startsWith(\"?\") ? search : \"?\" + search;\nvar normalizeHash = (hash) => !hash || hash === \"#\" ? \"\" : hash.startsWith(\"#\") ? hash : \"#\" + hash;\nvar DataWithResponseInit = class {\n constructor(data2, init) {\n this.type = \"DataWithResponseInit\";\n this.data = data2;\n this.init = init || null;\n }\n};\nfunction data(data2, init) {\n return new DataWithResponseInit(\n data2,\n typeof init === \"number\" ? { status: init } : init\n );\n}\nvar redirect = (url, init = 302) => {\n let responseInit = init;\n if (typeof responseInit === \"number\") {\n responseInit = { status: responseInit };\n } else if (typeof responseInit.status === \"undefined\") {\n responseInit.status = 302;\n }\n let headers = new Headers(responseInit.headers);\n headers.set(\"Location\", url);\n return new Response(null, { ...responseInit, headers });\n};\nvar redirectDocument = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Reload-Document\", \"true\");\n return response;\n};\nvar replace = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Replace\", \"true\");\n return response;\n};\nvar SUPPORTED_ERROR_TYPES = [\n \"EvalError\",\n \"RangeError\",\n \"ReferenceError\",\n \"SyntaxError\",\n \"TypeError\",\n \"URIError\"\n];\nvar ErrorResponseImpl = class {\n constructor(status, statusText, data2, internal = false) {\n this.status = status;\n this.statusText = statusText || \"\";\n this.internal = internal;\n if (data2 instanceof Error) {\n this.data = data2.toString();\n this.error = data2;\n } else {\n this.data = data2;\n }\n }\n};\nfunction isRouteErrorResponse(error) {\n return error != null && typeof error.status === \"number\" && typeof error.statusText === \"string\" && typeof error.internal === \"boolean\" && \"data\" in error;\n}\nfunction getRoutePattern(matches) {\n let parts = matches.map((m) => m.route.path).filter(Boolean);\n return joinPaths(parts) || \"/\";\n}\nvar isBrowser = typeof window !== \"undefined\" && typeof window.document !== \"undefined\" && typeof window.document.createElement !== \"undefined\";\nfunction parseToInfo(_to, basename) {\n let to = _to;\n if (typeof to !== \"string\" || !ABSOLUTE_URL_REGEX.test(to)) {\n return {\n absoluteURL: void 0,\n isExternal: false,\n to\n };\n }\n let absoluteURL = to;\n let isExternal = false;\n if (isBrowser) {\n try {\n let currentUrl = new URL(window.location.href);\n let targetUrl = PROTOCOL_RELATIVE_URL_REGEX.test(to) ? new URL(normalizeProtocolRelativeUrl(to, currentUrl.protocol)) : new URL(to);\n let path = stripBasename(targetUrl.pathname, basename);\n if (targetUrl.origin === currentUrl.origin && path != null) {\n to = path + targetUrl.search + targetUrl.hash;\n } else {\n isExternal = true;\n }\n } catch (e) {\n warning(\n false,\n ` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`\n );\n }\n }\n return {\n absoluteURL,\n isExternal,\n to\n };\n}\n\n// lib/router/instrumentation.ts\nvar UninstrumentedSymbol = Symbol(\"Uninstrumented\");\nfunction getRouteInstrumentationUpdates(fns, route) {\n let aggregated = {\n lazy: [],\n \"lazy.loader\": [],\n \"lazy.action\": [],\n \"lazy.middleware\": [],\n middleware: [],\n loader: [],\n action: []\n };\n fns.forEach(\n (fn) => fn({\n id: route.id,\n index: route.index,\n path: route.path,\n instrument(i) {\n let keys = Object.keys(aggregated);\n for (let key of keys) {\n if (i[key]) {\n aggregated[key].push(i[key]);\n }\n }\n }\n })\n );\n let updates = {};\n if (typeof route.lazy === \"function\" && aggregated.lazy.length > 0) {\n let instrumented = wrapImpl(aggregated.lazy, route.lazy, () => void 0);\n if (instrumented) {\n updates.lazy = instrumented;\n }\n }\n if (typeof route.lazy === \"object\") {\n let lazyObject = route.lazy;\n [\"middleware\", \"loader\", \"action\"].forEach((key) => {\n let lazyFn = lazyObject[key];\n let instrumentations = aggregated[`lazy.${key}`];\n if (typeof lazyFn === \"function\" && instrumentations.length > 0) {\n let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0);\n if (instrumented) {\n updates.lazy = Object.assign(updates.lazy || {}, {\n [key]: instrumented\n });\n }\n }\n });\n }\n [\"loader\", \"action\"].forEach((key) => {\n let handler = route[key];\n if (typeof handler === \"function\" && aggregated[key].length > 0) {\n let original = handler[UninstrumentedSymbol] ?? handler;\n let instrumented = wrapImpl(\n aggregated[key],\n original,\n (...args) => getHandlerInfo(args[0])\n );\n if (instrumented) {\n if (key === \"loader\" && original.hydrate === true) {\n instrumented.hydrate = true;\n }\n instrumented[UninstrumentedSymbol] = original;\n updates[key] = instrumented;\n }\n }\n });\n if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) {\n updates.middleware = route.middleware.map((middleware) => {\n let original = middleware[UninstrumentedSymbol] ?? middleware;\n let instrumented = wrapImpl(\n aggregated.middleware,\n original,\n (...args) => getHandlerInfo(args[0])\n );\n if (instrumented) {\n instrumented[UninstrumentedSymbol] = original;\n return instrumented;\n }\n return middleware;\n });\n }\n return updates;\n}\nfunction instrumentClientSideRouter(router, fns) {\n let aggregated = {\n navigate: [],\n fetch: []\n };\n fns.forEach(\n (fn) => fn({\n instrument(i) {\n let keys = Object.keys(i);\n for (let key of keys) {\n if (i[key]) {\n aggregated[key].push(i[key]);\n }\n }\n }\n })\n );\n if (aggregated.navigate.length > 0) {\n let navigate = router.navigate[UninstrumentedSymbol] ?? router.navigate;\n let instrumentedNavigate = wrapImpl(\n aggregated.navigate,\n navigate,\n (...args) => {\n let [to, opts] = args;\n return {\n to: typeof to === \"number\" || typeof to === \"string\" ? to : to ? createPath(to) : \".\",\n ...getRouterInfo(router, opts ?? {})\n };\n }\n );\n if (instrumentedNavigate) {\n instrumentedNavigate[UninstrumentedSymbol] = navigate;\n router.navigate = instrumentedNavigate;\n }\n }\n if (aggregated.fetch.length > 0) {\n let fetch2 = router.fetch[UninstrumentedSymbol] ?? router.fetch;\n let instrumentedFetch = wrapImpl(aggregated.fetch, fetch2, (...args) => {\n let [key, , href, opts] = args;\n return {\n href: href ?? \".\",\n fetcherKey: key,\n ...getRouterInfo(router, opts ?? {})\n };\n });\n if (instrumentedFetch) {\n instrumentedFetch[UninstrumentedSymbol] = fetch2;\n router.fetch = instrumentedFetch;\n }\n }\n return router;\n}\nfunction instrumentHandler(handler, fns) {\n let aggregated = {\n request: []\n };\n fns.forEach(\n (fn) => fn({\n instrument(i) {\n let keys = Object.keys(i);\n for (let key of keys) {\n if (i[key]) {\n aggregated[key].push(i[key]);\n }\n }\n }\n })\n );\n let instrumentedHandler = handler;\n if (aggregated.request.length > 0) {\n instrumentedHandler = wrapImpl(aggregated.request, handler, (...args) => {\n let [request, context] = args;\n return {\n request: getReadonlyRequest(request),\n context: context != null ? getReadonlyContext(context) : context\n };\n });\n }\n return instrumentedHandler;\n}\nfunction wrapImpl(impls, handler, getInfo) {\n if (impls.length === 0) {\n return null;\n }\n return async (...args) => {\n let result = await recurseRight(\n impls,\n getInfo(...args),\n () => handler(...args),\n impls.length - 1\n );\n if (result.type === \"error\") {\n throw result.value;\n }\n return result.value;\n };\n}\nasync function recurseRight(impls, info, handler, index) {\n let impl = impls[index];\n let result;\n if (!impl) {\n try {\n let value = await handler();\n result = { type: \"success\", value };\n } catch (e) {\n result = { type: \"error\", value: e };\n }\n } else {\n let handlerPromise = void 0;\n let callHandler = async () => {\n if (handlerPromise) {\n console.error(\"You cannot call instrumented handlers more than once\");\n } else {\n handlerPromise = recurseRight(impls, info, handler, index - 1);\n }\n result = await handlerPromise;\n invariant(result, \"Expected a result\");\n if (result.type === \"error\" && result.value instanceof Error) {\n return { status: \"error\", error: result.value };\n }\n return { status: \"success\", error: void 0 };\n };\n try {\n await impl(callHandler, info);\n } catch (e) {\n console.error(\"An instrumentation function threw an error:\", e);\n }\n if (!handlerPromise) {\n await callHandler();\n }\n await handlerPromise;\n }\n if (result) {\n return result;\n }\n return {\n type: \"error\",\n value: new Error(\"No result assigned in instrumentation chain.\")\n };\n}\nfunction getHandlerInfo(args) {\n let { request, context, params, pattern } = args;\n return {\n request: getReadonlyRequest(request),\n params: { ...params },\n pattern,\n context: getReadonlyContext(context)\n };\n}\nfunction getRouterInfo(router, opts) {\n return {\n currentUrl: createPath(router.state.location),\n ...\"formMethod\" in opts ? { formMethod: opts.formMethod } : {},\n ...\"formEncType\" in opts ? { formEncType: opts.formEncType } : {},\n ...\"formData\" in opts ? { formData: opts.formData } : {},\n ...\"body\" in opts ? { body: opts.body } : {}\n };\n}\nfunction getReadonlyRequest(request) {\n return {\n method: request.method,\n url: request.url,\n headers: {\n get: (...args) => request.headers.get(...args)\n }\n };\n}\nfunction getReadonlyContext(context) {\n if (isPlainObject(context)) {\n let frozen = { ...context };\n Object.freeze(frozen);\n return frozen;\n } else {\n return {\n get: (ctx) => context.get(ctx)\n };\n }\n}\nvar objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join(\"\\0\");\nfunction isPlainObject(thing) {\n if (thing === null || typeof thing !== \"object\") {\n return false;\n }\n const proto = Object.getPrototypeOf(thing);\n return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join(\"\\0\") === objectProtoNames;\n}\n\n// lib/router/router.ts\nvar validMutationMethodsArr = [\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\"\n];\nvar validMutationMethods = new Set(\n validMutationMethodsArr\n);\nvar validRequestMethodsArr = [\n \"GET\",\n ...validMutationMethodsArr\n];\nvar validRequestMethods = new Set(validRequestMethodsArr);\nvar redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);\nvar redirectPreserveMethodStatusCodes = /* @__PURE__ */ new Set([307, 308]);\nvar IDLE_NAVIGATION = {\n state: \"idle\",\n location: void 0,\n matches: void 0,\n historyAction: void 0,\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0\n};\nvar IDLE_FETCHER = {\n state: \"idle\",\n data: void 0,\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0\n};\nvar IDLE_BLOCKER = {\n state: \"unblocked\",\n proceed: void 0,\n reset: void 0,\n location: void 0\n};\nvar defaultMapRouteProperties = (route) => ({\n hasErrorBoundary: Boolean(route.hasErrorBoundary)\n});\nvar TRANSITIONS_STORAGE_KEY = \"remix-router-transitions\";\nvar ResetLoaderDataSymbol = Symbol(\"ResetLoaderData\");\nvar _routes, _branches, _hmrRoutes, _hmrBranches;\nvar DataRoutes = class {\n constructor(routes) {\n __privateAdd(this, _routes);\n __privateAdd(this, _branches);\n __privateAdd(this, _hmrRoutes);\n __privateAdd(this, _hmrBranches);\n __privateSet(this, _routes, routes);\n __privateSet(this, _branches, flattenAndRankRoutes(routes));\n }\n /** The stable route tree */\n get stableRoutes() {\n return __privateGet(this, _routes);\n }\n /** The in-flight route tree if one is active, otherwise the stable tree */\n get activeRoutes() {\n return __privateGet(this, _hmrRoutes) ?? __privateGet(this, _routes);\n }\n /** Pre-computed branches */\n get branches() {\n return __privateGet(this, _hmrBranches) ?? __privateGet(this, _branches);\n }\n get hasHMRRoutes() {\n return __privateGet(this, _hmrRoutes) != null;\n }\n /** Replace the stable route tree and recompute its branches */\n setRoutes(routes) {\n __privateSet(this, _routes, routes);\n __privateSet(this, _branches, flattenAndRankRoutes(routes));\n }\n /** Set a new in-flight route tree and recompute its branches */\n setHmrRoutes(routes) {\n __privateSet(this, _hmrRoutes, routes);\n __privateSet(this, _hmrBranches, flattenAndRankRoutes(routes));\n }\n /** Commit in-flight routes/branches to the stable slot and clear in-flight */\n commitHmrRoutes() {\n if (__privateGet(this, _hmrRoutes)) {\n __privateSet(this, _routes, __privateGet(this, _hmrRoutes));\n __privateSet(this, _branches, __privateGet(this, _hmrBranches));\n __privateSet(this, _hmrRoutes, void 0);\n __privateSet(this, _hmrBranches, void 0);\n }\n }\n};\n_routes = new WeakMap();\n_branches = new WeakMap();\n_hmrRoutes = new WeakMap();\n_hmrBranches = new WeakMap();\nfunction createRouter(init) {\n const routerWindow = init.window ? init.window : typeof window !== \"undefined\" ? window : void 0;\n const isBrowser3 = typeof routerWindow !== \"undefined\" && typeof routerWindow.document !== \"undefined\" && typeof routerWindow.document.createElement !== \"undefined\";\n invariant(\n init.routes.length > 0,\n \"You must provide a non-empty routes array to createRouter\"\n );\n let hydrationRouteProperties2 = init.hydrationRouteProperties || [];\n let _mapRouteProperties = init.mapRouteProperties || defaultMapRouteProperties;\n let mapRouteProperties2 = _mapRouteProperties;\n if (init.instrumentations) {\n let instrumentations = init.instrumentations;\n mapRouteProperties2 = (route) => {\n return {\n ..._mapRouteProperties(route),\n ...getRouteInstrumentationUpdates(\n instrumentations.map((i) => i.route).filter(Boolean),\n route\n )\n };\n };\n }\n let manifest = {};\n let dataRoutes = new DataRoutes(\n convertRoutesToDataRoutes(\n init.routes,\n mapRouteProperties2,\n void 0,\n manifest\n )\n );\n let basename = init.basename || \"/\";\n if (!basename.startsWith(\"/\")) {\n basename = `/${basename}`;\n }\n let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware;\n let future = {\n ...init.future\n };\n let unlistenHistory = null;\n let subscribers = /* @__PURE__ */ new Set();\n let bufferedInitialStateUpdate = null;\n let savedScrollPositions2 = null;\n let getScrollRestorationKey2 = null;\n let getScrollPosition = null;\n let initialScrollRestored = init.hydrationData != null;\n let initialMatches = matchRoutesImpl(\n dataRoutes.activeRoutes,\n init.history.location,\n basename,\n false,\n dataRoutes.branches\n );\n let initialMatchesIsFOW = false;\n let initialErrors = null;\n let initialized;\n let renderFallback;\n if (initialMatches == null && !init.patchRoutesOnNavigation) {\n let error = getInternalRouterError(404, {\n pathname: init.history.location.pathname\n });\n let { matches, route } = getShortCircuitMatches(dataRoutes.activeRoutes);\n initialized = true;\n renderFallback = !initialized;\n initialMatches = matches;\n initialErrors = { [route.id]: error };\n } else {\n if (initialMatches && !init.hydrationData) {\n let fogOfWar = checkFogOfWar(\n initialMatches,\n dataRoutes.activeRoutes,\n init.history.location.pathname\n );\n if (fogOfWar.active) {\n initialMatches = null;\n }\n }\n if (!initialMatches) {\n initialized = false;\n renderFallback = !initialized;\n initialMatches = [];\n let fogOfWar = checkFogOfWar(\n null,\n dataRoutes.activeRoutes,\n init.history.location.pathname\n );\n if (fogOfWar.active && fogOfWar.matches) {\n initialMatchesIsFOW = true;\n initialMatches = fogOfWar.matches;\n }\n } else if (initialMatches.some((m) => m.route.lazy)) {\n initialized = false;\n renderFallback = !initialized;\n } else if (!initialMatches.some((m) => routeHasLoaderOrMiddleware(m.route))) {\n initialized = true;\n renderFallback = !initialized;\n } else {\n let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;\n let errors = init.hydrationData ? init.hydrationData.errors : null;\n let relevantMatches = initialMatches;\n if (errors) {\n let idx = initialMatches.findIndex(\n (m) => errors[m.route.id] !== void 0\n );\n relevantMatches = relevantMatches.slice(0, idx + 1);\n }\n renderFallback = false;\n initialized = true;\n relevantMatches.forEach((m) => {\n let status = getRouteHydrationStatus(m.route, loaderData, errors);\n renderFallback = renderFallback || status.renderFallback;\n initialized = initialized && !status.shouldLoad;\n });\n }\n }\n let router;\n let state = {\n historyAction: init.history.action,\n location: init.history.location,\n matches: initialMatches,\n initialized,\n renderFallback,\n navigation: IDLE_NAVIGATION,\n // Don't restore on initial updateState() if we were SSR'd\n restoreScrollPosition: init.hydrationData != null ? false : null,\n preventScrollReset: false,\n revalidation: \"idle\",\n loaderData: init.hydrationData && init.hydrationData.loaderData || {},\n actionData: init.hydrationData && init.hydrationData.actionData || null,\n errors: init.hydrationData && init.hydrationData.errors || initialErrors,\n fetchers: /* @__PURE__ */ new Map(),\n blockers: /* @__PURE__ */ new Map()\n };\n let pendingAction = \"POP\" /* Pop */;\n let pendingPopstateNavigationDfd = null;\n let pendingPreventScrollReset = false;\n let pendingNavigationController;\n let pendingViewTransitionEnabled = false;\n let appliedViewTransitions = /* @__PURE__ */ new Map();\n let removePageHideEventListener = null;\n let isUninterruptedRevalidation = false;\n let isRevalidationRequired = false;\n let cancelledFetcherLoads = /* @__PURE__ */ new Set();\n let fetchControllers = /* @__PURE__ */ new Map();\n let incrementingLoadId = 0;\n let pendingNavigationLoadId = -1;\n let fetchReloadIds = /* @__PURE__ */ new Map();\n let fetchRedirectIds = /* @__PURE__ */ new Set();\n let fetchLoadMatches = /* @__PURE__ */ new Map();\n let activeFetchers = /* @__PURE__ */ new Map();\n let fetchersQueuedForDeletion = /* @__PURE__ */ new Set();\n let blockerFunctions = /* @__PURE__ */ new Map();\n let unblockBlockerHistoryUpdate = void 0;\n let pendingRevalidationDfd = null;\n function initialize() {\n unlistenHistory = init.history.listen(\n ({ action: historyAction, location, delta }) => {\n if (unblockBlockerHistoryUpdate) {\n unblockBlockerHistoryUpdate();\n unblockBlockerHistoryUpdate = void 0;\n return;\n }\n warning(\n blockerFunctions.size === 0 || delta != null,\n \"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.\"\n );\n let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction\n });\n if (blockerKey && delta != null) {\n let nextHistoryUpdatePromise = new Promise((resolve) => {\n unblockBlockerHistoryUpdate = resolve;\n });\n init.history.go(delta * -1);\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location,\n proceed() {\n updateBlocker(blockerKey, {\n state: \"proceeding\",\n proceed: void 0,\n reset: void 0,\n location\n });\n nextHistoryUpdatePromise.then(() => init.history.go(delta));\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey, IDLE_BLOCKER);\n updateState({ blockers });\n }\n });\n pendingPopstateNavigationDfd?.resolve();\n pendingPopstateNavigationDfd = null;\n return;\n }\n return startNavigation(historyAction, location);\n }\n );\n if (isBrowser3) {\n restoreAppliedTransitions(routerWindow, appliedViewTransitions);\n let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions);\n routerWindow.addEventListener(\"pagehide\", _saveAppliedTransitions);\n removePageHideEventListener = () => routerWindow.removeEventListener(\"pagehide\", _saveAppliedTransitions);\n }\n if (!state.initialized) {\n startNavigation(\"POP\" /* Pop */, state.location, {\n initialHydration: true\n });\n }\n return router;\n }\n function dispose() {\n if (unlistenHistory) {\n unlistenHistory();\n }\n if (removePageHideEventListener) {\n removePageHideEventListener();\n }\n subscribers.clear();\n pendingNavigationController && pendingNavigationController.abort();\n state.fetchers.forEach((_, key) => deleteFetcher(state.fetchers, key));\n state.blockers.forEach((_, key) => deleteBlocker(key));\n }\n function subscribe(fn) {\n subscribers.add(fn);\n if (bufferedInitialStateUpdate) {\n let { newErrors } = bufferedInitialStateUpdate;\n bufferedInitialStateUpdate = null;\n fn(state, {\n deletedFetchers: [],\n newErrors,\n viewTransitionOpts: void 0,\n flushSync: false\n });\n }\n return () => subscribers.delete(fn);\n }\n function updateState(newState, opts = {}) {\n if (newState.matches) {\n newState.matches = newState.matches.map((m) => {\n let route = manifest[m.route.id];\n let matchRoute = m.route;\n if (matchRoute.element !== route.element || matchRoute.errorElement !== route.errorElement || matchRoute.hydrateFallbackElement !== route.hydrateFallbackElement) {\n return {\n ...m,\n route\n };\n }\n return m;\n });\n }\n state = {\n ...state,\n ...newState\n };\n let unmountedFetchers = [];\n let mountedFetchers = [];\n state.fetchers.forEach((fetcher, key) => {\n if (fetcher.state === \"idle\") {\n if (fetchersQueuedForDeletion.has(key)) {\n unmountedFetchers.push(key);\n } else {\n mountedFetchers.push(key);\n }\n }\n });\n fetchersQueuedForDeletion.forEach((key) => {\n if (!state.fetchers.has(key) && !fetchControllers.has(key)) {\n unmountedFetchers.push(key);\n }\n });\n if (subscribers.size === 0) {\n bufferedInitialStateUpdate = { newErrors: newState.errors ?? null };\n }\n [...subscribers].forEach(\n (subscriber) => subscriber(state, {\n deletedFetchers: unmountedFetchers,\n newErrors: newState.errors ?? null,\n viewTransitionOpts: opts.viewTransitionOpts,\n flushSync: opts.flushSync === true\n })\n );\n unmountedFetchers.forEach((key) => deleteFetcher(state.fetchers, key));\n mountedFetchers.forEach((key) => state.fetchers.delete(key));\n }\n function completeNavigation(location, newState, { flushSync } = {}) {\n let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === \"loading\" && location.state?._isRedirect !== true;\n let actionData;\n if (newState.actionData) {\n if (Object.keys(newState.actionData).length > 0) {\n actionData = newState.actionData;\n } else {\n actionData = null;\n }\n } else if (isActionReload) {\n actionData = state.actionData;\n } else {\n actionData = null;\n }\n let loaderData = newState.loaderData ? mergeLoaderData(\n state.loaderData,\n newState.loaderData,\n newState.matches || [],\n newState.errors\n ) : state.loaderData;\n let blockers = state.blockers;\n if (blockers.size > 0) {\n blockers = new Map(blockers);\n blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));\n }\n let restoreScrollPosition = isUninterruptedRevalidation ? false : getSavedScrollPosition(location, newState.matches || state.matches);\n let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && location.state?._isRedirect !== true;\n dataRoutes.commitHmrRoutes();\n if (isUninterruptedRevalidation) {\n } else if (pendingAction === \"POP\" /* Pop */) {\n } else if (pendingAction === \"PUSH\" /* Push */) {\n init.history.push(location, location.state);\n } else if (pendingAction === \"REPLACE\" /* Replace */) {\n init.history.replace(location, location.state);\n }\n let viewTransitionOpts;\n if (pendingAction === \"POP\" /* Pop */) {\n let priorPaths = appliedViewTransitions.get(state.location.pathname);\n if (priorPaths && priorPaths.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location\n };\n } else if (appliedViewTransitions.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: location,\n nextLocation: state.location\n };\n }\n } else if (pendingViewTransitionEnabled) {\n let toPaths = appliedViewTransitions.get(state.location.pathname);\n if (toPaths) {\n toPaths.add(location.pathname);\n } else {\n toPaths = /* @__PURE__ */ new Set([location.pathname]);\n appliedViewTransitions.set(state.location.pathname, toPaths);\n }\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location\n };\n }\n updateState(\n {\n ...newState,\n // matches, errors, fetchers go through as-is\n actionData,\n loaderData,\n historyAction: pendingAction,\n location,\n initialized: true,\n renderFallback: false,\n navigation: IDLE_NAVIGATION,\n revalidation: \"idle\",\n restoreScrollPosition,\n preventScrollReset,\n blockers\n },\n {\n viewTransitionOpts,\n flushSync: flushSync === true\n }\n );\n pendingAction = \"POP\" /* Pop */;\n pendingPreventScrollReset = false;\n pendingViewTransitionEnabled = false;\n isUninterruptedRevalidation = false;\n isRevalidationRequired = false;\n pendingPopstateNavigationDfd?.resolve();\n pendingPopstateNavigationDfd = null;\n pendingRevalidationDfd?.resolve();\n pendingRevalidationDfd = null;\n }\n async function navigate(to, opts) {\n pendingPopstateNavigationDfd?.resolve();\n pendingPopstateNavigationDfd = null;\n if (typeof to === \"number\") {\n if (!pendingPopstateNavigationDfd) {\n pendingPopstateNavigationDfd = createDeferred();\n }\n let promise = pendingPopstateNavigationDfd.promise;\n init.history.go(to);\n return promise;\n }\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n to,\n opts?.fromRouteId,\n opts?.relative\n );\n let { path, submission, error } = normalizeNavigateOptions(\n false,\n normalizedPath,\n opts\n );\n let maskPath;\n if (opts?.mask) {\n let partialPath = typeof opts.mask === \"string\" ? parsePath(opts.mask) : {\n ...state.location.mask,\n ...opts.mask\n };\n maskPath = {\n pathname: \"\",\n search: \"\",\n hash: \"\",\n ...partialPath\n };\n }\n let currentLocation = state.location;\n let nextLocation = createLocation(\n currentLocation,\n path,\n opts && opts.state,\n void 0,\n maskPath\n );\n nextLocation = {\n ...nextLocation,\n ...init.history.encodeLocation(nextLocation)\n };\n let userReplace = opts && opts.replace != null ? opts.replace : void 0;\n let historyAction = \"PUSH\" /* Push */;\n if (userReplace === true) {\n historyAction = \"REPLACE\" /* Replace */;\n } else if (userReplace === false) {\n } else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {\n historyAction = \"REPLACE\" /* Replace */;\n }\n let preventScrollReset = opts && \"preventScrollReset\" in opts ? opts.preventScrollReset === true : void 0;\n let flushSync = (opts && opts.flushSync) === true;\n let blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction\n });\n if (blockerKey) {\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location: nextLocation,\n proceed() {\n updateBlocker(blockerKey, {\n state: \"proceeding\",\n proceed: void 0,\n reset: void 0,\n location: nextLocation\n });\n navigate(to, opts);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey, IDLE_BLOCKER);\n updateState({ blockers });\n }\n });\n return;\n }\n await startNavigation(historyAction, nextLocation, {\n submission,\n // Send through the formData serialization error if we have one so we can\n // render at the right error boundary after we match routes\n pendingError: error,\n preventScrollReset,\n replace: opts && opts.replace,\n enableViewTransition: opts && opts.viewTransition,\n flushSync,\n callSiteDefaultShouldRevalidate: opts && opts.defaultShouldRevalidate\n });\n }\n function revalidate() {\n if (!pendingRevalidationDfd) {\n pendingRevalidationDfd = createDeferred();\n }\n interruptActiveLoads();\n updateState({ revalidation: \"loading\" });\n let promise = pendingRevalidationDfd.promise;\n if (state.navigation.state === \"submitting\") {\n return promise;\n }\n if (state.navigation.state === \"idle\") {\n startNavigation(state.historyAction, state.location, {\n startUninterruptedRevalidation: true\n });\n return promise;\n }\n startNavigation(\n pendingAction || state.historyAction,\n state.navigation.location,\n {\n overrideNavigation: state.navigation,\n // Proxy through any rending view transition\n enableViewTransition: pendingViewTransitionEnabled === true\n }\n );\n return promise;\n }\n async function startNavigation(historyAction, location, opts) {\n pendingNavigationController && pendingNavigationController.abort();\n pendingNavigationController = null;\n pendingAction = historyAction;\n isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true;\n saveScrollPosition(state.location, state.matches);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;\n let routesToUse = dataRoutes.activeRoutes;\n let matches = opts?.initialHydration && state.matches && state.matches.length > 0 && !initialMatchesIsFOW ? (\n // `matchRoutes()` has already been called if we're in here via `router.initialize()`\n state.matches\n ) : matchRoutesImpl(\n routesToUse,\n location,\n basename,\n false,\n dataRoutes.branches\n );\n let flushSync = (opts && opts.flushSync) === true;\n if (matches && state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {\n completeNavigation(location, { matches }, { flushSync });\n return;\n }\n let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n if (!matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n completeNavigation(\n location,\n {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error\n }\n },\n { flushSync }\n );\n return;\n }\n let loadingNavigation = opts && opts.overrideNavigation ? {\n ...opts.overrideNavigation,\n matches,\n historyAction\n } : void 0;\n pendingNavigationController = new AbortController();\n let request = createClientSideRequest(\n init.history,\n location,\n pendingNavigationController.signal,\n opts && opts.submission\n );\n let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();\n let pendingActionResult;\n if (opts && opts.pendingError) {\n pendingActionResult = [\n findNearestBoundary(matches).route.id,\n { type: \"error\" /* error */, error: opts.pendingError }\n ];\n } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) {\n let actionResult = await handleAction(\n request,\n location,\n opts.submission,\n matches,\n historyAction,\n scopedContext,\n fogOfWar.active,\n opts && opts.initialHydration === true,\n { replace: opts.replace, flushSync }\n );\n if (actionResult.shortCircuited) {\n return;\n }\n if (actionResult.pendingActionResult) {\n let [routeId, result] = actionResult.pendingActionResult;\n if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) {\n pendingNavigationController = null;\n completeNavigation(location, {\n matches: actionResult.matches,\n loaderData: {},\n errors: {\n [routeId]: result.error\n }\n });\n return;\n }\n }\n matches = actionResult.matches || matches;\n pendingActionResult = actionResult.pendingActionResult;\n loadingNavigation = getLoadingNavigation(\n location,\n matches,\n historyAction,\n opts.submission\n );\n flushSync = false;\n fogOfWar.active = false;\n request = createClientSideRequest(\n init.history,\n request.url,\n request.signal\n );\n }\n let {\n shortCircuited,\n matches: updatedMatches,\n loaderData,\n errors,\n workingFetchers\n } = await handleLoaders(\n request,\n location,\n matches,\n historyAction,\n scopedContext,\n fogOfWar.active,\n loadingNavigation,\n opts && opts.submission,\n opts && opts.fetcherSubmission,\n opts && opts.replace,\n opts && opts.initialHydration === true,\n flushSync,\n pendingActionResult,\n opts && opts.callSiteDefaultShouldRevalidate\n );\n if (shortCircuited) {\n return;\n }\n pendingNavigationController = null;\n completeNavigation(location, {\n matches: updatedMatches || matches,\n ...getActionDataForCommit(pendingActionResult),\n loaderData,\n errors,\n ...workingFetchers ? { fetchers: workingFetchers } : {}\n });\n }\n async function handleAction(request, location, submission, matches, historyAction, scopedContext, isFogOfWar, initialHydration, opts = {}) {\n interruptActiveLoads();\n let navigation = getSubmittingNavigation(\n location,\n matches,\n historyAction,\n submission\n );\n updateState({ navigation }, { flushSync: opts.flushSync === true });\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n if (discoverResult.partialMatches.length === 0) {\n let { matches: matches2, route } = getShortCircuitMatches(\n dataRoutes.activeRoutes\n );\n return {\n matches: matches2,\n pendingActionResult: [\n route.id,\n {\n type: \"error\" /* error */,\n error: discoverResult.error\n }\n ]\n };\n }\n let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;\n return {\n matches: discoverResult.partialMatches,\n pendingActionResult: [\n boundaryId,\n {\n type: \"error\" /* error */,\n error: discoverResult.error\n }\n ]\n };\n } else if (!discoverResult.matches) {\n let { notFoundMatches, error, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n pendingActionResult: [\n route.id,\n {\n type: \"error\" /* error */,\n error\n }\n ]\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n let result;\n let actionMatch = getTargetMatch(matches, location);\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n result = {\n type: \"error\" /* error */,\n error: getInternalRouterError(405, {\n method: request.method,\n pathname: location.pathname,\n routeId: actionMatch.route.id\n })\n };\n } else {\n let dsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n request,\n location,\n matches,\n actionMatch,\n initialHydration ? [] : hydrationRouteProperties2,\n scopedContext\n );\n let results = await callDataStrategy(\n request,\n location,\n dsMatches,\n scopedContext,\n null\n );\n result = results[actionMatch.route.id];\n if (!result) {\n for (let match of matches) {\n if (results[match.route.id]) {\n result = results[match.route.id];\n break;\n }\n }\n }\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n }\n if (isRedirectResult(result)) {\n let replace2;\n if (opts && opts.replace != null) {\n replace2 = opts.replace;\n } else {\n let location2 = normalizeRedirectLocation(\n result.response.headers.get(\"Location\"),\n new URL(request.url),\n basename,\n init.history\n );\n replace2 = location2 === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(request, result, true, {\n submission,\n replace: replace2\n });\n return { shortCircuited: true };\n }\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n if ((opts && opts.replace) !== true) {\n pendingAction = \"PUSH\" /* Push */;\n }\n return {\n matches,\n pendingActionResult: [\n boundaryMatch.route.id,\n result,\n actionMatch.route.id\n ]\n };\n }\n return {\n matches,\n pendingActionResult: [actionMatch.route.id, result]\n };\n }\n async function handleLoaders(request, location, matches, historyAction, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult, callSiteDefaultShouldRevalidate) {\n let loadingNavigation = overrideNavigation || getLoadingNavigation(location, matches, historyAction, submission);\n let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);\n let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;\n if (isFogOfWar) {\n if (shouldUpdateNavigationState) {\n let actionData = getUpdatedActionData(pendingActionResult);\n updateState(\n {\n navigation: loadingNavigation,\n ...actionData !== void 0 ? { actionData } : {}\n },\n {\n flushSync\n }\n );\n }\n let discoverResult = await discoverRoutes(\n matches,\n location.pathname,\n request.signal\n );\n if (discoverResult.type === \"aborted\") {\n return { shortCircuited: true };\n } else if (discoverResult.type === \"error\") {\n if (discoverResult.partialMatches.length === 0) {\n let { matches: matches2, route } = getShortCircuitMatches(\n dataRoutes.activeRoutes\n );\n return {\n matches: matches2,\n loaderData: {},\n errors: {\n [route.id]: discoverResult.error\n }\n };\n }\n let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;\n return {\n matches: discoverResult.partialMatches,\n loaderData: {},\n errors: {\n [boundaryId]: discoverResult.error\n }\n };\n } else if (!discoverResult.matches) {\n let { error, notFoundMatches, route } = handleNavigational404(\n location.pathname\n );\n return {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error\n }\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n let routesToUse = dataRoutes.activeRoutes;\n let { dsMatches, revalidatingFetchers } = getMatchesToLoad(\n request,\n scopedContext,\n mapRouteProperties2,\n manifest,\n init.history,\n state,\n matches,\n activeSubmission,\n location,\n initialHydration ? [] : hydrationRouteProperties2,\n initialHydration === true,\n isRevalidationRequired,\n cancelledFetcherLoads,\n fetchersQueuedForDeletion,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n init.patchRoutesOnNavigation != null,\n dataRoutes.branches,\n pendingActionResult,\n callSiteDefaultShouldRevalidate\n );\n pendingNavigationLoadId = ++incrementingLoadId;\n if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && !dsMatches.some(\n (m) => m.route.middleware && m.route.middleware.length > 0\n ) && revalidatingFetchers.length === 0) {\n let workingFetchers2 = new Map(state.fetchers);\n let didUpdateFetcherRedirects2 = markFetchRedirectsDone(workingFetchers2);\n completeNavigation(\n location,\n {\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { [pendingActionResult[0]]: pendingActionResult[1].error } : null,\n ...getActionDataForCommit(pendingActionResult),\n ...didUpdateFetcherRedirects2 ? { fetchers: workingFetchers2 } : {}\n },\n { flushSync }\n );\n return { shortCircuited: true };\n }\n if (shouldUpdateNavigationState) {\n let updates = {};\n if (!isFogOfWar) {\n updates.navigation = loadingNavigation;\n let actionData = getUpdatedActionData(pendingActionResult);\n if (actionData !== void 0) {\n updates.actionData = actionData;\n }\n }\n if (revalidatingFetchers.length > 0) {\n updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);\n }\n updateState(updates, { flushSync });\n }\n revalidatingFetchers.forEach((rf) => {\n abortFetcher(rf.key);\n if (rf.controller) {\n fetchControllers.set(rf.key, rf.controller);\n }\n });\n let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((f) => abortFetcher(f.key));\n if (pendingNavigationController) {\n pendingNavigationController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(\n dsMatches,\n revalidatingFetchers,\n request,\n location,\n scopedContext\n );\n if (request.signal.aborted) {\n return { shortCircuited: true };\n }\n if (pendingNavigationController) {\n pendingNavigationController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n }\n revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));\n let redirect2 = findRedirect(loaderResults);\n if (redirect2) {\n await startRedirectNavigation(request, redirect2.result, true, {\n replace: replace2\n });\n return { shortCircuited: true };\n }\n redirect2 = findRedirect(fetcherResults);\n if (redirect2) {\n fetchRedirectIds.add(redirect2.key);\n await startRedirectNavigation(request, redirect2.result, true, {\n replace: replace2\n });\n return { shortCircuited: true };\n }\n let workingFetchers = new Map(state.fetchers);\n let { loaderData, errors } = processLoaderData(\n state,\n matches,\n loaderResults,\n pendingActionResult,\n revalidatingFetchers,\n fetcherResults,\n workingFetchers\n );\n if (initialHydration && state.errors) {\n errors = { ...state.errors, ...errors };\n }\n let didUpdateFetcherRedirects = markFetchRedirectsDone(workingFetchers);\n let didAbortFetchLoads = abortStaleFetchLoads(\n pendingNavigationLoadId,\n workingFetchers\n );\n let shouldUpdateFetchers = didUpdateFetcherRedirects || didAbortFetchLoads || revalidatingFetchers.length > 0;\n return {\n matches,\n loaderData,\n errors,\n ...shouldUpdateFetchers ? { workingFetchers } : {}\n };\n }\n function getUpdatedActionData(pendingActionResult) {\n if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {\n return {\n [pendingActionResult[0]]: pendingActionResult[1].data\n };\n } else if (state.actionData) {\n if (Object.keys(state.actionData).length === 0) {\n return null;\n } else {\n return state.actionData;\n }\n }\n }\n function getUpdatedRevalidatingFetchers(revalidatingFetchers) {\n let workingFetchers = new Map(state.fetchers);\n revalidatingFetchers.forEach((rf) => {\n let fetcher = workingFetchers.get(rf.key);\n let revalidatingFetcher = getLoadingFetcher(\n void 0,\n fetcher ? fetcher.data : void 0\n );\n workingFetchers.set(rf.key, revalidatingFetcher);\n });\n return workingFetchers;\n }\n async function fetch2(key, routeId, href, opts) {\n abortFetcher(key);\n let flushSync = (opts && opts.flushSync) === true;\n let routesToUse = dataRoutes.activeRoutes;\n let normalizedPath = normalizeTo(\n state.location,\n state.matches,\n basename,\n href,\n routeId,\n opts?.relative\n );\n let matches = matchRoutesImpl(\n routesToUse,\n normalizedPath,\n basename,\n false,\n dataRoutes.branches\n );\n let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n if (!matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: normalizedPath }),\n { flushSync }\n );\n return;\n }\n let { path, submission, error } = normalizeNavigateOptions(\n true,\n normalizedPath,\n opts\n );\n if (error) {\n setFetcherError(key, routeId, error, { flushSync });\n return;\n }\n let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();\n let preventScrollReset = (opts && opts.preventScrollReset) === true;\n if (submission && isMutationMethod(submission.formMethod)) {\n await handleFetcherAction(\n key,\n routeId,\n path,\n matches,\n scopedContext,\n fogOfWar.active,\n flushSync,\n preventScrollReset,\n submission,\n opts && opts.defaultShouldRevalidate\n );\n return;\n }\n fetchLoadMatches.set(key, { routeId, path });\n await handleFetcherLoader(\n key,\n routeId,\n path,\n matches,\n scopedContext,\n fogOfWar.active,\n flushSync,\n preventScrollReset,\n submission\n );\n }\n async function handleFetcherAction(key, routeId, path, requestMatches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission, callSiteDefaultShouldRevalidate) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {\n flushSync\n });\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal,\n submission\n );\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n requestMatches,\n new URL(fetchRequest.url).pathname,\n fetchRequest.signal,\n key\n );\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n setFetcherError(key, routeId, discoverResult.error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n requestMatches = discoverResult.matches;\n }\n }\n let match = getTargetMatch(requestMatches, path);\n if (!match.route.action && !match.route.lazy) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId\n });\n setFetcherError(key, routeId, error, { flushSync });\n return;\n }\n fetchControllers.set(key, abortController);\n let originatingLoadId = incrementingLoadId;\n let fetchMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n path,\n requestMatches,\n match,\n hydrationRouteProperties2,\n scopedContext\n );\n let actionResults = await callDataStrategy(\n fetchRequest,\n path,\n fetchMatches,\n scopedContext,\n key\n );\n let actionResult = actionResults[match.route.id];\n if (!actionResult) {\n for (let match2 of fetchMatches) {\n if (actionResults[match2.route.id]) {\n actionResult = actionResults[match2.route.id];\n break;\n }\n }\n }\n if (fetchRequest.signal.aborted) {\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n return;\n }\n if (fetchersQueuedForDeletion.has(key)) {\n if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {\n updateFetcherState(key, getDoneFetcher(void 0));\n return;\n }\n } else {\n if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n if (pendingNavigationLoadId > originatingLoadId) {\n updateFetcherState(key, getDoneFetcher(void 0));\n return;\n } else {\n fetchRedirectIds.add(key);\n updateFetcherState(key, getLoadingFetcher(submission));\n return startRedirectNavigation(fetchRequest, actionResult, false, {\n fetcherSubmission: submission,\n preventScrollReset\n });\n }\n }\n if (isErrorResult(actionResult)) {\n setFetcherError(key, routeId, actionResult.error);\n return;\n }\n }\n let nextLocation = state.navigation.location || state.location;\n let revalidationRequest = createClientSideRequest(\n init.history,\n nextLocation,\n abortController.signal\n );\n let routesToUse = dataRoutes.activeRoutes;\n let matches = state.navigation.state !== \"idle\" ? matchRoutesImpl(\n routesToUse,\n state.navigation.location,\n basename,\n false,\n dataRoutes.branches\n ) : state.matches;\n invariant(matches, \"Didn't find any matches after fetcher action\");\n let loadId = ++incrementingLoadId;\n fetchReloadIds.set(key, loadId);\n let { dsMatches, revalidatingFetchers } = getMatchesToLoad(\n revalidationRequest,\n scopedContext,\n mapRouteProperties2,\n manifest,\n init.history,\n state,\n matches,\n submission,\n nextLocation,\n hydrationRouteProperties2,\n false,\n isRevalidationRequired,\n cancelledFetcherLoads,\n fetchersQueuedForDeletion,\n fetchLoadMatches,\n fetchRedirectIds,\n routesToUse,\n basename,\n init.patchRoutesOnNavigation != null,\n dataRoutes.branches,\n [match.route.id, actionResult],\n callSiteDefaultShouldRevalidate\n );\n let loadFetcher = getLoadingFetcher(submission, actionResult.data);\n let workingFetchers = new Map(state.fetchers);\n workingFetchers.set(key, loadFetcher);\n revalidatingFetchers.filter((rf) => rf.key !== key).forEach((rf) => {\n let staleKey = rf.key;\n let existingFetcher2 = workingFetchers.get(staleKey);\n let revalidatingFetcher = getLoadingFetcher(\n void 0,\n existingFetcher2 ? existingFetcher2.data : void 0\n );\n workingFetchers.set(staleKey, revalidatingFetcher);\n abortFetcher(staleKey);\n if (rf.controller) {\n fetchControllers.set(staleKey, rf.controller);\n }\n });\n updateState({ fetchers: workingFetchers });\n let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));\n abortController.signal.addEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(\n dsMatches,\n revalidatingFetchers,\n revalidationRequest,\n nextLocation,\n scopedContext\n );\n if (abortController.signal.aborted) {\n return;\n }\n abortController.signal.removeEventListener(\n \"abort\",\n abortPendingFetchRevalidations\n );\n fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key));\n let fetcherIsMounted = state.fetchers.has(key);\n let getRedirectStateWithDoneFetcher = (s) => {\n if (!fetcherIsMounted) return s;\n let workingFetchers2 = new Map(s.fetchers);\n workingFetchers2.set(key, getDoneFetcher(actionResult.data));\n return { ...s, fetchers: workingFetchers2 };\n };\n let redirect2 = findRedirect(loaderResults);\n if (redirect2) {\n state = getRedirectStateWithDoneFetcher(state);\n return startRedirectNavigation(\n revalidationRequest,\n redirect2.result,\n false,\n { preventScrollReset }\n );\n }\n redirect2 = findRedirect(fetcherResults);\n if (redirect2) {\n fetchRedirectIds.add(redirect2.key);\n state = getRedirectStateWithDoneFetcher(state);\n return startRedirectNavigation(\n revalidationRequest,\n redirect2.result,\n false,\n { preventScrollReset }\n );\n }\n let finalFetchers = new Map(state.fetchers);\n if (fetcherIsMounted) {\n finalFetchers.set(key, getDoneFetcher(actionResult.data));\n }\n let { loaderData, errors } = processLoaderData(\n state,\n matches,\n loaderResults,\n void 0,\n revalidatingFetchers,\n fetcherResults,\n finalFetchers\n );\n abortStaleFetchLoads(loadId, finalFetchers);\n if (state.navigation.state === \"loading\" && loadId > pendingNavigationLoadId) {\n invariant(pendingAction, \"Expected pending action\");\n pendingNavigationController && pendingNavigationController.abort();\n completeNavigation(state.navigation.location, {\n matches,\n loaderData,\n errors,\n fetchers: finalFetchers\n });\n } else {\n updateState({\n errors,\n loaderData: mergeLoaderData(\n state.loaderData,\n loaderData,\n matches,\n errors\n ),\n fetchers: finalFetchers\n });\n isRevalidationRequired = false;\n }\n }\n async function handleFetcherLoader(key, routeId, path, matches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(\n key,\n getLoadingFetcher(\n submission,\n existingFetcher ? existingFetcher.data : void 0\n ),\n { flushSync }\n );\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(\n init.history,\n path,\n abortController.signal\n );\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(\n matches,\n new URL(fetchRequest.url).pathname,\n fetchRequest.signal,\n key\n );\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n setFetcherError(key, routeId, discoverResult.error, { flushSync });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(\n key,\n routeId,\n getInternalRouterError(404, { pathname: path }),\n { flushSync }\n );\n return;\n } else {\n matches = discoverResult.matches;\n }\n }\n let match = getTargetMatch(matches, path);\n fetchControllers.set(key, abortController);\n let originatingLoadId = incrementingLoadId;\n let dsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n path,\n matches,\n match,\n hydrationRouteProperties2,\n scopedContext\n );\n let results = await callDataStrategy(\n fetchRequest,\n path,\n dsMatches,\n scopedContext,\n key\n );\n let result = results[match.route.id];\n if (!result) {\n for (let match2 of matches) {\n if (results[match2.route.id]) {\n result = results[match2.route.id];\n break;\n }\n }\n }\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n if (fetchRequest.signal.aborted) {\n return;\n }\n if (fetchersQueuedForDeletion.has(key)) {\n updateFetcherState(key, getDoneFetcher(void 0));\n return;\n }\n if (isRedirectResult(result)) {\n if (pendingNavigationLoadId > originatingLoadId) {\n updateFetcherState(key, getDoneFetcher(void 0));\n return;\n } else {\n fetchRedirectIds.add(key);\n await startRedirectNavigation(fetchRequest, result, false, {\n preventScrollReset\n });\n return;\n }\n }\n if (isErrorResult(result)) {\n setFetcherError(key, routeId, result.error);\n return;\n }\n updateFetcherState(key, getDoneFetcher(result.data));\n }\n async function startRedirectNavigation(request, redirect2, isNavigation, {\n submission,\n fetcherSubmission,\n preventScrollReset,\n replace: replace2\n } = {}) {\n if (!isNavigation) {\n pendingPopstateNavigationDfd?.resolve();\n pendingPopstateNavigationDfd = null;\n }\n if (redirect2.response.headers.has(\"X-Remix-Revalidate\")) {\n isRevalidationRequired = true;\n }\n let location = redirect2.response.headers.get(\"Location\");\n invariant(location, \"Expected a Location header on the redirect Response\");\n location = normalizeRedirectLocation(\n location,\n new URL(request.url),\n basename,\n init.history\n );\n let redirectLocation = createLocation(state.location, location, {\n _isRedirect: true\n });\n if (isBrowser3) {\n let isDocumentReload = false;\n if (redirect2.response.headers.has(\"X-Remix-Reload-Document\")) {\n isDocumentReload = true;\n } else if (isAbsoluteUrl(location)) {\n const url = createBrowserURLImpl(routerWindow, location, true);\n isDocumentReload = // Hard reload if it's an absolute URL to a new origin\n url.origin !== routerWindow.location.origin || // Hard reload if it's an absolute URL that does not match our basename\n stripBasename(url.pathname, basename) == null;\n }\n if (isDocumentReload) {\n if (replace2) {\n routerWindow.location.replace(location);\n } else {\n routerWindow.location.assign(location);\n }\n return;\n }\n }\n pendingNavigationController = null;\n let redirectNavigationType = replace2 === true || redirect2.response.headers.has(\"X-Remix-Replace\") ? \"REPLACE\" /* Replace */ : \"PUSH\" /* Push */;\n let { formMethod, formAction, formEncType } = state.navigation;\n if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) {\n submission = getSubmissionFromNavigation(state.navigation);\n }\n let activeSubmission = submission || fetcherSubmission;\n if (redirectPreserveMethodStatusCodes.has(redirect2.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) {\n await startNavigation(redirectNavigationType, redirectLocation, {\n submission: {\n ...activeSubmission,\n formAction: location\n },\n // Preserve these flags across redirects\n preventScrollReset: preventScrollReset || pendingPreventScrollReset,\n enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0\n });\n } else {\n let overrideNavigation = getLoadingNavigation(\n redirectLocation,\n [],\n redirectNavigationType,\n submission\n );\n await startNavigation(redirectNavigationType, redirectLocation, {\n overrideNavigation,\n // Send fetcher submissions through for shouldRevalidate\n fetcherSubmission,\n // Preserve these flags across redirects\n preventScrollReset: preventScrollReset || pendingPreventScrollReset,\n enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0\n });\n }\n }\n async function callDataStrategy(request, path, matches, scopedContext, fetcherKey) {\n let results;\n let dataResults = {};\n try {\n results = await callDataStrategyImpl(\n dataStrategyImpl,\n request,\n path,\n matches,\n fetcherKey,\n scopedContext,\n false\n );\n } catch (e) {\n matches.filter((m) => m.shouldLoad).forEach((m) => {\n dataResults[m.route.id] = {\n type: \"error\" /* error */,\n error: e\n };\n });\n return dataResults;\n }\n if (request.signal.aborted) {\n return dataResults;\n }\n if (!isMutationMethod(request.method)) {\n for (let match of matches) {\n if (results[match.route.id]?.type === \"error\" /* error */) {\n break;\n }\n if (!results.hasOwnProperty(match.route.id) && !state.loaderData.hasOwnProperty(match.route.id) && (!state.errors || !state.errors.hasOwnProperty(match.route.id)) && match.shouldCallHandler()) {\n results[match.route.id] = {\n type: \"error\" /* error */,\n result: new Error(\n `No result returned from dataStrategy for route ${match.route.id}`\n )\n };\n }\n }\n }\n for (let [routeId, result] of Object.entries(results)) {\n if (isRedirectDataStrategyResult(result)) {\n let response = result.result;\n dataResults[routeId] = {\n type: \"redirect\" /* redirect */,\n response: normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n routeId,\n matches,\n basename\n )\n };\n } else {\n dataResults[routeId] = await convertDataStrategyResultToDataResult(result);\n }\n }\n return dataResults;\n }\n async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, location, scopedContext) {\n let loaderResultsPromise = callDataStrategy(\n request,\n location,\n matches,\n scopedContext,\n null\n );\n let fetcherResultsPromise = Promise.all(\n fetchersToLoad.map(async (f) => {\n if (f.matches && f.match && f.request && f.controller) {\n let results = await callDataStrategy(\n f.request,\n f.path,\n f.matches,\n scopedContext,\n f.key\n );\n let result = results[f.match.route.id];\n return { [f.key]: result };\n } else {\n return Promise.resolve({\n [f.key]: {\n type: \"error\" /* error */,\n error: getInternalRouterError(404, {\n pathname: f.path\n })\n }\n });\n }\n })\n );\n let loaderResults = await loaderResultsPromise;\n let fetcherResults = (await fetcherResultsPromise).reduce(\n (acc, r) => Object.assign(acc, r),\n {}\n );\n return {\n loaderResults,\n fetcherResults\n };\n }\n function interruptActiveLoads() {\n isRevalidationRequired = true;\n fetchLoadMatches.forEach((_, key) => {\n if (fetchControllers.has(key)) {\n cancelledFetcherLoads.add(key);\n }\n abortFetcher(key);\n });\n }\n function updateFetcherState(key, fetcher, opts = {}) {\n let workingFetchers = new Map(state.fetchers);\n workingFetchers.set(key, fetcher);\n updateState(\n { fetchers: workingFetchers },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n function setFetcherError(key, routeId, error, opts = {}) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n let workingFetchers = new Map(state.fetchers);\n deleteFetcher(workingFetchers, key);\n updateState(\n {\n errors: {\n [boundaryMatch.route.id]: error\n },\n fetchers: workingFetchers\n },\n { flushSync: (opts && opts.flushSync) === true }\n );\n }\n function getFetcher(key) {\n activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);\n if (fetchersQueuedForDeletion.has(key)) {\n fetchersQueuedForDeletion.delete(key);\n }\n return state.fetchers.get(key) || IDLE_FETCHER;\n }\n function resetFetcher(key, opts) {\n abortFetcher(key, opts?.reason);\n updateFetcherState(key, getDoneFetcher(null));\n }\n function deleteFetcher(fetchers, key) {\n let fetcher = state.fetchers.get(key);\n if (fetchControllers.has(key) && !(fetcher && fetcher.state === \"loading\" && fetchReloadIds.has(key))) {\n abortFetcher(key);\n }\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n fetchersQueuedForDeletion.delete(key);\n cancelledFetcherLoads.delete(key);\n fetchers.delete(key);\n }\n function queueFetcherForDeletion(key) {\n let count = (activeFetchers.get(key) || 0) - 1;\n if (count <= 0) {\n activeFetchers.delete(key);\n fetchersQueuedForDeletion.add(key);\n } else {\n activeFetchers.set(key, count);\n }\n updateState({ fetchers: new Map(state.fetchers) });\n }\n function abortFetcher(key, reason) {\n let controller = fetchControllers.get(key);\n if (controller) {\n controller.abort(reason);\n fetchControllers.delete(key);\n }\n }\n function markFetchersDone(keys, fetchers) {\n for (let key of keys) {\n let fetcher = fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n let doneFetcher = getDoneFetcher(fetcher.data);\n fetchers.set(key, doneFetcher);\n }\n }\n function markFetchRedirectsDone(fetchers) {\n let doneKeys = [];\n let didUpdateFetchers = false;\n for (let key of fetchRedirectIds) {\n let fetcher = fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n fetchRedirectIds.delete(key);\n doneKeys.push(key);\n didUpdateFetchers = true;\n }\n }\n markFetchersDone(doneKeys, fetchers);\n return didUpdateFetchers;\n }\n function abortStaleFetchLoads(landedId, fetchers) {\n let yeetedKeys = [];\n for (let [key, id] of fetchReloadIds) {\n if (id < landedId) {\n let fetcher = fetchers.get(key);\n invariant(fetcher, `Expected fetcher: ${key}`);\n if (fetcher.state === \"loading\") {\n abortFetcher(key);\n fetchReloadIds.delete(key);\n yeetedKeys.push(key);\n }\n }\n }\n markFetchersDone(yeetedKeys, fetchers);\n return yeetedKeys.length > 0;\n }\n function getBlocker(key, fn) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n if (blockerFunctions.get(key) !== fn) {\n blockerFunctions.set(key, fn);\n }\n return blocker;\n }\n function deleteBlocker(key) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n }\n function updateBlocker(key, newBlocker) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n invariant(\n blocker.state === \"unblocked\" && newBlocker.state === \"blocked\" || blocker.state === \"blocked\" && newBlocker.state === \"blocked\" || blocker.state === \"blocked\" && newBlocker.state === \"proceeding\" || blocker.state === \"blocked\" && newBlocker.state === \"unblocked\" || blocker.state === \"proceeding\" && newBlocker.state === \"unblocked\",\n `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}`\n );\n let blockers = new Map(state.blockers);\n blockers.set(key, newBlocker);\n updateState({ blockers });\n }\n function shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction\n }) {\n if (blockerFunctions.size === 0) {\n return;\n }\n if (blockerFunctions.size > 1) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n let entries = Array.from(blockerFunctions.entries());\n let [blockerKey, blockerFunction] = entries[entries.length - 1];\n let blocker = state.blockers.get(blockerKey);\n if (blocker && blocker.state === \"proceeding\") {\n return;\n }\n if (blockerFunction({ currentLocation, nextLocation, historyAction })) {\n return blockerKey;\n }\n }\n function handleNavigational404(pathname) {\n let error = getInternalRouterError(404, { pathname });\n let routesToUse = dataRoutes.activeRoutes;\n let { matches, route } = getShortCircuitMatches(routesToUse);\n return { notFoundMatches: matches, route, error };\n }\n function enableScrollRestoration(positions, getPosition, getKey) {\n savedScrollPositions2 = positions;\n getScrollPosition = getPosition;\n getScrollRestorationKey2 = getKey || null;\n if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {\n initialScrollRestored = true;\n let y = getSavedScrollPosition(state.location, state.matches);\n if (y != null) {\n updateState({ restoreScrollPosition: y });\n }\n }\n return () => {\n savedScrollPositions2 = null;\n getScrollPosition = null;\n getScrollRestorationKey2 = null;\n };\n }\n function getScrollKey(location, matches) {\n if (getScrollRestorationKey2) {\n let key = getScrollRestorationKey2(\n location,\n matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData))\n );\n return key || location.key;\n }\n return location.key;\n }\n function saveScrollPosition(location, matches) {\n if (savedScrollPositions2 && getScrollPosition) {\n let key = getScrollKey(location, matches);\n savedScrollPositions2[key] = getScrollPosition();\n }\n }\n function getSavedScrollPosition(location, matches) {\n if (savedScrollPositions2) {\n let key = getScrollKey(location, matches);\n let y = savedScrollPositions2[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n function checkFogOfWar(matches, routesToUse, pathname) {\n if (init.patchRoutesOnNavigation) {\n let activeBranches = dataRoutes.branches;\n if (!matches) {\n let fogMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true,\n activeBranches\n );\n return { active: true, matches: fogMatches || [] };\n } else {\n if (Object.keys(matches[0].params).length > 0) {\n let partialMatches = matchRoutesImpl(\n routesToUse,\n pathname,\n basename,\n true,\n activeBranches\n );\n return { active: true, matches: partialMatches };\n }\n }\n }\n return { active: false, matches: null };\n }\n async function discoverRoutes(matches, pathname, signal, fetcherKey) {\n if (!init.patchRoutesOnNavigation) {\n return { type: \"success\", matches };\n }\n let partialMatches = matches;\n while (true) {\n let localManifest = manifest;\n try {\n await init.patchRoutesOnNavigation({\n signal,\n path: pathname,\n matches: partialMatches,\n fetcherKey,\n patch: (routeId, children) => {\n if (signal.aborted) return;\n patchRoutesImpl(\n routeId,\n children,\n dataRoutes,\n localManifest,\n mapRouteProperties2,\n false\n );\n }\n });\n } catch (e) {\n return { type: \"error\", error: e, partialMatches };\n }\n if (signal.aborted) {\n return { type: \"aborted\" };\n }\n let activeBranches = dataRoutes.branches;\n let newMatches = matchRoutesImpl(\n dataRoutes.activeRoutes,\n pathname,\n basename,\n false,\n activeBranches\n );\n let newPartialMatches = null;\n if (newMatches) {\n if (Object.keys(newMatches[0].params).length === 0) {\n return { type: \"success\", matches: newMatches };\n } else {\n newPartialMatches = matchRoutesImpl(\n dataRoutes.activeRoutes,\n pathname,\n basename,\n true,\n activeBranches\n );\n let matchedDeeper = newPartialMatches && partialMatches.length < newPartialMatches.length && compareMatches(\n partialMatches,\n newPartialMatches.slice(0, partialMatches.length)\n );\n if (!matchedDeeper) {\n return { type: \"success\", matches: newMatches };\n }\n }\n }\n if (!newPartialMatches) {\n newPartialMatches = matchRoutesImpl(\n dataRoutes.activeRoutes,\n pathname,\n basename,\n true,\n activeBranches\n );\n }\n if (!newPartialMatches || compareMatches(partialMatches, newPartialMatches)) {\n return { type: \"success\", matches: null };\n }\n partialMatches = newPartialMatches;\n }\n }\n function compareMatches(a, b) {\n return a.length === b.length && a.every((m, i) => m.route.id === b[i].route.id);\n }\n function _internalSetRoutes(newRoutes) {\n manifest = {};\n dataRoutes.setHmrRoutes(\n convertRoutesToDataRoutes(\n newRoutes,\n mapRouteProperties2,\n void 0,\n manifest\n )\n );\n }\n function patchRoutes(routeId, children, unstable_allowElementMutations = false) {\n patchRoutesImpl(\n routeId,\n children,\n dataRoutes,\n manifest,\n mapRouteProperties2,\n unstable_allowElementMutations\n );\n if (!dataRoutes.hasHMRRoutes) {\n updateState({});\n }\n }\n router = {\n get basename() {\n return basename;\n },\n get future() {\n return future;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes.stableRoutes;\n },\n get branches() {\n return dataRoutes.branches;\n },\n get manifest() {\n return manifest;\n },\n get window() {\n return routerWindow;\n },\n initialize,\n subscribe,\n enableScrollRestoration,\n navigate,\n fetch: fetch2,\n revalidate,\n // Passthrough to history-aware createHref used by useHref so we get proper\n // hash-aware URLs in DOM paths\n createHref: (to) => init.history.createHref(to),\n encodeLocation: (to) => init.history.encodeLocation(to),\n getFetcher,\n resetFetcher,\n deleteFetcher: queueFetcherForDeletion,\n dispose,\n getBlocker,\n deleteBlocker,\n patchRoutes,\n _internalFetchControllers: fetchControllers,\n // TODO: Remove setRoutes, it's temporary to avoid dealing with\n // updating the tree while validating the update algorithm.\n _internalSetRoutes,\n _internalSetStateDoNotUseOrYouWillBreakYourApp(newState) {\n updateState(newState);\n }\n };\n if (init.instrumentations) {\n router = instrumentClientSideRouter(\n router,\n init.instrumentations.map((i) => i.router).filter(Boolean)\n );\n }\n return router;\n}\nfunction createStaticHandler(routes, opts) {\n invariant(\n routes.length > 0,\n \"You must provide a non-empty routes array to createStaticHandler\"\n );\n let manifest = {};\n let basename = (opts ? opts.basename : null) || \"/\";\n let _mapRouteProperties = opts?.mapRouteProperties || defaultMapRouteProperties;\n let mapRouteProperties2 = _mapRouteProperties;\n let future = {\n ...opts?.future\n };\n if (opts?.instrumentations) {\n let instrumentations = opts.instrumentations;\n mapRouteProperties2 = (route) => {\n return {\n ..._mapRouteProperties(route),\n ...getRouteInstrumentationUpdates(\n instrumentations.map((i) => i.route).filter(Boolean),\n route\n )\n };\n };\n }\n let dataRoutes = convertRoutesToDataRoutes(\n routes,\n mapRouteProperties2,\n void 0,\n manifest\n );\n let routeBranches = flattenAndRankRoutes(dataRoutes);\n async function query(request, {\n requestContext,\n filterMatchesToLoad,\n skipLoaderErrorBubbling,\n skipRevalidation,\n dataStrategy,\n generateMiddlewareResponse,\n normalizePath\n } = {}) {\n let normalizePathImpl = normalizePath || defaultNormalizePath;\n let method = request.method;\n let location = createLocation(\n \"\",\n normalizePathImpl(request),\n null,\n \"default\"\n );\n let matches = matchRoutesImpl(\n dataRoutes,\n location,\n basename,\n false,\n routeBranches\n );\n requestContext = requestContext != null ? requestContext : new RouterContextProvider();\n if (!isValidMethod(method) && method !== \"HEAD\") {\n let error = getInternalRouterError(405, { method });\n let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes);\n let staticContext = {\n basename,\n location,\n matches: methodNotAllowedMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {}\n };\n return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;\n } else if (!matches) {\n let error = getInternalRouterError(404, { pathname: location.pathname });\n let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes);\n let staticContext = {\n basename,\n location,\n matches: notFoundMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {}\n };\n return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext;\n }\n if (generateMiddlewareResponse) {\n invariant(\n requestContext instanceof RouterContextProvider,\n \"When using middleware in `staticHandler.query()`, any provided `requestContext` must be an instance of `RouterContextProvider`\"\n );\n try {\n await loadLazyMiddlewareForMatches(\n matches,\n manifest,\n mapRouteProperties2\n );\n let renderedStaticContext;\n let response = await runServerMiddlewarePipeline(\n {\n request,\n url: createDataFunctionUrl(request, location),\n pattern: getRoutePattern(matches),\n matches,\n params: matches[0].params,\n // If we're calling middleware then it must be enabled so we can cast\n // this to the proper type knowing it's not an `AppLoadContext`\n context: requestContext\n },\n async () => {\n let res = await generateMiddlewareResponse(\n async (revalidationRequest, opts2 = {}) => {\n let result2 = await queryImpl(\n revalidationRequest,\n location,\n matches,\n requestContext,\n dataStrategy || null,\n skipLoaderErrorBubbling === true,\n null,\n \"filterMatchesToLoad\" in opts2 ? opts2.filterMatchesToLoad ?? null : filterMatchesToLoad ?? null,\n skipRevalidation === true\n );\n if (isResponse(result2)) {\n return result2;\n }\n renderedStaticContext = { location, basename, ...result2 };\n return renderedStaticContext;\n }\n );\n return res;\n },\n async (error, routeId) => {\n if (isRedirectResponse(error)) {\n return error;\n }\n if (isResponse(error)) {\n try {\n error = new ErrorResponseImpl(\n error.status,\n error.statusText,\n await parseResponseBody(error)\n );\n } catch (e) {\n error = e;\n }\n }\n if (isDataWithResponseInit(error)) {\n error = dataWithResponseInitToErrorResponse(error);\n }\n if (renderedStaticContext) {\n if (routeId in renderedStaticContext.loaderData) {\n renderedStaticContext.loaderData[routeId] = void 0;\n }\n let staticContext = getStaticContextFromError(\n dataRoutes,\n renderedStaticContext,\n error,\n skipLoaderErrorBubbling ? routeId : findNearestBoundary(matches, routeId).route.id\n );\n return generateMiddlewareResponse(\n () => Promise.resolve(staticContext)\n );\n } else {\n let boundaryRouteId = skipLoaderErrorBubbling ? routeId : findNearestBoundary(\n matches,\n matches.find(\n (m) => m.route.id === routeId || m.route.loader\n )?.route.id || routeId\n ).route.id;\n let staticContext = {\n matches,\n location,\n basename,\n loaderData: {},\n actionData: null,\n errors: {\n [boundaryRouteId]: error\n },\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n actionHeaders: {},\n loaderHeaders: {}\n };\n return generateMiddlewareResponse(\n () => Promise.resolve(staticContext)\n );\n }\n }\n );\n invariant(isResponse(response), \"Expected a response in query()\");\n return response;\n } catch (e) {\n if (isResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n dataStrategy || null,\n skipLoaderErrorBubbling === true,\n null,\n filterMatchesToLoad || null,\n skipRevalidation === true\n );\n if (isResponse(result)) {\n return result;\n }\n return { location, basename, ...result };\n }\n async function queryRoute(request, {\n routeId,\n requestContext,\n dataStrategy,\n generateMiddlewareResponse,\n normalizePath\n } = {}) {\n let normalizePathImpl = normalizePath || defaultNormalizePath;\n let method = request.method;\n let location = createLocation(\n \"\",\n normalizePathImpl(request),\n null,\n \"default\"\n );\n let matches = matchRoutesImpl(\n dataRoutes,\n location,\n basename,\n false,\n routeBranches\n );\n requestContext = requestContext != null ? requestContext : new RouterContextProvider();\n if (!isValidMethod(method) && method !== \"HEAD\" && method !== \"OPTIONS\") {\n throw getInternalRouterError(405, { method });\n } else if (!matches) {\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n let match = routeId ? matches.find((m) => m.route.id === routeId) : getTargetMatch(matches, location);\n if (routeId && !match) {\n throw getInternalRouterError(403, {\n pathname: location.pathname,\n routeId\n });\n } else if (!match) {\n throw getInternalRouterError(404, { pathname: location.pathname });\n }\n if (generateMiddlewareResponse) {\n invariant(\n requestContext instanceof RouterContextProvider,\n \"When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must be an instance of `RouterContextProvider`\"\n );\n await loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2);\n let response = await runServerMiddlewarePipeline(\n {\n request,\n url: createDataFunctionUrl(request, location),\n pattern: getRoutePattern(matches),\n matches,\n params: matches[0].params,\n // If we're calling middleware then it must be enabled so we can cast\n // this to the proper type knowing it's not an `AppLoadContext`\n context: requestContext\n },\n async () => {\n let res = await generateMiddlewareResponse(\n async (innerRequest) => {\n let result2 = await queryImpl(\n innerRequest,\n location,\n matches,\n requestContext,\n dataStrategy || null,\n false,\n match,\n null,\n false\n );\n let processed = handleQueryResult(result2);\n return isResponse(processed) ? processed : typeof processed === \"string\" ? new Response(processed) : Response.json(processed);\n }\n );\n return res;\n },\n (error) => {\n if (isDataWithResponseInit(error)) {\n return Promise.resolve(dataWithResponseInitToResponse(error));\n }\n if (isResponse(error)) {\n return Promise.resolve(error);\n }\n throw error;\n }\n );\n return response;\n }\n let result = await queryImpl(\n request,\n location,\n matches,\n requestContext,\n dataStrategy || null,\n false,\n match,\n null,\n false\n );\n return handleQueryResult(result);\n function handleQueryResult(result2) {\n if (isResponse(result2)) {\n return result2;\n }\n let error = result2.errors ? Object.values(result2.errors)[0] : void 0;\n if (error !== void 0) {\n throw error;\n }\n if (result2.actionData) {\n return Object.values(result2.actionData)[0];\n }\n if (result2.loaderData) {\n return Object.values(result2.loaderData)[0];\n }\n return void 0;\n }\n }\n async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) {\n invariant(\n request.signal,\n \"query()/queryRoute() requests must contain an AbortController signal\"\n );\n try {\n if (isMutationMethod(request.method)) {\n let result2 = await submit(\n request,\n location,\n matches,\n routeMatch || getTargetMatch(matches, location),\n requestContext,\n dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch != null,\n filterMatchesToLoad,\n skipRevalidation\n );\n return result2;\n }\n let result = await loadRouteData(\n request,\n location,\n matches,\n requestContext,\n dataStrategy,\n skipLoaderErrorBubbling,\n routeMatch,\n filterMatchesToLoad\n );\n return isResponse(result) ? result : {\n ...result,\n actionData: null,\n actionHeaders: {}\n };\n } catch (e) {\n if (isDataStrategyResult(e) && isResponse(e.result)) {\n if (e.type === \"error\" /* error */) {\n throw e.result;\n }\n return e.result;\n }\n if (isRedirectResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n async function submit(request, location, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) {\n let result;\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n let error = getInternalRouterError(405, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: actionMatch.route.id\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: \"error\" /* error */,\n error\n };\n } else {\n let dsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n request,\n location,\n matches,\n actionMatch,\n [],\n requestContext\n );\n let results = await callDataStrategy(\n request,\n location,\n dsMatches,\n isRouteRequest,\n requestContext,\n dataStrategy\n );\n result = results[actionMatch.route.id];\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest);\n }\n }\n if (isRedirectResult(result)) {\n throw new Response(null, {\n status: result.response.status,\n headers: {\n Location: result.response.headers.get(\"Location\")\n }\n });\n }\n if (isRouteRequest) {\n if (isErrorResult(result)) {\n throw result.error;\n }\n return {\n matches: [actionMatch],\n loaderData: {},\n actionData: { [actionMatch.route.id]: result.data },\n errors: null,\n // Note: statusCode + headers are unused here since queryRoute will\n // return the raw Response or value\n statusCode: 200,\n loaderHeaders: {},\n actionHeaders: {}\n };\n }\n if (skipRevalidation) {\n if (isErrorResult(result)) {\n let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);\n return {\n statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,\n actionData: null,\n actionHeaders: {\n ...result.headers ? { [actionMatch.route.id]: result.headers } : {}\n },\n matches,\n loaderData: {},\n errors: {\n [boundaryMatch.route.id]: result.error\n },\n loaderHeaders: {}\n };\n } else {\n return {\n actionData: {\n [actionMatch.route.id]: result.data\n },\n actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {},\n matches,\n loaderData: {},\n errors: null,\n statusCode: result.statusCode || 200,\n loaderHeaders: {}\n };\n }\n }\n let loaderRequest = new Request(request.url, {\n headers: request.headers,\n redirect: request.redirect,\n signal: request.signal\n });\n if (isErrorResult(result)) {\n let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);\n let handlerContext2 = await loadRouteData(\n loaderRequest,\n location,\n matches,\n requestContext,\n dataStrategy,\n skipLoaderErrorBubbling,\n null,\n filterMatchesToLoad,\n [boundaryMatch.route.id, result]\n );\n return {\n ...handlerContext2,\n statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,\n actionData: null,\n actionHeaders: {\n ...result.headers ? { [actionMatch.route.id]: result.headers } : {}\n }\n };\n }\n let handlerContext = await loadRouteData(\n loaderRequest,\n location,\n matches,\n requestContext,\n dataStrategy,\n skipLoaderErrorBubbling,\n null,\n filterMatchesToLoad\n );\n return {\n ...handlerContext,\n actionData: {\n [actionMatch.route.id]: result.data\n },\n // action status codes take precedence over loader status codes\n ...result.statusCode ? { statusCode: result.statusCode } : {},\n actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}\n };\n }\n async function loadRouteData(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) {\n let isRouteRequest = routeMatch != null;\n if (isRouteRequest && !routeMatch?.route.loader && !routeMatch?.route.lazy) {\n throw getInternalRouterError(400, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: routeMatch?.route.id\n });\n }\n let dsMatches;\n if (routeMatch) {\n dsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n request,\n location,\n matches,\n routeMatch,\n [],\n requestContext\n );\n } else {\n let maxIdx = pendingActionResult && isErrorResult(pendingActionResult[1]) ? (\n // Up to but not including the boundary\n matches.findIndex((m) => m.route.id === pendingActionResult[0]) - 1\n ) : void 0;\n let pattern = getRoutePattern(matches);\n dsMatches = matches.map((match, index) => {\n if (maxIdx != null && index > maxIdx) {\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n location,\n pattern,\n match,\n [],\n requestContext,\n false\n );\n }\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n location,\n pattern,\n match,\n [],\n requestContext,\n (match.route.loader || match.route.lazy) != null && (!filterMatchesToLoad || filterMatchesToLoad(match))\n );\n });\n }\n if (!dataStrategy && !dsMatches.some((m) => m.shouldLoad)) {\n return {\n matches,\n loaderData: {},\n errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? {\n [pendingActionResult[0]]: pendingActionResult[1].error\n } : null,\n statusCode: 200,\n loaderHeaders: {}\n };\n }\n let results = await callDataStrategy(\n request,\n location,\n dsMatches,\n isRouteRequest,\n requestContext,\n dataStrategy\n );\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest);\n }\n let handlerContext = processRouteLoaderData(\n matches,\n results,\n pendingActionResult,\n true,\n skipLoaderErrorBubbling\n );\n return {\n ...handlerContext,\n matches\n };\n }\n async function callDataStrategy(request, location, matches, isRouteRequest, requestContext, dataStrategy) {\n let results = await callDataStrategyImpl(\n dataStrategy || defaultDataStrategy,\n request,\n location,\n matches,\n null,\n requestContext,\n true\n );\n let dataResults = {};\n await Promise.all(\n matches.map(async (match) => {\n if (!(match.route.id in results)) {\n return;\n }\n let result = results[match.route.id];\n if (isRedirectDataStrategyResult(result)) {\n let response = result.result;\n throw normalizeRelativeRoutingRedirectResponse(\n response,\n request,\n match.route.id,\n matches,\n basename\n );\n }\n if (isRouteRequest) {\n if (isResponse(result.result)) {\n throw result;\n } else if (isDataWithResponseInit(result.result)) {\n throw dataWithResponseInitToResponse(result.result);\n }\n }\n dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result);\n })\n );\n return dataResults;\n }\n return {\n dataRoutes,\n _internalRouteBranches: routeBranches,\n query,\n queryRoute\n };\n}\nfunction getStaticContextFromError(routes, handlerContext, error, boundaryId) {\n let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id;\n return {\n ...handlerContext,\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n errors: {\n [errorBoundaryId]: error\n }\n };\n}\nfunction throwStaticHandlerAbortedError(request, isRouteRequest) {\n if (request.signal.reason !== void 0) {\n throw request.signal.reason;\n }\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(\n `${method}() call aborted without an \\`AbortSignal.reason\\`: ${request.method} ${request.url}`\n );\n}\nfunction isSubmissionNavigation(opts) {\n return opts != null && (\"formData\" in opts && opts.formData != null || \"body\" in opts && opts.body !== void 0);\n}\nfunction defaultNormalizePath(request) {\n let url = new URL(request.url);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash\n };\n}\nfunction normalizeTo(location, matches, basename, to, fromRouteId, relative) {\n let contextualMatches;\n let activeRouteMatch;\n if (fromRouteId) {\n contextualMatches = [];\n for (let match of matches) {\n contextualMatches.push(match);\n if (match.route.id === fromRouteId) {\n activeRouteMatch = match;\n break;\n }\n }\n } else {\n contextualMatches = matches;\n activeRouteMatch = matches[matches.length - 1];\n }\n let path = resolveTo(\n to ? to : \".\",\n getResolveToMatches(contextualMatches),\n stripBasename(location.pathname, basename) || location.pathname,\n relative === \"path\"\n );\n if (to == null) {\n path.search = location.search;\n path.hash = location.hash;\n }\n if ((to == null || to === \"\" || to === \".\") && activeRouteMatch) {\n let nakedIndex = hasNakedIndexQuery(path.search);\n if (activeRouteMatch.route.index && !nakedIndex) {\n path.search = path.search ? path.search.replace(/^\\?/, \"?index&\") : \"?index\";\n } else if (!activeRouteMatch.route.index && nakedIndex) {\n let params = new URLSearchParams(path.search);\n let indexValues = params.getAll(\"index\");\n params.delete(\"index\");\n indexValues.filter((v) => v).forEach((v) => params.append(\"index\", v));\n let qs = params.toString();\n path.search = qs ? `?${qs}` : \"\";\n }\n }\n if (basename !== \"/\") {\n path.pathname = prependBasename({ basename, pathname: path.pathname });\n }\n return createPath(path);\n}\nfunction normalizeNavigateOptions(isFetcher, path, opts) {\n if (!opts || !isSubmissionNavigation(opts)) {\n return { path };\n }\n if (opts.formMethod && !isValidMethod(opts.formMethod)) {\n return {\n path,\n error: getInternalRouterError(405, { method: opts.formMethod })\n };\n }\n let getInvalidBodyError = () => ({\n path,\n error: getInternalRouterError(400, { type: \"invalid-body\" })\n });\n let rawFormMethod = opts.formMethod || \"get\";\n let formMethod = rawFormMethod.toUpperCase();\n let formAction = stripHashFromPath(path);\n if (opts.body !== void 0) {\n if (opts.formEncType === \"text/plain\") {\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n let text = typeof opts.body === \"string\" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? (\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data\n Array.from(opts.body.entries()).reduce(\n (acc, [name, value]) => `${acc}${name}=${value}\n`,\n \"\"\n )\n ) : String(opts.body);\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: void 0,\n json: void 0,\n text\n }\n };\n } else if (opts.formEncType === \"application/json\") {\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n try {\n let json = typeof opts.body === \"string\" ? JSON.parse(opts.body) : opts.body;\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: void 0,\n json,\n text: void 0\n }\n };\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n }\n invariant(\n typeof FormData === \"function\",\n \"FormData is not available in this environment\"\n );\n let searchParams;\n let formData;\n if (opts.formData) {\n searchParams = convertFormDataToSearchParams(opts.formData);\n formData = opts.formData;\n } else if (opts.body instanceof FormData) {\n searchParams = convertFormDataToSearchParams(opts.body);\n formData = opts.body;\n } else if (opts.body instanceof URLSearchParams) {\n searchParams = opts.body;\n formData = convertSearchParamsToFormData(searchParams);\n } else if (opts.body == null) {\n searchParams = new URLSearchParams();\n formData = new FormData();\n } else {\n try {\n searchParams = new URLSearchParams(opts.body);\n formData = convertSearchParamsToFormData(searchParams);\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n let submission = {\n formMethod,\n formAction,\n formEncType: opts && opts.formEncType || \"application/x-www-form-urlencoded\",\n formData,\n json: void 0,\n text: void 0\n };\n if (isMutationMethod(submission.formMethod)) {\n return { path, submission };\n }\n let parsedPath = parsePath(path);\n if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = `?${searchParams}`;\n return { path: createPath(parsedPath), submission };\n}\nfunction getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest, history, state, matches, submission, location, lazyRoutePropertiesToSkip, initialHydration, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, hasPatchRoutesOnNavigation, branches, pendingActionResult, callSiteDefaultShouldRevalidate) {\n let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : void 0;\n let currentUrl = history.createURL(state.location);\n let nextUrl = history.createURL(location);\n let maxIdx;\n if (initialHydration && state.errors) {\n let boundaryId = Object.keys(state.errors)[0];\n maxIdx = matches.findIndex((m) => m.route.id === boundaryId);\n } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) {\n let boundaryId = pendingActionResult[0];\n maxIdx = matches.findIndex((m) => m.route.id === boundaryId) - 1;\n }\n let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : void 0;\n let shouldSkipRevalidation = actionStatus && actionStatus >= 400;\n let baseShouldRevalidateArgs = {\n currentUrl,\n currentParams: state.matches[0]?.params || {},\n nextUrl,\n nextParams: matches[0].params,\n ...submission,\n actionResult,\n actionStatus\n };\n let pattern = getRoutePattern(matches);\n let dsMatches = matches.map((match, index) => {\n let { route } = match;\n let forceShouldLoad = null;\n if (maxIdx != null && index > maxIdx) {\n forceShouldLoad = false;\n } else if (route.lazy) {\n forceShouldLoad = true;\n } else if (!routeHasLoaderOrMiddleware(route)) {\n forceShouldLoad = false;\n } else if (initialHydration) {\n let { shouldLoad: shouldLoad2 } = getRouteHydrationStatus(\n route,\n state.loaderData,\n state.errors\n );\n forceShouldLoad = shouldLoad2;\n } else if (isNewLoader(state.loaderData, state.matches[index], match)) {\n forceShouldLoad = true;\n }\n if (forceShouldLoad !== null) {\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n location,\n pattern,\n match,\n lazyRoutePropertiesToSkip,\n scopedContext,\n forceShouldLoad\n );\n }\n let defaultShouldRevalidate = false;\n if (typeof callSiteDefaultShouldRevalidate === \"boolean\") {\n defaultShouldRevalidate = callSiteDefaultShouldRevalidate;\n } else if (shouldSkipRevalidation) {\n defaultShouldRevalidate = false;\n } else if (isRevalidationRequired) {\n defaultShouldRevalidate = true;\n } else if (currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search) {\n defaultShouldRevalidate = true;\n } else if (currentUrl.search !== nextUrl.search) {\n defaultShouldRevalidate = true;\n } else if (isNewRouteInstance(state.matches[index], match)) {\n defaultShouldRevalidate = true;\n }\n let shouldRevalidateArgs = {\n ...baseShouldRevalidateArgs,\n defaultShouldRevalidate\n };\n let shouldLoad = shouldRevalidateLoader(match, shouldRevalidateArgs);\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n location,\n pattern,\n match,\n lazyRoutePropertiesToSkip,\n scopedContext,\n shouldLoad,\n shouldRevalidateArgs,\n callSiteDefaultShouldRevalidate\n );\n });\n let revalidatingFetchers = [];\n fetchLoadMatches.forEach((f, key) => {\n if (initialHydration || !matches.some((m) => m.route.id === f.routeId) || fetchersQueuedForDeletion.has(key)) {\n return;\n }\n let fetcher = state.fetchers.get(key);\n let isMidInitialLoad = fetcher && fetcher.state !== \"idle\" && fetcher.data === void 0;\n let fetcherMatches = matchRoutesImpl(\n routesToUse,\n f.path,\n basename ?? \"/\",\n false,\n branches\n );\n if (!fetcherMatches) {\n if (hasPatchRoutesOnNavigation && isMidInitialLoad) {\n return;\n }\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: null,\n match: null,\n request: null,\n controller: null\n });\n return;\n }\n if (fetchRedirectIds.has(key)) {\n return;\n }\n let fetcherMatch = getTargetMatch(fetcherMatches, f.path);\n let fetchController = new AbortController();\n let fetchRequest = createClientSideRequest(\n history,\n f.path,\n fetchController.signal\n );\n let fetcherDsMatches = null;\n if (cancelledFetcherLoads.has(key)) {\n cancelledFetcherLoads.delete(key);\n fetcherDsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n f.path,\n fetcherMatches,\n fetcherMatch,\n lazyRoutePropertiesToSkip,\n scopedContext\n );\n } else if (isMidInitialLoad) {\n if (isRevalidationRequired) {\n fetcherDsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n f.path,\n fetcherMatches,\n fetcherMatch,\n lazyRoutePropertiesToSkip,\n scopedContext\n );\n }\n } else {\n let defaultShouldRevalidate;\n if (typeof callSiteDefaultShouldRevalidate === \"boolean\") {\n defaultShouldRevalidate = callSiteDefaultShouldRevalidate;\n } else if (shouldSkipRevalidation) {\n defaultShouldRevalidate = false;\n } else {\n defaultShouldRevalidate = isRevalidationRequired;\n }\n let shouldRevalidateArgs = {\n ...baseShouldRevalidateArgs,\n defaultShouldRevalidate\n };\n if (shouldRevalidateLoader(fetcherMatch, shouldRevalidateArgs)) {\n fetcherDsMatches = getTargetedDataStrategyMatches(\n mapRouteProperties2,\n manifest,\n fetchRequest,\n f.path,\n fetcherMatches,\n fetcherMatch,\n lazyRoutePropertiesToSkip,\n scopedContext,\n shouldRevalidateArgs\n );\n }\n }\n if (fetcherDsMatches) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: fetcherDsMatches,\n match: fetcherMatch,\n request: fetchRequest,\n controller: fetchController\n });\n }\n });\n return { dsMatches, revalidatingFetchers };\n}\nfunction routeHasLoaderOrMiddleware(route) {\n return route.loader != null || route.middleware != null && route.middleware.length > 0;\n}\nfunction getRouteHydrationStatus(route, loaderData, errors) {\n if (route.lazy) {\n return { shouldLoad: true, renderFallback: true };\n }\n if (!routeHasLoaderOrMiddleware(route)) {\n return { shouldLoad: false, renderFallback: false };\n }\n let hasData = loaderData != null && route.id in loaderData;\n let hasError = errors != null && errors[route.id] !== void 0;\n if (!hasData && hasError) {\n return { shouldLoad: false, renderFallback: false };\n }\n if (typeof route.loader === \"function\" && route.loader.hydrate === true) {\n return { shouldLoad: true, renderFallback: !hasData };\n }\n let shouldLoad = !hasData && !hasError;\n return { shouldLoad, renderFallback: shouldLoad };\n}\nfunction isNewLoader(currentLoaderData, currentMatch, match) {\n let isNew = (\n // [a] -> [a, b]\n !currentMatch || // [a, b] -> [a, c]\n match.route.id !== currentMatch.route.id\n );\n let isMissingData = !currentLoaderData.hasOwnProperty(match.route.id);\n return isNew || isMissingData;\n}\nfunction isNewRouteInstance(currentMatch, match) {\n let currentPath = currentMatch.route.path;\n return (\n // param change for this match, /users/123 -> /users/456\n currentMatch.pathname !== match.pathname || // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n currentPath != null && currentPath.endsWith(\"*\") && currentMatch.params[\"*\"] !== match.params[\"*\"]\n );\n}\nfunction shouldRevalidateLoader(loaderMatch, arg) {\n if (loaderMatch.route.shouldRevalidate) {\n let routeChoice = loaderMatch.route.shouldRevalidate(arg);\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n return arg.defaultShouldRevalidate;\n}\nfunction patchRoutesImpl(routeId, children, dataRoutes, manifest, mapRouteProperties2, allowElementMutations) {\n let childrenToPatch;\n if (routeId) {\n let route = manifest[routeId];\n invariant(\n route,\n `No route found to patch children into: routeId = ${routeId}`\n );\n if (!route.children) {\n route.children = [];\n }\n childrenToPatch = route.children;\n } else {\n childrenToPatch = dataRoutes.activeRoutes;\n }\n let uniqueChildren = [];\n let existingChildren = [];\n children.forEach((newRoute) => {\n let existingRoute = childrenToPatch.find(\n (existingRoute2) => isSameRoute(newRoute, existingRoute2)\n );\n if (existingRoute) {\n existingChildren.push({ existingRoute, newRoute });\n } else {\n uniqueChildren.push(newRoute);\n }\n });\n if (uniqueChildren.length > 0) {\n let newRoutes = convertRoutesToDataRoutes(\n uniqueChildren,\n mapRouteProperties2,\n [routeId || \"_\", \"patch\", String(childrenToPatch?.length || \"0\")],\n manifest\n );\n childrenToPatch.push(...newRoutes);\n }\n if (allowElementMutations && existingChildren.length > 0) {\n for (let i = 0; i < existingChildren.length; i++) {\n let { existingRoute, newRoute } = existingChildren[i];\n let existingRouteTyped = existingRoute;\n let [newRouteTyped] = convertRoutesToDataRoutes(\n [newRoute],\n mapRouteProperties2,\n [],\n // Doesn't matter for mutated routes since they already have an id\n {},\n // Don't touch the manifest here since we're updating in place\n true\n );\n Object.assign(existingRouteTyped, {\n element: newRouteTyped.element ? newRouteTyped.element : existingRouteTyped.element,\n errorElement: newRouteTyped.errorElement ? newRouteTyped.errorElement : existingRouteTyped.errorElement,\n hydrateFallbackElement: newRouteTyped.hydrateFallbackElement ? newRouteTyped.hydrateFallbackElement : existingRouteTyped.hydrateFallbackElement\n });\n }\n }\n if (!dataRoutes.hasHMRRoutes) {\n dataRoutes.setRoutes([...dataRoutes.activeRoutes]);\n }\n}\nfunction isSameRoute(newRoute, existingRoute) {\n if (\"id\" in newRoute && \"id\" in existingRoute && newRoute.id === existingRoute.id) {\n return true;\n }\n if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) {\n return false;\n }\n if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) {\n return true;\n }\n return newRoute.children?.every(\n (aChild, i) => existingRoute.children?.some((bChild) => isSameRoute(aChild, bChild))\n ) ?? false;\n}\nvar lazyRoutePropertyCache = /* @__PURE__ */ new WeakMap();\nvar loadLazyRouteProperty = ({\n key,\n route,\n manifest,\n mapRouteProperties: mapRouteProperties2\n}) => {\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n if (!routeToUpdate.lazy || typeof routeToUpdate.lazy !== \"object\") {\n return;\n }\n let lazyFn = routeToUpdate.lazy[key];\n if (!lazyFn) {\n return;\n }\n let cache = lazyRoutePropertyCache.get(routeToUpdate);\n if (!cache) {\n cache = {};\n lazyRoutePropertyCache.set(routeToUpdate, cache);\n }\n let cachedPromise = cache[key];\n if (cachedPromise) {\n return cachedPromise;\n }\n let propertyPromise = (async () => {\n let isUnsupported = isUnsupportedLazyRouteObjectKey(key);\n let staticRouteValue = routeToUpdate[key];\n let isStaticallyDefined = staticRouteValue !== void 0 && key !== \"hasErrorBoundary\";\n if (isUnsupported) {\n warning(\n !isUnsupported,\n \"Route property \" + key + \" is not a supported lazy route property. This property will be ignored.\"\n );\n cache[key] = Promise.resolve();\n } else if (isStaticallyDefined) {\n warning(\n false,\n `Route \"${routeToUpdate.id}\" has a static property \"${key}\" defined. The lazy property will be ignored.`\n );\n } else {\n let value = await lazyFn();\n if (value != null) {\n Object.assign(routeToUpdate, { [key]: value });\n Object.assign(routeToUpdate, mapRouteProperties2(routeToUpdate));\n }\n }\n if (typeof routeToUpdate.lazy === \"object\") {\n routeToUpdate.lazy[key] = void 0;\n if (Object.values(routeToUpdate.lazy).every((value) => value === void 0)) {\n routeToUpdate.lazy = void 0;\n }\n }\n })();\n cache[key] = propertyPromise;\n return propertyPromise;\n};\nvar lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap();\nfunction loadLazyRoute(route, type, manifest, mapRouteProperties2, lazyRoutePropertiesToSkip) {\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n if (!route.lazy) {\n return {\n lazyRoutePromise: void 0,\n lazyHandlerPromise: void 0\n };\n }\n if (typeof route.lazy === \"function\") {\n let cachedPromise = lazyRouteFunctionCache.get(routeToUpdate);\n if (cachedPromise) {\n return {\n lazyRoutePromise: cachedPromise,\n lazyHandlerPromise: cachedPromise\n };\n }\n let lazyRoutePromise2 = (async () => {\n invariant(\n typeof route.lazy === \"function\",\n \"No lazy route function found\"\n );\n let lazyRoute = await route.lazy();\n let routeUpdates = {};\n for (let lazyRouteProperty in lazyRoute) {\n let lazyValue = lazyRoute[lazyRouteProperty];\n if (lazyValue === void 0) {\n continue;\n }\n let isUnsupported = isUnsupportedLazyRouteFunctionKey(lazyRouteProperty);\n let staticRouteValue = routeToUpdate[lazyRouteProperty];\n let isStaticallyDefined = staticRouteValue !== void 0 && // This property isn't static since it should always be updated based\n // on the route updates\n lazyRouteProperty !== \"hasErrorBoundary\";\n if (isUnsupported) {\n warning(\n !isUnsupported,\n \"Route property \" + lazyRouteProperty + \" is not a supported property to be returned from a lazy route function. This property will be ignored.\"\n );\n } else if (isStaticallyDefined) {\n warning(\n !isStaticallyDefined,\n `Route \"${routeToUpdate.id}\" has a static property \"${lazyRouteProperty}\" defined but its lazy function is also returning a value for this property. The lazy route property \"${lazyRouteProperty}\" will be ignored.`\n );\n } else {\n routeUpdates[lazyRouteProperty] = lazyValue;\n }\n }\n Object.assign(routeToUpdate, routeUpdates);\n Object.assign(routeToUpdate, {\n // To keep things framework agnostic, we use the provided `mapRouteProperties`\n // function to set the framework-aware properties (`element`/`hasErrorBoundary`)\n // since the logic will differ between frameworks.\n ...mapRouteProperties2(routeToUpdate),\n lazy: void 0\n });\n })();\n lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise2);\n lazyRoutePromise2.catch(() => {\n });\n return {\n lazyRoutePromise: lazyRoutePromise2,\n lazyHandlerPromise: lazyRoutePromise2\n };\n }\n let lazyKeys = Object.keys(route.lazy);\n let lazyPropertyPromises = [];\n let lazyHandlerPromise = void 0;\n for (let key of lazyKeys) {\n if (lazyRoutePropertiesToSkip && lazyRoutePropertiesToSkip.includes(key)) {\n continue;\n }\n let promise = loadLazyRouteProperty({\n key,\n route,\n manifest,\n mapRouteProperties: mapRouteProperties2\n });\n if (promise) {\n lazyPropertyPromises.push(promise);\n if (key === type) {\n lazyHandlerPromise = promise;\n }\n }\n }\n let lazyRoutePromise = lazyPropertyPromises.length > 0 ? Promise.all(lazyPropertyPromises).then(() => {\n }) : void 0;\n lazyRoutePromise?.catch(() => {\n });\n lazyHandlerPromise?.catch(() => {\n });\n return {\n lazyRoutePromise,\n lazyHandlerPromise\n };\n}\nfunction isNonNullable(value) {\n return value !== void 0;\n}\nfunction loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2) {\n let promises = matches.map(({ route }) => {\n if (typeof route.lazy !== \"object\" || !route.lazy.middleware) {\n return void 0;\n }\n return loadLazyRouteProperty({\n key: \"middleware\",\n route,\n manifest,\n mapRouteProperties: mapRouteProperties2\n });\n }).filter(isNonNullable);\n return promises.length > 0 ? Promise.all(promises) : void 0;\n}\nasync function defaultDataStrategy(args) {\n let matchesToLoad = args.matches.filter((m) => m.shouldLoad);\n let keyedResults = {};\n let results = await Promise.all(matchesToLoad.map((m) => m.resolve()));\n results.forEach((result, i) => {\n keyedResults[matchesToLoad[i].route.id] = result;\n });\n return keyedResults;\n}\nasync function defaultDataStrategyWithMiddleware(args) {\n if (!args.matches.some((m) => m.route.middleware)) {\n return defaultDataStrategy(args);\n }\n return runClientMiddlewarePipeline(args, () => defaultDataStrategy(args));\n}\nfunction runServerMiddlewarePipeline(args, handler, errorHandler) {\n return runMiddlewarePipeline(\n args,\n handler,\n processResult,\n isResponse,\n errorHandler\n );\n function processResult(result) {\n return isDataWithResponseInit(result) ? dataWithResponseInitToResponse(result) : result;\n }\n}\nfunction runClientMiddlewarePipeline(args, handler) {\n return runMiddlewarePipeline(\n args,\n handler,\n (r) => {\n if (isRedirectResponse(r)) {\n throw r;\n }\n return r;\n },\n isDataStrategyResults,\n errorHandler\n );\n function errorHandler(error, routeId, nextResult) {\n if (nextResult) {\n return Promise.resolve(\n Object.assign(nextResult.value, {\n [routeId]: { type: \"error\", result: error }\n })\n );\n } else {\n let { matches } = args;\n let maxBoundaryIdx = Math.min(\n // Throwing route\n Math.max(\n matches.findIndex((m) => m.route.id === routeId),\n 0\n ),\n // or the shallowest route that needs to load data\n Math.max(\n matches.findIndex((m) => m.shouldCallHandler()),\n 0\n )\n );\n let boundaryRouteId = findNearestBoundary(\n matches,\n matches[maxBoundaryIdx].route.id\n ).route.id;\n return Promise.resolve({\n [boundaryRouteId]: { type: \"error\", result: error }\n });\n }\n }\n}\nasync function runMiddlewarePipeline(args, handler, processResult, isResult, errorHandler) {\n let { matches, ...dataFnArgs } = args;\n let tuples = matches.flatMap(\n (m) => m.route.middleware ? m.route.middleware.map((fn) => [m.route.id, fn]) : []\n );\n let result = await callRouteMiddleware(\n dataFnArgs,\n tuples,\n handler,\n processResult,\n isResult,\n errorHandler\n );\n return result;\n}\nasync function callRouteMiddleware(args, middlewares, handler, processResult, isResult, errorHandler, idx = 0) {\n let { request } = args;\n if (request.signal.aborted) {\n throw request.signal.reason ?? new Error(`Request aborted: ${request.method} ${request.url}`);\n }\n let tuple = middlewares[idx];\n if (!tuple) {\n let result = await handler();\n return result;\n }\n let [routeId, middleware] = tuple;\n let nextResult;\n let next = async () => {\n if (nextResult) {\n throw new Error(\"You may only call `next()` once per middleware\");\n }\n try {\n let result = await callRouteMiddleware(\n args,\n middlewares,\n handler,\n processResult,\n isResult,\n errorHandler,\n idx + 1\n );\n nextResult = { value: result };\n return nextResult.value;\n } catch (error) {\n nextResult = { value: await errorHandler(error, routeId, nextResult) };\n return nextResult.value;\n }\n };\n try {\n let value = await middleware(args, next);\n let result = value != null ? processResult(value) : void 0;\n if (isResult(result)) {\n return result;\n } else if (nextResult) {\n return result ?? nextResult.value;\n } else {\n nextResult = { value: await next() };\n return nextResult.value;\n }\n } catch (error) {\n let response = await errorHandler(error, routeId, nextResult);\n return response;\n }\n}\nfunction getDataStrategyMatchLazyPromises(mapRouteProperties2, manifest, request, match, lazyRoutePropertiesToSkip) {\n let lazyMiddlewarePromise = loadLazyRouteProperty({\n key: \"middleware\",\n route: match.route,\n manifest,\n mapRouteProperties: mapRouteProperties2\n });\n let lazyRoutePromises = loadLazyRoute(\n match.route,\n isMutationMethod(request.method) ? \"action\" : \"loader\",\n manifest,\n mapRouteProperties2,\n lazyRoutePropertiesToSkip\n );\n return {\n middleware: lazyMiddlewarePromise,\n route: lazyRoutePromises.lazyRoutePromise,\n handler: lazyRoutePromises.lazyHandlerPromise\n };\n}\nfunction getDataStrategyMatch(mapRouteProperties2, manifest, request, path, pattern, match, lazyRoutePropertiesToSkip, scopedContext, shouldLoad, shouldRevalidateArgs = null, callSiteDefaultShouldRevalidate) {\n let isUsingNewApi = false;\n let _lazyPromises = getDataStrategyMatchLazyPromises(\n mapRouteProperties2,\n manifest,\n request,\n match,\n lazyRoutePropertiesToSkip\n );\n return {\n ...match,\n _lazyPromises,\n shouldLoad,\n shouldRevalidateArgs,\n shouldCallHandler(defaultShouldRevalidate) {\n isUsingNewApi = true;\n if (!shouldRevalidateArgs) {\n return shouldLoad;\n }\n if (typeof callSiteDefaultShouldRevalidate === \"boolean\") {\n return shouldRevalidateLoader(match, {\n ...shouldRevalidateArgs,\n defaultShouldRevalidate: callSiteDefaultShouldRevalidate\n });\n }\n if (typeof defaultShouldRevalidate === \"boolean\") {\n return shouldRevalidateLoader(match, {\n ...shouldRevalidateArgs,\n defaultShouldRevalidate\n });\n }\n return shouldRevalidateLoader(match, shouldRevalidateArgs);\n },\n resolve(handlerOverride) {\n let { lazy, loader, middleware } = match.route;\n let callHandler = isUsingNewApi || shouldLoad || handlerOverride && !isMutationMethod(request.method) && (lazy || loader);\n let isMiddlewareOnlyRoute = middleware && middleware.length > 0 && !loader && !lazy;\n if (callHandler && (isMutationMethod(request.method) || !isMiddlewareOnlyRoute)) {\n return callLoaderOrAction({\n request,\n path,\n pattern,\n match,\n lazyHandlerPromise: _lazyPromises?.handler,\n lazyRoutePromise: _lazyPromises?.route,\n handlerOverride,\n scopedContext\n });\n }\n return Promise.resolve({ type: \"data\" /* data */, result: void 0 });\n }\n };\n}\nfunction getTargetedDataStrategyMatches(mapRouteProperties2, manifest, request, path, matches, targetMatch, lazyRoutePropertiesToSkip, scopedContext, shouldRevalidateArgs = null) {\n return matches.map((match) => {\n if (match.route.id !== targetMatch.route.id) {\n return {\n ...match,\n shouldLoad: false,\n shouldRevalidateArgs,\n shouldCallHandler: () => false,\n _lazyPromises: getDataStrategyMatchLazyPromises(\n mapRouteProperties2,\n manifest,\n request,\n match,\n lazyRoutePropertiesToSkip\n ),\n resolve: () => Promise.resolve({ type: \"data\", result: void 0 })\n };\n }\n return getDataStrategyMatch(\n mapRouteProperties2,\n manifest,\n request,\n path,\n getRoutePattern(matches),\n match,\n lazyRoutePropertiesToSkip,\n scopedContext,\n true,\n shouldRevalidateArgs\n );\n });\n}\nasync function callDataStrategyImpl(dataStrategyImpl, request, path, matches, fetcherKey, scopedContext, isStaticHandler) {\n if (matches.some((m) => m._lazyPromises?.middleware)) {\n await Promise.all(matches.map((m) => m._lazyPromises?.middleware));\n }\n let dataStrategyArgs = {\n request,\n url: createDataFunctionUrl(request, path),\n pattern: getRoutePattern(matches),\n params: matches[0].params,\n context: scopedContext,\n matches\n };\n let runClientMiddleware = isStaticHandler ? () => {\n throw new Error(\n \"You cannot call `runClientMiddleware()` from a static handler `dataStrategy`. Middleware is run outside of `dataStrategy` during SSR in order to bubble up the Response. You can enable middleware via the `respond` API in `query`/`queryRoute`\"\n );\n } : (cb) => {\n let typedDataStrategyArgs = dataStrategyArgs;\n return runClientMiddlewarePipeline(typedDataStrategyArgs, () => {\n return cb({\n ...typedDataStrategyArgs,\n fetcherKey,\n runClientMiddleware: () => {\n throw new Error(\n \"Cannot call `runClientMiddleware()` from within an `runClientMiddleware` handler\"\n );\n }\n });\n });\n };\n let results = await dataStrategyImpl({\n ...dataStrategyArgs,\n fetcherKey,\n runClientMiddleware\n });\n try {\n await Promise.all(\n matches.flatMap((m) => [\n m._lazyPromises?.handler,\n m._lazyPromises?.route\n ])\n );\n } catch (e) {\n }\n return results;\n}\nasync function callLoaderOrAction({\n request,\n path,\n pattern,\n match,\n lazyHandlerPromise,\n lazyRoutePromise,\n handlerOverride,\n scopedContext\n}) {\n let result;\n let onReject;\n let isAction = isMutationMethod(request.method);\n let type = isAction ? \"action\" : \"loader\";\n let runHandler = (handler) => {\n let reject;\n let abortPromise = new Promise((_, r) => reject = r);\n onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n let actualHandler = (ctx) => {\n if (typeof handler !== \"function\") {\n return Promise.reject(\n new Error(\n `You cannot call the handler for a route which defines a boolean \"${type}\" [routeId: ${match.route.id}]`\n )\n );\n }\n return handler(\n {\n request,\n url: createDataFunctionUrl(request, path),\n pattern,\n params: match.params,\n context: scopedContext\n },\n ...ctx !== void 0 ? [ctx] : []\n );\n };\n let handlerPromise = (async () => {\n try {\n let val = await (handlerOverride ? handlerOverride((ctx) => actualHandler(ctx)) : actualHandler());\n return { type: \"data\", result: val };\n } catch (e) {\n return { type: \"error\", result: e };\n }\n })();\n return Promise.race([handlerPromise, abortPromise]);\n };\n try {\n let handler = isAction ? match.route.action : match.route.loader;\n if (lazyHandlerPromise || lazyRoutePromise) {\n if (handler) {\n let handlerError;\n let [value] = await Promise.all([\n // If the handler throws, don't let it immediately bubble out,\n // since we need to let the lazy() execution finish so we know if this\n // route has a boundary that can handle the error\n runHandler(handler).catch((e) => {\n handlerError = e;\n }),\n // Ensure all lazy route promises are resolved before continuing\n lazyHandlerPromise,\n lazyRoutePromise\n ]);\n if (handlerError !== void 0) {\n throw handlerError;\n }\n result = value;\n } else {\n await lazyHandlerPromise;\n let handler2 = isAction ? match.route.action : match.route.loader;\n if (handler2) {\n [result] = await Promise.all([runHandler(handler2), lazyRoutePromise]);\n } else if (type === \"action\") {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(405, {\n method: request.method,\n pathname,\n routeId: match.route.id\n });\n } else {\n return { type: \"data\" /* data */, result: void 0 };\n }\n }\n } else if (!handler) {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(404, {\n pathname\n });\n } else {\n result = await runHandler(handler);\n }\n } catch (e) {\n return { type: \"error\" /* error */, result: e };\n } finally {\n if (onReject) {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n }\n return result;\n}\nasync function parseResponseBody(response) {\n let contentType = response.headers.get(\"Content-Type\");\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n return response.body == null ? null : response.json();\n }\n return response.text();\n}\nasync function convertDataStrategyResultToDataResult(dataStrategyResult) {\n let { result, type } = dataStrategyResult;\n if (isResponse(result)) {\n let data2;\n try {\n data2 = await parseResponseBody(result);\n } catch (e) {\n return { type: \"error\" /* error */, error: e };\n }\n if (type === \"error\" /* error */) {\n return {\n type: \"error\" /* error */,\n error: new ErrorResponseImpl(result.status, result.statusText, data2),\n statusCode: result.status,\n headers: result.headers\n };\n }\n return {\n type: \"data\" /* data */,\n data: data2,\n statusCode: result.status,\n headers: result.headers\n };\n }\n if (type === \"error\" /* error */) {\n if (isDataWithResponseInit(result)) {\n if (result.data instanceof Error) {\n return {\n type: \"error\" /* error */,\n error: result.data,\n statusCode: result.init?.status,\n headers: result.init?.headers ? new Headers(result.init.headers) : void 0\n };\n }\n return {\n type: \"error\" /* error */,\n error: dataWithResponseInitToErrorResponse(result),\n statusCode: isRouteErrorResponse(result) ? result.status : void 0,\n headers: result.init?.headers ? new Headers(result.init.headers) : void 0\n };\n }\n return {\n type: \"error\" /* error */,\n error: result,\n statusCode: isRouteErrorResponse(result) ? result.status : void 0\n };\n }\n if (isDataWithResponseInit(result)) {\n return {\n type: \"data\" /* data */,\n data: result.data,\n statusCode: result.init?.status,\n headers: result.init?.headers ? new Headers(result.init.headers) : void 0\n };\n }\n return { type: \"data\" /* data */, data: result };\n}\nfunction normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename) {\n let location = response.headers.get(\"Location\");\n invariant(\n location,\n \"Redirects returned/thrown from loaders/actions must have a Location header\"\n );\n if (!isAbsoluteUrl(location)) {\n let trimmedMatches = matches.slice(\n 0,\n matches.findIndex((m) => m.route.id === routeId) + 1\n );\n location = normalizeTo(\n new URL(request.url),\n trimmedMatches,\n basename,\n location\n );\n response.headers.set(\"Location\", location);\n }\n return response;\n}\nvar invalidProtocols = [\n \"about:\",\n \"blob:\",\n \"chrome:\",\n \"chrome-untrusted:\",\n \"content:\",\n \"data:\",\n \"devtools:\",\n \"file:\",\n \"filesystem:\",\n // eslint-disable-next-line no-script-url\n \"javascript:\"\n];\nfunction hasInvalidProtocol(location) {\n try {\n return invalidProtocols.includes(new URL(location).protocol);\n } catch {\n return false;\n }\n}\nfunction normalizeRedirectLocation(location, currentUrl, basename, historyInstance) {\n if (isAbsoluteUrl(location)) {\n let normalizedLocation = location;\n let url = PROTOCOL_RELATIVE_URL_REGEX.test(normalizedLocation) ? new URL(\n normalizeProtocolRelativeUrl(normalizedLocation, currentUrl.protocol)\n ) : new URL(normalizedLocation);\n if (hasInvalidProtocol(url.toString())) {\n throw new Error(\"Invalid redirect location\");\n }\n let isSameBasename = stripBasename(url.pathname, basename) != null;\n if (url.origin === currentUrl.origin && isSameBasename) {\n return removeDoubleSlashes(url.pathname) + url.search + url.hash;\n }\n }\n try {\n let url = historyInstance.createURL(location);\n if (hasInvalidProtocol(url.toString())) {\n throw new Error(\"Invalid redirect location\");\n }\n } catch (e) {\n }\n return location;\n}\nfunction createClientSideRequest(history, location, signal, submission) {\n let url = history.createURL(stripHashFromPath(location)).toString();\n let init = { signal };\n if (submission && isMutationMethod(submission.formMethod)) {\n let { formMethod, formEncType } = submission;\n init.method = formMethod.toUpperCase();\n if (formEncType === \"application/json\") {\n init.headers = new Headers({ \"Content-Type\": formEncType });\n init.body = JSON.stringify(submission.json);\n } else if (formEncType === \"text/plain\") {\n init.body = submission.text;\n } else if (formEncType === \"application/x-www-form-urlencoded\" && submission.formData) {\n init.body = convertFormDataToSearchParams(submission.formData);\n } else {\n init.body = submission.formData;\n }\n }\n return new Request(url, init);\n}\nfunction createDataFunctionUrl(request, path) {\n let url = new URL(request.url);\n let parsed = typeof path === \"string\" ? parsePath(path) : path;\n url.pathname = parsed.pathname || \"/\";\n if (parsed.search) {\n let searchParams = new URLSearchParams(parsed.search);\n let indexValues = searchParams.getAll(\"index\");\n searchParams.delete(\"index\");\n for (let value of indexValues.filter(Boolean)) {\n searchParams.append(\"index\", value);\n }\n url.search = searchParams.size ? `?${searchParams.toString()}` : \"\";\n } else {\n url.search = \"\";\n }\n url.hash = parsed.hash || \"\";\n return url;\n}\nfunction convertFormDataToSearchParams(formData) {\n let searchParams = new URLSearchParams();\n for (let [key, value] of formData.entries()) {\n searchParams.append(key, typeof value === \"string\" ? value : value.name);\n }\n return searchParams;\n}\nfunction convertSearchParamsToFormData(searchParams) {\n let formData = new FormData();\n for (let [key, value] of searchParams.entries()) {\n formData.append(key, value);\n }\n return formData;\n}\nfunction processRouteLoaderData(matches, results, pendingActionResult, isStaticHandler = false, skipLoaderErrorBubbling = false) {\n let loaderData = {};\n let errors = null;\n let statusCode;\n let foundError = false;\n let loaderHeaders = {};\n let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : void 0;\n matches.forEach((match) => {\n if (!(match.route.id in results)) {\n return;\n }\n let id = match.route.id;\n let result = results[id];\n invariant(\n !isRedirectResult(result),\n \"Cannot handle redirect results in processLoaderData\"\n );\n if (isErrorResult(result)) {\n let error = result.error;\n if (pendingError !== void 0) {\n error = pendingError;\n pendingError = void 0;\n }\n errors = errors || {};\n if (skipLoaderErrorBubbling) {\n errors[id] = error;\n } else {\n let boundaryMatch = findNearestBoundary(matches, id);\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\n }\n }\n if (!isStaticHandler) {\n loaderData[id] = ResetLoaderDataSymbol;\n }\n if (!foundError) {\n foundError = true;\n statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n loaderData[id] = result.data;\n if (result.statusCode && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n }\n });\n if (pendingError !== void 0 && pendingActionResult) {\n errors = { [pendingActionResult[0]]: pendingError };\n if (pendingActionResult[2]) {\n loaderData[pendingActionResult[2]] = void 0;\n }\n }\n return {\n loaderData,\n errors,\n statusCode: statusCode || 200,\n loaderHeaders\n };\n}\nfunction processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults, workingFetchers) {\n let { loaderData, errors } = processRouteLoaderData(\n matches,\n results,\n pendingActionResult\n );\n revalidatingFetchers.filter((f) => !f.matches || f.matches.some((m) => m.shouldLoad)).forEach((rf) => {\n let { key, match, controller } = rf;\n if (controller && controller.signal.aborted) {\n return;\n }\n let result = fetcherResults[key];\n invariant(result, \"Did not find corresponding fetcher result\");\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, match?.route.id);\n if (!(errors && errors[boundaryMatch.route.id])) {\n errors = {\n ...errors,\n [boundaryMatch.route.id]: result.error\n };\n }\n workingFetchers.delete(key);\n } else if (isRedirectResult(result)) {\n invariant(false, \"Unhandled fetcher revalidation redirect\");\n } else {\n let doneFetcher = getDoneFetcher(result.data);\n workingFetchers.set(key, doneFetcher);\n }\n });\n return { loaderData, errors };\n}\nfunction mergeLoaderData(loaderData, newLoaderData, matches, errors) {\n let mergedLoaderData = Object.entries(newLoaderData).filter(([, v]) => v !== ResetLoaderDataSymbol).reduce((merged, [k, v]) => {\n merged[k] = v;\n return merged;\n }, {});\n for (let match of matches) {\n let id = match.route.id;\n if (!newLoaderData.hasOwnProperty(id) && loaderData.hasOwnProperty(id) && match.route.loader) {\n mergedLoaderData[id] = loaderData[id];\n }\n if (errors && errors.hasOwnProperty(id)) {\n break;\n }\n }\n return mergedLoaderData;\n}\nfunction getActionDataForCommit(pendingActionResult) {\n if (!pendingActionResult) {\n return {};\n }\n return isErrorResult(pendingActionResult[1]) ? {\n // Clear out prior actionData on errors\n actionData: {}\n } : {\n actionData: {\n [pendingActionResult[0]]: pendingActionResult[1].data\n }\n };\n}\nfunction findNearestBoundary(matches, routeId) {\n let eligibleMatches = routeId ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1) : [...matches];\n return eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) || matches[0];\n}\nfunction getShortCircuitMatches(routes) {\n let route = routes.length === 1 ? routes[0] : routes.find((r) => r.index || !r.path || r.path === \"/\") || {\n id: `__shim-error-route__`\n };\n return {\n matches: [\n {\n params: {},\n pathname: \"\",\n pathnameBase: \"\",\n route\n }\n ],\n route\n };\n}\nfunction getInternalRouterError(status, {\n pathname,\n routeId,\n method,\n type,\n message\n} = {}) {\n let statusText = \"Unknown Server Error\";\n let errorMessage = \"Unknown @remix-run/router error\";\n if (status === 400) {\n statusText = \"Bad Request\";\n if (method && pathname && routeId) {\n errorMessage = `You made a ${method} request to \"${pathname}\" but did not provide a \\`loader\\` for route \"${routeId}\", so there is no way to handle the request.`;\n } else if (type === \"invalid-body\") {\n errorMessage = \"Unable to encode submission body\";\n }\n } else if (status === 403) {\n statusText = \"Forbidden\";\n errorMessage = `Route \"${routeId}\" does not match URL \"${pathname}\"`;\n } else if (status === 404) {\n statusText = \"Not Found\";\n errorMessage = `No route matches URL \"${pathname}\"`;\n } else if (status === 405) {\n statusText = \"Method Not Allowed\";\n if (method && pathname && routeId) {\n errorMessage = `You made a ${method.toUpperCase()} request to \"${pathname}\" but did not provide an \\`action\\` for route \"${routeId}\", so there is no way to handle the request.`;\n } else if (method) {\n errorMessage = `Invalid request method \"${method.toUpperCase()}\"`;\n }\n }\n return new ErrorResponseImpl(\n status || 500,\n statusText,\n new Error(errorMessage),\n true\n );\n}\nfunction findRedirect(results) {\n let entries = Object.entries(results);\n for (let i = entries.length - 1; i >= 0; i--) {\n let [key, result] = entries[i];\n if (isRedirectResult(result)) {\n return { key, result };\n }\n }\n}\nfunction stripHashFromPath(path) {\n let parsedPath = typeof path === \"string\" ? parsePath(path) : path;\n return createPath({ ...parsedPath, hash: \"\" });\n}\nfunction isHashChangeOnly(a, b) {\n if (a.pathname !== b.pathname || a.search !== b.search) {\n return false;\n }\n if (a.hash === \"\") {\n return b.hash !== \"\";\n } else if (a.hash === b.hash) {\n return true;\n } else if (b.hash !== \"\") {\n return true;\n }\n return false;\n}\nfunction dataWithResponseInitToResponse(data2) {\n return Response.json(data2.data, data2.init ?? void 0);\n}\nfunction dataWithResponseInitToErrorResponse(data2) {\n return new ErrorResponseImpl(\n data2.init?.status ?? 500,\n data2.init?.statusText ?? \"Internal Server Error\",\n data2.data\n );\n}\nfunction isDataStrategyResults(result) {\n return result != null && typeof result === \"object\" && Object.entries(result).every(\n ([key, value]) => typeof key === \"string\" && isDataStrategyResult(value)\n );\n}\nfunction isDataStrategyResult(result) {\n return result != null && typeof result === \"object\" && \"type\" in result && \"result\" in result && (result.type === \"data\" /* data */ || result.type === \"error\" /* error */);\n}\nfunction isRedirectDataStrategyResult(result) {\n return isResponse(result.result) && redirectStatusCodes.has(result.result.status);\n}\nfunction isErrorResult(result) {\n return result.type === \"error\" /* error */;\n}\nfunction isRedirectResult(result) {\n return (result && result.type) === \"redirect\" /* redirect */;\n}\nfunction isDataWithResponseInit(value) {\n return typeof value === \"object\" && value != null && \"type\" in value && \"data\" in value && \"init\" in value && value.type === \"DataWithResponseInit\";\n}\nfunction isResponse(value) {\n return value != null && typeof value.status === \"number\" && typeof value.statusText === \"string\" && typeof value.headers === \"object\" && typeof value.body !== \"undefined\";\n}\nfunction isRedirectStatusCode(statusCode) {\n return redirectStatusCodes.has(statusCode);\n}\nfunction isRedirectResponse(result) {\n return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has(\"Location\");\n}\nfunction isValidMethod(method) {\n return validRequestMethods.has(method.toUpperCase());\n}\nfunction isMutationMethod(method) {\n return validMutationMethods.has(method.toUpperCase());\n}\nfunction hasNakedIndexQuery(search) {\n return new URLSearchParams(search).getAll(\"index\").some((v) => v === \"\");\n}\nfunction getTargetMatch(matches, location) {\n let search = typeof location === \"string\" ? parsePath(location).search : location.search;\n if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || \"\")) {\n return matches[matches.length - 1];\n }\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches[pathMatches.length - 1];\n}\nfunction getSubmissionFromNavigation(navigation) {\n let { formMethod, formAction, formEncType, text, formData, json } = navigation;\n if (!formMethod || !formAction || !formEncType) {\n return;\n }\n if (text != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: void 0,\n json: void 0,\n text\n };\n } else if (formData != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData,\n json: void 0,\n text: void 0\n };\n } else if (json !== void 0) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: void 0,\n json,\n text: void 0\n };\n }\n}\nfunction getLoadingNavigation(location, matches, historyAction, submission) {\n if (submission) {\n let navigation = {\n state: \"loading\",\n location,\n matches,\n historyAction,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text\n };\n return navigation;\n } else {\n let navigation = {\n state: \"loading\",\n location,\n matches,\n historyAction,\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0\n };\n return navigation;\n }\n}\nfunction getSubmittingNavigation(location, matches, historyAction, submission) {\n let navigation = {\n state: \"submitting\",\n location,\n matches,\n historyAction,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text\n };\n return navigation;\n}\nfunction getLoadingFetcher(submission, data2) {\n if (submission) {\n let fetcher = {\n state: \"loading\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: data2\n };\n return fetcher;\n } else {\n let fetcher = {\n state: \"loading\",\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0,\n data: data2\n };\n return fetcher;\n }\n}\nfunction getSubmittingFetcher(submission, existingFetcher) {\n let fetcher = {\n state: \"submitting\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: existingFetcher ? existingFetcher.data : void 0\n };\n return fetcher;\n}\nfunction getDoneFetcher(data2) {\n let fetcher = {\n state: \"idle\",\n formMethod: void 0,\n formAction: void 0,\n formEncType: void 0,\n formData: void 0,\n json: void 0,\n text: void 0,\n data: data2\n };\n return fetcher;\n}\nfunction restoreAppliedTransitions(_window, transitions) {\n try {\n let sessionPositions = _window.sessionStorage.getItem(\n TRANSITIONS_STORAGE_KEY\n );\n if (sessionPositions) {\n let json = JSON.parse(sessionPositions);\n for (let [k, v] of Object.entries(json || {})) {\n if (v && Array.isArray(v)) {\n transitions.set(k, new Set(v || []));\n }\n }\n }\n } catch (e) {\n }\n}\nfunction persistAppliedTransitions(_window, transitions) {\n if (transitions.size > 0) {\n let json = {};\n for (let [k, v] of transitions) {\n json[k] = [...v];\n }\n try {\n _window.sessionStorage.setItem(\n TRANSITIONS_STORAGE_KEY,\n JSON.stringify(json)\n );\n } catch (error) {\n warning(\n false,\n `Failed to save applied view transitions in sessionStorage (${error}).`\n );\n }\n }\n}\nfunction createDeferred() {\n let resolve;\n let reject;\n let promise = new Promise((res, rej) => {\n resolve = async (val) => {\n res(val);\n try {\n await promise;\n } catch (e) {\n }\n };\n reject = async (error) => {\n rej(error);\n try {\n await promise;\n } catch (e) {\n }\n };\n });\n return {\n promise,\n //@ts-ignore\n resolve,\n //@ts-ignore\n reject\n };\n}\n\n// lib/context.ts\nimport * as React from \"react\";\nvar DataRouterContext = React.createContext(null);\nDataRouterContext.displayName = \"DataRouter\";\nvar DataRouterStateContext = React.createContext(null);\nDataRouterStateContext.displayName = \"DataRouterState\";\nvar RSCRouterContext = React.createContext(false);\nfunction useIsRSCRouterContext() {\n return React.useContext(RSCRouterContext);\n}\nvar ViewTransitionContext = React.createContext({\n isTransitioning: false\n});\nViewTransitionContext.displayName = \"ViewTransition\";\nvar FetchersContext = React.createContext(\n /* @__PURE__ */ new Map()\n);\nFetchersContext.displayName = \"Fetchers\";\nvar AwaitContext = React.createContext(null);\nAwaitContext.displayName = \"Await\";\nvar AwaitContextProvider = (props) => React.createElement(AwaitContext.Provider, props);\nvar NavigationContext = React.createContext(\n null\n);\nNavigationContext.displayName = \"Navigation\";\nvar LocationContext = React.createContext(\n null\n);\nLocationContext.displayName = \"Location\";\nvar RouteContext = React.createContext({\n outlet: null,\n matches: [],\n isDataRoute: false\n});\nRouteContext.displayName = \"Route\";\nvar RouteErrorContext = React.createContext(null);\nRouteErrorContext.displayName = \"RouteError\";\nvar ENABLE_DEV_WARNINGS = true;\n\n// lib/hooks.tsx\nimport * as React2 from \"react\";\n\n// lib/errors.ts\nvar ERROR_DIGEST_BASE = \"REACT_ROUTER_ERROR\";\nvar ERROR_DIGEST_REDIRECT = \"REDIRECT\";\nvar ERROR_DIGEST_ROUTE_ERROR_RESPONSE = \"ROUTE_ERROR_RESPONSE\";\nfunction decodeRedirectErrorDigest(digest) {\n if (digest.startsWith(`${ERROR_DIGEST_BASE}:${ERROR_DIGEST_REDIRECT}:{`)) {\n try {\n let parsed = JSON.parse(digest.slice(28));\n if (typeof parsed === \"object\" && parsed && typeof parsed.status === \"number\" && typeof parsed.statusText === \"string\" && typeof parsed.location === \"string\" && typeof parsed.reloadDocument === \"boolean\" && typeof parsed.replace === \"boolean\") {\n return parsed;\n }\n } catch {\n }\n }\n}\nfunction decodeRouteErrorResponseDigest(digest) {\n if (digest.startsWith(\n `${ERROR_DIGEST_BASE}:${ERROR_DIGEST_ROUTE_ERROR_RESPONSE}:{`\n )) {\n try {\n let parsed = JSON.parse(digest.slice(40));\n if (typeof parsed === \"object\" && parsed && typeof parsed.status === \"number\" && typeof parsed.statusText === \"string\") {\n return new ErrorResponseImpl(\n parsed.status,\n parsed.statusText,\n parsed.data\n );\n }\n } catch {\n }\n }\n}\n\n// lib/hooks.tsx\nfunction useHref(to, { relative } = {}) {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useHref() may be used only in the context of a component.`\n );\n let { basename, navigator } = React2.useContext(NavigationContext);\n let { hash, pathname, search } = useResolvedPath(to, { relative });\n let joinedPathname = pathname;\n if (basename !== \"/\") {\n joinedPathname = pathname === \"/\" ? basename : joinPaths([basename, pathname]);\n }\n return navigator.createHref({ pathname: joinedPathname, search, hash });\n}\nfunction useInRouterContext() {\n return React2.useContext(LocationContext) != null;\n}\nfunction useLocation() {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useLocation() may be used only in the context of a component.`\n );\n return React2.useContext(LocationContext).location;\n}\nfunction useNavigationType() {\n return React2.useContext(LocationContext).navigationType;\n}\nfunction useMatch(pattern) {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useMatch() may be used only in the context of a component.`\n );\n let { pathname } = useLocation();\n return React2.useMemo(\n () => matchPath(pattern, decodePath(pathname)),\n [pathname, pattern]\n );\n}\nvar navigateEffectWarning = `You should call navigate() in a React.useEffect(), not when your component is first rendered.`;\nfunction useIsomorphicLayoutEffect(cb) {\n let isStatic = React2.useContext(NavigationContext).static;\n if (!isStatic) {\n React2.useLayoutEffect(cb);\n }\n}\nfunction useNavigate() {\n let { isDataRoute } = React2.useContext(RouteContext);\n return isDataRoute ? useNavigateStable() : useNavigateUnstable();\n}\nfunction useNavigateUnstable() {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useNavigate() may be used only in the context of a component.`\n );\n let dataRouterContext = React2.useContext(DataRouterContext);\n let { basename, navigator } = React2.useContext(NavigationContext);\n let { matches } = React2.useContext(RouteContext);\n let { pathname: locationPathname } = useLocation();\n let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));\n let activeRef = React2.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React2.useCallback(\n (to, options = {}) => {\n warning(activeRef.current, navigateEffectWarning);\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n navigator.go(to);\n return;\n }\n let path = resolveTo(\n to,\n JSON.parse(routePathnamesJson),\n locationPathname,\n options.relative === \"path\"\n );\n if (dataRouterContext == null && basename !== \"/\") {\n path.pathname = path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n (!!options.replace ? navigator.replace : navigator.push)(\n path,\n options.state,\n options\n );\n },\n [\n basename,\n navigator,\n routePathnamesJson,\n locationPathname,\n dataRouterContext\n ]\n );\n return navigate;\n}\nvar OutletContext = React2.createContext(null);\nfunction useOutletContext() {\n return React2.useContext(OutletContext);\n}\nfunction useOutlet(context) {\n let outlet = React2.useContext(RouteContext).outlet;\n return React2.useMemo(\n () => outlet && /* @__PURE__ */ React2.createElement(OutletContext.Provider, { value: context }, outlet),\n [outlet, context]\n );\n}\nfunction useParams() {\n let { matches } = React2.useContext(RouteContext);\n let routeMatch = matches[matches.length - 1];\n return routeMatch?.params ?? {};\n}\nfunction useResolvedPath(to, { relative } = {}) {\n let { matches } = React2.useContext(RouteContext);\n let { pathname: locationPathname } = useLocation();\n let routePathnamesJson = JSON.stringify(getResolveToMatches(matches));\n return React2.useMemo(\n () => resolveTo(\n to,\n JSON.parse(routePathnamesJson),\n locationPathname,\n relative === \"path\"\n ),\n [to, routePathnamesJson, locationPathname, relative]\n );\n}\nfunction useRoutes(routes, locationArg) {\n return useRoutesImpl(routes, locationArg);\n}\nfunction useRoutesImpl(routes, locationArg, dataRouterOpts) {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n `useRoutes() may be used only in the context of a component.`\n );\n let { navigator } = React2.useContext(NavigationContext);\n let { matches: parentMatches } = React2.useContext(RouteContext);\n let routeMatch = parentMatches[parentMatches.length - 1];\n let parentParams = routeMatch ? routeMatch.params : {};\n let parentPathname = routeMatch ? routeMatch.pathname : \"/\";\n let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : \"/\";\n let parentRoute = routeMatch && routeMatch.route;\n if (ENABLE_DEV_WARNINGS) {\n let parentPath = parentRoute && parentRoute.path || \"\";\n warningOnce(\n parentPathname,\n !parentRoute || parentPath.endsWith(\"*\") || parentPath.endsWith(\"*?\"),\n `You rendered descendant (or called \\`useRoutes()\\`) at \"${parentPathname}\" (under ) but the parent route path has no trailing \"*\". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.\n\nPlease change the parent to .`\n );\n }\n let locationFromContext = useLocation();\n let location;\n if (locationArg) {\n let parsedLocationArg = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n invariant(\n parentPathnameBase === \"/\" || parsedLocationArg.pathname?.startsWith(parentPathnameBase),\n `When overriding the location using \\`\\` or \\`useRoutes(routes, location)\\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is \"${parentPathnameBase}\" but pathname \"${parsedLocationArg.pathname}\" was given in the \\`location\\` prop.`\n );\n location = parsedLocationArg;\n } else {\n location = locationFromContext;\n }\n let pathname = location.pathname || \"/\";\n let remainingPathname = pathname;\n if (parentPathnameBase !== \"/\") {\n let parentSegments = parentPathnameBase.replace(/^\\//, \"\").split(\"/\");\n let segments = pathname.replace(/^\\//, \"\").split(\"/\");\n remainingPathname = \"/\" + segments.slice(parentSegments.length).join(\"/\");\n }\n let matches = dataRouterOpts && dataRouterOpts.state.matches.length ? (\n // If we're in a data router, use the matches we've already identified but ensure\n // we have the latest route instances from the manifest in case elements have changed\n dataRouterOpts.state.matches.map(\n (m) => Object.assign(m, {\n route: dataRouterOpts.manifest[m.route.id] || m.route\n })\n )\n ) : matchRoutes(routes, { pathname: remainingPathname });\n if (ENABLE_DEV_WARNINGS) {\n warning(\n parentRoute || matches != null,\n `No routes matched location \"${location.pathname}${location.search}${location.hash}\" `\n );\n warning(\n matches == null || matches[matches.length - 1].route.element !== void 0 || matches[matches.length - 1].route.Component !== void 0 || matches[matches.length - 1].route.lazy !== void 0,\n `Matched leaf route at location \"${location.pathname}${location.search}${location.hash}\" does not have an element or Component. This means it will render an with a null value by default resulting in an \"empty\" page.`\n );\n }\n let renderedMatches = _renderMatches(\n matches && matches.map(\n (match) => Object.assign({}, match, {\n params: Object.assign({}, parentParams, match.params),\n pathname: joinPaths([\n parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes.\n // Pre-encode `%`, `?` and `#` ahead of `encodeLocation` because it uses\n // `new URL()` internally and we need to prevent it from treating\n // them as separators\n navigator.encodeLocation ? navigator.encodeLocation(\n match.pathname.replace(/%/g, \"%25\").replace(/\\?/g, \"%3F\").replace(/#/g, \"%23\")\n ).pathname : match.pathname\n ]),\n pathnameBase: match.pathnameBase === \"/\" ? parentPathnameBase : joinPaths([\n parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes\n // Pre-encode `%`, `?` and `#` ahead of `encodeLocation` because it uses\n // `new URL()` internally and we need to prevent it from treating\n // them as separators\n navigator.encodeLocation ? navigator.encodeLocation(\n match.pathnameBase.replace(/%/g, \"%25\").replace(/\\?/g, \"%3F\").replace(/#/g, \"%23\")\n ).pathname : match.pathnameBase\n ])\n })\n ),\n parentMatches,\n dataRouterOpts\n );\n if (locationArg && renderedMatches) {\n return /* @__PURE__ */ React2.createElement(\n LocationContext.Provider,\n {\n value: {\n location: {\n pathname: \"/\",\n search: \"\",\n hash: \"\",\n state: null,\n key: \"default\",\n mask: void 0,\n ...location\n },\n navigationType: \"POP\" /* Pop */\n }\n },\n renderedMatches\n );\n }\n return renderedMatches;\n}\nfunction DefaultErrorComponent() {\n let error = useRouteError();\n let message = isRouteErrorResponse(error) ? `${error.status} ${error.statusText}` : error instanceof Error ? error.message : JSON.stringify(error);\n let stack = error instanceof Error ? error.stack : null;\n let lightgrey = \"rgba(200,200,200, 0.5)\";\n let preStyles = { padding: \"0.5rem\", backgroundColor: lightgrey };\n let codeStyles = { padding: \"2px 4px\", backgroundColor: lightgrey };\n let devInfo = null;\n if (ENABLE_DEV_WARNINGS) {\n console.error(\n \"Error handled by React Router default ErrorBoundary:\",\n error\n );\n devInfo = /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(\"p\", null, \"\\u{1F4BF} Hey developer \\u{1F44B}\"), /* @__PURE__ */ React2.createElement(\"p\", null, \"You can provide a way better UX than this when your app throws errors by providing your own \", /* @__PURE__ */ React2.createElement(\"code\", { style: codeStyles }, \"ErrorBoundary\"), \" or\", \" \", /* @__PURE__ */ React2.createElement(\"code\", { style: codeStyles }, \"errorElement\"), \" prop on your route.\"));\n }\n return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(\"h2\", null, \"Unexpected Application Error!\"), /* @__PURE__ */ React2.createElement(\"h3\", { style: { fontStyle: \"italic\" } }, message), stack ? /* @__PURE__ */ React2.createElement(\"pre\", { style: preStyles }, stack) : null, devInfo);\n}\nvar defaultErrorElement = /* @__PURE__ */ React2.createElement(DefaultErrorComponent, null);\nvar RenderErrorBoundary = class extends React2.Component {\n constructor(props) {\n super(props);\n this.state = {\n location: props.location,\n revalidation: props.revalidation,\n error: props.error\n };\n }\n static getDerivedStateFromError(error) {\n return { error };\n }\n static getDerivedStateFromProps(props, state) {\n if (state.location !== props.location || state.revalidation !== \"idle\" && props.revalidation === \"idle\") {\n return {\n error: props.error,\n location: props.location,\n revalidation: props.revalidation\n };\n }\n return {\n error: props.error !== void 0 ? props.error : state.error,\n location: state.location,\n revalidation: props.revalidation || state.revalidation\n };\n }\n componentDidCatch(error, errorInfo) {\n if (this.props.onError) {\n this.props.onError(error, errorInfo);\n } else {\n console.error(\n \"React Router caught the following error during render\",\n error\n );\n }\n }\n render() {\n let error = this.state.error;\n if (this.context && typeof error === \"object\" && error && \"digest\" in error && typeof error.digest === \"string\") {\n const decoded = decodeRouteErrorResponseDigest(error.digest);\n if (decoded) error = decoded;\n }\n let result = error !== void 0 ? /* @__PURE__ */ React2.createElement(RouteContext.Provider, { value: this.props.routeContext }, /* @__PURE__ */ React2.createElement(\n RouteErrorContext.Provider,\n {\n value: error,\n children: this.props.component\n }\n )) : this.props.children;\n if (this.context) {\n return /* @__PURE__ */ React2.createElement(RSCErrorHandler, { error }, result);\n }\n return result;\n }\n};\nRenderErrorBoundary.contextType = RSCRouterContext;\nvar errorRedirectHandledMap = /* @__PURE__ */ new WeakMap();\nfunction RSCErrorHandler({\n children,\n error\n}) {\n let { basename } = React2.useContext(NavigationContext);\n if (typeof error === \"object\" && error && \"digest\" in error && typeof error.digest === \"string\") {\n let redirect2 = decodeRedirectErrorDigest(error.digest);\n if (redirect2) {\n let existingRedirect = errorRedirectHandledMap.get(error);\n if (existingRedirect) throw existingRedirect;\n let parsed = parseToInfo(redirect2.location, basename);\n let target = parsed.absoluteURL || parsed.to;\n if (hasInvalidProtocol(target)) {\n throw new Error(\"Invalid redirect location\");\n }\n if (isBrowser && !errorRedirectHandledMap.get(error)) {\n if (parsed.isExternal || redirect2.reloadDocument) {\n window.location.href = target;\n } else {\n const redirectPromise = Promise.resolve().then(\n () => window.__reactRouterDataRouter.navigate(parsed.to, {\n replace: redirect2.replace\n })\n );\n errorRedirectHandledMap.set(error, redirectPromise);\n throw redirectPromise;\n }\n }\n return /* @__PURE__ */ React2.createElement(\"meta\", { httpEquiv: \"refresh\", content: `0;url=${target}` });\n }\n }\n return children;\n}\nfunction RenderedRoute({ routeContext, match, children }) {\n let dataRouterContext = React2.useContext(DataRouterContext);\n if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {\n dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;\n }\n return /* @__PURE__ */ React2.createElement(RouteContext.Provider, { value: routeContext }, children);\n}\nfunction _renderMatches(matches, parentMatches = [], dataRouterOpts) {\n let dataRouterState = dataRouterOpts?.state;\n if (matches == null) {\n if (!dataRouterState) {\n return null;\n }\n if (dataRouterState.errors) {\n matches = dataRouterState.matches;\n } else if (parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {\n matches = dataRouterState.matches;\n } else {\n return null;\n }\n }\n let renderedMatches = matches;\n let errors = dataRouterState?.errors;\n if (errors != null) {\n let errorIndex = renderedMatches.findIndex(\n (m) => m.route.id && errors?.[m.route.id] !== void 0\n );\n invariant(\n errorIndex >= 0,\n `Could not find a matching route for errors on route IDs: ${Object.keys(\n errors\n ).join(\",\")}`\n );\n renderedMatches = renderedMatches.slice(\n 0,\n Math.min(renderedMatches.length, errorIndex + 1)\n );\n }\n let renderFallback = false;\n let fallbackIndex = -1;\n if (dataRouterOpts && dataRouterState) {\n renderFallback = dataRouterState.renderFallback;\n for (let i = 0; i < renderedMatches.length; i++) {\n let match = renderedMatches[i];\n if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {\n fallbackIndex = i;\n }\n if (match.route.id) {\n let { loaderData, errors: errors2 } = dataRouterState;\n let needsToRunLoader = match.route.loader && !loaderData.hasOwnProperty(match.route.id) && (!errors2 || errors2[match.route.id] === void 0);\n if (match.route.lazy || needsToRunLoader) {\n if (dataRouterOpts.isStatic) {\n renderFallback = true;\n }\n if (fallbackIndex >= 0) {\n renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);\n } else {\n renderedMatches = [renderedMatches[0]];\n }\n break;\n }\n }\n }\n }\n let onErrorHandler = dataRouterOpts?.onError;\n let onError = dataRouterState && onErrorHandler ? (error, errorInfo) => {\n onErrorHandler(error, {\n location: dataRouterState.location,\n params: dataRouterState.matches?.[0]?.params ?? {},\n pattern: getRoutePattern(dataRouterState.matches),\n errorInfo\n });\n } : void 0;\n return renderedMatches.reduceRight(\n (outlet, match, index) => {\n let error;\n let shouldRenderHydrateFallback = false;\n let errorElement = null;\n let hydrateFallbackElement = null;\n if (dataRouterState) {\n error = errors && match.route.id ? errors[match.route.id] : void 0;\n errorElement = match.route.errorElement || defaultErrorElement;\n if (renderFallback) {\n if (fallbackIndex < 0 && index === 0) {\n warningOnce(\n \"route-fallback\",\n false,\n \"No `HydrateFallback` element provided to render during initial hydration\"\n );\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = null;\n } else if (fallbackIndex === index) {\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = match.route.hydrateFallbackElement || null;\n }\n }\n }\n let matches2 = parentMatches.concat(renderedMatches.slice(0, index + 1));\n let getChildren = () => {\n let children;\n if (error) {\n children = errorElement;\n } else if (shouldRenderHydrateFallback) {\n children = hydrateFallbackElement;\n } else if (match.route.Component) {\n children = /* @__PURE__ */ React2.createElement(match.route.Component, null);\n } else if (match.route.element) {\n children = match.route.element;\n } else {\n children = outlet;\n }\n return /* @__PURE__ */ React2.createElement(\n RenderedRoute,\n {\n match,\n routeContext: {\n outlet,\n matches: matches2,\n isDataRoute: dataRouterState != null\n },\n children\n }\n );\n };\n return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /* @__PURE__ */ React2.createElement(\n RenderErrorBoundary,\n {\n location: dataRouterState.location,\n revalidation: dataRouterState.revalidation,\n component: errorElement,\n error,\n children: getChildren(),\n routeContext: { outlet: null, matches: matches2, isDataRoute: true },\n onError\n }\n ) : getChildren();\n },\n null\n );\n}\nfunction getDataRouterConsoleError(hookName) {\n return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`;\n}\nfunction useDataRouterContext(hookName) {\n let ctx = React2.useContext(DataRouterContext);\n invariant(ctx, getDataRouterConsoleError(hookName));\n return ctx;\n}\nfunction useDataRouterState(hookName) {\n let state = React2.useContext(DataRouterStateContext);\n invariant(state, getDataRouterConsoleError(hookName));\n return state;\n}\nfunction useRouteContext(hookName) {\n let route = React2.useContext(RouteContext);\n invariant(route, getDataRouterConsoleError(hookName));\n return route;\n}\nfunction useCurrentRouteId(hookName) {\n let route = useRouteContext(hookName);\n let thisRoute = route.matches[route.matches.length - 1];\n invariant(\n thisRoute.route.id,\n `${hookName} can only be used on routes that contain a unique \"id\"`\n );\n return thisRoute.route.id;\n}\nfunction useRouteId() {\n return useCurrentRouteId(\"useRouteId\" /* UseRouteId */);\n}\nfunction useNavigation() {\n let state = useDataRouterState(\"useNavigation\" /* UseNavigation */);\n return React2.useMemo(() => {\n let { matches, historyAction, ...rest } = state.navigation;\n return rest;\n }, [state.navigation]);\n}\nfunction useRevalidator() {\n let dataRouterContext = useDataRouterContext(\"useRevalidator\" /* UseRevalidator */);\n let state = useDataRouterState(\"useRevalidator\" /* UseRevalidator */);\n let revalidate = React2.useCallback(async () => {\n await dataRouterContext.router.revalidate();\n }, [dataRouterContext.router]);\n return React2.useMemo(\n () => ({ revalidate, state: state.revalidation }),\n [revalidate, state.revalidation]\n );\n}\nfunction useMatches() {\n let { matches, loaderData } = useDataRouterState(\n \"useMatches\" /* UseMatches */\n );\n return React2.useMemo(\n () => matches.map((m) => convertRouteMatchToUiMatch(m, loaderData)),\n [matches, loaderData]\n );\n}\nfunction useLoaderData() {\n let state = useDataRouterState(\"useLoaderData\" /* UseLoaderData */);\n let routeId = useCurrentRouteId(\"useLoaderData\" /* UseLoaderData */);\n return state.loaderData[routeId];\n}\nfunction useRouteLoaderData(routeId) {\n let state = useDataRouterState(\"useRouteLoaderData\" /* UseRouteLoaderData */);\n return state.loaderData[routeId];\n}\nfunction useActionData() {\n let state = useDataRouterState(\"useActionData\" /* UseActionData */);\n let routeId = useCurrentRouteId(\"useLoaderData\" /* UseLoaderData */);\n return state.actionData ? state.actionData[routeId] : void 0;\n}\nfunction useRouteError() {\n let error = React2.useContext(RouteErrorContext);\n let state = useDataRouterState(\"useRouteError\" /* UseRouteError */);\n let routeId = useCurrentRouteId(\"useRouteError\" /* UseRouteError */);\n if (error !== void 0) {\n return error;\n }\n return state.errors?.[routeId];\n}\nfunction useAsyncValue() {\n let value = React2.useContext(AwaitContext);\n return value?._data;\n}\nfunction useAsyncError() {\n let value = React2.useContext(AwaitContext);\n return value?._error;\n}\nvar blockerId = 0;\nfunction useBlocker(shouldBlock) {\n let { router, basename } = useDataRouterContext(\"useBlocker\" /* UseBlocker */);\n let state = useDataRouterState(\"useBlocker\" /* UseBlocker */);\n let [blockerKey, setBlockerKey] = React2.useState(\"\");\n let blockerFunction = React2.useCallback(\n (arg) => {\n if (typeof shouldBlock !== \"function\") {\n return !!shouldBlock;\n }\n if (basename === \"/\") {\n return shouldBlock(arg);\n }\n let { currentLocation, nextLocation, historyAction } = arg;\n return shouldBlock({\n currentLocation: {\n ...currentLocation,\n pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname\n },\n nextLocation: {\n ...nextLocation,\n pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname\n },\n historyAction\n });\n },\n [basename, shouldBlock]\n );\n React2.useEffect(() => {\n let key = String(++blockerId);\n setBlockerKey(key);\n return () => router.deleteBlocker(key);\n }, [router]);\n React2.useEffect(() => {\n if (blockerKey !== \"\") {\n router.getBlocker(blockerKey, blockerFunction);\n }\n }, [router, blockerKey, blockerFunction]);\n return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;\n}\nfunction useNavigateStable() {\n let { router } = useDataRouterContext(\"useNavigate\" /* UseNavigateStable */);\n let id = useCurrentRouteId(\"useNavigate\" /* UseNavigateStable */);\n let activeRef = React2.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React2.useCallback(\n async (to, options = {}) => {\n warning(activeRef.current, navigateEffectWarning);\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n await router.navigate(to);\n } else {\n await router.navigate(to, { fromRouteId: id, ...options });\n }\n },\n [router, id]\n );\n return navigate;\n}\nvar alreadyWarned = {};\nfunction warningOnce(key, cond, message) {\n if (!cond && !alreadyWarned[key]) {\n alreadyWarned[key] = true;\n warning(false, message);\n }\n}\nfunction useRoute(...args) {\n const currentRouteId = useCurrentRouteId(\n \"useRoute\" /* UseRoute */\n );\n const id = args[0] ?? currentRouteId;\n const state = useDataRouterState(\"useRoute\" /* UseRoute */);\n const route = state.matches.find(({ route: route2 }) => route2.id === id);\n if (route === void 0) return void 0;\n return {\n handle: route.route.handle,\n loaderData: state.loaderData[id],\n actionData: state.actionData?.[id]\n };\n}\nfunction toRouterStateMatch(match) {\n return {\n id: match.route.id,\n pathname: match.pathname,\n params: match.params,\n handle: match.route.handle\n };\n}\nfunction useRouterState() {\n let {\n location,\n historyAction: type,\n matches,\n navigation\n } = useDataRouterState(\"unstable_useRouterState\" /* UseRouterState */);\n let active = React2.useMemo(\n () => ({\n type,\n location,\n searchParams: new URLSearchParams(location.search),\n params: matches[matches.length - 1]?.params ?? {},\n matches: matches.map((m) => toRouterStateMatch(m))\n }),\n [location, matches, type]\n );\n let pending = React2.useMemo(() => {\n if (navigation.state === \"idle\") return null;\n let shared = {\n type: navigation.historyAction,\n location: navigation.location,\n searchParams: new URLSearchParams(navigation.location.search),\n params: navigation.matches[navigation.matches.length - 1]?.params ?? {},\n matches: navigation.matches.map((m) => toRouterStateMatch(m))\n };\n return navigation.state === \"loading\" ? {\n ...shared,\n state: \"loading\",\n formMethod: navigation.formMethod,\n formAction: navigation.formAction,\n formEncType: navigation.formEncType,\n formData: navigation.formData,\n json: navigation.json,\n text: navigation.text\n } : {\n ...shared,\n state: \"submitting\",\n formMethod: navigation.formMethod,\n formAction: navigation.formAction,\n formEncType: navigation.formEncType,\n formData: navigation.formData,\n json: navigation.json,\n text: navigation.text\n };\n }, [navigation]);\n return React2.useMemo(\n () => ({ active, pending }),\n [active, pending]\n );\n}\n\n// lib/components.tsx\nimport * as React3 from \"react\";\n\n// lib/server-runtime/warnings.ts\nvar alreadyWarned2 = {};\nfunction warnOnce(condition, message) {\n if (!condition && !alreadyWarned2[message]) {\n alreadyWarned2[message] = true;\n console.warn(message);\n }\n}\n\n// lib/components.tsx\nvar USE_OPTIMISTIC = \"useOptimistic\";\nvar useOptimisticImpl = React3[USE_OPTIMISTIC];\nvar stableUseOptimisticSetter = () => void 0;\nfunction useOptimisticSafe(val) {\n if (useOptimisticImpl) {\n return useOptimisticImpl(val);\n } else {\n return [val, stableUseOptimisticSetter];\n }\n}\nfunction mapRouteProperties(route) {\n let updates = {\n // Note: this check also occurs in createRoutesFromChildren so update\n // there if you change this -- please and thank you!\n hasErrorBoundary: route.hasErrorBoundary || route.ErrorBoundary != null || route.errorElement != null\n };\n if (route.Component) {\n if (ENABLE_DEV_WARNINGS) {\n if (route.element) {\n warning(\n false,\n \"You should not include both `Component` and `element` on your route - `Component` will be used.\"\n );\n }\n }\n Object.assign(updates, {\n element: React3.createElement(route.Component),\n Component: void 0\n });\n }\n if (route.HydrateFallback) {\n if (ENABLE_DEV_WARNINGS) {\n if (route.hydrateFallbackElement) {\n warning(\n false,\n \"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used.\"\n );\n }\n }\n Object.assign(updates, {\n hydrateFallbackElement: React3.createElement(route.HydrateFallback),\n HydrateFallback: void 0\n });\n }\n if (route.ErrorBoundary) {\n if (ENABLE_DEV_WARNINGS) {\n if (route.errorElement) {\n warning(\n false,\n \"You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used.\"\n );\n }\n }\n Object.assign(updates, {\n errorElement: React3.createElement(route.ErrorBoundary),\n ErrorBoundary: void 0\n });\n }\n return updates;\n}\nvar hydrationRouteProperties = [\n \"HydrateFallback\",\n \"hydrateFallbackElement\"\n];\nfunction createMemoryRouter(routes, opts) {\n return createRouter({\n basename: opts?.basename,\n getContext: opts?.getContext,\n future: opts?.future,\n history: createMemoryHistory({\n initialEntries: opts?.initialEntries,\n initialIndex: opts?.initialIndex\n }),\n hydrationData: opts?.hydrationData,\n routes,\n hydrationRouteProperties,\n mapRouteProperties,\n dataStrategy: opts?.dataStrategy,\n patchRoutesOnNavigation: opts?.patchRoutesOnNavigation,\n instrumentations: opts?.instrumentations\n }).initialize();\n}\nvar Deferred = class {\n constructor() {\n this.status = \"pending\";\n this.promise = new Promise((resolve, reject) => {\n this.resolve = (value) => {\n if (this.status === \"pending\") {\n this.status = \"resolved\";\n resolve(value);\n }\n };\n this.reject = (reason) => {\n if (this.status === \"pending\") {\n this.status = \"rejected\";\n reject(reason);\n }\n };\n });\n }\n};\nfunction RouterProvider({\n router,\n flushSync: reactDomFlushSyncImpl,\n onError,\n useTransitions\n}) {\n let unstable_rsc = useIsRSCRouterContext();\n useTransitions = unstable_rsc || useTransitions;\n let [_state, setStateImpl] = React3.useState(router.state);\n let [state, setOptimisticState] = useOptimisticSafe(_state);\n let [pendingState, setPendingState] = React3.useState();\n let [vtContext, setVtContext] = React3.useState({\n isTransitioning: false\n });\n let [renderDfd, setRenderDfd] = React3.useState();\n let [transition, setTransition] = React3.useState();\n let [interruption, setInterruption] = React3.useState();\n let fetcherData = React3.useRef(/* @__PURE__ */ new Map());\n let setState = React3.useCallback(\n (newState, { deletedFetchers, newErrors, flushSync, viewTransitionOpts }) => {\n if (newErrors && onError) {\n Object.values(newErrors).forEach(\n (error) => onError(error, {\n location: newState.location,\n params: newState.matches[0]?.params ?? {},\n pattern: getRoutePattern(newState.matches)\n })\n );\n }\n newState.fetchers.forEach((fetcher, key) => {\n if (fetcher.data !== void 0) {\n fetcherData.current.set(key, fetcher.data);\n }\n });\n deletedFetchers.forEach((key) => fetcherData.current.delete(key));\n warnOnce(\n flushSync === false || reactDomFlushSyncImpl != null,\n 'You provided the `flushSync` option to a router update, but you are not using the `` from `react-router/dom` so `ReactDOM.flushSync()` is unavailable. Please update your app to `import { RouterProvider } from \"react-router/dom\"` and ensure you have `react-dom` installed as a dependency to use the `flushSync` option.'\n );\n let isViewTransitionAvailable = router.window != null && router.window.document != null && typeof router.window.document.startViewTransition === \"function\";\n warnOnce(\n viewTransitionOpts == null || isViewTransitionAvailable,\n \"You provided the `viewTransition` option to a router update, but you do not appear to be running in a DOM environment as `window.startViewTransition` is not available.\"\n );\n if (!viewTransitionOpts || !isViewTransitionAvailable) {\n if (reactDomFlushSyncImpl && flushSync) {\n reactDomFlushSyncImpl(() => setStateImpl(newState));\n } else if (useTransitions === false) {\n setStateImpl(newState);\n } else {\n React3.startTransition(() => {\n if (useTransitions === true) {\n setOptimisticState((s) => getOptimisticRouterState(s, newState));\n }\n setStateImpl(newState);\n });\n }\n return;\n }\n if (reactDomFlushSyncImpl && flushSync) {\n reactDomFlushSyncImpl(() => {\n if (transition) {\n renderDfd?.resolve();\n transition.skipTransition();\n }\n setVtContext({\n isTransitioning: true,\n flushSync: true,\n currentLocation: viewTransitionOpts.currentLocation,\n nextLocation: viewTransitionOpts.nextLocation\n });\n });\n let t = router.window.document.startViewTransition(() => {\n reactDomFlushSyncImpl(() => setStateImpl(newState));\n });\n t.finished.finally(() => {\n reactDomFlushSyncImpl(() => {\n setRenderDfd(void 0);\n setTransition(void 0);\n setPendingState(void 0);\n setVtContext({ isTransitioning: false });\n });\n });\n reactDomFlushSyncImpl(() => setTransition(t));\n return;\n }\n if (transition) {\n renderDfd?.resolve();\n transition.skipTransition();\n setInterruption({\n state: newState,\n currentLocation: viewTransitionOpts.currentLocation,\n nextLocation: viewTransitionOpts.nextLocation\n });\n } else {\n setPendingState(newState);\n setVtContext({\n isTransitioning: true,\n flushSync: false,\n currentLocation: viewTransitionOpts.currentLocation,\n nextLocation: viewTransitionOpts.nextLocation\n });\n }\n },\n [\n router.window,\n reactDomFlushSyncImpl,\n transition,\n renderDfd,\n useTransitions,\n setOptimisticState,\n onError\n ]\n );\n React3.useLayoutEffect(() => router.subscribe(setState), [router, setState]);\n React3.useEffect(() => {\n if (vtContext.isTransitioning && !vtContext.flushSync) {\n setRenderDfd(new Deferred());\n }\n }, [vtContext]);\n React3.useEffect(() => {\n if (renderDfd && pendingState && router.window) {\n let newState = pendingState;\n let renderPromise = renderDfd.promise;\n let transition2 = router.window.document.startViewTransition(async () => {\n if (useTransitions === false) {\n setStateImpl(newState);\n } else {\n React3.startTransition(() => {\n if (useTransitions === true) {\n setOptimisticState((s) => getOptimisticRouterState(s, newState));\n }\n setStateImpl(newState);\n });\n }\n await renderPromise;\n });\n transition2.finished.finally(() => {\n setRenderDfd(void 0);\n setTransition(void 0);\n setPendingState(void 0);\n setVtContext({ isTransitioning: false });\n });\n setTransition(transition2);\n }\n }, [\n pendingState,\n renderDfd,\n router.window,\n useTransitions,\n setOptimisticState\n ]);\n React3.useEffect(() => {\n if (renderDfd && pendingState && state.location.key === pendingState.location.key) {\n renderDfd.resolve();\n }\n }, [renderDfd, transition, state.location, pendingState]);\n React3.useEffect(() => {\n if (!vtContext.isTransitioning && interruption) {\n setPendingState(interruption.state);\n setVtContext({\n isTransitioning: true,\n flushSync: false,\n currentLocation: interruption.currentLocation,\n nextLocation: interruption.nextLocation\n });\n setInterruption(void 0);\n }\n }, [vtContext.isTransitioning, interruption]);\n let navigator = React3.useMemo(() => {\n return {\n createHref: router.createHref,\n encodeLocation: router.encodeLocation,\n go: (n) => router.navigate(n),\n push: (to, state2, opts) => router.navigate(to, {\n state: state2,\n preventScrollReset: opts?.preventScrollReset\n }),\n replace: (to, state2, opts) => router.navigate(to, {\n replace: true,\n state: state2,\n preventScrollReset: opts?.preventScrollReset\n })\n };\n }, [router]);\n let basename = router.basename || \"/\";\n let dataRouterContext = React3.useMemo(\n () => ({\n router,\n navigator,\n static: false,\n basename,\n onError\n }),\n [router, navigator, basename, onError]\n );\n return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(DataRouterContext.Provider, { value: dataRouterContext }, /* @__PURE__ */ React3.createElement(DataRouterStateContext.Provider, { value: state }, /* @__PURE__ */ React3.createElement(FetchersContext.Provider, { value: fetcherData.current }, /* @__PURE__ */ React3.createElement(ViewTransitionContext.Provider, { value: vtContext }, /* @__PURE__ */ React3.createElement(\n Router,\n {\n basename,\n location: state.location,\n navigationType: state.historyAction,\n navigator,\n useTransitions\n },\n /* @__PURE__ */ React3.createElement(\n MemoizedDataRoutes,\n {\n routes: router.routes,\n manifest: router.manifest,\n future: router.future,\n state,\n isStatic: false,\n onError\n }\n )\n ))))), null);\n}\nfunction getOptimisticRouterState(currentState, newState) {\n return {\n // Don't surface \"current location specific\" stuff mid-navigation\n // (historyAction, location, matches, loaderData, errors, initialized,\n // restoreScroll, preventScrollReset, blockers, etc.)\n ...currentState,\n // Only surface \"pending/in-flight stuff\"\n // (navigation, revalidation, actionData, fetchers, )\n navigation: newState.navigation.state !== \"idle\" ? newState.navigation : currentState.navigation,\n revalidation: newState.revalidation !== \"idle\" ? newState.revalidation : currentState.revalidation,\n actionData: newState.navigation.state !== \"submitting\" ? newState.actionData : currentState.actionData,\n fetchers: newState.fetchers\n };\n}\nvar MemoizedDataRoutes = React3.memo(DataRoutes2);\nfunction DataRoutes2({\n routes,\n manifest,\n future,\n state,\n isStatic,\n onError\n}) {\n return useRoutesImpl(routes, void 0, {\n manifest,\n state,\n isStatic,\n onError,\n future\n });\n}\nfunction MemoryRouter({\n basename,\n children,\n initialEntries,\n initialIndex,\n useTransitions\n}) {\n let historyRef = React3.useRef();\n if (historyRef.current == null) {\n historyRef.current = createMemoryHistory({\n initialEntries,\n initialIndex,\n v5Compat: true\n });\n }\n let history = historyRef.current;\n let [state, setStateImpl] = React3.useState({\n action: history.action,\n location: history.location\n });\n let setState = React3.useCallback(\n (newState) => {\n if (useTransitions === false) {\n setStateImpl(newState);\n } else {\n React3.startTransition(() => setStateImpl(newState));\n }\n },\n [useTransitions]\n );\n React3.useLayoutEffect(() => history.listen(setState), [history, setState]);\n return /* @__PURE__ */ React3.createElement(\n Router,\n {\n basename,\n children,\n location: state.location,\n navigationType: state.action,\n navigator: history,\n useTransitions\n }\n );\n}\nfunction Navigate({\n to,\n replace: replace2,\n state,\n relative\n}) {\n invariant(\n useInRouterContext(),\n // TODO: This error is probably because they somehow have 2 versions of\n // the router loaded. We can help them understand how to avoid that.\n ` may be used only in the context of a component.`\n );\n let { static: isStatic } = React3.useContext(NavigationContext);\n warning(\n !isStatic,\n ` must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.`\n );\n let { matches } = React3.useContext(RouteContext);\n let { pathname: locationPathname } = useLocation();\n let navigate = useNavigate();\n let path = resolveTo(\n to,\n getResolveToMatches(matches),\n locationPathname,\n relative === \"path\"\n );\n let jsonPath = JSON.stringify(path);\n React3.useEffect(() => {\n navigate(JSON.parse(jsonPath), { replace: replace2, state, relative });\n }, [navigate, jsonPath, relative, replace2, state]);\n return null;\n}\nfunction Outlet(props) {\n return useOutlet(props.context);\n}\nfunction Route(props) {\n invariant(\n false,\n `A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .`\n );\n}\nfunction Router({\n basename: basenameProp = \"/\",\n children = null,\n location: locationProp,\n navigationType = \"POP\" /* Pop */,\n navigator,\n static: staticProp = false,\n useTransitions\n}) {\n invariant(\n !useInRouterContext(),\n `You cannot render a inside another . You should never have more than one in your app.`\n );\n let basename = basenameProp.replace(/^\\/*/, \"/\");\n let navigationContext = React3.useMemo(\n () => ({\n basename,\n navigator,\n static: staticProp,\n useTransitions,\n future: {}\n }),\n [basename, navigator, staticProp, useTransitions]\n );\n if (typeof locationProp === \"string\") {\n locationProp = parsePath(locationProp);\n }\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n state = null,\n key = \"default\",\n mask\n } = locationProp;\n let locationContext = React3.useMemo(() => {\n let trailingPathname = stripBasename(pathname, basename);\n if (trailingPathname == null) {\n return null;\n }\n return {\n location: {\n pathname: trailingPathname,\n search,\n hash,\n state,\n key,\n mask\n },\n navigationType\n };\n }, [basename, pathname, search, hash, state, key, navigationType, mask]);\n warning(\n locationContext != null,\n ` is not able to match the URL \"${pathname}${search}${hash}\" because it does not start with the basename, so the won't render anything.`\n );\n if (locationContext == null) {\n return null;\n }\n return /* @__PURE__ */ React3.createElement(NavigationContext.Provider, { value: navigationContext }, /* @__PURE__ */ React3.createElement(LocationContext.Provider, { children, value: locationContext }));\n}\nfunction Routes({\n children,\n location\n}) {\n return useRoutes(createRoutesFromChildren(children), location);\n}\nfunction Await({\n children,\n errorElement,\n resolve\n}) {\n let dataRouterContext = React3.useContext(DataRouterContext);\n let dataRouterStateContext = React3.useContext(DataRouterStateContext);\n let onError = React3.useCallback(\n (error, errorInfo) => {\n if (dataRouterContext && dataRouterContext.onError && dataRouterStateContext) {\n dataRouterContext.onError(error, {\n location: dataRouterStateContext.location,\n params: dataRouterStateContext.matches[0]?.params || {},\n pattern: getRoutePattern(dataRouterStateContext.matches),\n errorInfo\n });\n }\n },\n [dataRouterContext, dataRouterStateContext]\n );\n return /* @__PURE__ */ React3.createElement(\n AwaitErrorBoundary,\n {\n resolve,\n errorElement,\n onError\n },\n /* @__PURE__ */ React3.createElement(ResolveAwait, null, children)\n );\n}\nvar AwaitErrorBoundary = class extends React3.Component {\n constructor(props) {\n super(props);\n this.state = { error: null };\n }\n static getDerivedStateFromError(error) {\n return { error };\n }\n componentDidCatch(error, errorInfo) {\n if (this.props.onError) {\n this.props.onError(error, errorInfo);\n } else {\n console.error(\n \" caught the following error during render\",\n error,\n errorInfo\n );\n }\n }\n render() {\n let { children, errorElement, resolve } = this.props;\n let promise = null;\n let status = 0 /* pending */;\n if (!(resolve instanceof Promise)) {\n status = 1 /* success */;\n promise = Promise.resolve();\n Object.defineProperty(promise, \"_tracked\", { get: () => true });\n Object.defineProperty(promise, \"_data\", { get: () => resolve });\n } else if (this.state.error) {\n status = 2 /* error */;\n let renderError = this.state.error;\n promise = Promise.reject().catch(() => {\n });\n Object.defineProperty(promise, \"_tracked\", { get: () => true });\n Object.defineProperty(promise, \"_error\", { get: () => renderError });\n } else if (resolve._tracked) {\n promise = resolve;\n status = \"_error\" in promise ? 2 /* error */ : \"_data\" in promise ? 1 /* success */ : 0 /* pending */;\n } else {\n status = 0 /* pending */;\n Object.defineProperty(resolve, \"_tracked\", { get: () => true });\n promise = resolve.then(\n (data2) => Object.defineProperty(resolve, \"_data\", { get: () => data2 }),\n (error) => {\n this.props.onError?.(error);\n Object.defineProperty(resolve, \"_error\", { get: () => error });\n }\n );\n }\n if (status === 2 /* error */ && !errorElement) {\n throw promise._error;\n }\n if (status === 2 /* error */) {\n return /* @__PURE__ */ React3.createElement(AwaitContext.Provider, { value: promise, children: errorElement });\n }\n if (status === 1 /* success */) {\n return /* @__PURE__ */ React3.createElement(AwaitContext.Provider, { value: promise, children });\n }\n throw promise;\n }\n};\nfunction ResolveAwait({\n children\n}) {\n let data2 = useAsyncValue();\n let toRender = typeof children === \"function\" ? children(data2) : children;\n return /* @__PURE__ */ React3.createElement(React3.Fragment, null, toRender);\n}\nfunction createRoutesFromChildren(children, parentPath = []) {\n let routes = [];\n React3.Children.forEach(children, (element, index) => {\n if (!React3.isValidElement(element)) {\n return;\n }\n let treePath = [...parentPath, index];\n if (element.type === React3.Fragment) {\n routes.push.apply(\n routes,\n createRoutesFromChildren(element.props.children, treePath)\n );\n return;\n }\n invariant(\n element.type === Route,\n `[${typeof element.type === \"string\" ? element.type : element.type.name}] is not a component. All component children of must be a or `\n );\n invariant(\n !element.props.index || !element.props.children,\n \"An index route cannot have child routes.\"\n );\n let route = {\n id: element.props.id || treePath.join(\"-\"),\n caseSensitive: element.props.caseSensitive,\n element: element.props.element,\n Component: element.props.Component,\n index: element.props.index,\n path: element.props.path,\n middleware: element.props.middleware,\n loader: element.props.loader,\n action: element.props.action,\n hydrateFallbackElement: element.props.hydrateFallbackElement,\n HydrateFallback: element.props.HydrateFallback,\n errorElement: element.props.errorElement,\n ErrorBoundary: element.props.ErrorBoundary,\n hasErrorBoundary: element.props.hasErrorBoundary === true || element.props.ErrorBoundary != null || element.props.errorElement != null,\n shouldRevalidate: element.props.shouldRevalidate,\n handle: element.props.handle,\n lazy: element.props.lazy\n };\n if (element.props.children) {\n route.children = createRoutesFromChildren(\n element.props.children,\n treePath\n );\n }\n routes.push(route);\n });\n return routes;\n}\nvar createRoutesFromElements = createRoutesFromChildren;\nfunction renderMatches(matches) {\n return _renderMatches(matches);\n}\nfunction useRouteComponentProps() {\n return {\n params: useParams(),\n loaderData: useLoaderData(),\n actionData: useActionData(),\n matches: useMatches()\n };\n}\nfunction WithComponentProps({\n children\n}) {\n const props = useRouteComponentProps();\n return React3.cloneElement(children, props);\n}\nfunction withComponentProps(Component4) {\n return function WithComponentProps2() {\n const props = useRouteComponentProps();\n return React3.createElement(Component4, props);\n };\n}\nfunction useHydrateFallbackProps() {\n return {\n params: useParams(),\n loaderData: useLoaderData(),\n actionData: useActionData()\n };\n}\nfunction WithHydrateFallbackProps({\n children\n}) {\n const props = useHydrateFallbackProps();\n return React3.cloneElement(children, props);\n}\nfunction withHydrateFallbackProps(HydrateFallback) {\n return function WithHydrateFallbackProps2() {\n const props = useHydrateFallbackProps();\n return React3.createElement(HydrateFallback, props);\n };\n}\nfunction useErrorBoundaryProps() {\n return {\n params: useParams(),\n loaderData: useLoaderData(),\n actionData: useActionData(),\n error: useRouteError()\n };\n}\nfunction WithErrorBoundaryProps({\n children\n}) {\n const props = useErrorBoundaryProps();\n return React3.cloneElement(children, props);\n}\nfunction withErrorBoundaryProps(ErrorBoundary) {\n return function WithErrorBoundaryProps2() {\n const props = useErrorBoundaryProps();\n return React3.createElement(ErrorBoundary, props);\n };\n}\n\n// lib/dom/dom.ts\nvar defaultMethod = \"get\";\nvar defaultEncType = \"application/x-www-form-urlencoded\";\nfunction isHtmlElement(object) {\n return typeof HTMLElement !== \"undefined\" && object instanceof HTMLElement;\n}\nfunction isButtonElement(object) {\n return isHtmlElement(object) && object.tagName.toLowerCase() === \"button\";\n}\nfunction isFormElement(object) {\n return isHtmlElement(object) && object.tagName.toLowerCase() === \"form\";\n}\nfunction isInputElement(object) {\n return isHtmlElement(object) && object.tagName.toLowerCase() === \"input\";\n}\nfunction isModifiedEvent(event) {\n return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);\n}\nfunction shouldProcessLinkClick(event, target) {\n return event.button === 0 && // Ignore everything but left clicks\n (!target || target === \"_self\") && // Let browser handle \"target=_blank\" etc.\n !isModifiedEvent(event);\n}\nfunction createSearchParams(init = \"\") {\n return new URLSearchParams(\n typeof init === \"string\" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo2, key) => {\n let value = init[key];\n return memo2.concat(\n Array.isArray(value) ? value.map((v) => [key, v]) : [[key, value]]\n );\n }, [])\n );\n}\nfunction getSearchParamsForLocation(locationSearch, defaultSearchParams) {\n let searchParams = createSearchParams(locationSearch);\n if (defaultSearchParams) {\n defaultSearchParams.forEach((_, key) => {\n if (!searchParams.has(key)) {\n defaultSearchParams.getAll(key).forEach((value) => {\n searchParams.append(key, value);\n });\n }\n });\n }\n return searchParams;\n}\nvar _formDataSupportsSubmitter = null;\nfunction isFormDataSubmitterSupported() {\n if (_formDataSupportsSubmitter === null) {\n try {\n new FormData(\n document.createElement(\"form\"),\n // @ts-expect-error if FormData supports the submitter parameter, this will throw\n 0\n );\n _formDataSupportsSubmitter = false;\n } catch (e) {\n _formDataSupportsSubmitter = true;\n }\n }\n return _formDataSupportsSubmitter;\n}\nvar supportedFormEncTypes = /* @__PURE__ */ new Set([\n \"application/x-www-form-urlencoded\",\n \"multipart/form-data\",\n \"text/plain\"\n]);\nfunction getFormEncType(encType) {\n if (encType != null && !supportedFormEncTypes.has(encType)) {\n warning(\n false,\n `\"${encType}\" is not a valid \\`encType\\` for \\`
\\`/\\`\\` and will default to \"${defaultEncType}\"`\n );\n return null;\n }\n return encType;\n}\nfunction getFormSubmissionInfo(target, basename) {\n let method;\n let action;\n let encType;\n let formData;\n let body;\n if (isFormElement(target)) {\n let attr = target.getAttribute(\"action\");\n action = attr ? stripBasename(attr, basename) : null;\n method = target.getAttribute(\"method\") || defaultMethod;\n encType = getFormEncType(target.getAttribute(\"enctype\")) || defaultEncType;\n formData = new FormData(target);\n } else if (isButtonElement(target) || isInputElement(target) && (target.type === \"submit\" || target.type === \"image\")) {\n let form = target.form;\n if (form == null) {\n throw new Error(\n `Cannot submit a \n * \n * );\n * }\n * ```\n *\n * When the button is clicked the component will shift to the `'entering'` state\n * and stay there for 500ms (the value of `timeout`) before it finally switches\n * to `'entered'`.\n *\n * When `in` is `false` the same thing happens except the state moves from\n * `'exiting'` to `'exited'`.\n */\n\nvar Transition = /*#__PURE__*/function (_React$Component) {\n _inheritsLoose(Transition, _React$Component);\n\n function Transition(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n var parentGroup = context; // In the context of a TransitionGroup all enters are really appears\n\n var appear = parentGroup && !parentGroup.isMounting ? props.enter : props.appear;\n var initialStatus;\n _this.appearStatus = null;\n\n if (props.in) {\n if (appear) {\n initialStatus = EXITED;\n _this.appearStatus = ENTERING;\n } else {\n initialStatus = ENTERED;\n }\n } else {\n if (props.unmountOnExit || props.mountOnEnter) {\n initialStatus = UNMOUNTED;\n } else {\n initialStatus = EXITED;\n }\n }\n\n _this.state = {\n status: initialStatus\n };\n _this.nextCallback = null;\n return _this;\n }\n\n Transition.getDerivedStateFromProps = function getDerivedStateFromProps(_ref, prevState) {\n var nextIn = _ref.in;\n\n if (nextIn && prevState.status === UNMOUNTED) {\n return {\n status: EXITED\n };\n }\n\n return null;\n } // getSnapshotBeforeUpdate(prevProps) {\n // let nextStatus = null\n // if (prevProps !== this.props) {\n // const { status } = this.state\n // if (this.props.in) {\n // if (status !== ENTERING && status !== ENTERED) {\n // nextStatus = ENTERING\n // }\n // } else {\n // if (status === ENTERING || status === ENTERED) {\n // nextStatus = EXITING\n // }\n // }\n // }\n // return { nextStatus }\n // }\n ;\n\n var _proto = Transition.prototype;\n\n _proto.componentDidMount = function componentDidMount() {\n this.updateStatus(true, this.appearStatus);\n };\n\n _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n var nextStatus = null;\n\n if (prevProps !== this.props) {\n var status = this.state.status;\n\n if (this.props.in) {\n if (status !== ENTERING && status !== ENTERED) {\n nextStatus = ENTERING;\n }\n } else {\n if (status === ENTERING || status === ENTERED) {\n nextStatus = EXITING;\n }\n }\n }\n\n this.updateStatus(false, nextStatus);\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.cancelNextCallback();\n };\n\n _proto.getTimeouts = function getTimeouts() {\n var timeout = this.props.timeout;\n var exit, enter, appear;\n exit = enter = appear = timeout;\n\n if (timeout != null && typeof timeout !== 'number') {\n exit = timeout.exit;\n enter = timeout.enter; // TODO: remove fallback for next major\n\n appear = timeout.appear !== undefined ? timeout.appear : enter;\n }\n\n return {\n exit: exit,\n enter: enter,\n appear: appear\n };\n };\n\n _proto.updateStatus = function updateStatus(mounting, nextStatus) {\n if (mounting === void 0) {\n mounting = false;\n }\n\n if (nextStatus !== null) {\n // nextStatus will always be ENTERING or EXITING.\n this.cancelNextCallback();\n\n if (nextStatus === ENTERING) {\n if (this.props.unmountOnExit || this.props.mountOnEnter) {\n var node = this.props.nodeRef ? this.props.nodeRef.current : ReactDOM.findDOMNode(this); // https://github.com/reactjs/react-transition-group/pull/749\n // With unmountOnExit or mountOnEnter, the enter animation should happen at the transition between `exited` and `entering`.\n // To make the animation happen, we have to separate each rendering and avoid being processed as batched.\n\n if (node) forceReflow(node);\n }\n\n this.performEnter(mounting);\n } else {\n this.performExit();\n }\n } else if (this.props.unmountOnExit && this.state.status === EXITED) {\n this.setState({\n status: UNMOUNTED\n });\n }\n };\n\n _proto.performEnter = function performEnter(mounting) {\n var _this2 = this;\n\n var enter = this.props.enter;\n var appearing = this.context ? this.context.isMounting : mounting;\n\n var _ref2 = this.props.nodeRef ? [appearing] : [ReactDOM.findDOMNode(this), appearing],\n maybeNode = _ref2[0],\n maybeAppearing = _ref2[1];\n\n var timeouts = this.getTimeouts();\n var enterTimeout = appearing ? timeouts.appear : timeouts.enter; // no enter animation skip right to ENTERED\n // if we are mounting and running this it means appear _must_ be set\n\n if (!mounting && !enter || config.disabled) {\n this.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(maybeNode);\n });\n return;\n }\n\n this.props.onEnter(maybeNode, maybeAppearing);\n this.safeSetState({\n status: ENTERING\n }, function () {\n _this2.props.onEntering(maybeNode, maybeAppearing);\n\n _this2.onTransitionEnd(enterTimeout, function () {\n _this2.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(maybeNode, maybeAppearing);\n });\n });\n });\n };\n\n _proto.performExit = function performExit() {\n var _this3 = this;\n\n var exit = this.props.exit;\n var timeouts = this.getTimeouts();\n var maybeNode = this.props.nodeRef ? undefined : ReactDOM.findDOMNode(this); // no exit animation skip right to EXITED\n\n if (!exit || config.disabled) {\n this.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(maybeNode);\n });\n return;\n }\n\n this.props.onExit(maybeNode);\n this.safeSetState({\n status: EXITING\n }, function () {\n _this3.props.onExiting(maybeNode);\n\n _this3.onTransitionEnd(timeouts.exit, function () {\n _this3.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(maybeNode);\n });\n });\n });\n };\n\n _proto.cancelNextCallback = function cancelNextCallback() {\n if (this.nextCallback !== null) {\n this.nextCallback.cancel();\n this.nextCallback = null;\n }\n };\n\n _proto.safeSetState = function safeSetState(nextState, callback) {\n // This shouldn't be necessary, but there are weird race conditions with\n // setState callbacks and unmounting in testing, so always make sure that\n // we can cancel any pending setState callbacks after we unmount.\n callback = this.setNextCallback(callback);\n this.setState(nextState, callback);\n };\n\n _proto.setNextCallback = function setNextCallback(callback) {\n var _this4 = this;\n\n var active = true;\n\n this.nextCallback = function (event) {\n if (active) {\n active = false;\n _this4.nextCallback = null;\n callback(event);\n }\n };\n\n this.nextCallback.cancel = function () {\n active = false;\n };\n\n return this.nextCallback;\n };\n\n _proto.onTransitionEnd = function onTransitionEnd(timeout, handler) {\n this.setNextCallback(handler);\n var node = this.props.nodeRef ? this.props.nodeRef.current : ReactDOM.findDOMNode(this);\n var doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener;\n\n if (!node || doesNotHaveTimeoutOrListener) {\n setTimeout(this.nextCallback, 0);\n return;\n }\n\n if (this.props.addEndListener) {\n var _ref3 = this.props.nodeRef ? [this.nextCallback] : [node, this.nextCallback],\n maybeNode = _ref3[0],\n maybeNextCallback = _ref3[1];\n\n this.props.addEndListener(maybeNode, maybeNextCallback);\n }\n\n if (timeout != null) {\n setTimeout(this.nextCallback, timeout);\n }\n };\n\n _proto.render = function render() {\n var status = this.state.status;\n\n if (status === UNMOUNTED) {\n return null;\n }\n\n var _this$props = this.props,\n children = _this$props.children,\n _in = _this$props.in,\n _mountOnEnter = _this$props.mountOnEnter,\n _unmountOnExit = _this$props.unmountOnExit,\n _appear = _this$props.appear,\n _enter = _this$props.enter,\n _exit = _this$props.exit,\n _timeout = _this$props.timeout,\n _addEndListener = _this$props.addEndListener,\n _onEnter = _this$props.onEnter,\n _onEntering = _this$props.onEntering,\n _onEntered = _this$props.onEntered,\n _onExit = _this$props.onExit,\n _onExiting = _this$props.onExiting,\n _onExited = _this$props.onExited,\n _nodeRef = _this$props.nodeRef,\n childProps = _objectWithoutPropertiesLoose(_this$props, [\"children\", \"in\", \"mountOnEnter\", \"unmountOnExit\", \"appear\", \"enter\", \"exit\", \"timeout\", \"addEndListener\", \"onEnter\", \"onEntering\", \"onEntered\", \"onExit\", \"onExiting\", \"onExited\", \"nodeRef\"]);\n\n return (\n /*#__PURE__*/\n // allows for nested Transitions\n React.createElement(TransitionGroupContext.Provider, {\n value: null\n }, typeof children === 'function' ? children(status, childProps) : React.cloneElement(React.Children.only(children), childProps))\n );\n };\n\n return Transition;\n}(React.Component);\n\nTransition.contextType = TransitionGroupContext;\nTransition.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * A React reference to DOM element that need to transition:\n * https://stackoverflow.com/a/51127130/4671932\n *\n * - When `nodeRef` prop is used, `node` is not passed to callback functions\n * (e.g. `onEnter`) because user already has direct access to the node.\n * - When changing `key` prop of `Transition` in a `TransitionGroup` a new\n * `nodeRef` need to be provided to `Transition` with changed `key` prop\n * (see\n * [test/CSSTransition-test.js](https://github.com/reactjs/react-transition-group/blob/13435f897b3ab71f6e19d724f145596f5910581c/test/CSSTransition-test.js#L362-L437)).\n */\n nodeRef: PropTypes.shape({\n current: typeof Element === 'undefined' ? PropTypes.any : function (propValue, key, componentName, location, propFullName, secret) {\n var value = propValue[key];\n return PropTypes.instanceOf(value && 'ownerDocument' in value ? value.ownerDocument.defaultView.Element : Element)(propValue, key, componentName, location, propFullName, secret);\n }\n }),\n\n /**\n * A `function` child can be used instead of a React element. This function is\n * called with the current transition status (`'entering'`, `'entered'`,\n * `'exiting'`, `'exited'`), which can be used to apply context\n * specific props to a component.\n *\n * ```jsx\n * \n * {state => (\n * \n * )}\n * \n * ```\n */\n children: PropTypes.oneOfType([PropTypes.func.isRequired, PropTypes.element.isRequired]).isRequired,\n\n /**\n * Show the component; triggers the enter or exit states\n */\n in: PropTypes.bool,\n\n /**\n * By default the child component is mounted immediately along with\n * the parent `Transition` component. If you want to \"lazy mount\" the component on the\n * first `in={true}` you can set `mountOnEnter`. After the first enter transition the component will stay\n * mounted, even on \"exited\", unless you also specify `unmountOnExit`.\n */\n mountOnEnter: PropTypes.bool,\n\n /**\n * By default the child component stays mounted after it reaches the `'exited'` state.\n * Set `unmountOnExit` if you'd prefer to unmount the component after it finishes exiting.\n */\n unmountOnExit: PropTypes.bool,\n\n /**\n * By default the child component does not perform the enter transition when\n * it first mounts, regardless of the value of `in`. If you want this\n * behavior, set both `appear` and `in` to `true`.\n *\n * > **Note**: there are no special appear states like `appearing`/`appeared`, this prop\n * > only adds an additional enter transition. However, in the\n * > `` component that first enter transition does result in\n * > additional `.appear-*` classes, that way you can choose to style it\n * > differently.\n */\n appear: PropTypes.bool,\n\n /**\n * Enable or disable enter transitions.\n */\n enter: PropTypes.bool,\n\n /**\n * Enable or disable exit transitions.\n */\n exit: PropTypes.bool,\n\n /**\n * The duration of the transition, in milliseconds.\n * Required unless `addEndListener` is provided.\n *\n * You may specify a single timeout for all transitions:\n *\n * ```jsx\n * timeout={500}\n * ```\n *\n * or individually:\n *\n * ```jsx\n * timeout={{\n * appear: 500,\n * enter: 300,\n * exit: 500,\n * }}\n * ```\n *\n * - `appear` defaults to the value of `enter`\n * - `enter` defaults to `0`\n * - `exit` defaults to `0`\n *\n * @type {number | { enter?: number, exit?: number, appear?: number }}\n */\n timeout: function timeout(props) {\n var pt = timeoutsShape;\n if (!props.addEndListener) pt = pt.isRequired;\n\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n return pt.apply(void 0, [props].concat(args));\n },\n\n /**\n * Add a custom transition end trigger. Called with the transitioning\n * DOM node and a `done` callback. Allows for more fine grained transition end\n * logic. Timeouts are still used as a fallback if provided.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * ```jsx\n * addEndListener={(node, done) => {\n * // use the css transitionend event to mark the finish of a transition\n * node.addEventListener('transitionend', done, false);\n * }}\n * ```\n */\n addEndListener: PropTypes.func,\n\n /**\n * Callback fired before the \"entering\" status is applied. An extra parameter\n * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEnter: PropTypes.func,\n\n /**\n * Callback fired after the \"entering\" status is applied. An extra parameter\n * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntering: PropTypes.func,\n\n /**\n * Callback fired after the \"entered\" status is applied. An extra parameter\n * `isAppearing` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEntered: PropTypes.func,\n\n /**\n * Callback fired before the \"exiting\" status is applied.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExit: PropTypes.func,\n\n /**\n * Callback fired after the \"exiting\" status is applied.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExiting: PropTypes.func,\n\n /**\n * Callback fired after the \"exited\" status is applied.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExited: PropTypes.func\n} : {}; // Name the function so it is clearer in the documentation\n\nfunction noop() {}\n\nTransition.defaultProps = {\n in: false,\n mountOnEnter: false,\n unmountOnExit: false,\n appear: false,\n enter: true,\n exit: true,\n onEnter: noop,\n onEntering: noop,\n onEntered: noop,\n onExit: noop,\n onExiting: noop,\n onExited: noop\n};\nTransition.UNMOUNTED = UNMOUNTED;\nTransition.EXITED = EXITED;\nTransition.ENTERING = ENTERING;\nTransition.ENTERED = ENTERED;\nTransition.EXITING = EXITING;\nexport default Transition;", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport PropTypes from 'prop-types';\nimport addOneClass from 'dom-helpers/addClass';\nimport removeOneClass from 'dom-helpers/removeClass';\nimport React from 'react';\nimport Transition from './Transition';\nimport { classNamesShape } from './utils/PropTypes';\nimport { forceReflow } from './utils/reflow';\n\nvar _addClass = function addClass(node, classes) {\n return node && classes && classes.split(' ').forEach(function (c) {\n return addOneClass(node, c);\n });\n};\n\nvar removeClass = function removeClass(node, classes) {\n return node && classes && classes.split(' ').forEach(function (c) {\n return removeOneClass(node, c);\n });\n};\n/**\n * A transition component inspired by the excellent\n * [ng-animate](https://docs.angularjs.org/api/ngAnimate) library, you should\n * use it if you're using CSS transitions or animations. It's built upon the\n * [`Transition`](https://reactcommunity.org/react-transition-group/transition)\n * component, so it inherits all of its props.\n *\n * `CSSTransition` applies a pair of class names during the `appear`, `enter`,\n * and `exit` states of the transition. The first class is applied and then a\n * second `*-active` class in order to activate the CSS transition. After the\n * transition, matching `*-done` class names are applied to persist the\n * transition state.\n *\n * ```jsx\n * function App() {\n * const [inProp, setInProp] = useState(false);\n * return (\n *
\n * \n *
\n * {\"I'll receive my-node-* classes\"}\n *
\n *
\n * \n *
\n * );\n * }\n * ```\n *\n * When the `in` prop is set to `true`, the child component will first receive\n * the class `example-enter`, then the `example-enter-active` will be added in\n * the next tick. `CSSTransition` [forces a\n * reflow](https://github.com/reactjs/react-transition-group/blob/5007303e729a74be66a21c3e2205e4916821524b/src/CSSTransition.js#L208-L215)\n * between before adding the `example-enter-active`. This is an important trick\n * because it allows us to transition between `example-enter` and\n * `example-enter-active` even though they were added immediately one after\n * another. Most notably, this is what makes it possible for us to animate\n * _appearance_.\n *\n * ```css\n * .my-node-enter {\n * opacity: 0;\n * }\n * .my-node-enter-active {\n * opacity: 1;\n * transition: opacity 200ms;\n * }\n * .my-node-exit {\n * opacity: 1;\n * }\n * .my-node-exit-active {\n * opacity: 0;\n * transition: opacity 200ms;\n * }\n * ```\n *\n * `*-active` classes represent which styles you want to animate **to**, so it's\n * important to add `transition` declaration only to them, otherwise transitions\n * might not behave as intended! This might not be obvious when the transitions\n * are symmetrical, i.e. when `*-enter-active` is the same as `*-exit`, like in\n * the example above (minus `transition`), but it becomes apparent in more\n * complex transitions.\n *\n * **Note**: If you're using the\n * [`appear`](http://reactcommunity.org/react-transition-group/transition#Transition-prop-appear)\n * prop, make sure to define styles for `.appear-*` classes as well.\n */\n\n\nvar CSSTransition = /*#__PURE__*/function (_React$Component) {\n _inheritsLoose(CSSTransition, _React$Component);\n\n function CSSTransition() {\n var _this;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;\n _this.appliedClasses = {\n appear: {},\n enter: {},\n exit: {}\n };\n\n _this.onEnter = function (maybeNode, maybeAppearing) {\n var _this$resolveArgument = _this.resolveArguments(maybeNode, maybeAppearing),\n node = _this$resolveArgument[0],\n appearing = _this$resolveArgument[1];\n\n _this.removeClasses(node, 'exit');\n\n _this.addClass(node, appearing ? 'appear' : 'enter', 'base');\n\n if (_this.props.onEnter) {\n _this.props.onEnter(maybeNode, maybeAppearing);\n }\n };\n\n _this.onEntering = function (maybeNode, maybeAppearing) {\n var _this$resolveArgument2 = _this.resolveArguments(maybeNode, maybeAppearing),\n node = _this$resolveArgument2[0],\n appearing = _this$resolveArgument2[1];\n\n var type = appearing ? 'appear' : 'enter';\n\n _this.addClass(node, type, 'active');\n\n if (_this.props.onEntering) {\n _this.props.onEntering(maybeNode, maybeAppearing);\n }\n };\n\n _this.onEntered = function (maybeNode, maybeAppearing) {\n var _this$resolveArgument3 = _this.resolveArguments(maybeNode, maybeAppearing),\n node = _this$resolveArgument3[0],\n appearing = _this$resolveArgument3[1];\n\n var type = appearing ? 'appear' : 'enter';\n\n _this.removeClasses(node, type);\n\n _this.addClass(node, type, 'done');\n\n if (_this.props.onEntered) {\n _this.props.onEntered(maybeNode, maybeAppearing);\n }\n };\n\n _this.onExit = function (maybeNode) {\n var _this$resolveArgument4 = _this.resolveArguments(maybeNode),\n node = _this$resolveArgument4[0];\n\n _this.removeClasses(node, 'appear');\n\n _this.removeClasses(node, 'enter');\n\n _this.addClass(node, 'exit', 'base');\n\n if (_this.props.onExit) {\n _this.props.onExit(maybeNode);\n }\n };\n\n _this.onExiting = function (maybeNode) {\n var _this$resolveArgument5 = _this.resolveArguments(maybeNode),\n node = _this$resolveArgument5[0];\n\n _this.addClass(node, 'exit', 'active');\n\n if (_this.props.onExiting) {\n _this.props.onExiting(maybeNode);\n }\n };\n\n _this.onExited = function (maybeNode) {\n var _this$resolveArgument6 = _this.resolveArguments(maybeNode),\n node = _this$resolveArgument6[0];\n\n _this.removeClasses(node, 'exit');\n\n _this.addClass(node, 'exit', 'done');\n\n if (_this.props.onExited) {\n _this.props.onExited(maybeNode);\n }\n };\n\n _this.resolveArguments = function (maybeNode, maybeAppearing) {\n return _this.props.nodeRef ? [_this.props.nodeRef.current, maybeNode] // here `maybeNode` is actually `appearing`\n : [maybeNode, maybeAppearing];\n };\n\n _this.getClassNames = function (type) {\n var classNames = _this.props.classNames;\n var isStringClassNames = typeof classNames === 'string';\n var prefix = isStringClassNames && classNames ? classNames + \"-\" : '';\n var baseClassName = isStringClassNames ? \"\" + prefix + type : classNames[type];\n var activeClassName = isStringClassNames ? baseClassName + \"-active\" : classNames[type + \"Active\"];\n var doneClassName = isStringClassNames ? baseClassName + \"-done\" : classNames[type + \"Done\"];\n return {\n baseClassName: baseClassName,\n activeClassName: activeClassName,\n doneClassName: doneClassName\n };\n };\n\n return _this;\n }\n\n var _proto = CSSTransition.prototype;\n\n _proto.addClass = function addClass(node, type, phase) {\n var className = this.getClassNames(type)[phase + \"ClassName\"];\n\n var _this$getClassNames = this.getClassNames('enter'),\n doneClassName = _this$getClassNames.doneClassName;\n\n if (type === 'appear' && phase === 'done' && doneClassName) {\n className += \" \" + doneClassName;\n } // This is to force a repaint,\n // which is necessary in order to transition styles when adding a class name.\n\n\n if (phase === 'active') {\n if (node) forceReflow(node);\n }\n\n if (className) {\n this.appliedClasses[type][phase] = className;\n\n _addClass(node, className);\n }\n };\n\n _proto.removeClasses = function removeClasses(node, type) {\n var _this$appliedClasses$ = this.appliedClasses[type],\n baseClassName = _this$appliedClasses$.base,\n activeClassName = _this$appliedClasses$.active,\n doneClassName = _this$appliedClasses$.done;\n this.appliedClasses[type] = {};\n\n if (baseClassName) {\n removeClass(node, baseClassName);\n }\n\n if (activeClassName) {\n removeClass(node, activeClassName);\n }\n\n if (doneClassName) {\n removeClass(node, doneClassName);\n }\n };\n\n _proto.render = function render() {\n var _this$props = this.props,\n _ = _this$props.classNames,\n props = _objectWithoutPropertiesLoose(_this$props, [\"classNames\"]);\n\n return /*#__PURE__*/React.createElement(Transition, _extends({}, props, {\n onEnter: this.onEnter,\n onEntered: this.onEntered,\n onEntering: this.onEntering,\n onExit: this.onExit,\n onExiting: this.onExiting,\n onExited: this.onExited\n }));\n };\n\n return CSSTransition;\n}(React.Component);\n\nCSSTransition.defaultProps = {\n classNames: ''\n};\nCSSTransition.propTypes = process.env.NODE_ENV !== \"production\" ? _extends({}, Transition.propTypes, {\n /**\n * The animation classNames applied to the component as it appears, enters,\n * exits or has finished the transition. A single name can be provided, which\n * will be suffixed for each stage, e.g. `classNames=\"fade\"` applies:\n *\n * - `fade-appear`, `fade-appear-active`, `fade-appear-done`\n * - `fade-enter`, `fade-enter-active`, `fade-enter-done`\n * - `fade-exit`, `fade-exit-active`, `fade-exit-done`\n *\n * A few details to note about how these classes are applied:\n *\n * 1. They are _joined_ with the ones that are already defined on the child\n * component, so if you want to add some base styles, you can use\n * `className` without worrying that it will be overridden.\n *\n * 2. If the transition component mounts with `in={false}`, no classes are\n * applied yet. You might be expecting `*-exit-done`, but if you think\n * about it, a component cannot finish exiting if it hasn't entered yet.\n *\n * 2. `fade-appear-done` and `fade-enter-done` will _both_ be applied. This\n * allows you to define different behavior for when appearing is done and\n * when regular entering is done, using selectors like\n * `.fade-enter-done:not(.fade-appear-done)`. For example, you could apply\n * an epic entrance animation when element first appears in the DOM using\n * [Animate.css](https://daneden.github.io/animate.css/). Otherwise you can\n * simply use `fade-enter-done` for defining both cases.\n *\n * Each individual classNames can also be specified independently like:\n *\n * ```js\n * classNames={{\n * appear: 'my-appear',\n * appearActive: 'my-active-appear',\n * appearDone: 'my-done-appear',\n * enter: 'my-enter',\n * enterActive: 'my-active-enter',\n * enterDone: 'my-done-enter',\n * exit: 'my-exit',\n * exitActive: 'my-active-exit',\n * exitDone: 'my-done-exit',\n * }}\n * ```\n *\n * If you want to set these classes using CSS Modules:\n *\n * ```js\n * import styles from './styles.css';\n * ```\n *\n * you might want to use camelCase in your CSS file, that way could simply\n * spread them instead of listing them one by one:\n *\n * ```js\n * classNames={{ ...styles }}\n * ```\n *\n * @type {string | {\n * appear?: string,\n * appearActive?: string,\n * appearDone?: string,\n * enter?: string,\n * enterActive?: string,\n * enterDone?: string,\n * exit?: string,\n * exitActive?: string,\n * exitDone?: string,\n * }}\n */\n classNames: classNamesShape,\n\n /**\n * A `` callback fired immediately after the 'enter' or 'appear' class is\n * applied.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEnter: PropTypes.func,\n\n /**\n * A `` callback fired immediately after the 'enter-active' or\n * 'appear-active' class is applied.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntering: PropTypes.func,\n\n /**\n * A `` callback fired immediately after the 'enter' or\n * 'appear' classes are **removed** and the `done` class is added to the DOM node.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed.\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntered: PropTypes.func,\n\n /**\n * A `` callback fired immediately after the 'exit' class is\n * applied.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed\n *\n * @type Function(node: HtmlElement)\n */\n onExit: PropTypes.func,\n\n /**\n * A `` callback fired immediately after the 'exit-active' is applied.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed\n *\n * @type Function(node: HtmlElement)\n */\n onExiting: PropTypes.func,\n\n /**\n * A `` callback fired immediately after the 'exit' classes\n * are **removed** and the `exit-done` class is added to the DOM node.\n *\n * **Note**: when `nodeRef` prop is passed, `node` is not passed\n *\n * @type Function(node: HtmlElement)\n */\n onExited: PropTypes.func\n}) : {};\nexport default CSSTransition;", "function _assertThisInitialized(e) {\n if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n return e;\n}\nexport { _assertThisInitialized as default };", "import { Children, cloneElement, isValidElement } from 'react';\n/**\n * Given `this.props.children`, return an object mapping key to child.\n *\n * @param {*} children `this.props.children`\n * @return {object} Mapping of key to child\n */\n\nexport function getChildMapping(children, mapFn) {\n var mapper = function mapper(child) {\n return mapFn && isValidElement(child) ? mapFn(child) : child;\n };\n\n var result = Object.create(null);\n if (children) Children.map(children, function (c) {\n return c;\n }).forEach(function (child) {\n // run the map function here instead so that the key is the computed one\n result[child.key] = mapper(child);\n });\n return result;\n}\n/**\n * When you're adding or removing children some may be added or removed in the\n * same render pass. We want to show *both* since we want to simultaneously\n * animate elements in and out. This function takes a previous set of keys\n * and a new set of keys and merges them with its best guess of the correct\n * ordering. In the future we may expose some of the utilities in\n * ReactMultiChild to make this easy, but for now React itself does not\n * directly have this concept of the union of prevChildren and nextChildren\n * so we implement it here.\n *\n * @param {object} prev prev children as returned from\n * `ReactTransitionChildMapping.getChildMapping()`.\n * @param {object} next next children as returned from\n * `ReactTransitionChildMapping.getChildMapping()`.\n * @return {object} a key set that contains all keys in `prev` and all keys\n * in `next` in a reasonable order.\n */\n\nexport function mergeChildMappings(prev, next) {\n prev = prev || {};\n next = next || {};\n\n function getValueForKey(key) {\n return key in next ? next[key] : prev[key];\n } // For each key of `next`, the list of keys to insert before that key in\n // the combined list\n\n\n var nextKeysPending = Object.create(null);\n var pendingKeys = [];\n\n for (var prevKey in prev) {\n if (prevKey in next) {\n if (pendingKeys.length) {\n nextKeysPending[prevKey] = pendingKeys;\n pendingKeys = [];\n }\n } else {\n pendingKeys.push(prevKey);\n }\n }\n\n var i;\n var childMapping = {};\n\n for (var nextKey in next) {\n if (nextKeysPending[nextKey]) {\n for (i = 0; i < nextKeysPending[nextKey].length; i++) {\n var pendingNextKey = nextKeysPending[nextKey][i];\n childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey);\n }\n }\n\n childMapping[nextKey] = getValueForKey(nextKey);\n } // Finally, add the keys which didn't appear before any key in `next`\n\n\n for (i = 0; i < pendingKeys.length; i++) {\n childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]);\n }\n\n return childMapping;\n}\n\nfunction getProp(child, prop, props) {\n return props[prop] != null ? props[prop] : child.props[prop];\n}\n\nexport function getInitialChildMapping(props, onExited) {\n return getChildMapping(props.children, function (child) {\n return cloneElement(child, {\n onExited: onExited.bind(null, child),\n in: true,\n appear: getProp(child, 'appear', props),\n enter: getProp(child, 'enter', props),\n exit: getProp(child, 'exit', props)\n });\n });\n}\nexport function getNextChildMapping(nextProps, prevChildMapping, onExited) {\n var nextChildMapping = getChildMapping(nextProps.children);\n var children = mergeChildMappings(prevChildMapping, nextChildMapping);\n Object.keys(children).forEach(function (key) {\n var child = children[key];\n if (!isValidElement(child)) return;\n var hasPrev = (key in prevChildMapping);\n var hasNext = (key in nextChildMapping);\n var prevChild = prevChildMapping[key];\n var isLeaving = isValidElement(prevChild) && !prevChild.props.in; // item is new (entering)\n\n if (hasNext && (!hasPrev || isLeaving)) {\n // console.log('entering', key)\n children[key] = cloneElement(child, {\n onExited: onExited.bind(null, child),\n in: true,\n exit: getProp(child, 'exit', nextProps),\n enter: getProp(child, 'enter', nextProps)\n });\n } else if (!hasNext && hasPrev && !isLeaving) {\n // item is old (exiting)\n // console.log('leaving', key)\n children[key] = cloneElement(child, {\n in: false\n });\n } else if (hasNext && hasPrev && isValidElement(prevChild)) {\n // item hasn't changed transition states\n // copy over the last transition props;\n // console.log('unchanged', key)\n children[key] = cloneElement(child, {\n onExited: onExited.bind(null, child),\n in: prevChild.props.in,\n exit: getProp(child, 'exit', nextProps),\n enter: getProp(child, 'enter', nextProps)\n });\n }\n });\n return children;\n}", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _assertThisInitialized from \"@babel/runtime/helpers/esm/assertThisInitialized\";\nimport _inheritsLoose from \"@babel/runtime/helpers/esm/inheritsLoose\";\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport TransitionGroupContext from './TransitionGroupContext';\nimport { getChildMapping, getInitialChildMapping, getNextChildMapping } from './utils/ChildMapping';\n\nvar values = Object.values || function (obj) {\n return Object.keys(obj).map(function (k) {\n return obj[k];\n });\n};\n\nvar defaultProps = {\n component: 'div',\n childFactory: function childFactory(child) {\n return child;\n }\n};\n/**\n * The `` component manages a set of transition components\n * (`` and ``) in a list. Like with the transition\n * components, `` is a state machine for managing the mounting\n * and unmounting of components over time.\n *\n * Consider the example below. As items are removed or added to the TodoList the\n * `in` prop is toggled automatically by the ``.\n *\n * Note that `` does not define any animation behavior!\n * Exactly _how_ a list item animates is up to the individual transition\n * component. This means you can mix and match animations across different list\n * items.\n */\n\nvar TransitionGroup = /*#__PURE__*/function (_React$Component) {\n _inheritsLoose(TransitionGroup, _React$Component);\n\n function TransitionGroup(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n\n var handleExited = _this.handleExited.bind(_assertThisInitialized(_this)); // Initial children should all be entering, dependent on appear\n\n\n _this.state = {\n contextValue: {\n isMounting: true\n },\n handleExited: handleExited,\n firstRender: true\n };\n return _this;\n }\n\n var _proto = TransitionGroup.prototype;\n\n _proto.componentDidMount = function componentDidMount() {\n this.mounted = true;\n this.setState({\n contextValue: {\n isMounting: false\n }\n });\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.mounted = false;\n };\n\n TransitionGroup.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, _ref) {\n var prevChildMapping = _ref.children,\n handleExited = _ref.handleExited,\n firstRender = _ref.firstRender;\n return {\n children: firstRender ? getInitialChildMapping(nextProps, handleExited) : getNextChildMapping(nextProps, prevChildMapping, handleExited),\n firstRender: false\n };\n } // node is `undefined` when user provided `nodeRef` prop\n ;\n\n _proto.handleExited = function handleExited(child, node) {\n var currentChildMapping = getChildMapping(this.props.children);\n if (child.key in currentChildMapping) return;\n\n if (child.props.onExited) {\n child.props.onExited(node);\n }\n\n if (this.mounted) {\n this.setState(function (state) {\n var children = _extends({}, state.children);\n\n delete children[child.key];\n return {\n children: children\n };\n });\n }\n };\n\n _proto.render = function render() {\n var _this$props = this.props,\n Component = _this$props.component,\n childFactory = _this$props.childFactory,\n props = _objectWithoutPropertiesLoose(_this$props, [\"component\", \"childFactory\"]);\n\n var contextValue = this.state.contextValue;\n var children = values(this.state.children).map(childFactory);\n delete props.appear;\n delete props.enter;\n delete props.exit;\n\n if (Component === null) {\n return /*#__PURE__*/React.createElement(TransitionGroupContext.Provider, {\n value: contextValue\n }, children);\n }\n\n return /*#__PURE__*/React.createElement(TransitionGroupContext.Provider, {\n value: contextValue\n }, /*#__PURE__*/React.createElement(Component, props, children));\n };\n\n return TransitionGroup;\n}(React.Component);\n\nTransitionGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * `` renders a `
` by default. You can change this\n * behavior by providing a `component` prop.\n * If you use React v16+ and would like to avoid a wrapping `
` element\n * you can pass in `component={null}`. This is useful if the wrapping div\n * borks your css styles.\n */\n component: PropTypes.any,\n\n /**\n * A set of `` components, that are toggled `in` and out as they\n * leave. the `` will inject specific transition props, so\n * remember to spread them through if you are wrapping the `` as\n * with our `` example.\n *\n * While this component is meant for multiple `Transition` or `CSSTransition`\n * children, sometimes you may want to have a single transition child with\n * content that you want to be transitioned out and in when you change it\n * (e.g. routes, images etc.) In that case you can change the `key` prop of\n * the transition child as you change its content, this will cause\n * `TransitionGroup` to transition the child out and back in.\n */\n children: PropTypes.node,\n\n /**\n * A convenience prop that enables or disables appear animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n appear: PropTypes.bool,\n\n /**\n * A convenience prop that enables or disables enter animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n enter: PropTypes.bool,\n\n /**\n * A convenience prop that enables or disables exit animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n exit: PropTypes.bool,\n\n /**\n * You may need to apply reactive updates to a child as it is exiting.\n * This is generally done by using `cloneElement` however in the case of an exiting\n * child the element has already been removed and not accessible to the consumer.\n *\n * If you do need to update a child as it leaves you can provide a `childFactory`\n * to wrap every child, even the ones that are leaving.\n *\n * @type Function(child: ReactElement) -> ReactElement\n */\n childFactory: PropTypes.func\n} : {};\nTransitionGroup.defaultProps = defaultProps;\nexport default TransitionGroup;", "export { default as CSSTransition } from './CSSTransition';\nexport { default as ReplaceTransition } from './ReplaceTransition';\nexport { default as SwitchTransition } from './SwitchTransition';\nexport { default as TransitionGroup } from './TransitionGroup';\nexport { default as Transition } from './Transition';\nexport { default as config } from './config';", "export const reflow = node => node.scrollTop;\nexport function getTransitionProps(props, options) {\n var _style$transitionDura, _style$transitionTimi;\n const {\n timeout,\n easing,\n style = {}\n } = props;\n return {\n duration: (_style$transitionDura = style.transitionDuration) != null ? _style$transitionDura : typeof timeout === 'number' ? timeout : timeout[options.mode] || 0,\n easing: (_style$transitionTimi = style.transitionTimingFunction) != null ? _style$transitionTimi : typeof easing === 'object' ? easing[options.mode] : easing,\n delay: style.transitionDelay\n };\n}", "import { unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nimport generateUtilityClass from '../generateUtilityClass';\nexport function getCollapseUtilityClass(slot) {\n return generateUtilityClass('MuiCollapse', slot);\n}\nconst collapseClasses = generateUtilityClasses('MuiCollapse', ['root', 'horizontal', 'vertical', 'entered', 'hidden', 'wrapper', 'wrapperInner']);\nexport default collapseClasses;", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"addEndListener\", \"children\", \"className\", \"collapsedSize\", \"component\", \"easing\", \"in\", \"onEnter\", \"onEntered\", \"onEntering\", \"onExit\", \"onExited\", \"onExiting\", \"orientation\", \"style\", \"timeout\", \"TransitionComponent\"];\nimport * as React from 'react';\nimport clsx from 'clsx';\nimport PropTypes from 'prop-types';\nimport { Transition } from 'react-transition-group';\nimport { elementTypeAcceptingRef } from '@mui/utils';\nimport { unstable_composeClasses as composeClasses } from '@mui/base';\nimport styled from '../styles/styled';\nimport useThemeProps from '../styles/useThemeProps';\nimport { duration } from '../styles/createTransitions';\nimport { getTransitionProps } from '../transitions/utils';\nimport useTheme from '../styles/useTheme';\nimport { useForkRef } from '../utils';\nimport { getCollapseUtilityClass } from './collapseClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n orientation,\n classes\n } = ownerState;\n const slots = {\n root: ['root', `${orientation}`],\n entered: ['entered'],\n hidden: ['hidden'],\n wrapper: ['wrapper', `${orientation}`],\n wrapperInner: ['wrapperInner', `${orientation}`]\n };\n return composeClasses(slots, getCollapseUtilityClass, classes);\n};\nconst CollapseRoot = styled('div', {\n name: 'MuiCollapse',\n slot: 'Root',\n overridesResolver: (props, styles) => {\n const {\n ownerState\n } = props;\n return [styles.root, styles[ownerState.orientation], ownerState.state === 'entered' && styles.entered, ownerState.state === 'exited' && !ownerState.in && ownerState.collapsedSize === '0px' && styles.hidden];\n }\n})(({\n theme,\n ownerState\n}) => _extends({\n height: 0,\n overflow: 'hidden',\n transition: theme.transitions.create('height')\n}, ownerState.orientation === 'horizontal' && {\n height: 'auto',\n width: 0,\n transition: theme.transitions.create('width')\n}, ownerState.state === 'entered' && _extends({\n height: 'auto',\n overflow: 'visible'\n}, ownerState.orientation === 'horizontal' && {\n width: 'auto'\n}), ownerState.state === 'exited' && !ownerState.in && ownerState.collapsedSize === '0px' && {\n visibility: 'hidden'\n}));\nconst CollapseWrapper = styled('div', {\n name: 'MuiCollapse',\n slot: 'Wrapper',\n overridesResolver: (props, styles) => styles.wrapper\n})(({\n ownerState\n}) => _extends({\n // Hack to get children with a negative margin to not falsify the height computation.\n display: 'flex',\n width: '100%'\n}, ownerState.orientation === 'horizontal' && {\n width: 'auto',\n height: '100%'\n}));\nconst CollapseWrapperInner = styled('div', {\n name: 'MuiCollapse',\n slot: 'WrapperInner',\n overridesResolver: (props, styles) => styles.wrapperInner\n})(({\n ownerState\n}) => _extends({\n width: '100%'\n}, ownerState.orientation === 'horizontal' && {\n width: 'auto',\n height: '100%'\n}));\n\n/**\n * The Collapse transition is used by the\n * [Vertical Stepper](/material-ui/react-stepper/#vertical-stepper) StepContent component.\n * It uses [react-transition-group](https://github.com/reactjs/react-transition-group) internally.\n */\nconst Collapse = /*#__PURE__*/React.forwardRef(function Collapse(inProps, ref) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiCollapse'\n });\n const {\n addEndListener,\n children,\n className,\n collapsedSize: collapsedSizeProp = '0px',\n component,\n easing,\n in: inProp,\n onEnter,\n onEntered,\n onEntering,\n onExit,\n onExited,\n onExiting,\n orientation = 'vertical',\n style,\n timeout = duration.standard,\n // eslint-disable-next-line react/prop-types\n TransitionComponent = Transition\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const ownerState = _extends({}, props, {\n orientation,\n collapsedSize: collapsedSizeProp\n });\n const classes = useUtilityClasses(ownerState);\n const theme = useTheme();\n const timer = React.useRef();\n const wrapperRef = React.useRef(null);\n const autoTransitionDuration = React.useRef();\n const collapsedSize = typeof collapsedSizeProp === 'number' ? `${collapsedSizeProp}px` : collapsedSizeProp;\n const isHorizontal = orientation === 'horizontal';\n const size = isHorizontal ? 'width' : 'height';\n React.useEffect(() => {\n return () => {\n clearTimeout(timer.current);\n };\n }, []);\n const nodeRef = React.useRef(null);\n const handleRef = useForkRef(ref, nodeRef);\n const normalizedTransitionCallback = callback => maybeIsAppearing => {\n if (callback) {\n const node = nodeRef.current;\n\n // onEnterXxx and onExitXxx callbacks have a different arguments.length value.\n if (maybeIsAppearing === undefined) {\n callback(node);\n } else {\n callback(node, maybeIsAppearing);\n }\n }\n };\n const getWrapperSize = () => wrapperRef.current ? wrapperRef.current[isHorizontal ? 'clientWidth' : 'clientHeight'] : 0;\n const handleEnter = normalizedTransitionCallback((node, isAppearing) => {\n if (wrapperRef.current && isHorizontal) {\n // Set absolute position to get the size of collapsed content\n wrapperRef.current.style.position = 'absolute';\n }\n node.style[size] = collapsedSize;\n if (onEnter) {\n onEnter(node, isAppearing);\n }\n });\n const handleEntering = normalizedTransitionCallback((node, isAppearing) => {\n const wrapperSize = getWrapperSize();\n if (wrapperRef.current && isHorizontal) {\n // After the size is read reset the position back to default\n wrapperRef.current.style.position = '';\n }\n const {\n duration: transitionDuration,\n easing: transitionTimingFunction\n } = getTransitionProps({\n style,\n timeout,\n easing\n }, {\n mode: 'enter'\n });\n if (timeout === 'auto') {\n const duration2 = theme.transitions.getAutoHeightDuration(wrapperSize);\n node.style.transitionDuration = `${duration2}ms`;\n autoTransitionDuration.current = duration2;\n } else {\n node.style.transitionDuration = typeof transitionDuration === 'string' ? transitionDuration : `${transitionDuration}ms`;\n }\n node.style[size] = `${wrapperSize}px`;\n node.style.transitionTimingFunction = transitionTimingFunction;\n if (onEntering) {\n onEntering(node, isAppearing);\n }\n });\n const handleEntered = normalizedTransitionCallback((node, isAppearing) => {\n node.style[size] = 'auto';\n if (onEntered) {\n onEntered(node, isAppearing);\n }\n });\n const handleExit = normalizedTransitionCallback(node => {\n node.style[size] = `${getWrapperSize()}px`;\n if (onExit) {\n onExit(node);\n }\n });\n const handleExited = normalizedTransitionCallback(onExited);\n const handleExiting = normalizedTransitionCallback(node => {\n const wrapperSize = getWrapperSize();\n const {\n duration: transitionDuration,\n easing: transitionTimingFunction\n } = getTransitionProps({\n style,\n timeout,\n easing\n }, {\n mode: 'exit'\n });\n if (timeout === 'auto') {\n // TODO: rename getAutoHeightDuration to something more generic (width support)\n // Actually it just calculates animation duration based on size\n const duration2 = theme.transitions.getAutoHeightDuration(wrapperSize);\n node.style.transitionDuration = `${duration2}ms`;\n autoTransitionDuration.current = duration2;\n } else {\n node.style.transitionDuration = typeof transitionDuration === 'string' ? transitionDuration : `${transitionDuration}ms`;\n }\n node.style[size] = collapsedSize;\n node.style.transitionTimingFunction = transitionTimingFunction;\n if (onExiting) {\n onExiting(node);\n }\n });\n const handleAddEndListener = next => {\n if (timeout === 'auto') {\n timer.current = setTimeout(next, autoTransitionDuration.current || 0);\n }\n if (addEndListener) {\n // Old call signature before `react-transition-group` implemented `nodeRef`\n addEndListener(nodeRef.current, next);\n }\n };\n return /*#__PURE__*/_jsx(TransitionComponent, _extends({\n in: inProp,\n onEnter: handleEnter,\n onEntered: handleEntered,\n onEntering: handleEntering,\n onExit: handleExit,\n onExited: handleExited,\n onExiting: handleExiting,\n addEndListener: handleAddEndListener,\n nodeRef: nodeRef,\n timeout: timeout === 'auto' ? null : timeout\n }, other, {\n children: (state, childProps) => /*#__PURE__*/_jsx(CollapseRoot, _extends({\n as: component,\n className: clsx(classes.root, className, {\n 'entered': classes.entered,\n 'exited': !inProp && collapsedSize === '0px' && classes.hidden\n }[state]),\n style: _extends({\n [isHorizontal ? 'minWidth' : 'minHeight']: collapsedSize\n }, style),\n ownerState: _extends({}, ownerState, {\n state\n }),\n ref: handleRef\n }, childProps, {\n children: /*#__PURE__*/_jsx(CollapseWrapper, {\n ownerState: _extends({}, ownerState, {\n state\n }),\n className: classes.wrapper,\n ref: wrapperRef,\n children: /*#__PURE__*/_jsx(CollapseWrapperInner, {\n ownerState: _extends({}, ownerState, {\n state\n }),\n className: classes.wrapperInner,\n children: children\n })\n })\n }))\n }));\n});\nprocess.env.NODE_ENV !== \"production\" ? Collapse.propTypes /* remove-proptypes */ = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the d.ts file and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * Add a custom transition end trigger. Called with the transitioning DOM\n * node and a done callback. Allows for more fine grained transition end\n * logic. Note: Timeouts are still used as a fallback if provided.\n */\n addEndListener: PropTypes.func,\n /**\n * The content node to be collapsed.\n */\n children: PropTypes.node,\n /**\n * Override or extend the styles applied to the component.\n */\n classes: PropTypes.object,\n /**\n * @ignore\n */\n className: PropTypes.string,\n /**\n * The width (horizontal) or height (vertical) of the container when collapsed.\n * @default '0px'\n */\n collapsedSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n /**\n * The component used for the root node.\n * Either a string to use a HTML element or a component.\n */\n component: elementTypeAcceptingRef,\n /**\n * The transition timing function.\n * You may specify a single easing or a object containing enter and exit values.\n */\n easing: PropTypes.oneOfType([PropTypes.shape({\n enter: PropTypes.string,\n exit: PropTypes.string\n }), PropTypes.string]),\n /**\n * If `true`, the component will transition in.\n */\n in: PropTypes.bool,\n /**\n * @ignore\n */\n onEnter: PropTypes.func,\n /**\n * @ignore\n */\n onEntered: PropTypes.func,\n /**\n * @ignore\n */\n onEntering: PropTypes.func,\n /**\n * @ignore\n */\n onExit: PropTypes.func,\n /**\n * @ignore\n */\n onExited: PropTypes.func,\n /**\n * @ignore\n */\n onExiting: PropTypes.func,\n /**\n * The transition orientation.\n * @default 'vertical'\n */\n orientation: PropTypes.oneOf(['horizontal', 'vertical']),\n /**\n * @ignore\n */\n style: PropTypes.object,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n /**\n * The duration for the transition, in milliseconds.\n * You may specify a single timeout for all transitions, or individually with an object.\n *\n * Set to 'auto' to automatically calculate transition time based on height.\n * @default duration.standard\n */\n timeout: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.shape({\n appear: PropTypes.number,\n enter: PropTypes.number,\n exit: PropTypes.number\n })])\n} : void 0;\nCollapse.muiSupportAuto = true;\nexport default Collapse;", "export { default } from './Collapse';\nexport { default as collapseClasses } from './collapseClasses';\nexport * from './collapseClasses';", "import { unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nimport generateUtilityClass from '../generateUtilityClass';\nexport function getPaperUtilityClass(slot) {\n return generateUtilityClass('MuiPaper', slot);\n}\nconst paperClasses = generateUtilityClasses('MuiPaper', ['root', 'rounded', 'outlined', 'elevation', 'elevation0', 'elevation1', 'elevation2', 'elevation3', 'elevation4', 'elevation5', 'elevation6', 'elevation7', 'elevation8', 'elevation9', 'elevation10', 'elevation11', 'elevation12', 'elevation13', 'elevation14', 'elevation15', 'elevation16', 'elevation17', 'elevation18', 'elevation19', 'elevation20', 'elevation21', 'elevation22', 'elevation23', 'elevation24']);\nexport default paperClasses;", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"className\", \"component\", \"elevation\", \"square\", \"variant\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport { chainPropTypes, integerPropType } from '@mui/utils';\nimport { unstable_composeClasses as composeClasses } from '@mui/base';\nimport { alpha } from '@mui/system';\nimport styled from '../styles/styled';\nimport getOverlayAlpha from '../styles/getOverlayAlpha';\nimport useThemeProps from '../styles/useThemeProps';\nimport useTheme from '../styles/useTheme';\nimport { getPaperUtilityClass } from './paperClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n square,\n elevation,\n variant,\n classes\n } = ownerState;\n const slots = {\n root: ['root', variant, !square && 'rounded', variant === 'elevation' && `elevation${elevation}`]\n };\n return composeClasses(slots, getPaperUtilityClass, classes);\n};\nconst PaperRoot = styled('div', {\n name: 'MuiPaper',\n slot: 'Root',\n overridesResolver: (props, styles) => {\n const {\n ownerState\n } = props;\n return [styles.root, styles[ownerState.variant], !ownerState.square && styles.rounded, ownerState.variant === 'elevation' && styles[`elevation${ownerState.elevation}`]];\n }\n})(({\n theme,\n ownerState\n}) => {\n var _theme$vars$overlays;\n return _extends({\n backgroundColor: (theme.vars || theme).palette.background.paper,\n color: (theme.vars || theme).palette.text.primary,\n transition: theme.transitions.create('box-shadow')\n }, !ownerState.square && {\n borderRadius: theme.shape.borderRadius\n }, ownerState.variant === 'outlined' && {\n border: `1px solid ${(theme.vars || theme).palette.divider}`\n }, ownerState.variant === 'elevation' && _extends({\n boxShadow: (theme.vars || theme).shadows[ownerState.elevation]\n }, !theme.vars && theme.palette.mode === 'dark' && {\n backgroundImage: `linear-gradient(${alpha('#fff', getOverlayAlpha(ownerState.elevation))}, ${alpha('#fff', getOverlayAlpha(ownerState.elevation))})`\n }, theme.vars && {\n backgroundImage: (_theme$vars$overlays = theme.vars.overlays) == null ? void 0 : _theme$vars$overlays[ownerState.elevation]\n }));\n});\nconst Paper = /*#__PURE__*/React.forwardRef(function Paper(inProps, ref) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPaper'\n });\n const {\n className,\n component = 'div',\n elevation = 1,\n square = false,\n variant = 'elevation'\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const ownerState = _extends({}, props, {\n component,\n elevation,\n square,\n variant\n });\n const classes = useUtilityClasses(ownerState);\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const theme = useTheme();\n if (theme.shadows[elevation] === undefined) {\n console.error([`MUI: The elevation provided is not available in the theme.`, `Please make sure that \\`theme.shadows[${elevation}]\\` is defined.`].join('\\n'));\n }\n }\n return /*#__PURE__*/_jsx(PaperRoot, _extends({\n as: component,\n ownerState: ownerState,\n className: clsx(classes.root, className),\n ref: ref\n }, other));\n});\nprocess.env.NODE_ENV !== \"production\" ? Paper.propTypes /* remove-proptypes */ = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the d.ts file and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * The content of the component.\n */\n children: PropTypes.node,\n /**\n * Override or extend the styles applied to the component.\n */\n classes: PropTypes.object,\n /**\n * @ignore\n */\n className: PropTypes.string,\n /**\n * The component used for the root node.\n * Either a string to use a HTML element or a component.\n */\n component: PropTypes.elementType,\n /**\n * Shadow depth, corresponds to `dp` in the spec.\n * It accepts values between 0 and 24 inclusive.\n * @default 1\n */\n elevation: chainPropTypes(integerPropType, props => {\n const {\n elevation,\n variant\n } = props;\n if (elevation > 0 && variant === 'outlined') {\n return new Error(`MUI: Combining \\`elevation={${elevation}}\\` with \\`variant=\"${variant}\"\\` has no effect. Either use \\`elevation={0}\\` or use a different \\`variant\\`.`);\n }\n return null;\n }),\n /**\n * If `true`, rounded corners are disabled.\n * @default false\n */\n square: PropTypes.bool,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n /**\n * The variant to use.\n * @default 'elevation'\n */\n variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['elevation', 'outlined']), PropTypes.string])\n} : void 0;\nexport default Paper;", "export { default } from './Paper';\nexport { default as paperClasses } from './paperClasses';\nexport * from './paperClasses';", "import { unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nimport generateUtilityClass from '../generateUtilityClass';\nexport function getAccordionUtilityClass(slot) {\n return generateUtilityClass('MuiAccordion', slot);\n}\nconst accordionClasses = generateUtilityClasses('MuiAccordion', ['root', 'rounded', 'expanded', 'disabled', 'gutters', 'region']);\nexport default accordionClasses;", "export { default } from './Accordion';\nexport { default as accordionClasses } from './accordionClasses';\nexport * from './accordionClasses';", "import { unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nimport generateUtilityClass from '../generateUtilityClass';\nexport function getAccordionActionsUtilityClass(slot) {\n return generateUtilityClass('MuiAccordionActions', slot);\n}\nconst accordionActionsClasses = generateUtilityClasses('MuiAccordionActions', ['root', 'spacing']);\nexport default accordionActionsClasses;", "export { default } from './AccordionActions';\nexport { default as accordionActionsClasses } from './accordionActionsClasses';\nexport * from './accordionActionsClasses';", "import { unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nimport generateUtilityClass from '../generateUtilityClass';\nexport function getAccordionDetailsUtilityClass(slot) {\n return generateUtilityClass('MuiAccordionDetails', slot);\n}\nconst accordionDetailsClasses = generateUtilityClasses('MuiAccordionDetails', ['root']);\nexport default accordionDetailsClasses;", "export { default } from './AccordionDetails';\nexport { default as accordionDetailsClasses } from './accordionDetailsClasses';\nexport * from './accordionDetailsClasses';", "import * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\n\n/**\n * @ignore - internal component.\n */\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nfunction Ripple(props) {\n const {\n className,\n classes,\n pulsate = false,\n rippleX,\n rippleY,\n rippleSize,\n in: inProp,\n onExited,\n timeout\n } = props;\n const [leaving, setLeaving] = React.useState(false);\n const rippleClassName = clsx(className, classes.ripple, classes.rippleVisible, pulsate && classes.ripplePulsate);\n const rippleStyles = {\n width: rippleSize,\n height: rippleSize,\n top: -(rippleSize / 2) + rippleY,\n left: -(rippleSize / 2) + rippleX\n };\n const childClassName = clsx(classes.child, leaving && classes.childLeaving, pulsate && classes.childPulsate);\n if (!inProp && !leaving) {\n setLeaving(true);\n }\n React.useEffect(() => {\n if (!inProp && onExited != null) {\n // react-transition-group#onExited\n const timeoutId = setTimeout(onExited, timeout);\n return () => {\n clearTimeout(timeoutId);\n };\n }\n return undefined;\n }, [onExited, inProp, timeout]);\n return /*#__PURE__*/_jsx(\"span\", {\n className: rippleClassName,\n style: rippleStyles,\n children: /*#__PURE__*/_jsx(\"span\", {\n className: childClassName\n })\n });\n}\nprocess.env.NODE_ENV !== \"production\" ? Ripple.propTypes = {\n /**\n * Override or extend the styles applied to the component.\n * See [CSS API](#css) below for more details.\n */\n classes: PropTypes.object.isRequired,\n className: PropTypes.string,\n /**\n * @ignore - injected from TransitionGroup\n */\n in: PropTypes.bool,\n /**\n * @ignore - injected from TransitionGroup\n */\n onExited: PropTypes.func,\n /**\n * If `true`, the ripple pulsates, typically indicating the keyboard focus state of an element.\n */\n pulsate: PropTypes.bool,\n /**\n * Diameter of the ripple.\n */\n rippleSize: PropTypes.number,\n /**\n * Horizontal position of the ripple center.\n */\n rippleX: PropTypes.number,\n /**\n * Vertical position of the ripple center.\n */\n rippleY: PropTypes.number,\n /**\n * exit delay\n */\n timeout: PropTypes.number.isRequired\n} : void 0;\nexport default Ripple;", "import { unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nimport generateUtilityClass from '../generateUtilityClass';\nexport function getTouchRippleUtilityClass(slot) {\n return generateUtilityClass('MuiTouchRipple', slot);\n}\nconst touchRippleClasses = generateUtilityClasses('MuiTouchRipple', ['root', 'ripple', 'rippleVisible', 'ripplePulsate', 'child', 'childLeaving', 'childPulsate']);\nexport default touchRippleClasses;", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"center\", \"classes\", \"className\"];\nlet _ = t => t,\n _t,\n _t2,\n _t3,\n _t4;\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport { TransitionGroup } from 'react-transition-group';\nimport clsx from 'clsx';\nimport { keyframes } from '@mui/system';\nimport styled from '../styles/styled';\nimport useThemeProps from '../styles/useThemeProps';\nimport Ripple from './Ripple';\nimport touchRippleClasses from './touchRippleClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst DURATION = 550;\nexport const DELAY_RIPPLE = 80;\nconst enterKeyframe = keyframes(_t || (_t = _`\n 0% {\n transform: scale(0);\n opacity: 0.1;\n }\n\n 100% {\n transform: scale(1);\n opacity: 0.3;\n }\n`));\nconst exitKeyframe = keyframes(_t2 || (_t2 = _`\n 0% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n }\n`));\nconst pulsateKeyframe = keyframes(_t3 || (_t3 = _`\n 0% {\n transform: scale(1);\n }\n\n 50% {\n transform: scale(0.92);\n }\n\n 100% {\n transform: scale(1);\n }\n`));\nexport const TouchRippleRoot = styled('span', {\n name: 'MuiTouchRipple',\n slot: 'Root'\n})({\n overflow: 'hidden',\n pointerEvents: 'none',\n position: 'absolute',\n zIndex: 0,\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n borderRadius: 'inherit'\n});\n\n// This `styled()` function invokes keyframes. `styled-components` only supports keyframes\n// in string templates. Do not convert these styles in JS object as it will break.\nexport const TouchRippleRipple = styled(Ripple, {\n name: 'MuiTouchRipple',\n slot: 'Ripple'\n})(_t4 || (_t4 = _`\n opacity: 0;\n position: absolute;\n\n &.${0} {\n opacity: 0.3;\n transform: scale(1);\n animation-name: ${0};\n animation-duration: ${0}ms;\n animation-timing-function: ${0};\n }\n\n &.${0} {\n animation-duration: ${0}ms;\n }\n\n & .${0} {\n opacity: 1;\n display: block;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background-color: currentColor;\n }\n\n & .${0} {\n opacity: 0;\n animation-name: ${0};\n animation-duration: ${0}ms;\n animation-timing-function: ${0};\n }\n\n & .${0} {\n position: absolute;\n /* @noflip */\n left: 0px;\n top: 0;\n animation-name: ${0};\n animation-duration: 2500ms;\n animation-timing-function: ${0};\n animation-iteration-count: infinite;\n animation-delay: 200ms;\n }\n`), touchRippleClasses.rippleVisible, enterKeyframe, DURATION, ({\n theme\n}) => theme.transitions.easing.easeInOut, touchRippleClasses.ripplePulsate, ({\n theme\n}) => theme.transitions.duration.shorter, touchRippleClasses.child, touchRippleClasses.childLeaving, exitKeyframe, DURATION, ({\n theme\n}) => theme.transitions.easing.easeInOut, touchRippleClasses.childPulsate, pulsateKeyframe, ({\n theme\n}) => theme.transitions.easing.easeInOut);\n\n/**\n * @ignore - internal component.\n *\n * TODO v5: Make private\n */\nconst TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps, ref) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiTouchRipple'\n });\n const {\n center: centerProp = false,\n classes = {},\n className\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const [ripples, setRipples] = React.useState([]);\n const nextKey = React.useRef(0);\n const rippleCallback = React.useRef(null);\n React.useEffect(() => {\n if (rippleCallback.current) {\n rippleCallback.current();\n rippleCallback.current = null;\n }\n }, [ripples]);\n\n // Used to filter out mouse emulated events on mobile.\n const ignoringMouseDown = React.useRef(false);\n // We use a timer in order to only show the ripples for touch \"click\" like events.\n // We don't want to display the ripple for touch scroll events.\n const startTimer = React.useRef(0);\n\n // This is the hook called once the previous timeout is ready.\n const startTimerCommit = React.useRef(null);\n const container = React.useRef(null);\n React.useEffect(() => {\n return () => {\n if (startTimer.current) {\n clearTimeout(startTimer.current);\n }\n };\n }, []);\n const startCommit = React.useCallback(params => {\n const {\n pulsate,\n rippleX,\n rippleY,\n rippleSize,\n cb\n } = params;\n setRipples(oldRipples => [...oldRipples, /*#__PURE__*/_jsx(TouchRippleRipple, {\n classes: {\n ripple: clsx(classes.ripple, touchRippleClasses.ripple),\n rippleVisible: clsx(classes.rippleVisible, touchRippleClasses.rippleVisible),\n ripplePulsate: clsx(classes.ripplePulsate, touchRippleClasses.ripplePulsate),\n child: clsx(classes.child, touchRippleClasses.child),\n childLeaving: clsx(classes.childLeaving, touchRippleClasses.childLeaving),\n childPulsate: clsx(classes.childPulsate, touchRippleClasses.childPulsate)\n },\n timeout: DURATION,\n pulsate: pulsate,\n rippleX: rippleX,\n rippleY: rippleY,\n rippleSize: rippleSize\n }, nextKey.current)]);\n nextKey.current += 1;\n rippleCallback.current = cb;\n }, [classes]);\n const start = React.useCallback((event = {}, options = {}, cb = () => {}) => {\n const {\n pulsate = false,\n center = centerProp || options.pulsate,\n fakeElement = false // For test purposes\n } = options;\n if ((event == null ? void 0 : event.type) === 'mousedown' && ignoringMouseDown.current) {\n ignoringMouseDown.current = false;\n return;\n }\n if ((event == null ? void 0 : event.type) === 'touchstart') {\n ignoringMouseDown.current = true;\n }\n const element = fakeElement ? null : container.current;\n const rect = element ? element.getBoundingClientRect() : {\n width: 0,\n height: 0,\n left: 0,\n top: 0\n };\n\n // Get the size of the ripple\n let rippleX;\n let rippleY;\n let rippleSize;\n if (center || event === undefined || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {\n rippleX = Math.round(rect.width / 2);\n rippleY = Math.round(rect.height / 2);\n } else {\n const {\n clientX,\n clientY\n } = event.touches && event.touches.length > 0 ? event.touches[0] : event;\n rippleX = Math.round(clientX - rect.left);\n rippleY = Math.round(clientY - rect.top);\n }\n if (center) {\n rippleSize = Math.sqrt((2 * rect.width ** 2 + rect.height ** 2) / 3);\n\n // For some reason the animation is broken on Mobile Chrome if the size is even.\n if (rippleSize % 2 === 0) {\n rippleSize += 1;\n }\n } else {\n const sizeX = Math.max(Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;\n const sizeY = Math.max(Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;\n rippleSize = Math.sqrt(sizeX ** 2 + sizeY ** 2);\n }\n\n // Touche devices\n if (event != null && event.touches) {\n // check that this isn't another touchstart due to multitouch\n // otherwise we will only clear a single timer when unmounting while two\n // are running\n if (startTimerCommit.current === null) {\n // Prepare the ripple effect.\n startTimerCommit.current = () => {\n startCommit({\n pulsate,\n rippleX,\n rippleY,\n rippleSize,\n cb\n });\n };\n // Delay the execution of the ripple effect.\n startTimer.current = setTimeout(() => {\n if (startTimerCommit.current) {\n startTimerCommit.current();\n startTimerCommit.current = null;\n }\n }, DELAY_RIPPLE); // We have to make a tradeoff with this value.\n }\n } else {\n startCommit({\n pulsate,\n rippleX,\n rippleY,\n rippleSize,\n cb\n });\n }\n }, [centerProp, startCommit]);\n const pulsate = React.useCallback(() => {\n start({}, {\n pulsate: true\n });\n }, [start]);\n const stop = React.useCallback((event, cb) => {\n clearTimeout(startTimer.current);\n\n // The touch interaction occurs too quickly.\n // We still want to show ripple effect.\n if ((event == null ? void 0 : event.type) === 'touchend' && startTimerCommit.current) {\n startTimerCommit.current();\n startTimerCommit.current = null;\n startTimer.current = setTimeout(() => {\n stop(event, cb);\n });\n return;\n }\n startTimerCommit.current = null;\n setRipples(oldRipples => {\n if (oldRipples.length > 0) {\n return oldRipples.slice(1);\n }\n return oldRipples;\n });\n rippleCallback.current = cb;\n }, []);\n React.useImperativeHandle(ref, () => ({\n pulsate,\n start,\n stop\n }), [pulsate, start, stop]);\n return /*#__PURE__*/_jsx(TouchRippleRoot, _extends({\n className: clsx(touchRippleClasses.root, classes.root, className),\n ref: container\n }, other, {\n children: /*#__PURE__*/_jsx(TransitionGroup, {\n component: null,\n exit: true,\n children: ripples\n })\n }));\n});\nprocess.env.NODE_ENV !== \"production\" ? TouchRipple.propTypes = {\n /**\n * If `true`, the ripple starts at the center of the component\n * rather than at the point of interaction.\n */\n center: PropTypes.bool,\n /**\n * Override or extend the styles applied to the component.\n * See [CSS API](#css) below for more details.\n */\n classes: PropTypes.object,\n /**\n * @ignore\n */\n className: PropTypes.string\n} : void 0;\nexport default TouchRipple;", "import { unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nimport generateUtilityClass from '../generateUtilityClass';\nexport function getButtonBaseUtilityClass(slot) {\n return generateUtilityClass('MuiButtonBase', slot);\n}\nconst buttonBaseClasses = generateUtilityClasses('MuiButtonBase', ['root', 'disabled', 'focusVisible']);\nexport default buttonBaseClasses;", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"action\", \"centerRipple\", \"children\", \"className\", \"component\", \"disabled\", \"disableRipple\", \"disableTouchRipple\", \"focusRipple\", \"focusVisibleClassName\", \"LinkComponent\", \"onBlur\", \"onClick\", \"onContextMenu\", \"onDragLeave\", \"onFocus\", \"onFocusVisible\", \"onKeyDown\", \"onKeyUp\", \"onMouseDown\", \"onMouseLeave\", \"onMouseUp\", \"onTouchEnd\", \"onTouchMove\", \"onTouchStart\", \"tabIndex\", \"TouchRippleProps\", \"touchRippleRef\", \"type\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport { elementTypeAcceptingRef, refType } from '@mui/utils';\nimport composeClasses from '@mui/base/composeClasses';\nimport styled from '../styles/styled';\nimport useThemeProps from '../styles/useThemeProps';\nimport useForkRef from '../utils/useForkRef';\nimport useEventCallback from '../utils/useEventCallback';\nimport useIsFocusVisible from '../utils/useIsFocusVisible';\nimport TouchRipple from './TouchRipple';\nimport buttonBaseClasses, { getButtonBaseUtilityClass } from './buttonBaseClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nimport { jsxs as _jsxs } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n disabled,\n focusVisible,\n focusVisibleClassName,\n classes\n } = ownerState;\n const slots = {\n root: ['root', disabled && 'disabled', focusVisible && 'focusVisible']\n };\n const composedClasses = composeClasses(slots, getButtonBaseUtilityClass, classes);\n if (focusVisible && focusVisibleClassName) {\n composedClasses.root += ` ${focusVisibleClassName}`;\n }\n return composedClasses;\n};\nexport const ButtonBaseRoot = styled('button', {\n name: 'MuiButtonBase',\n slot: 'Root',\n overridesResolver: (props, styles) => styles.root\n})({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n WebkitTapHighlightColor: 'transparent',\n backgroundColor: 'transparent',\n // Reset default value\n // We disable the focus ring for mouse, touch and keyboard users.\n outline: 0,\n border: 0,\n margin: 0,\n // Remove the margin in Safari\n borderRadius: 0,\n padding: 0,\n // Remove the padding in Firefox\n cursor: 'pointer',\n userSelect: 'none',\n verticalAlign: 'middle',\n MozAppearance: 'none',\n // Reset\n WebkitAppearance: 'none',\n // Reset\n textDecoration: 'none',\n // So we take precedent over the style of a native element.\n color: 'inherit',\n '&::-moz-focus-inner': {\n borderStyle: 'none' // Remove Firefox dotted outline.\n },\n\n [`&.${buttonBaseClasses.disabled}`]: {\n pointerEvents: 'none',\n // Disable link interactions\n cursor: 'default'\n },\n '@media print': {\n colorAdjust: 'exact'\n }\n});\n\n/**\n * `ButtonBase` contains as few styles as possible.\n * It aims to be a simple building block for creating a button.\n * It contains a load of style reset and some focus/ripple logic.\n */\nconst ButtonBase = /*#__PURE__*/React.forwardRef(function ButtonBase(inProps, ref) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiButtonBase'\n });\n const {\n action,\n centerRipple = false,\n children,\n className,\n component = 'button',\n disabled = false,\n disableRipple = false,\n disableTouchRipple = false,\n focusRipple = false,\n LinkComponent = 'a',\n onBlur,\n onClick,\n onContextMenu,\n onDragLeave,\n onFocus,\n onFocusVisible,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n onMouseLeave,\n onMouseUp,\n onTouchEnd,\n onTouchMove,\n onTouchStart,\n tabIndex = 0,\n TouchRippleProps,\n touchRippleRef,\n type\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const buttonRef = React.useRef(null);\n const rippleRef = React.useRef(null);\n const handleRippleRef = useForkRef(rippleRef, touchRippleRef);\n const {\n isFocusVisibleRef,\n onFocus: handleFocusVisible,\n onBlur: handleBlurVisible,\n ref: focusVisibleRef\n } = useIsFocusVisible();\n const [focusVisible, setFocusVisible] = React.useState(false);\n if (disabled && focusVisible) {\n setFocusVisible(false);\n }\n React.useImperativeHandle(action, () => ({\n focusVisible: () => {\n setFocusVisible(true);\n buttonRef.current.focus();\n }\n }), []);\n const [mountedState, setMountedState] = React.useState(false);\n React.useEffect(() => {\n setMountedState(true);\n }, []);\n const enableTouchRipple = mountedState && !disableRipple && !disabled;\n React.useEffect(() => {\n if (focusVisible && focusRipple && !disableRipple && mountedState) {\n rippleRef.current.pulsate();\n }\n }, [disableRipple, focusRipple, focusVisible, mountedState]);\n function useRippleHandler(rippleAction, eventCallback, skipRippleAction = disableTouchRipple) {\n return useEventCallback(event => {\n if (eventCallback) {\n eventCallback(event);\n }\n const ignore = skipRippleAction;\n if (!ignore && rippleRef.current) {\n rippleRef.current[rippleAction](event);\n }\n return true;\n });\n }\n const handleMouseDown = useRippleHandler('start', onMouseDown);\n const handleContextMenu = useRippleHandler('stop', onContextMenu);\n const handleDragLeave = useRippleHandler('stop', onDragLeave);\n const handleMouseUp = useRippleHandler('stop', onMouseUp);\n const handleMouseLeave = useRippleHandler('stop', event => {\n if (focusVisible) {\n event.preventDefault();\n }\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n });\n const handleTouchStart = useRippleHandler('start', onTouchStart);\n const handleTouchEnd = useRippleHandler('stop', onTouchEnd);\n const handleTouchMove = useRippleHandler('stop', onTouchMove);\n const handleBlur = useRippleHandler('stop', event => {\n handleBlurVisible(event);\n if (isFocusVisibleRef.current === false) {\n setFocusVisible(false);\n }\n if (onBlur) {\n onBlur(event);\n }\n }, false);\n const handleFocus = useEventCallback(event => {\n // Fix for https://github.com/facebook/react/issues/7769\n if (!buttonRef.current) {\n buttonRef.current = event.currentTarget;\n }\n handleFocusVisible(event);\n if (isFocusVisibleRef.current === true) {\n setFocusVisible(true);\n if (onFocusVisible) {\n onFocusVisible(event);\n }\n }\n if (onFocus) {\n onFocus(event);\n }\n });\n const isNonNativeButton = () => {\n const button = buttonRef.current;\n return component && component !== 'button' && !(button.tagName === 'A' && button.href);\n };\n\n /**\n * IE11 shim for https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat\n */\n const keydownRef = React.useRef(false);\n const handleKeyDown = useEventCallback(event => {\n // Check if key is already down to avoid repeats being counted as multiple activations\n if (focusRipple && !keydownRef.current && focusVisible && rippleRef.current && event.key === ' ') {\n keydownRef.current = true;\n rippleRef.current.stop(event, () => {\n rippleRef.current.start(event);\n });\n }\n if (event.target === event.currentTarget && isNonNativeButton() && event.key === ' ') {\n event.preventDefault();\n }\n if (onKeyDown) {\n onKeyDown(event);\n }\n\n // Keyboard accessibility for non interactive elements\n if (event.target === event.currentTarget && isNonNativeButton() && event.key === 'Enter' && !disabled) {\n event.preventDefault();\n if (onClick) {\n onClick(event);\n }\n }\n });\n const handleKeyUp = useEventCallback(event => {\n // calling preventDefault in keyUp on a \n * )\n * }\n * ```\n */\nexport const useTiptap = () => useContext(TiptapContext)\n\n/**\n * Select a slice of the editor state using the context-provided editor.\n *\n * This is a thin wrapper around `useEditorState` that reads the `editor`\n * instance from `useTiptap()` so callers don't have to pass it manually.\n *\n * @typeParam TSelectorResult - The type returned by the selector.\n * @param selector - Function that receives the editor state snapshot and\n * returns the piece of state you want to subscribe to.\n * @param equalityFn - Optional function to compare previous/next selected\n * values and avoid unnecessary updates.\n * @returns The selected slice of the editor state.\n *\n * @example\n * ```tsx\n * function WordCount() {\n * const wordCount = useTiptapState(state => {\n * const text = state.editor.state.doc.textContent\n * return text.split(/\\s+/).filter(Boolean).length\n * })\n *\n * return {wordCount} words\n * }\n * ```\n */\nexport function useTiptapState(\n selector: (context: EditorStateSnapshot) => TSelectorResult,\n equalityFn?: (a: TSelectorResult, b: TSelectorResult | null) => boolean,\n) {\n const { editor } = useTiptap()\n\n return useEditorState({\n editor,\n selector,\n equalityFn,\n })\n}\n\n/**\n * Props for the `Tiptap` root/provider component.\n */\nexport type TiptapWrapperProps = {\n /**\n * The editor instance to provide to child components.\n * Use `useEditor()` to create this instance.\n */\n editor?: Editor\n\n /**\n * @deprecated Use `editor` instead. Will be removed in the next major version.\n */\n instance?: Editor\n\n children: ReactNode\n}\n\n/**\n * Top-level provider component that makes the editor instance available via\n * React context to all child components.\n *\n * This component also provides backwards compatibility with the legacy\n * `EditorContext`, so components using `useCurrentEditor()` will work\n * inside a `` provider.\n *\n * @param props - Component props.\n * @returns A context provider element wrapping `children`.\n *\n * @example\n * ```tsx\n * import { Tiptap, useEditor } from '@tiptap/react'\n *\n * function App() {\n * const editor = useEditor({ extensions: [...] })\n *\n * return (\n * \n * \n * \n * \n * )\n * }\n * ```\n */\nexport function TiptapWrapper({ editor, instance, children }: TiptapWrapperProps) {\n const resolvedEditor = editor ?? instance\n\n if (!resolvedEditor) {\n throw new Error('Tiptap: An editor instance is required. Pass a non-null `editor` prop.')\n }\n\n const tiptapContextValue = useMemo(() => ({ editor: resolvedEditor }), [resolvedEditor])\n\n // Provide backwards compatibility with the legacy EditorContext\n // so components using useCurrentEditor() work inside \n const legacyContextValue = useMemo(() => ({ editor: resolvedEditor }), [resolvedEditor])\n\n return (\n \n {children}\n \n )\n}\n\nTiptapWrapper.displayName = 'Tiptap'\n\n/**\n * Convenience component that renders `EditorContent` using the context-provided\n * editor instance. Use this instead of manually passing the `editor` prop.\n *\n * @param props - All `EditorContent` props except `editor` and `ref`.\n * @returns An `EditorContent` element bound to the context editor.\n *\n * @example\n * ```tsx\n * // inside a Tiptap provider\n * \n * ```\n */\nexport function TiptapContent({ ...rest }: Omit) {\n const { editor } = useTiptap()\n\n return \n}\n\nTiptapContent.displayName = 'Tiptap.Content'\n\n/**\n * Root `Tiptap` component. Use it as the provider for all child components.\n *\n * The exported object includes the `Content` subcomponent for rendering the\n * editor content area.\n *\n * This component provides both the new `TiptapContext` (accessed via `useTiptap()`)\n * and the legacy `EditorContext` (accessed via `useCurrentEditor()`) for\n * backwards compatibility.\n *\n * For bubble menus and floating menus, import them separately from\n * `@tiptap/react/menus` to keep floating-ui as an optional dependency.\n *\n * @example\n * ```tsx\n * import { Tiptap, useEditor } from '@tiptap/react'\n * import { BubbleMenu } from '@tiptap/react/menus'\n *\n * function App() {\n * const editor = useEditor({ extensions: [...] })\n *\n * return (\n * \n * \n * \n * \n * \n * \n * )\n * }\n * ```\n */\nexport const Tiptap = Object.assign(TiptapWrapper, {\n /**\n * The Tiptap Content component that renders the EditorContent with the editor instance from the context.\n * @see TiptapContent\n */\n Content: TiptapContent,\n})\n\nexport default Tiptap\n", "export * from './Context.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './ReactMarkViewRenderer.js'\nexport * from './ReactNodeViewRenderer.js'\nexport * from './ReactRenderer.js'\nexport * from './Tiptap.js'\nexport * from './types.js'\nexport * from './useEditor.js'\nexport * from './useEditorState.js'\nexport * from './useReactNodeView.js'\nexport * from '@tiptap/core'\n", "export type Attributes = Record\n\nexport type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray\n/**\n * Better describes the output of a `renderHTML` function in prosemirror\n * @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec\n */\nexport type DOMOutputSpecArray =\n | [string]\n | [string, Attributes]\n | [string, 0]\n | [string, Attributes, 0]\n | [string, Attributes, DOMOutputSpecArray | 0]\n | [string, DOMOutputSpecArray]\n\n// Child lists and DOM output specs are both arrays, so track JSX boundaries by identity.\nconst jsxElements = new WeakSet()\nconst jsxFragments = new WeakSet()\n\n/** Create a new JSX element from the given spec */\nfunction createJSXElement(spec: unknown[]): DOMOutputSpecArray {\n const element = spec as DOMOutputSpecArray\n\n jsxElements.add(element)\n\n return element\n}\n\n/** Check if a spec is a JSX element */\nfunction isJSXElement(value: unknown): value is DOMOutputSpecArray {\n return Array.isArray(value) && jsxElements.has(value as DOMOutputSpecArray)\n}\n\nfunction flattenFragmentChildren(children: unknown[]): unknown[] {\n return children.flatMap(child => {\n if (child == null) {\n return []\n }\n\n if (Array.isArray(child) && jsxFragments.has(child) && !isJSXElement(child)) {\n return flattenFragmentChildren(child)\n }\n\n return [child]\n })\n}\n\n// JSX types for Tiptap's JSX runtime\n// These types only apply when using @jsxImportSource @tiptap/core\nexport declare namespace JSX {\n export type Element = DOMOutputSpecArray\n export interface IntrinsicElements {\n [key: string]: any\n }\n export interface ElementChildrenAttribute {\n children: unknown\n }\n}\n\ntype JSXChild = DOMOutputSpecElement | string | null | undefined | JSXChild[]\n\nexport type JSXRenderer = (\n tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement),\n props?: Attributes,\n ...children: JSXChild[]\n) => DOMOutputSpecArray | DOMOutputSpecElement\n\nexport function Fragment(props: { children: JSXChild[] }) {\n jsxFragments.add(props.children)\n\n return props.children\n}\n\nfunction render(tag: Parameters[0], attributes: Attributes | undefined) {\n // Treat the slot tag as the Prosemirror hole to render content into\n if (tag === 'slot') {\n return 0\n }\n\n // If the tag is a function, call it with the props\n if (tag instanceof Function) {\n const result = tag(attributes)\n\n if (Array.isArray(result) && !isJSXElement(result) && !jsxFragments.has(result)) {\n return createJSXElement(result)\n }\n\n return result\n }\n\n const { children, ...rest } = attributes ?? {}\n\n if (tag === 'svg') {\n throw new Error(\n 'SVG elements are not supported in the JSX syntax, use the array syntax instead',\n )\n }\n\n // Handle children array by spreading elements\n if (Array.isArray(children)) {\n if (isJSXElement(children)) {\n return createJSXElement([tag, rest, children])\n }\n\n if (children.length === 0) {\n // Empty array means no children\n return createJSXElement([tag, rest])\n }\n\n const flattenedChildren = flattenFragmentChildren(children)\n\n if (flattenedChildren.length === 0) {\n return createJSXElement([tag, rest])\n }\n\n // Spread children into the result array\n return createJSXElement([tag, rest, ...flattenedChildren])\n }\n\n // Single child or no children\n if (children !== undefined && children !== null) {\n return createJSXElement([tag, rest, children])\n }\n\n return createJSXElement([tag, rest])\n}\n\nexport const h: JSXRenderer = (tag, attributes) => render(tag, attributes)\n\nexport const jsxs: JSXRenderer = (tag, attributes) => render(tag, attributes)\n\nexport const jsxDEV = (\n tag: Parameters[0],\n attributes?: Attributes,\n _key?: unknown,\n _isStaticChildren?: boolean,\n) => {\n return render(tag, attributes)\n}\n\n// See\n// https://esbuild.github.io/api/#jsx-import-source\n// https://www.typescriptlang.org/tsconfig/#jsxImportSource\n\nexport { h as createElement, h as jsx }\n", "export * from '../dist/jsx-runtime/jsx-runtime.js'\n", "/** @jsxImportSource @tiptap/core */\nimport { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'\n\nexport interface BlockquoteOptions {\n /**\n * HTML attributes to add to the blockquote element\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n blockQuote: {\n /**\n * Set a blockquote node\n */\n setBlockquote: () => ReturnType\n /**\n * Toggle a blockquote node\n */\n toggleBlockquote: () => ReturnType\n /**\n * Unset a blockquote node\n */\n unsetBlockquote: () => ReturnType\n }\n }\n}\n\n/**\n * Matches a blockquote to a `>` as input.\n */\nexport const inputRegex = /^\\s*>\\s$/\n\n/**\n * This extension allows you to create blockquotes.\n * @see https://tiptap.dev/api/nodes/blockquote\n */\nexport const Blockquote = Node.create({\n name: 'blockquote',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n content: 'block+',\n\n group: 'block',\n\n defining: true,\n\n parseHTML() {\n return [{ tag: 'blockquote' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return (\n
\n \n
\n )\n },\n\n parseMarkdown: (token, helpers) => {\n return helpers.createNode('blockquote', undefined, helpers.parseChildren(token.tokens || []))\n },\n\n renderMarkdown: (node, h) => {\n if (!node.content) {\n return ''\n }\n\n // Use a single '>' prefix regardless of nesting level\n // Nested blockquotes will add their own '>' prefix recursively\n const prefix = '>'\n const result: string[] = []\n\n node.content.forEach(child => {\n // Render each child node as an array so it gets processed properly\n const childContent = h.renderChildren([child])\n const lines = childContent.split('\\n')\n\n const linesWithPrefix = lines.map(line => {\n // Don't add prefix to empty lines\n if (line.trim() === '') {\n return prefix\n }\n\n // Nested blockquotes will already have their own prefixes\n // We just need to add our own prefix at the start\n return `${prefix} ${line}`\n })\n\n result.push(linesWithPrefix.join('\\n'))\n })\n\n // Add separator lines between children\n return result.join(`\\n${prefix}\\n`)\n },\n\n addCommands() {\n return {\n setBlockquote:\n () =>\n ({ commands }) => {\n return commands.wrapIn(this.name)\n },\n toggleBlockquote:\n () =>\n ({ commands }) => {\n return commands.toggleWrap(this.name)\n },\n unsetBlockquote:\n () =>\n ({ commands }) => {\n return commands.lift(this.name)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Shift-b': () => this.editor.commands.toggleBlockquote(),\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: inputRegex,\n type: this.type,\n }),\n ]\n },\n})\n", "import { Blockquote } from './blockquote.jsx'\n\nexport * from './blockquote.jsx'\n\nexport default Blockquote\n", "/** @jsxImportSource @tiptap/core */\nimport { Mark, markInputRule, markPasteRule, mergeAttributes } from '@tiptap/core'\n\nexport interface BoldOptions {\n /**\n * HTML attributes to add to the bold element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n bold: {\n /**\n * Set a bold mark\n */\n setBold: () => ReturnType\n /**\n * Toggle a bold mark\n */\n toggleBold: () => ReturnType\n /**\n * Unset a bold mark\n */\n unsetBold: () => ReturnType\n }\n }\n}\n\n/**\n * Matches bold text via `**` as input.\n */\nexport const starInputRegex = /(?:^|\\s)(\\*\\*(?!\\s+\\*\\*)((?:[^*]+))\\*\\*(?!\\s+\\*\\*))$/\n\n/**\n * Matches bold text via `**` while pasting.\n */\nexport const starPasteRegex = /(?:^|\\s)(\\*\\*(?!\\s+\\*\\*)((?:[^*]+))\\*\\*(?!\\s+\\*\\*))/g\n\n/**\n * Matches bold text via `__` as input.\n */\nexport const underscoreInputRegex = /(?:^|\\s)(__(?!\\s+__)((?:[^_]+))__(?!\\s+__))$/\n\n/**\n * Matches bold text via `__` while pasting.\n */\nexport const underscorePasteRegex = /(?:^|\\s)(__(?!\\s+__)((?:[^_]+))__(?!\\s+__))/g\n\n/**\n * This extension allows you to mark text as bold.\n * @see https://tiptap.dev/api/marks/bold\n */\nexport const Bold = Mark.create({\n name: 'bold',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'strong',\n },\n {\n tag: 'b',\n getAttrs: node => (node as HTMLElement).style.fontWeight !== 'normal' && null,\n },\n {\n style: 'font-weight=400',\n clearMark: mark => mark.type.name === this.name,\n },\n {\n style: 'font-weight',\n getAttrs: value => /^(bold(er)?|[5-9]\\d{2,})$/.test(value as string) && null,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return (\n \n \n \n )\n },\n\n markdownTokenName: 'strong',\n\n parseMarkdown: (token, helpers) => {\n // Convert 'strong' token to bold mark\n return helpers.applyMark('bold', helpers.parseInline(token.tokens || []))\n },\n\n renderMarkdown: (node, h) => {\n return `**${h.renderChildren(node)}**`\n },\n\n addCommands() {\n return {\n setBold:\n () =>\n ({ commands }) => {\n return commands.setMark(this.name)\n },\n toggleBold:\n () =>\n ({ commands }) => {\n return commands.toggleMark(this.name)\n },\n unsetBold:\n () =>\n ({ commands }) => {\n return commands.unsetMark(this.name)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-b': () => this.editor.commands.toggleBold(),\n 'Mod-B': () => this.editor.commands.toggleBold(),\n }\n },\n\n addInputRules() {\n return [\n markInputRule({\n find: starInputRegex,\n type: this.type,\n }),\n markInputRule({\n find: underscoreInputRegex,\n type: this.type,\n }),\n ]\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: starPasteRegex,\n type: this.type,\n }),\n markPasteRule({\n find: underscorePasteRegex,\n type: this.type,\n }),\n ]\n },\n})\n", "import { Bold } from './bold.jsx'\n\nexport * from './bold.jsx'\n\nexport default Bold\n", "import { Mark, markInputRule, markPasteRule, mergeAttributes } from '@tiptap/core'\n\nexport interface CodeOptions {\n /**\n * The HTML attributes applied to the code element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n code: {\n /**\n * Set a code mark\n */\n setCode: () => ReturnType\n /**\n * Toggle inline code\n */\n toggleCode: () => ReturnType\n /**\n * Unset a code mark\n */\n unsetCode: () => ReturnType\n }\n }\n}\n\n/**\n * Regular expressions to match inline code blocks enclosed in backticks.\n * It matches:\n * - An opening backtick, followed by\n * - Any text that doesn't include a backtick (captured for marking), followed by\n * - A closing backtick as the final character.\n * This ensures that any text between backticks is formatted as code,\n * regardless of the surrounding characters (exception being another backtick).\n */\nexport const inputRegex = /(^|[^`])`([^`]+)`(?!`)$/\n\n/**\n * Matches inline code while pasting.\n */\nexport const pasteRegex = /(^|[^`])`([^`]+)`(?!`)/g\n\n/**\n * This extension allows you to mark text as inline code.\n * @see https://tiptap.dev/api/marks/code\n */\nexport const Code = Mark.create({\n name: 'code',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n excludes: '_',\n\n code: true,\n\n exitable: true,\n\n parseHTML() {\n return [{ tag: 'code' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['code', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n markdownTokenName: 'codespan',\n\n parseMarkdown: (token, helpers) => {\n // Convert 'codespan' token to code mark\n // For codespan tokens, we use the raw text content, not tokens\n return helpers.applyMark('code', [{ type: 'text', text: token.text || '' }])\n },\n\n renderMarkdown: (node, h) => {\n if (!node.content) {\n return ''\n }\n\n return `\\`${h.renderChildren(node.content)}\\``\n },\n\n addCommands() {\n return {\n setCode:\n () =>\n ({ commands }) => {\n return commands.setMark(this.name)\n },\n toggleCode:\n () =>\n ({ commands }) => {\n return commands.toggleMark(this.name)\n },\n unsetCode:\n () =>\n ({ commands }) => {\n return commands.unsetMark(this.name)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-e': () => this.editor.commands.toggleCode(),\n }\n },\n\n addInputRules() {\n return [\n markInputRule({\n find: inputRegex,\n type: this.type,\n }),\n ]\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: pasteRegex,\n type: this.type,\n }),\n ]\n },\n})\n", "import { Code } from './code.js'\n\nexport * from './code.js'\n\nexport default Code\n", "import { mergeAttributes, Node, textblockTypeInputRule } from '@tiptap/core'\nimport { Plugin, PluginKey, Selection, TextSelection } from '@tiptap/pm/state'\n\nconst DEFAULT_TAB_SIZE = 4\n\nexport interface CodeBlockOptions {\n /**\n * Adds a prefix to language classes that are applied to code tags.\n * @default 'language-'\n */\n languageClassPrefix: string | null | undefined\n /**\n * Define whether the node should be exited on triple enter.\n * @default true\n */\n exitOnTripleEnter: boolean | null | undefined\n /**\n * Define whether the node should be exited on arrow down if there is no node after it.\n * @default true\n */\n exitOnArrowDown: boolean | null | undefined\n /**\n * The default language.\n * @default null\n * @example 'js'\n */\n defaultLanguage: string | null | undefined\n /**\n * Enable tab key for indentation in code blocks.\n * @default false\n */\n enableTabIndentation: boolean | null | undefined\n /**\n * The number of spaces to use for tab indentation.\n * @default 4\n */\n tabSize: number | null | undefined\n /**\n * Custom HTML attributes that should be added to the rendered HTML tag.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n codeBlock: {\n /**\n * Set a code block\n * @param attributes Code block attributes\n * @example editor.commands.setCodeBlock({ language: 'javascript' })\n */\n setCodeBlock: (attributes?: { language: string }) => ReturnType\n /**\n * Toggle a code block\n * @param attributes Code block attributes\n * @example editor.commands.toggleCodeBlock({ language: 'javascript' })\n */\n toggleCodeBlock: (attributes?: { language: string }) => ReturnType\n }\n }\n}\n\n/**\n * Matches a code block with backticks.\n */\nexport const backtickInputRegex = /^```([a-z]+)?[\\s\\n]$/\n\n/**\n * Matches a code block with tildes.\n */\nexport const tildeInputRegex = /^~~~([a-z]+)?[\\s\\n]$/\n\n/**\n * This extension allows you to create code blocks.\n * @see https://tiptap.dev/api/nodes/code-block\n */\nexport const CodeBlock = Node.create({\n name: 'codeBlock',\n\n addOptions() {\n return {\n languageClassPrefix: 'language-',\n exitOnTripleEnter: true,\n exitOnArrowDown: true,\n defaultLanguage: null,\n enableTabIndentation: false,\n tabSize: DEFAULT_TAB_SIZE,\n HTMLAttributes: {},\n }\n },\n\n content: 'text*',\n\n marks: '',\n\n group: 'block',\n\n code: true,\n\n defining: true,\n\n addAttributes() {\n return {\n language: {\n default: this.options.defaultLanguage,\n parseHTML: element => {\n const { languageClassPrefix } = this.options\n\n if (!languageClassPrefix) {\n return null\n }\n\n const classNames = [...(element.firstElementChild?.classList || [])]\n const languages = classNames\n .filter(className => className.startsWith(languageClassPrefix))\n .map(className => className.replace(languageClassPrefix, ''))\n const language = languages[0]\n\n if (!language) {\n return null\n }\n\n return language\n },\n rendered: false,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'pre',\n preserveWhitespace: 'full',\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'pre',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n [\n 'code',\n {\n class: node.attrs.language ? this.options.languageClassPrefix + node.attrs.language : null,\n },\n 0,\n ],\n ]\n },\n\n markdownTokenName: 'code',\n\n parseMarkdown: (token, helpers) => {\n if (\n token.raw?.startsWith('```') === false &&\n token.raw?.startsWith('~~~') === false &&\n token.codeBlockStyle !== 'indented'\n ) {\n return []\n }\n\n return helpers.createNode(\n 'codeBlock',\n { language: token.lang || null },\n token.text ? [helpers.createTextNode(token.text)] : [],\n )\n },\n\n renderMarkdown: (node, h) => {\n let output = ''\n const language = node.attrs?.language || ''\n\n if (!node.content) {\n output = `\\`\\`\\`${language}\\n\\n\\`\\`\\``\n } else {\n const lines = [`\\`\\`\\`${language}`, h.renderChildren(node.content), '```']\n output = lines.join('\\n')\n }\n\n return output\n },\n\n addCommands() {\n return {\n setCodeBlock:\n attributes =>\n ({ commands }) => {\n return commands.setNode(this.name, attributes)\n },\n toggleCodeBlock:\n attributes =>\n ({ commands }) => {\n return commands.toggleNode(this.name, 'paragraph', attributes)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Alt-c': () => this.editor.commands.toggleCodeBlock(),\n\n // remove code block when at start of document or code block is empty\n Backspace: () => {\n const { empty, $anchor } = this.editor.state.selection\n const isAtStart = $anchor.pos === 1\n\n if (!empty || $anchor.parent.type.name !== this.name) {\n return false\n }\n\n if (isAtStart || !$anchor.parent.textContent.length) {\n return this.editor.commands.clearNodes()\n }\n\n return false\n },\n\n // handle tab indentation\n Tab: ({ editor }) => {\n if (!this.options.enableTabIndentation) {\n return false\n }\n\n const tabSize = this.options.tabSize ?? DEFAULT_TAB_SIZE\n const { state } = editor\n const { selection } = state\n const { $from, empty } = selection\n\n if ($from.parent.type !== this.type) {\n return false\n }\n\n const indent = ' '.repeat(tabSize)\n\n if (empty) {\n return editor.commands.insertContent(indent)\n }\n\n return editor.commands.command(({ tr }) => {\n const { from, to } = selection\n const text = state.doc.textBetween(from, to, '\\n', '\\n')\n const lines = text.split('\\n')\n const indentedText = lines.map(line => indent + line).join('\\n')\n\n tr.replaceWith(from, to, state.schema.text(indentedText))\n return true\n })\n },\n\n // handle shift+tab reverse indentation\n 'Shift-Tab': ({ editor }) => {\n if (!this.options.enableTabIndentation) {\n return false\n }\n\n const tabSize = this.options.tabSize ?? DEFAULT_TAB_SIZE\n const { state } = editor\n const { selection } = state\n const { $from, empty } = selection\n\n if ($from.parent.type !== this.type) {\n return false\n }\n\n if (empty) {\n return editor.commands.command(({ tr }) => {\n const { pos } = $from\n const codeBlockStart = $from.start()\n const codeBlockEnd = $from.end()\n\n const allText = state.doc.textBetween(codeBlockStart, codeBlockEnd, '\\n', '\\n')\n const lines = allText.split('\\n')\n\n let currentLineIndex = 0\n let charCount = 0\n const relativeCursorPos = pos - codeBlockStart\n\n for (let i = 0; i < lines.length; i += 1) {\n if (charCount + lines[i].length >= relativeCursorPos) {\n currentLineIndex = i\n break\n }\n charCount += lines[i].length + 1\n }\n\n const currentLine = lines[currentLineIndex]\n const leadingSpaces = currentLine.match(/^ */)?.[0] || ''\n const spacesToRemove = Math.min(leadingSpaces.length, tabSize)\n\n if (spacesToRemove === 0) {\n return true\n }\n\n let lineStartPos = codeBlockStart\n for (let i = 0; i < currentLineIndex; i += 1) {\n lineStartPos += lines[i].length + 1\n }\n\n tr.delete(lineStartPos, lineStartPos + spacesToRemove)\n\n const cursorPosInLine = pos - lineStartPos\n if (cursorPosInLine <= spacesToRemove) {\n tr.setSelection(TextSelection.create(tr.doc, lineStartPos))\n }\n\n return true\n })\n }\n\n return editor.commands.command(({ tr }) => {\n const { from, to } = selection\n const text = state.doc.textBetween(from, to, '\\n', '\\n')\n const lines = text.split('\\n')\n const reverseIndentText = lines\n .map(line => {\n const leadingSpaces = line.match(/^ */)?.[0] || ''\n const spacesToRemove = Math.min(leadingSpaces.length, tabSize)\n return line.slice(spacesToRemove)\n })\n .join('\\n')\n\n tr.replaceWith(from, to, state.schema.text(reverseIndentText))\n return true\n })\n },\n\n // exit node on triple enter\n Enter: ({ editor }) => {\n if (!this.options.exitOnTripleEnter) {\n return false\n }\n\n const { state } = editor\n const { selection } = state\n const { $from, empty } = selection\n\n if (!empty || $from.parent.type !== this.type) {\n return false\n }\n\n const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2\n const endsWithDoubleNewline = $from.parent.textContent.endsWith('\\n\\n')\n\n if (!isAtEnd || !endsWithDoubleNewline) {\n return false\n }\n\n return editor\n .chain()\n .command(({ tr }) => {\n tr.delete($from.pos - 2, $from.pos)\n\n return true\n })\n .exitCode()\n .run()\n },\n\n // exit node on arrow down\n ArrowDown: ({ editor }) => {\n if (!this.options.exitOnArrowDown) {\n return false\n }\n\n const { state } = editor\n const { selection, doc } = state\n const { $from, empty } = selection\n\n if (!empty || $from.parent.type !== this.type) {\n return false\n }\n\n const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2\n\n if (!isAtEnd) {\n return false\n }\n\n const after = $from.after()\n\n if (after === undefined) {\n return false\n }\n\n const nodeAfter = doc.nodeAt(after)\n\n if (nodeAfter) {\n return editor.commands.command(({ tr }) => {\n tr.setSelection(Selection.near(doc.resolve(after)))\n return true\n })\n }\n\n return editor.commands.exitCode()\n },\n }\n },\n\n addInputRules() {\n return [\n textblockTypeInputRule({\n find: backtickInputRegex,\n type: this.type,\n getAttributes: match => ({\n language: match[1],\n }),\n }),\n textblockTypeInputRule({\n find: tildeInputRegex,\n type: this.type,\n getAttributes: match => ({\n language: match[1],\n }),\n }),\n ]\n },\n\n addProseMirrorPlugins() {\n return [\n // this plugin creates a code block for pasted content from VS Code\n // we can also detect the copied code language\n new Plugin({\n key: new PluginKey('codeBlockVSCodeHandler'),\n props: {\n handlePaste: (view, event) => {\n if (!event.clipboardData) {\n return false\n }\n\n // don’t create a new code block within code blocks\n if (this.editor.isActive(this.type.name)) {\n return false\n }\n\n const text = event.clipboardData.getData('text/plain')\n const vscode = event.clipboardData.getData('vscode-editor-data')\n const vscodeData = vscode ? JSON.parse(vscode) : undefined\n const language = vscodeData?.mode\n\n if (!text || !language) {\n return false\n }\n\n const { tr, schema } = view.state\n\n // prepare a text node\n // strip carriage return chars from text pasted as code\n // see: https://github.com/ProseMirror/prosemirror-view/commit/a50a6bcceb4ce52ac8fcc6162488d8875613aacd\n const textNode = schema.text(text.replace(/\\r\\n?/g, '\\n'))\n\n // create a code block with the text node\n // replace selection with the code block\n tr.replaceSelectionWith(this.type.create({ language }, textNode))\n\n if (tr.selection.$from.parent.type !== this.type) {\n // put cursor inside the newly created code block\n tr.setSelection(TextSelection.near(tr.doc.resolve(Math.max(0, tr.selection.from - 2))))\n }\n\n // store meta information\n // this is useful for other plugins that depends on the paste event\n // like the paste rule plugin\n tr.setMeta('paste', true)\n\n view.dispatch(tr)\n\n return true\n },\n },\n }),\n ]\n },\n})\n", "import { CodeBlock } from './code-block.js'\n\nexport * from './code-block.js'\n\nexport default CodeBlock\n", "import { Node } from '@tiptap/core'\n\n/**\n * The default document node which represents the top level node of the editor.\n * @see https://tiptap.dev/api/nodes/document\n */\nexport const Document = Node.create({\n name: 'doc',\n topNode: true,\n content: 'block+',\n\n renderMarkdown: (node, h) => {\n if (!node.content) {\n return ''\n }\n\n return h.renderChildren(node.content, '\\n\\n')\n },\n})\n", "import { Document } from './document.js'\n\nexport * from './document.js'\n\nexport default Document\n", "import { mergeAttributes, Node } from '@tiptap/core'\n\nexport interface HardBreakOptions {\n /**\n * Controls if marks should be kept after being split by a hard break.\n * @default true\n * @example false\n */\n keepMarks: boolean\n\n /**\n * HTML attributes to add to the hard break element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n hardBreak: {\n /**\n * Add a hard break\n * @example editor.commands.setHardBreak()\n */\n setHardBreak: () => ReturnType\n }\n }\n}\n\n/**\n * This extension allows you to insert hard breaks.\n * @see https://www.tiptap.dev/api/nodes/hard-break\n */\nexport const HardBreak = Node.create({\n name: 'hardBreak',\n\n markdownTokenName: 'br',\n\n addOptions() {\n return {\n keepMarks: true,\n HTMLAttributes: {},\n }\n },\n\n inline: true,\n\n group: 'inline',\n\n selectable: false,\n\n linebreakReplacement: true,\n\n parseHTML() {\n return [{ tag: 'br' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['br', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)]\n },\n\n renderText() {\n return '\\n'\n },\n\n renderMarkdown: () => ` \\n`,\n\n parseMarkdown: () => {\n return {\n type: 'hardBreak',\n }\n },\n\n addCommands() {\n return {\n setHardBreak:\n () =>\n ({ commands, chain, state, editor }) => {\n return commands.first([\n () => commands.exitCode(),\n () =>\n commands.command(() => {\n const { selection, storedMarks } = state\n\n if (selection.$from.parent.type.spec.isolating) {\n return false\n }\n\n const { keepMarks } = this.options\n const { splittableMarks } = editor.extensionManager\n const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks())\n\n return chain()\n .insertContent({ type: this.name })\n .command(({ tr, dispatch }) => {\n if (dispatch && marks && keepMarks) {\n const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name))\n\n tr.ensureMarks(filteredMarks)\n }\n\n return true\n })\n .run()\n }),\n ])\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Enter': () => this.editor.commands.setHardBreak(),\n 'Shift-Enter': () => this.editor.commands.setHardBreak(),\n }\n },\n})\n", "import { HardBreak } from './hard-break.js'\n\nexport * from './hard-break.js'\n\nexport default HardBreak\n", "import { mergeAttributes, Node, textblockTypeInputRule } from '@tiptap/core'\n\n/**\n * The heading level options.\n */\nexport type Level = 1 | 2 | 3 | 4 | 5 | 6\n\nexport interface HeadingOptions {\n /**\n * The available heading levels.\n * @default [1, 2, 3, 4, 5, 6]\n * @example [1, 2, 3]\n */\n levels: Level[]\n\n /**\n * The HTML attributes for a heading node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n heading: {\n /**\n * Set a heading node\n * @param attributes The heading attributes\n * @example editor.commands.setHeading({ level: 1 })\n */\n setHeading: (attributes: { level: Level }) => ReturnType\n /**\n * Toggle a heading node\n * @param attributes The heading attributes\n * @example editor.commands.toggleHeading({ level: 1 })\n */\n toggleHeading: (attributes: { level: Level }) => ReturnType\n }\n }\n}\n\n/**\n * This extension allows you to create headings.\n * @see https://www.tiptap.dev/api/nodes/heading\n */\nexport const Heading = Node.create({\n name: 'heading',\n\n addOptions() {\n return {\n levels: [1, 2, 3, 4, 5, 6],\n HTMLAttributes: {},\n }\n },\n\n content: 'inline*',\n\n group: 'block',\n\n defining: true,\n\n addAttributes() {\n return {\n level: {\n default: 1,\n rendered: false,\n },\n }\n },\n\n parseHTML() {\n return this.options.levels.map((level: Level) => ({\n tag: `h${level}`,\n attrs: { level },\n }))\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const hasLevel = this.options.levels.includes(node.attrs.level)\n const level = hasLevel ? node.attrs.level : this.options.levels[0]\n\n return [`h${level}`, mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n parseMarkdown: (token, helpers) => {\n // Convert 'heading' token to heading node\n // marked provides 'depth' property (1-6) for heading level\n return helpers.createNode('heading', { level: token.depth || 1 }, helpers.parseInline(token.tokens || []))\n },\n\n renderMarkdown: (node, h) => {\n const level = node.attrs?.level ? parseInt(node.attrs.level as string, 10) : 1\n const headingChars = '#'.repeat(level)\n\n if (!node.content) {\n return ''\n }\n\n // Use current context for proper joining/spacing\n return `${headingChars} ${h.renderChildren(node.content)}`\n },\n\n addCommands() {\n return {\n setHeading:\n attributes =>\n ({ commands }) => {\n if (!this.options.levels.includes(attributes.level)) {\n return false\n }\n\n return commands.setNode(this.name, attributes)\n },\n toggleHeading:\n attributes =>\n ({ commands }) => {\n if (!this.options.levels.includes(attributes.level)) {\n return false\n }\n\n return commands.toggleNode(this.name, 'paragraph', attributes)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return this.options.levels.reduce(\n (items, level) => ({\n ...items,\n ...{\n [`Mod-Alt-${level}`]: () => this.editor.commands.toggleHeading({ level }),\n },\n }),\n {},\n )\n },\n\n addInputRules() {\n return this.options.levels.map(level => {\n return textblockTypeInputRule({\n find: new RegExp(`^(#{${Math.min(...this.options.levels)},${level}})\\\\s$`),\n type: this.type,\n getAttributes: {\n level,\n },\n })\n })\n },\n})\n", "import { Heading } from './heading.js'\n\nexport * from './heading.js'\n\nexport default Heading\n", "import { canInsertNode, isNodeSelection, mergeAttributes, Node, nodeInputRule } from '@tiptap/core'\nimport { NodeSelection, TextSelection } from '@tiptap/pm/state'\n\nexport interface HorizontalRuleOptions {\n /**\n * The HTML attributes for a horizontal rule node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n /**\n * The default type to insert after the horizontal rule.\n * @default \"paragraph\"\n * @example \"heading\"\n */\n nextNodeType: string\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n horizontalRule: {\n /**\n * Add a horizontal rule\n * @example editor.commands.setHorizontalRule()\n */\n setHorizontalRule: () => ReturnType\n }\n }\n}\n\n/**\n * This extension allows you to insert horizontal rules.\n * @see https://www.tiptap.dev/api/nodes/horizontal-rule\n */\nexport const HorizontalRule = Node.create({\n name: 'horizontalRule',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n nextNodeType: 'paragraph',\n }\n },\n\n group: 'block',\n\n parseHTML() {\n return [{ tag: 'hr' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['hr', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)]\n },\n\n markdownTokenName: 'hr',\n\n parseMarkdown: (token, helpers) => {\n return helpers.createNode('horizontalRule')\n },\n\n renderMarkdown: () => {\n return '---'\n },\n\n addCommands() {\n return {\n setHorizontalRule:\n () =>\n ({ chain, state }) => {\n // Check if we can insert the node at the current selection\n if (!canInsertNode(state, state.schema.nodes[this.name])) {\n return false\n }\n\n const { selection } = state\n const { $to: $originTo } = selection\n\n const currentChain = chain()\n\n if (isNodeSelection(selection)) {\n currentChain.insertContentAt($originTo.pos, {\n type: this.name,\n })\n } else {\n currentChain.insertContent({ type: this.name })\n }\n\n return (\n currentChain\n // set cursor after horizontal rule\n .command(({ state: chainState, tr, dispatch }) => {\n if (dispatch) {\n const { $to } = tr.selection\n const posAfter = $to.end()\n\n if ($to.nodeAfter) {\n if ($to.nodeAfter.isTextblock) {\n tr.setSelection(TextSelection.create(tr.doc, $to.pos + 1))\n } else if ($to.nodeAfter.isBlock) {\n tr.setSelection(NodeSelection.create(tr.doc, $to.pos))\n } else {\n tr.setSelection(TextSelection.create(tr.doc, $to.pos))\n }\n } else {\n // add node after horizontal rule if it’s the end of the document\n const nodeType =\n chainState.schema.nodes[this.options.nextNodeType] || $to.parent.type.contentMatch.defaultType\n const node = nodeType?.create()\n\n if (node) {\n tr.insert(posAfter, node)\n tr.setSelection(TextSelection.create(tr.doc, posAfter + 1))\n }\n }\n\n tr.scrollIntoView()\n }\n\n return true\n })\n .run()\n )\n },\n }\n },\n\n addInputRules() {\n return [\n nodeInputRule({\n find: /^(?:---|—-|___\\s|\\*\\*\\*\\s)$/,\n type: this.type,\n }),\n ]\n },\n})\n", "import { HorizontalRule } from './horizontal-rule.js'\n\nexport * from './horizontal-rule.js'\n\nexport default HorizontalRule\n", "import { Mark, markInputRule, markPasteRule, mergeAttributes } from '@tiptap/core'\n\nexport interface ItalicOptions {\n /**\n * HTML attributes to add to the italic element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n italic: {\n /**\n * Set an italic mark\n * @example editor.commands.setItalic()\n */\n setItalic: () => ReturnType\n /**\n * Toggle an italic mark\n * @example editor.commands.toggleItalic()\n */\n toggleItalic: () => ReturnType\n /**\n * Unset an italic mark\n * @example editor.commands.unsetItalic()\n */\n unsetItalic: () => ReturnType\n }\n }\n}\n\n/**\n * Matches an italic to a *italic* on input.\n */\nexport const starInputRegex = /(?:^|\\s)(\\*(?!\\s+\\*)((?:[^*]+))\\*(?!\\s+\\*))$/\n\n/**\n * Matches an italic to a *italic* on paste.\n */\nexport const starPasteRegex = /(?:^|\\s)(\\*(?!\\s+\\*)((?:[^*]+))\\*(?!\\s+\\*))/g\n\n/**\n * Matches an italic to a _italic_ on input.\n */\nexport const underscoreInputRegex = /(?:^|\\s)(_(?!\\s+_)((?:[^_]+))_(?!\\s+_))$/\n\n/**\n * Matches an italic to a _italic_ on paste.\n */\nexport const underscorePasteRegex = /(?:^|\\s)(_(?!\\s+_)((?:[^_]+))_(?!\\s+_))/g\n\n/**\n * This extension allows you to create italic text.\n * @see https://www.tiptap.dev/api/marks/italic\n */\nexport const Italic = Mark.create({\n name: 'italic',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'em',\n },\n {\n tag: 'i',\n getAttrs: node => (node as HTMLElement).style.fontStyle !== 'normal' && null,\n },\n {\n style: 'font-style=normal',\n clearMark: mark => mark.type.name === this.name,\n },\n {\n style: 'font-style=italic',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['em', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setItalic:\n () =>\n ({ commands }) => {\n return commands.setMark(this.name)\n },\n toggleItalic:\n () =>\n ({ commands }) => {\n return commands.toggleMark(this.name)\n },\n unsetItalic:\n () =>\n ({ commands }) => {\n return commands.unsetMark(this.name)\n },\n }\n },\n\n markdownTokenName: 'em',\n\n parseMarkdown: (token, helpers) => {\n // Convert 'em' token to italic mark\n return helpers.applyMark('italic', helpers.parseInline(token.tokens || []))\n },\n\n renderMarkdown: (node, h) => {\n return `*${h.renderChildren(node)}*`\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-i': () => this.editor.commands.toggleItalic(),\n 'Mod-I': () => this.editor.commands.toggleItalic(),\n }\n },\n\n addInputRules() {\n return [\n markInputRule({\n find: starInputRegex,\n type: this.type,\n }),\n markInputRule({\n find: underscoreInputRegex,\n type: this.type,\n }),\n ]\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: starPasteRegex,\n type: this.type,\n }),\n markPasteRule({\n find: underscorePasteRegex,\n type: this.type,\n }),\n ]\n },\n})\n", "import { Italic } from './italic.js'\n\nexport * from './italic.js'\n\nexport default Italic\n", "// THIS FILE IS AUTOMATICALLY GENERATED DO NOT EDIT DIRECTLY\n// See update-tlds.js for encoding/decoding format\n// https://data.iana.org/TLD/tlds-alpha-by-domain.txt\nconst encodedTlds = 'aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3nlop4pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2o0dyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rckmsd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0stone5umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5m\u00F6gensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2olterskluwer11odside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2';\n// Internationalized domain names containing non-ASCII\nconst encodedUtlds = '\u03B5\u03BB1\u03C52\u0431\u04331\u0435\u043B3\u0434\u0435\u0442\u04384\u0435\u044E2\u043A\u0430\u0442\u043E\u043B\u0438\u043A6\u043E\u043C3\u043C\u043A\u04342\u043E\u043D1\u0441\u043A\u0432\u04306\u043E\u043D\u043B\u0430\u0439\u043D5\u0440\u04333\u0440\u0443\u04412\u04442\u0441\u0430\u0439\u04423\u0440\u04313\u0443\u043A\u04403\u049B\u0430\u04373\u0570\u0561\u05753\u05D9\u05E9\u05E8\u05D0\u05DC5\u05E7\u05D5\u05DD3\u0627\u0628\u0648\u0638\u0628\u064A5\u0631\u0627\u0645\u0643\u06485\u0644\u0627\u0631\u062F\u06464\u0628\u062D\u0631\u064A\u06465\u062C\u0632\u0627\u0626\u06315\u0633\u0639\u0648\u062F\u064A\u06296\u0639\u0644\u064A\u0627\u06465\u0645\u063A\u0631\u06285\u0645\u0627\u0631\u0627\u062A5\u06CC\u0631\u0627\u06465\u0628\u0627\u0631\u062A2\u0632\u0627\u06314\u064A\u062A\u06433\u06BE\u0627\u0631\u062A5\u062A\u0648\u0646\u06334\u0633\u0648\u062F\u0627\u06463\u0631\u064A\u06295\u0634\u0628\u0643\u06294\u0639\u0631\u0627\u06422\u06282\u0645\u0627\u06464\u0641\u0644\u0633\u0637\u064A\u06466\u0642\u0637\u06313\u0643\u0627\u062B\u0648\u0644\u064A\u06436\u0648\u06453\u0645\u0635\u06312\u0644\u064A\u0633\u064A\u06275\u0648\u0631\u064A\u062A\u0627\u0646\u064A\u06277\u0642\u06394\u0647\u0645\u0631\u0627\u06475\u067E\u0627\u06A9\u0633\u062A\u0627\u06467\u0680\u0627\u0631\u062A4\u0915\u0949\u092E3\u0928\u0947\u091F3\u092D\u093E\u0930\u09240\u092E\u094D3\u094B\u09245\u0938\u0902\u0917\u0920\u09285\u09AC\u09BE\u0982\u09B2\u09BE5\u09AD\u09BE\u09B0\u09A42\u09F0\u09A44\u0A2D\u0A3E\u0A30\u0A244\u0AAD\u0ABE\u0AB0\u0AA44\u0B2D\u0B3E\u0B30\u0B244\u0B87\u0BA8\u0BCD\u0BA4\u0BBF\u0BAF\u0BBE6\u0BB2\u0B99\u0BCD\u0B95\u0BC86\u0B9A\u0BBF\u0B99\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0BC2\u0BB0\u0BCD11\u0C2D\u0C3E\u0C30\u0C24\u0C4D5\u0CAD\u0CBE\u0CB0\u0CA44\u0D2D\u0D3E\u0D30\u0D24\u0D025\u0DBD\u0D82\u0D9A\u0DCF4\u0E04\u0E2D\u0E213\u0E44\u0E17\u0E223\u0EA5\u0EB2\u0EA73\u10D2\u10D42\u307F\u3093\u306A3\u30A2\u30DE\u30BE\u30F34\u30AF\u30E9\u30A6\u30C94\u30B0\u30FC\u30B0\u30EB4\u30B3\u30E02\u30B9\u30C8\u30A23\u30BB\u30FC\u30EB3\u30D5\u30A1\u30C3\u30B7\u30E7\u30F36\u30DD\u30A4\u30F3\u30C84\u4E16\u754C2\u4E2D\u4FE11\u56FD1\u570B1\u6587\u7F513\u4E9A\u9A6C\u900A3\u4F01\u4E1A2\u4F5B\u5C712\u4FE1\u606F2\u5065\u5EB72\u516B\u53662\u516C\u53F81\u76CA2\u53F0\u6E7E1\u70632\u5546\u57CE1\u5E971\u68072\u5609\u91CC0\u5927\u9152\u5E975\u5728\u7EBF2\u5927\u62FF2\u5929\u4E3B\u65593\u5A31\u4E502\u5BB6\u96FB2\u5E7F\u4E1C2\u5FAE\u535A2\u6148\u55842\u6211\u7231\u4F603\u624B\u673A2\u62DB\u80582\u653F\u52A11\u5E9C2\u65B0\u52A0\u57612\u95FB2\u65F6\u5C1A2\u66F8\u7C4D2\u673A\u67842\u6DE1\u9A6C\u95213\u6E38\u620F2\u6FB3\u95802\u70B9\u770B2\u79FB\u52A82\u7EC4\u7EC7\u673A\u67844\u7F51\u57401\u5E971\u7AD91\u7EDC2\u8054\u901A2\u8C37\u6B4C2\u8D2D\u72692\u901A\u8CA92\u96C6\u56E22\u96FB\u8A0A\u76C8\u79D14\u98DE\u5229\u6D663\u98DF\u54C12\u9910\u53852\u9999\u683C\u91CC\u62C93\u6E2F2\uB2F7\uB1371\uCEF42\uC0BC\uC1312\uD55C\uAD6D2';\n\n/**\n * Finite State Machine generation utilities\n */\n\n/**\n * @template T\n * @typedef {{ [group: string]: T[] }} Collections\n */\n\n/**\n * @typedef {{ [group: string]: true }} Flags\n */\n\n// Keys in scanner Collections instances\nconst numeric = 'numeric';\nconst ascii = 'ascii';\nconst alpha = 'alpha';\nconst asciinumeric = 'asciinumeric';\nconst alphanumeric = 'alphanumeric';\nconst domain = 'domain';\nconst emoji = 'emoji';\nconst scheme = 'scheme';\nconst slashscheme = 'slashscheme';\nconst whitespace = 'whitespace';\n\n/**\n * @template T\n * @param {string} name\n * @param {Collections} groups to register in\n * @returns {T[]} Current list of tokens in the given collection\n */\nfunction registerGroup(name, groups) {\n if (!(name in groups)) {\n groups[name] = [];\n }\n return groups[name];\n}\n\n/**\n * @template T\n * @param {T} t token to add\n * @param {Collections} groups\n * @param {Flags} flags\n */\nfunction addToGroups(t, flags, groups) {\n if (flags[numeric]) {\n flags[asciinumeric] = true;\n flags[alphanumeric] = true;\n }\n if (flags[ascii]) {\n flags[asciinumeric] = true;\n flags[alpha] = true;\n }\n if (flags[asciinumeric]) {\n flags[alphanumeric] = true;\n }\n if (flags[alpha]) {\n flags[alphanumeric] = true;\n }\n if (flags[alphanumeric]) {\n flags[domain] = true;\n }\n if (flags[emoji]) {\n flags[domain] = true;\n }\n for (const k in flags) {\n const group = registerGroup(k, groups);\n if (group.indexOf(t) < 0) {\n group.push(t);\n }\n }\n}\n\n/**\n * @template T\n * @param {T} t token to check\n * @param {Collections} groups\n * @returns {Flags} group flags that contain this token\n */\nfunction flagsForToken(t, groups) {\n const result = {};\n for (const c in groups) {\n if (groups[c].indexOf(t) >= 0) {\n result[c] = true;\n }\n }\n return result;\n}\n\n/**\n * @template T\n * @typedef {null | T } Transition\n */\n\n/**\n * Define a basic state machine state. j is the list of character transitions,\n * jr is the list of regex-match transitions, jd is the default state to\n * transition to t is the accepting token type, if any. If this is the terminal\n * state, then it does not emit a token.\n *\n * The template type T represents the type of the token this state accepts. This\n * should be a string (such as of the token exports in `text.js`) or a\n * MultiToken subclass (from `multi.js`)\n *\n * @template T\n * @param {T} [token] Token that this state emits\n */\nfunction State(token = null) {\n // this.n = null; // DEBUG: State name\n /** @type {{ [input: string]: State }} j */\n this.j = {}; // IMPLEMENTATION 1\n // this.j = []; // IMPLEMENTATION 2\n /** @type {[RegExp, State][]} jr */\n this.jr = [];\n /** @type {?State} jd */\n this.jd = null;\n /** @type {?T} t */\n this.t = token;\n}\n\n/**\n * Scanner token groups\n * @type Collections\n */\nState.groups = {};\nState.prototype = {\n accepts() {\n return !!this.t;\n },\n /**\n * Follow an existing transition from the given input to the next state.\n * Does not mutate.\n * @param {string} input character or token type to transition on\n * @returns {?State} the next state, if any\n */\n go(input) {\n const state = this;\n const nextState = state.j[input];\n if (nextState) {\n return nextState;\n }\n for (let i = 0; i < state.jr.length; i++) {\n const regex = state.jr[i][0];\n const nextState = state.jr[i][1]; // note: might be empty to prevent default jump\n if (nextState && regex.test(input)) {\n return nextState;\n }\n }\n // Nowhere left to jump! Return default, if any\n return state.jd;\n },\n /**\n * Whether the state has a transition for the given input. Set the second\n * argument to true to only look for an exact match (and not a default or\n * regular-expression-based transition)\n * @param {string} input\n * @param {boolean} exactOnly\n */\n has(input, exactOnly = false) {\n return exactOnly ? input in this.j : !!this.go(input);\n },\n /**\n * Short for \"transition all\"; create a transition from the array of items\n * in the given list to the same final resulting state.\n * @param {string | string[]} inputs Group of inputs to transition on\n * @param {Transition | State} [next] Transition options\n * @param {Flags} [flags] Collections flags to add token to\n * @param {Collections} [groups] Master list of token groups\n */\n ta(inputs, next, flags, groups) {\n for (let i = 0; i < inputs.length; i++) {\n this.tt(inputs[i], next, flags, groups);\n }\n },\n /**\n * Short for \"take regexp transition\"; defines a transition for this state\n * when it encounters a token which matches the given regular expression\n * @param {RegExp} regexp Regular expression transition (populate first)\n * @param {T | State} [next] Transition options\n * @param {Flags} [flags] Collections flags to add token to\n * @param {Collections} [groups] Master list of token groups\n * @returns {State} taken after the given input\n */\n tr(regexp, next, flags, groups) {\n groups = groups || State.groups;\n let nextState;\n if (next && next.j) {\n nextState = next;\n } else {\n // Token with maybe token groups\n nextState = new State(next);\n if (flags && groups) {\n addToGroups(next, flags, groups);\n }\n }\n this.jr.push([regexp, nextState]);\n return nextState;\n },\n /**\n * Short for \"take transitions\", will take as many sequential transitions as\n * the length of the given input and returns the\n * resulting final state.\n * @param {string | string[]} input\n * @param {T | State} [next] Transition options\n * @param {Flags} [flags] Collections flags to add token to\n * @param {Collections} [groups] Master list of token groups\n * @returns {State} taken after the given input\n */\n ts(input, next, flags, groups) {\n let state = this;\n const len = input.length;\n if (!len) {\n return state;\n }\n for (let i = 0; i < len - 1; i++) {\n state = state.tt(input[i]);\n }\n return state.tt(input[len - 1], next, flags, groups);\n },\n /**\n * Short for \"take transition\", this is a method for building/working with\n * state machines.\n *\n * If a state already exists for the given input, returns it.\n *\n * If a token is specified, that state will emit that token when reached by\n * the linkify engine.\n *\n * If no state exists, it will be initialized with some default transitions\n * that resemble existing default transitions.\n *\n * If a state is given for the second argument, that state will be\n * transitioned to on the given input regardless of what that input\n * previously did.\n *\n * Specify a token group flags to define groups that this token belongs to.\n * The token will be added to corresponding entires in the given groups\n * object.\n *\n * @param {string} input character, token type to transition on\n * @param {T | State} [next] Transition options\n * @param {Flags} [flags] Collections flags to add token to\n * @param {Collections} [groups] Master list of groups\n * @returns {State} taken after the given input\n */\n tt(input, next, flags, groups) {\n groups = groups || State.groups;\n const state = this;\n\n // Check if existing state given, just a basic transition\n if (next && next.j) {\n state.j[input] = next;\n return next;\n }\n const t = next;\n\n // Take the transition with the usual default mechanisms and use that as\n // a template for creating the next state\n let nextState,\n templateState = state.go(input);\n if (templateState) {\n nextState = new State();\n Object.assign(nextState.j, templateState.j);\n nextState.jr.push.apply(nextState.jr, templateState.jr);\n nextState.jd = templateState.jd;\n nextState.t = templateState.t;\n } else {\n nextState = new State();\n }\n if (t) {\n // Ensure newly token is in the same groups as the old token\n if (groups) {\n if (nextState.t && typeof nextState.t === 'string') {\n const allFlags = Object.assign(flagsForToken(nextState.t, groups), flags);\n addToGroups(t, allFlags, groups);\n } else if (flags) {\n addToGroups(t, flags, groups);\n }\n }\n nextState.t = t; // overwrite anything that was previously there\n }\n state.j[input] = nextState;\n return nextState;\n }\n};\n\n// Helper functions to improve minification (not exported outside linkifyjs module)\n\n/**\n * @template T\n * @param {State} state\n * @param {string | string[]} input\n * @param {Flags} [flags]\n * @param {Collections} [groups]\n */\nconst ta = (state, input, next, flags, groups) => state.ta(input, next, flags, groups);\n\n/**\n * @template T\n * @param {State} state\n * @param {RegExp} regexp\n * @param {T | State} [next]\n * @param {Flags} [flags]\n * @param {Collections} [groups]\n */\nconst tr = (state, regexp, next, flags, groups) => state.tr(regexp, next, flags, groups);\n\n/**\n * @template T\n * @param {State} state\n * @param {string | string[]} input\n * @param {T | State} [next]\n * @param {Flags} [flags]\n * @param {Collections} [groups]\n */\nconst ts = (state, input, next, flags, groups) => state.ts(input, next, flags, groups);\n\n/**\n * @template T\n * @param {State} state\n * @param {string} input\n * @param {T | State} [next]\n * @param {Collections} [groups]\n * @param {Flags} [flags]\n */\nconst tt = (state, input, next, flags, groups) => state.tt(input, next, flags, groups);\n\n/******************************************************************************\nText Tokens\nIdentifiers for token outputs from the regexp scanner\n******************************************************************************/\n\n// A valid web domain token\nconst WORD = 'WORD'; // only contains a-z\nconst UWORD = 'UWORD'; // contains letters other than a-z, used for IDN\nconst ASCIINUMERICAL = 'ASCIINUMERICAL'; // contains a-z, 0-9\nconst ALPHANUMERICAL = 'ALPHANUMERICAL'; // contains numbers and letters other than a-z, used for IDN\n\n// Special case of word\nconst LOCALHOST = 'LOCALHOST';\n\n// Valid top-level domain, special case of WORD (see tlds.js)\nconst TLD = 'TLD';\n\n// Valid IDN TLD, special case of UWORD (see tlds.js)\nconst UTLD = 'UTLD';\n\n// The scheme portion of a web URI protocol. Supported types include: `mailto`,\n// `file`, and user-defined custom protocols. Limited to schemes that contain\n// only letters\nconst SCHEME = 'SCHEME';\n\n// Similar to SCHEME, except makes distinction for schemes that must always be\n// followed by `://`, not just `:`. Supported types include `http`, `https`,\n// `ftp`, `ftps`\nconst SLASH_SCHEME = 'SLASH_SCHEME';\n\n// Any sequence of digits 0-9\nconst NUM = 'NUM';\n\n// Any number of consecutive whitespace characters that are not newline\nconst WS = 'WS';\n\n// New line (unix style)\nconst NL = 'NL'; // \\n\n\n// Opening/closing bracket classes\n// TODO: Rename OPEN -> LEFT and CLOSE -> RIGHT in v5 to fit with Unicode names\n// Also rename angle brackes to LESSTHAN and GREATER THAN\nconst OPENBRACE = 'OPENBRACE'; // {\nconst CLOSEBRACE = 'CLOSEBRACE'; // }\nconst OPENBRACKET = 'OPENBRACKET'; // [\nconst CLOSEBRACKET = 'CLOSEBRACKET'; // ]\nconst OPENPAREN = 'OPENPAREN'; // (\nconst CLOSEPAREN = 'CLOSEPAREN'; // )\nconst OPENANGLEBRACKET = 'OPENANGLEBRACKET'; // <\nconst CLOSEANGLEBRACKET = 'CLOSEANGLEBRACKET'; // >\nconst FULLWIDTHLEFTPAREN = 'FULLWIDTHLEFTPAREN'; // \uFF08\nconst FULLWIDTHRIGHTPAREN = 'FULLWIDTHRIGHTPAREN'; // \uFF09\nconst LEFTCORNERBRACKET = 'LEFTCORNERBRACKET'; // \u300C\nconst RIGHTCORNERBRACKET = 'RIGHTCORNERBRACKET'; // \u300D\nconst LEFTWHITECORNERBRACKET = 'LEFTWHITECORNERBRACKET'; // \u300E\nconst RIGHTWHITECORNERBRACKET = 'RIGHTWHITECORNERBRACKET'; // \u300F\nconst FULLWIDTHLESSTHAN = 'FULLWIDTHLESSTHAN'; // \uFF1C\nconst FULLWIDTHGREATERTHAN = 'FULLWIDTHGREATERTHAN'; // \uFF1E\n\n// Various symbols\nconst AMPERSAND = 'AMPERSAND'; // &\nconst APOSTROPHE = 'APOSTROPHE'; // '\nconst ASTERISK = 'ASTERISK'; // *\nconst AT = 'AT'; // @\nconst BACKSLASH = 'BACKSLASH'; // \\\nconst BACKTICK = 'BACKTICK'; // `\nconst CARET = 'CARET'; // ^\nconst COLON = 'COLON'; // :\nconst COMMA = 'COMMA'; // ,\nconst DOLLAR = 'DOLLAR'; // $\nconst DOT = 'DOT'; // .\nconst EQUALS = 'EQUALS'; // =\nconst EXCLAMATION = 'EXCLAMATION'; // !\nconst HYPHEN = 'HYPHEN'; // -\nconst PERCENT = 'PERCENT'; // %\nconst PIPE = 'PIPE'; // |\nconst PLUS = 'PLUS'; // +\nconst POUND = 'POUND'; // #\nconst QUERY = 'QUERY'; // ?\nconst QUOTE = 'QUOTE'; // \"\nconst FULLWIDTHMIDDLEDOT = 'FULLWIDTHMIDDLEDOT'; // \u30FB\n\nconst SEMI = 'SEMI'; // ;\nconst SLASH = 'SLASH'; // /\nconst TILDE = 'TILDE'; // ~\nconst UNDERSCORE = 'UNDERSCORE'; // _\n\n// Emoji symbol\nconst EMOJI$1 = 'EMOJI';\n\n// Default token - anything that is not one of the above\nconst SYM = 'SYM';\n\nvar tk = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tALPHANUMERICAL: ALPHANUMERICAL,\n\tAMPERSAND: AMPERSAND,\n\tAPOSTROPHE: APOSTROPHE,\n\tASCIINUMERICAL: ASCIINUMERICAL,\n\tASTERISK: ASTERISK,\n\tAT: AT,\n\tBACKSLASH: BACKSLASH,\n\tBACKTICK: BACKTICK,\n\tCARET: CARET,\n\tCLOSEANGLEBRACKET: CLOSEANGLEBRACKET,\n\tCLOSEBRACE: CLOSEBRACE,\n\tCLOSEBRACKET: CLOSEBRACKET,\n\tCLOSEPAREN: CLOSEPAREN,\n\tCOLON: COLON,\n\tCOMMA: COMMA,\n\tDOLLAR: DOLLAR,\n\tDOT: DOT,\n\tEMOJI: EMOJI$1,\n\tEQUALS: EQUALS,\n\tEXCLAMATION: EXCLAMATION,\n\tFULLWIDTHGREATERTHAN: FULLWIDTHGREATERTHAN,\n\tFULLWIDTHLEFTPAREN: FULLWIDTHLEFTPAREN,\n\tFULLWIDTHLESSTHAN: FULLWIDTHLESSTHAN,\n\tFULLWIDTHMIDDLEDOT: FULLWIDTHMIDDLEDOT,\n\tFULLWIDTHRIGHTPAREN: FULLWIDTHRIGHTPAREN,\n\tHYPHEN: HYPHEN,\n\tLEFTCORNERBRACKET: LEFTCORNERBRACKET,\n\tLEFTWHITECORNERBRACKET: LEFTWHITECORNERBRACKET,\n\tLOCALHOST: LOCALHOST,\n\tNL: NL,\n\tNUM: NUM,\n\tOPENANGLEBRACKET: OPENANGLEBRACKET,\n\tOPENBRACE: OPENBRACE,\n\tOPENBRACKET: OPENBRACKET,\n\tOPENPAREN: OPENPAREN,\n\tPERCENT: PERCENT,\n\tPIPE: PIPE,\n\tPLUS: PLUS,\n\tPOUND: POUND,\n\tQUERY: QUERY,\n\tQUOTE: QUOTE,\n\tRIGHTCORNERBRACKET: RIGHTCORNERBRACKET,\n\tRIGHTWHITECORNERBRACKET: RIGHTWHITECORNERBRACKET,\n\tSCHEME: SCHEME,\n\tSEMI: SEMI,\n\tSLASH: SLASH,\n\tSLASH_SCHEME: SLASH_SCHEME,\n\tSYM: SYM,\n\tTILDE: TILDE,\n\tTLD: TLD,\n\tUNDERSCORE: UNDERSCORE,\n\tUTLD: UTLD,\n\tUWORD: UWORD,\n\tWORD: WORD,\n\tWS: WS\n});\n\n// Note that these two Unicode ones expand into a really big one with Babel\nconst ASCII_LETTER = /[a-z]/;\nconst LETTER = /\\p{L}/u; // Any Unicode character with letter data type\nconst EMOJI = /\\p{Emoji}/u; // Any Unicode emoji character\nconst EMOJI_VARIATION$1 = /\\ufe0f/;\nconst DIGIT = /\\d/;\nconst SPACE = /\\s/;\n\nvar regexp = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tASCII_LETTER: ASCII_LETTER,\n\tDIGIT: DIGIT,\n\tEMOJI: EMOJI,\n\tEMOJI_VARIATION: EMOJI_VARIATION$1,\n\tLETTER: LETTER,\n\tSPACE: SPACE\n});\n\n/**\n\tThe scanner provides an interface that takes a string of text as input, and\n\toutputs an array of tokens instances that can be used for easy URL parsing.\n*/\n\nconst CR = '\\r'; // carriage-return character\nconst LF = '\\n'; // line-feed character\nconst EMOJI_VARIATION = '\\ufe0f'; // Variation selector, follows heart and others\nconst EMOJI_JOINER = '\\u200d'; // zero-width joiner\nconst OBJECT_REPLACEMENT = '\\ufffc'; // whitespace placeholder that sometimes appears in rich text editors\n\nlet tlds = null,\n utlds = null; // don't change so only have to be computed once\n\n/**\n * Scanner output token:\n * - `t` is the token name (e.g., 'NUM', 'EMOJI', 'TLD')\n * - `v` is the value of the token (e.g., '123', '\u2764\uFE0F', 'com')\n * - `s` is the start index of the token in the original string\n * - `e` is the end index of the token in the original string\n * @typedef {{t: string, v: string, s: number, e: number}} Token\n */\n\n/**\n * @template T\n * @typedef {{ [collection: string]: T[] }} Collections\n */\n\n/**\n * Initialize the scanner character-based state machine for the given start\n * state\n * @param {[string, boolean][]} customSchemes List of custom schemes, where each\n * item is a length-2 tuple with the first element set to the string scheme, and\n * the second element set to `true` if the `://` after the scheme is optional\n */\nfunction init$2(customSchemes = []) {\n // Frequently used states (name argument removed during minification)\n /** @type Collections */\n const groups = {}; // of tokens\n State.groups = groups;\n /** @type State */\n const Start = new State();\n if (tlds == null) {\n tlds = decodeTlds(encodedTlds);\n }\n if (utlds == null) {\n utlds = decodeTlds(encodedUtlds);\n }\n\n // States for special URL symbols that accept immediately after start\n tt(Start, \"'\", APOSTROPHE);\n tt(Start, '{', OPENBRACE);\n tt(Start, '}', CLOSEBRACE);\n tt(Start, '[', OPENBRACKET);\n tt(Start, ']', CLOSEBRACKET);\n tt(Start, '(', OPENPAREN);\n tt(Start, ')', CLOSEPAREN);\n tt(Start, '<', OPENANGLEBRACKET);\n tt(Start, '>', CLOSEANGLEBRACKET);\n tt(Start, '\uFF08', FULLWIDTHLEFTPAREN);\n tt(Start, '\uFF09', FULLWIDTHRIGHTPAREN);\n tt(Start, '\u300C', LEFTCORNERBRACKET);\n tt(Start, '\u300D', RIGHTCORNERBRACKET);\n tt(Start, '\u300E', LEFTWHITECORNERBRACKET);\n tt(Start, '\u300F', RIGHTWHITECORNERBRACKET);\n tt(Start, '\uFF1C', FULLWIDTHLESSTHAN);\n tt(Start, '\uFF1E', FULLWIDTHGREATERTHAN);\n tt(Start, '&', AMPERSAND);\n tt(Start, '*', ASTERISK);\n tt(Start, '@', AT);\n tt(Start, '`', BACKTICK);\n tt(Start, '^', CARET);\n tt(Start, ':', COLON);\n tt(Start, ',', COMMA);\n tt(Start, '$', DOLLAR);\n tt(Start, '.', DOT);\n tt(Start, '=', EQUALS);\n tt(Start, '!', EXCLAMATION);\n tt(Start, '-', HYPHEN);\n tt(Start, '%', PERCENT);\n tt(Start, '|', PIPE);\n tt(Start, '+', PLUS);\n tt(Start, '#', POUND);\n tt(Start, '?', QUERY);\n tt(Start, '\"', QUOTE);\n tt(Start, '/', SLASH);\n tt(Start, ';', SEMI);\n tt(Start, '~', TILDE);\n tt(Start, '_', UNDERSCORE);\n tt(Start, '\\\\', BACKSLASH);\n tt(Start, '\u30FB', FULLWIDTHMIDDLEDOT);\n const Num = tr(Start, DIGIT, NUM, {\n [numeric]: true\n });\n tr(Num, DIGIT, Num);\n const Asciinumeric = tr(Num, ASCII_LETTER, ASCIINUMERICAL, {\n [asciinumeric]: true\n });\n const Alphanumeric = tr(Num, LETTER, ALPHANUMERICAL, {\n [alphanumeric]: true\n });\n\n // State which emits a word token\n const Word = tr(Start, ASCII_LETTER, WORD, {\n [ascii]: true\n });\n tr(Word, DIGIT, Asciinumeric);\n tr(Word, ASCII_LETTER, Word);\n tr(Asciinumeric, DIGIT, Asciinumeric);\n tr(Asciinumeric, ASCII_LETTER, Asciinumeric);\n\n // Same as previous, but specific to non-fsm.ascii alphabet words\n const UWord = tr(Start, LETTER, UWORD, {\n [alpha]: true\n });\n tr(UWord, ASCII_LETTER); // Non-accepting\n tr(UWord, DIGIT, Alphanumeric);\n tr(UWord, LETTER, UWord);\n tr(Alphanumeric, DIGIT, Alphanumeric);\n tr(Alphanumeric, ASCII_LETTER); // Non-accepting\n tr(Alphanumeric, LETTER, Alphanumeric); // Non-accepting\n\n // Whitespace jumps\n // Tokens of only non-newline whitespace are arbitrarily long\n // If any whitespace except newline, more whitespace!\n const Nl = tt(Start, LF, NL, {\n [whitespace]: true\n });\n const Cr = tt(Start, CR, WS, {\n [whitespace]: true\n });\n const Ws = tr(Start, SPACE, WS, {\n [whitespace]: true\n });\n tt(Start, OBJECT_REPLACEMENT, Ws);\n tt(Cr, LF, Nl); // \\r\\n\n tt(Cr, OBJECT_REPLACEMENT, Ws);\n tr(Cr, SPACE, Ws);\n tt(Ws, CR); // non-accepting state to avoid mixing whitespaces\n tt(Ws, LF); // non-accepting state to avoid mixing whitespaces\n tr(Ws, SPACE, Ws);\n tt(Ws, OBJECT_REPLACEMENT, Ws);\n\n // Emoji tokens. They are not grouped by the scanner except in cases where a\n // zero-width joiner is present\n const Emoji = tr(Start, EMOJI, EMOJI$1, {\n [emoji]: true\n });\n tt(Emoji, '#'); // no transition, emoji regex seems to match #\n tr(Emoji, EMOJI, Emoji);\n tt(Emoji, EMOJI_VARIATION, Emoji);\n // tt(Start, EMOJI_VARIATION, Emoji); // This one is sketchy\n\n const EmojiJoiner = tt(Emoji, EMOJI_JOINER);\n tt(EmojiJoiner, '#');\n tr(EmojiJoiner, EMOJI, Emoji);\n // tt(EmojiJoiner, EMOJI_VARIATION, Emoji); // also sketchy\n\n // Generates states for top-level domains\n // Note that this is most accurate when tlds are in alphabetical order\n const wordjr = [[ASCII_LETTER, Word], [DIGIT, Asciinumeric]];\n const uwordjr = [[ASCII_LETTER, null], [LETTER, UWord], [DIGIT, Alphanumeric]];\n for (let i = 0; i < tlds.length; i++) {\n fastts(Start, tlds[i], TLD, WORD, wordjr);\n }\n for (let i = 0; i < utlds.length; i++) {\n fastts(Start, utlds[i], UTLD, UWORD, uwordjr);\n }\n addToGroups(TLD, {\n tld: true,\n ascii: true\n }, groups);\n addToGroups(UTLD, {\n utld: true,\n alpha: true\n }, groups);\n\n // Collect the states generated by different protocols. NOTE: If any new TLDs\n // get added that are also protocols, set the token to be the same as the\n // protocol to ensure parsing works as expected.\n fastts(Start, 'file', SCHEME, WORD, wordjr);\n fastts(Start, 'mailto', SCHEME, WORD, wordjr);\n fastts(Start, 'http', SLASH_SCHEME, WORD, wordjr);\n fastts(Start, 'https', SLASH_SCHEME, WORD, wordjr);\n fastts(Start, 'ftp', SLASH_SCHEME, WORD, wordjr);\n fastts(Start, 'ftps', SLASH_SCHEME, WORD, wordjr);\n addToGroups(SCHEME, {\n scheme: true,\n ascii: true\n }, groups);\n addToGroups(SLASH_SCHEME, {\n slashscheme: true,\n ascii: true\n }, groups);\n\n // Register custom schemes. Assumes each scheme is asciinumeric with hyphens\n customSchemes = customSchemes.sort((a, b) => a[0] > b[0] ? 1 : -1);\n for (let i = 0; i < customSchemes.length; i++) {\n const sch = customSchemes[i][0];\n const optionalSlashSlash = customSchemes[i][1];\n const flags = optionalSlashSlash ? {\n [scheme]: true\n } : {\n [slashscheme]: true\n };\n if (sch.indexOf('-') >= 0) {\n flags[domain] = true;\n } else if (!ASCII_LETTER.test(sch)) {\n flags[numeric] = true; // numbers only\n } else if (DIGIT.test(sch)) {\n flags[asciinumeric] = true;\n } else {\n flags[ascii] = true;\n }\n ts(Start, sch, sch, flags);\n }\n\n // Localhost token\n ts(Start, 'localhost', LOCALHOST, {\n ascii: true\n });\n\n // Set default transition for start state (some symbol)\n Start.jd = new State(SYM);\n return {\n start: Start,\n tokens: Object.assign({\n groups\n }, tk)\n };\n}\n\n/**\n\tGiven a string, returns an array of TOKEN instances representing the\n\tcomposition of that string.\n\n\t@method run\n\t@param {State} start scanner starting state\n\t@param {string} str input string to scan\n\t@return {Token[]} list of tokens, each with a type and value\n*/\nfunction run$1(start, str) {\n // State machine is not case sensitive, so input is tokenized in lowercased\n // form (still returns regular case). Uses selective `toLowerCase` because\n // lowercasing the entire string causes the length and character position to\n // vary in some non-English strings with V8-based runtimes.\n const iterable = stringToArray(str.replace(/[A-Z]/g, c => c.toLowerCase()));\n const charCount = iterable.length; // <= len if there are emojis, etc\n const tokens = []; // return value\n\n // cursor through the string itself, accounting for characters that have\n // width with length 2 such as emojis\n let cursor = 0;\n\n // Cursor through the array-representation of the string\n let charCursor = 0;\n\n // Tokenize the string\n while (charCursor < charCount) {\n let state = start;\n let nextState = null;\n let tokenLength = 0;\n let latestAccepting = null;\n let sinceAccepts = -1;\n let charsSinceAccepts = -1;\n while (charCursor < charCount && (nextState = state.go(iterable[charCursor]))) {\n state = nextState;\n\n // Keep track of the latest accepting state\n if (state.accepts()) {\n sinceAccepts = 0;\n charsSinceAccepts = 0;\n latestAccepting = state;\n } else if (sinceAccepts >= 0) {\n sinceAccepts += iterable[charCursor].length;\n charsSinceAccepts++;\n }\n tokenLength += iterable[charCursor].length;\n cursor += iterable[charCursor].length;\n charCursor++;\n }\n\n // Roll back to the latest accepting state\n cursor -= sinceAccepts;\n charCursor -= charsSinceAccepts;\n tokenLength -= sinceAccepts;\n\n // No more jumps, just make a new token from the last accepting one\n tokens.push({\n t: latestAccepting.t,\n // token type/name\n v: str.slice(cursor - tokenLength, cursor),\n // string value\n s: cursor - tokenLength,\n // start index\n e: cursor // end index (excluding)\n });\n }\n return tokens;\n}\n\n/**\n * Convert a String to an Array of characters, taking into account that some\n * characters like emojis take up two string indexes.\n *\n * Adapted from core-js (MIT license)\n * https://github.com/zloirock/core-js/blob/2d69cf5f99ab3ea3463c395df81e5a15b68f49d9/packages/core-js/internals/string-multibyte.js\n *\n * @function stringToArray\n * @param {string} str\n * @returns {string[]}\n */\nfunction stringToArray(str) {\n const result = [];\n const len = str.length;\n let index = 0;\n while (index < len) {\n let first = str.charCodeAt(index);\n let second;\n let char = first < 0xd800 || first > 0xdbff || index + 1 === len || (second = str.charCodeAt(index + 1)) < 0xdc00 || second > 0xdfff ? str[index] // single character\n : str.slice(index, index + 2); // two-index characters\n result.push(char);\n index += char.length;\n }\n return result;\n}\n\n/**\n * Fast version of ts function for when transition defaults are well known\n * @param {State} state\n * @param {string} input\n * @param {string} t\n * @param {string} defaultt\n * @param {[RegExp, State][]} jr\n * @returns {State}\n */\nfunction fastts(state, input, t, defaultt, jr) {\n let next;\n const len = input.length;\n for (let i = 0; i < len - 1; i++) {\n const char = input[i];\n if (state.j[char]) {\n next = state.j[char];\n } else {\n next = new State(defaultt);\n next.jr = jr.slice();\n state.j[char] = next;\n }\n state = next;\n }\n next = new State(t);\n next.jr = jr.slice();\n state.j[input[len - 1]] = next;\n return next;\n}\n\n/**\n * Converts a string of Top-Level Domain names encoded in update-tlds.js back\n * into a list of strings.\n * @param {str} encoded encoded TLDs string\n * @returns {str[]} original TLDs list\n */\nfunction decodeTlds(encoded) {\n const words = [];\n const stack = [];\n let i = 0;\n let digits = '0123456789';\n while (i < encoded.length) {\n let popDigitCount = 0;\n while (digits.indexOf(encoded[i + popDigitCount]) >= 0) {\n popDigitCount++; // encountered some digits, have to pop to go one level up trie\n }\n if (popDigitCount > 0) {\n words.push(stack.join('')); // whatever preceded the pop digits must be a word\n for (let popCount = parseInt(encoded.substring(i, i + popDigitCount), 10); popCount > 0; popCount--) {\n stack.pop();\n }\n i += popDigitCount;\n } else {\n stack.push(encoded[i]); // drop down a level into the trie\n i++;\n }\n }\n return words;\n}\n\n/**\n * An object where each key is a valid DOM Event Name such as `click` or `focus`\n * and each value is an event handler function.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/Element#events\n * @typedef {?{ [event: string]: Function }} EventListeners\n */\n\n/**\n * All formatted properties required to render a link, including `tagName`,\n * `attributes`, `content` and `eventListeners`.\n * @typedef {{ tagName: any, attributes: {[attr: string]: any}, content: string,\n * eventListeners: EventListeners }} IntermediateRepresentation\n */\n\n/**\n * Specify either an object described by the template type `O` or a function.\n *\n * The function takes a string value (usually the link's href attribute), the\n * link type (`'url'`, `'hashtag`', etc.) and an internal token representation\n * of the link. It should return an object of the template type `O`\n * @template O\n * @typedef {O | ((value: string, type: string, token: MultiToken) => O)} OptObj\n */\n\n/**\n * Specify either a function described by template type `F` or an object.\n *\n * Each key in the object should be a link type (`'url'`, `'hashtag`', etc.). Each\n * value should be a function with template type `F` that is called when the\n * corresponding link type is encountered.\n * @template F\n * @typedef {F | { [type: string]: F}} OptFn\n */\n\n/**\n * Specify either a value with template type `V`, a function that returns `V` or\n * an object where each value resolves to `V`.\n *\n * The function takes a string value (usually the link's href attribute), the\n * link type (`'url'`, `'hashtag`', etc.) and an internal token representation\n * of the link. It should return an object of the template type `V`\n *\n * For the object, each key should be a link type (`'url'`, `'hashtag`', etc.).\n * Each value should either have type `V` or a function that returns V. This\n * function similarly takes a string value and a token.\n *\n * Example valid types for `Opt`:\n *\n * ```js\n * 'hello'\n * (value, type, token) => 'world'\n * { url: 'hello', email: (value, token) => 'world'}\n * ```\n * @template V\n * @typedef {V | ((value: string, type: string, token: MultiToken) => V) | { [type: string]: V | ((value: string, token: MultiToken) => V) }} Opt\n */\n\n/**\n * See available options: https://linkify.js.org/docs/options.html\n * @typedef {{\n * \tdefaultProtocol?: string,\n * events?: OptObj,\n * \tformat?: Opt,\n * \tformatHref?: Opt,\n * \tnl2br?: boolean,\n * \ttagName?: Opt,\n * \ttarget?: Opt,\n * \trel?: Opt,\n * \tvalidate?: Opt,\n * \ttruncate?: Opt,\n * \tclassName?: Opt,\n * \tattributes?: OptObj<({ [attr: string]: any })>,\n * ignoreTags?: string[],\n * \trender?: OptFn<((ir: IntermediateRepresentation) => any)>\n * }} Opts\n */\n\n/**\n * @type Required\n */\nconst defaults = {\n defaultProtocol: 'http',\n events: null,\n format: noop,\n formatHref: noop,\n nl2br: false,\n tagName: 'a',\n target: null,\n rel: null,\n validate: true,\n truncate: Infinity,\n className: null,\n attributes: null,\n ignoreTags: [],\n render: null\n};\n\n/**\n * Utility class for linkify interfaces to apply specified\n * {@link Opts formatting and rendering options}.\n *\n * @param {Opts | Options} [opts] Option value overrides.\n * @param {(ir: IntermediateRepresentation) => any} [defaultRender] (For\n * internal use) default render function that determines how to generate an\n * HTML element based on a link token's derived tagName, attributes and HTML.\n * Similar to render option\n */\nfunction Options(opts, defaultRender = null) {\n let o = Object.assign({}, defaults);\n if (opts) {\n o = Object.assign(o, opts instanceof Options ? opts.o : opts);\n }\n\n // Ensure all ignored tags are uppercase\n const ignoredTags = o.ignoreTags;\n const uppercaseIgnoredTags = [];\n for (let i = 0; i < ignoredTags.length; i++) {\n uppercaseIgnoredTags.push(ignoredTags[i].toUpperCase());\n }\n /** @protected */\n this.o = o;\n if (defaultRender) {\n this.defaultRender = defaultRender;\n }\n this.ignoreTags = uppercaseIgnoredTags;\n}\nOptions.prototype = {\n o: defaults,\n /**\n * @type string[]\n */\n ignoreTags: [],\n /**\n * @param {IntermediateRepresentation} ir\n * @returns {any}\n */\n defaultRender(ir) {\n return ir;\n },\n /**\n * Returns true or false based on whether a token should be displayed as a\n * link based on the user options.\n * @param {MultiToken} token\n * @returns {boolean}\n */\n check(token) {\n return this.get('validate', token.toString(), token);\n },\n // Private methods\n\n /**\n * Resolve an option's value based on the value of the option and the given\n * params. If operator and token are specified and the target option is\n * callable, automatically calls the function with the given argument.\n * @template {keyof Opts} K\n * @param {K} key Name of option to use\n * @param {string} [operator] will be passed to the target option if it's a\n * function. If not specified, RAW function value gets returned\n * @param {MultiToken} [token] The token from linkify.tokenize\n * @returns {Opts[K] | any}\n */\n get(key, operator, token) {\n const isCallable = operator != null;\n let option = this.o[key];\n if (!option) {\n return option;\n }\n if (typeof option === 'object') {\n option = token.t in option ? option[token.t] : defaults[key];\n if (typeof option === 'function' && isCallable) {\n option = option(operator, token);\n }\n } else if (typeof option === 'function' && isCallable) {\n option = option(operator, token.t, token);\n }\n return option;\n },\n /**\n * @template {keyof Opts} L\n * @param {L} key Name of options object to use\n * @param {string} [operator]\n * @param {MultiToken} [token]\n * @returns {Opts[L] | any}\n */\n getObj(key, operator, token) {\n let obj = this.o[key];\n if (typeof obj === 'function' && operator != null) {\n obj = obj(operator, token.t, token);\n }\n return obj;\n },\n /**\n * Convert the given token to a rendered element that may be added to the\n * calling-interface's DOM\n * @param {MultiToken} token Token to render to an HTML element\n * @returns {any} Render result; e.g., HTML string, DOM element, React\n * Component, etc.\n */\n render(token) {\n const ir = token.render(this); // intermediate representation\n const renderFn = this.get('render', null, token) || this.defaultRender;\n return renderFn(ir, token.t, token);\n }\n};\nfunction noop(val) {\n return val;\n}\n\nvar options = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tOptions: Options,\n\tdefaults: defaults\n});\n\n/******************************************************************************\n\tMulti-Tokens\n\tTokens composed of arrays of TextTokens\n******************************************************************************/\n\n/**\n * @param {string} value\n * @param {Token[]} tokens\n */\nfunction MultiToken(value, tokens) {\n this.t = 'token';\n this.v = value;\n this.tk = tokens;\n}\n\n/**\n * Abstract class used for manufacturing tokens of text tokens. That is rather\n * than the value for a token being a small string of text, it's value an array\n * of text tokens.\n *\n * Used for grouping together URLs, emails, hashtags, and other potential\n * creations.\n * @class MultiToken\n * @property {string} t\n * @property {string} v\n * @property {Token[]} tk\n * @abstract\n */\nMultiToken.prototype = {\n isLink: false,\n /**\n * Return the string this token represents.\n * @return {string}\n */\n toString() {\n return this.v;\n },\n /**\n * What should the value for this token be in the `href` HTML attribute?\n * Returns the `.toString` value by default.\n * @param {string} [scheme]\n * @return {string}\n */\n toHref(scheme) {\n return this.toString();\n },\n /**\n * @param {Options} options Formatting options\n * @returns {string}\n */\n toFormattedString(options) {\n const val = this.toString();\n const truncate = options.get('truncate', val, this);\n const formatted = options.get('format', val, this);\n return truncate && formatted.length > truncate ? formatted.substring(0, truncate) + '\u2026' : formatted;\n },\n /**\n *\n * @param {Options} options\n * @returns {string}\n */\n toFormattedHref(options) {\n return options.get('formatHref', this.toHref(options.get('defaultProtocol')), this);\n },\n /**\n * The start index of this token in the original input string\n * @returns {number}\n */\n startIndex() {\n return this.tk[0].s;\n },\n /**\n * The end index of this token in the original input string (up to this\n * index but not including it)\n * @returns {number}\n */\n endIndex() {\n return this.tk[this.tk.length - 1].e;\n },\n /**\n \tReturns an object of relevant values for this token, which includes keys\n \t* type - Kind of token ('url', 'email', etc.)\n \t* value - Original text\n \t* href - The value that should be added to the anchor tag's href\n \t\tattribute\n \t\t@method toObject\n \t@param {string} [protocol] `'http'` by default\n */\n toObject(protocol = defaults.defaultProtocol) {\n return {\n type: this.t,\n value: this.toString(),\n isLink: this.isLink,\n href: this.toHref(protocol),\n start: this.startIndex(),\n end: this.endIndex()\n };\n },\n /**\n *\n * @param {Options} options Formatting option\n */\n toFormattedObject(options) {\n return {\n type: this.t,\n value: this.toFormattedString(options),\n isLink: this.isLink,\n href: this.toFormattedHref(options),\n start: this.startIndex(),\n end: this.endIndex()\n };\n },\n /**\n * Whether this token should be rendered as a link according to the given options\n * @param {Options} options\n * @returns {boolean}\n */\n validate(options) {\n return options.get('validate', this.toString(), this);\n },\n /**\n * Return an object that represents how this link should be rendered.\n * @param {Options} options Formattinng options\n */\n render(options) {\n const token = this;\n const href = this.toHref(options.get('defaultProtocol'));\n const formattedHref = options.get('formatHref', href, this);\n const tagName = options.get('tagName', href, token);\n const content = this.toFormattedString(options);\n const attributes = {};\n const className = options.get('className', href, token);\n const target = options.get('target', href, token);\n const rel = options.get('rel', href, token);\n const attrs = options.getObj('attributes', href, token);\n const eventListeners = options.getObj('events', href, token);\n attributes.href = formattedHref;\n if (className) {\n attributes.class = className;\n }\n if (target) {\n attributes.target = target;\n }\n if (rel) {\n attributes.rel = rel;\n }\n if (attrs) {\n Object.assign(attributes, attrs);\n }\n return {\n tagName,\n attributes,\n content,\n eventListeners\n };\n }\n};\n\n/**\n * Create a new token that can be emitted by the parser state machine\n * @param {string} type readable type of the token\n * @param {object} props properties to assign or override, including isLink = true or false\n * @returns {new (value: string, tokens: Token[]) => MultiToken} new token class\n */\nfunction createTokenClass(type, props) {\n class Token extends MultiToken {\n constructor(value, tokens) {\n super(value, tokens);\n this.t = type;\n }\n }\n for (const p in props) {\n Token.prototype[p] = props[p];\n }\n Token.t = type;\n return Token;\n}\n\n/**\n\tRepresents a list of tokens making up a valid email address\n*/\nconst Email = createTokenClass('email', {\n isLink: true,\n toHref() {\n return 'mailto:' + this.toString();\n }\n});\n\n/**\n\tRepresents some plain text\n*/\nconst Text = createTokenClass('text');\n\n/**\n\tMulti-linebreak token - represents a line break\n\t@class Nl\n*/\nconst Nl = createTokenClass('nl');\n\n/**\n\tRepresents a list of text tokens making up a valid URL\n\t@class Url\n*/\nconst Url = createTokenClass('url', {\n isLink: true,\n /**\n \tLowercases relevant parts of the domain and adds the protocol if\n \trequired. Note that this will not escape unsafe HTML characters in the\n \tURL.\n \t\t@param {string} [scheme] default scheme (e.g., 'https')\n \t@return {string} the full href\n */\n toHref(scheme = defaults.defaultProtocol) {\n // Check if already has a prefix scheme\n return this.hasProtocol() ? this.v : `${scheme}://${this.v}`;\n },\n /**\n * Check whether this URL token has a protocol\n * @return {boolean}\n */\n hasProtocol() {\n const tokens = this.tk;\n return tokens.length >= 2 && tokens[0].t !== LOCALHOST && tokens[1].t === COLON;\n }\n});\n\nvar multi = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tBase: MultiToken,\n\tEmail: Email,\n\tMultiToken: MultiToken,\n\tNl: Nl,\n\tText: Text,\n\tUrl: Url,\n\tcreateTokenClass: createTokenClass\n});\n\n/**\n\tNot exactly parser, more like the second-stage scanner (although we can\n\ttheoretically hotswap the code here with a real parser in the future... but\n\tfor a little URL-finding utility abstract syntax trees may be a little\n\toverkill).\n\n\tURL format: http://en.wikipedia.org/wiki/URI_scheme\n\tEmail format: http://en.wikipedia.org/wiki/EmailAddress (links to RFC in\n\treference)\n\n\t@module linkify\n\t@submodule parser\n\t@main run\n*/\n\nconst makeState = arg => new State(arg);\n\n/**\n * Generate the parser multi token-based state machine\n * @param {{ groups: Collections }} tokens\n */\nfunction init$1({\n groups\n}) {\n // Types of characters the URL can definitely end in\n const qsAccepting = groups.domain.concat([AMPERSAND, ASTERISK, AT, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, NUM, PERCENT, PIPE, PLUS, POUND, SLASH, SYM, TILDE, UNDERSCORE]);\n\n // Types of tokens that can follow a URL and be part of the query string\n // but cannot be the very last characters\n // Characters that cannot appear in the URL at all should be excluded\n const qsNonAccepting = [APOSTROPHE, COLON, COMMA, DOT, EXCLAMATION, PERCENT, QUERY, QUOTE, SEMI, OPENANGLEBRACKET, CLOSEANGLEBRACKET, OPENBRACE, CLOSEBRACE, CLOSEBRACKET, OPENBRACKET, OPENPAREN, CLOSEPAREN, FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN, LEFTCORNERBRACKET, RIGHTCORNERBRACKET, LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET, FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN];\n\n // For addresses without the mailto prefix\n // Tokens allowed in the localpart of the email\n const localpartAccepting = [AMPERSAND, APOSTROPHE, ASTERISK, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, OPENBRACE, CLOSEBRACE, PERCENT, PIPE, PLUS, POUND, QUERY, SLASH, SYM, TILDE, UNDERSCORE];\n\n // The universal starting state.\n /**\n * @type State\n */\n const Start = makeState();\n const Localpart = tt(Start, TILDE); // Local part of the email address\n ta(Localpart, localpartAccepting, Localpart);\n ta(Localpart, groups.domain, Localpart);\n const Domain = makeState(),\n Scheme = makeState(),\n SlashScheme = makeState();\n ta(Start, groups.domain, Domain); // parsed string ends with a potential domain name (A)\n ta(Start, groups.scheme, Scheme); // e.g., 'mailto'\n ta(Start, groups.slashscheme, SlashScheme); // e.g., 'http'\n\n ta(Domain, localpartAccepting, Localpart);\n ta(Domain, groups.domain, Domain);\n const LocalpartAt = tt(Domain, AT); // Local part of the email address plus @\n\n tt(Localpart, AT, LocalpartAt); // close to an email address now\n\n // Local part of an email address can be e.g. 'http' or 'mailto'\n tt(Scheme, AT, LocalpartAt);\n tt(SlashScheme, AT, LocalpartAt);\n const LocalpartDot = tt(Localpart, DOT); // Local part of the email address plus '.' (localpart cannot end in .)\n ta(LocalpartDot, localpartAccepting, Localpart);\n ta(LocalpartDot, groups.domain, Localpart);\n const EmailDomain = makeState();\n ta(LocalpartAt, groups.domain, EmailDomain); // parsed string starts with local email info + @ with a potential domain name\n ta(EmailDomain, groups.domain, EmailDomain);\n const EmailDomainDot = tt(EmailDomain, DOT); // domain followed by DOT\n ta(EmailDomainDot, groups.domain, EmailDomain);\n const Email$1 = makeState(Email); // Possible email address (could have more tlds)\n ta(EmailDomainDot, groups.tld, Email$1);\n ta(EmailDomainDot, groups.utld, Email$1);\n tt(LocalpartAt, LOCALHOST, Email$1);\n\n // Hyphen can jump back to a domain name\n const EmailDomainHyphen = tt(EmailDomain, HYPHEN); // parsed string starts with local email info + @ with a potential domain name\n tt(EmailDomainHyphen, HYPHEN, EmailDomainHyphen);\n ta(EmailDomainHyphen, groups.domain, EmailDomain);\n ta(Email$1, groups.domain, EmailDomain);\n tt(Email$1, DOT, EmailDomainDot);\n tt(Email$1, HYPHEN, EmailDomainHyphen);\n\n // Final possible email states\n const EmailColon = tt(Email$1, COLON); // URL followed by colon (potential port number here)\n /*const EmailColonPort = */\n ta(EmailColon, groups.numeric, Email); // URL followed by colon and port number\n\n // Account for dots and hyphens. Hyphens are usually parts of domain names\n // (but not TLDs)\n const DomainHyphen = tt(Domain, HYPHEN); // domain followed by hyphen\n const DomainDot = tt(Domain, DOT); // domain followed by DOT\n tt(DomainHyphen, HYPHEN, DomainHyphen);\n ta(DomainHyphen, groups.domain, Domain);\n ta(DomainDot, localpartAccepting, Localpart);\n ta(DomainDot, groups.domain, Domain);\n const DomainDotTld = makeState(Url); // Simplest possible URL with no query string\n ta(DomainDot, groups.tld, DomainDotTld);\n ta(DomainDot, groups.utld, DomainDotTld);\n ta(DomainDotTld, groups.domain, Domain);\n ta(DomainDotTld, localpartAccepting, Localpart);\n tt(DomainDotTld, DOT, DomainDot);\n tt(DomainDotTld, HYPHEN, DomainHyphen);\n tt(DomainDotTld, AT, LocalpartAt);\n const DomainDotTldColon = tt(DomainDotTld, COLON); // URL followed by colon (potential port number here)\n const DomainDotTldColonPort = makeState(Url); // TLD followed by a port number\n ta(DomainDotTldColon, groups.numeric, DomainDotTldColonPort);\n\n // Long URL with optional port and maybe query string\n const Url$1 = makeState(Url);\n\n // URL with extra symbols at the end, followed by an opening bracket\n const UrlNonaccept = makeState(); // URL followed by some symbols (will not be part of the final URL)\n\n // Query strings\n ta(Url$1, qsAccepting, Url$1);\n ta(Url$1, qsNonAccepting, UrlNonaccept);\n ta(UrlNonaccept, qsAccepting, Url$1);\n ta(UrlNonaccept, qsNonAccepting, UrlNonaccept);\n\n // Become real URLs after `SLASH` or `COLON NUM SLASH`\n // Here works with or without scheme:// prefix\n tt(DomainDotTld, SLASH, Url$1);\n tt(DomainDotTldColonPort, SLASH, Url$1);\n\n // Note that domains that begin with schemes are treated slighly differently\n const SchemeColon = tt(Scheme, COLON); // e.g., 'mailto:'\n const SlashSchemeColon = tt(SlashScheme, COLON); // e.g., 'http:'\n const SlashSchemeColonSlash = tt(SlashSchemeColon, SLASH); // e.g., 'http:/'\n\n const UriPrefix = tt(SlashSchemeColonSlash, SLASH); // e.g., 'http://'\n\n // Scheme states can transition to domain states\n ta(Scheme, groups.domain, Domain);\n tt(Scheme, DOT, DomainDot);\n tt(Scheme, HYPHEN, DomainHyphen);\n ta(SlashScheme, groups.domain, Domain);\n tt(SlashScheme, DOT, DomainDot);\n tt(SlashScheme, HYPHEN, DomainHyphen);\n\n // Force URL with scheme prefix followed by anything sane\n ta(SchemeColon, groups.domain, Url$1);\n tt(SchemeColon, SLASH, Url$1);\n tt(SchemeColon, QUERY, Url$1);\n ta(UriPrefix, groups.domain, Url$1);\n ta(UriPrefix, qsAccepting, Url$1);\n tt(UriPrefix, SLASH, Url$1);\n const bracketPairs = [[OPENBRACE, CLOSEBRACE],\n // {}\n [OPENBRACKET, CLOSEBRACKET],\n // []\n [OPENPAREN, CLOSEPAREN],\n // ()\n [OPENANGLEBRACKET, CLOSEANGLEBRACKET],\n // <>\n [FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN],\n // \uFF08\uFF09\n [LEFTCORNERBRACKET, RIGHTCORNERBRACKET],\n // \u300C\u300D\n [LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET],\n // \u300E\u300F\n [FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN] // \uFF1C\uFF1E\n ];\n for (let i = 0; i < bracketPairs.length; i++) {\n const [OPEN, CLOSE] = bracketPairs[i];\n const UrlOpen = tt(Url$1, OPEN); // URL followed by open bracket\n\n // Continue not accepting for open brackets\n tt(UrlNonaccept, OPEN, UrlOpen);\n\n // Closing bracket component. This character WILL be included in the URL\n tt(UrlOpen, CLOSE, Url$1);\n\n // URL that beings with an opening bracket, followed by a symbols.\n // Note that the final state can still be `UrlOpen` (if the URL has a\n // single opening bracket for some reason).\n const UrlOpenQ = makeState(Url);\n ta(UrlOpen, qsAccepting, UrlOpenQ);\n const UrlOpenSyms = makeState(); // UrlOpen followed by some symbols it cannot end it\n ta(UrlOpen, qsNonAccepting);\n\n // URL that begins with an opening bracket, followed by some symbols\n ta(UrlOpenQ, qsAccepting, UrlOpenQ);\n ta(UrlOpenQ, qsNonAccepting, UrlOpenSyms);\n ta(UrlOpenSyms, qsAccepting, UrlOpenQ);\n ta(UrlOpenSyms, qsNonAccepting, UrlOpenSyms);\n\n // Close brace/bracket to become regular URL\n tt(UrlOpenQ, CLOSE, Url$1);\n tt(UrlOpenSyms, CLOSE, Url$1);\n }\n tt(Start, LOCALHOST, DomainDotTld); // localhost is a valid URL state\n tt(Start, NL, Nl); // single new line\n\n return {\n start: Start,\n tokens: tk\n };\n}\n\n/**\n * Run the parser state machine on a list of scanned string-based tokens to\n * create a list of multi tokens, each of which represents a URL, email address,\n * plain text, etc.\n *\n * @param {State} start parser start state\n * @param {string} input the original input used to generate the given tokens\n * @param {Token[]} tokens list of scanned tokens\n * @returns {MultiToken[]}\n */\nfunction run(start, input, tokens) {\n let len = tokens.length;\n let cursor = 0;\n let multis = [];\n let textTokens = [];\n while (cursor < len) {\n let state = start;\n let secondState = null;\n let nextState = null;\n let multiLength = 0;\n let latestAccepting = null;\n let sinceAccepts = -1;\n while (cursor < len && !(secondState = state.go(tokens[cursor].t))) {\n // Starting tokens with nowhere to jump to.\n // Consider these to be just plain text\n textTokens.push(tokens[cursor++]);\n }\n while (cursor < len && (nextState = secondState || state.go(tokens[cursor].t))) {\n // Get the next state\n secondState = null;\n state = nextState;\n\n // Keep track of the latest accepting state\n if (state.accepts()) {\n sinceAccepts = 0;\n latestAccepting = state;\n } else if (sinceAccepts >= 0) {\n sinceAccepts++;\n }\n cursor++;\n multiLength++;\n }\n if (sinceAccepts < 0) {\n // No accepting state was found, part of a regular text token add\n // the first text token to the text tokens array and try again from\n // the next\n cursor -= multiLength;\n if (cursor < len) {\n textTokens.push(tokens[cursor]);\n cursor++;\n }\n } else {\n // Accepting state!\n // First close off the textTokens (if available)\n if (textTokens.length > 0) {\n multis.push(initMultiToken(Text, input, textTokens));\n textTokens = [];\n }\n\n // Roll back to the latest accepting state\n cursor -= sinceAccepts;\n multiLength -= sinceAccepts;\n\n // Create a new multitoken\n const Multi = latestAccepting.t;\n const subtokens = tokens.slice(cursor - multiLength, cursor);\n multis.push(initMultiToken(Multi, input, subtokens));\n }\n }\n\n // Finally close off the textTokens (if available)\n if (textTokens.length > 0) {\n multis.push(initMultiToken(Text, input, textTokens));\n }\n return multis;\n}\n\n/**\n * Utility function for instantiating a new multitoken with all the relevant\n * fields during parsing.\n * @param {new (value: string, tokens: Token[]) => MultiToken} Multi class to instantiate\n * @param {string} input original input string\n * @param {Token[]} tokens consecutive tokens scanned from input string\n * @returns {MultiToken}\n */\nfunction initMultiToken(Multi, input, tokens) {\n const startIdx = tokens[0].s;\n const endIdx = tokens[tokens.length - 1].e;\n const value = input.slice(startIdx, endIdx);\n return new Multi(value, tokens);\n}\n\nconst warn = typeof console !== 'undefined' && console && console.warn || (() => {});\nconst warnAdvice = 'until manual call of linkify.init(). Register all schemes and plugins before invoking linkify the first time.';\n\n// Side-effect initialization state\nconst INIT = {\n scanner: null,\n parser: null,\n tokenQueue: [],\n pluginQueue: [],\n customSchemes: [],\n initialized: false\n};\n\n/**\n * @typedef {{\n * \tstart: State,\n * \ttokens: { groups: Collections } & typeof tk\n * }} ScannerInit\n */\n\n/**\n * @typedef {{\n * \tstart: State,\n * \ttokens: typeof multi\n * }} ParserInit\n */\n\n/**\n * @typedef {(arg: { scanner: ScannerInit }) => void} TokenPlugin\n */\n\n/**\n * @typedef {(arg: { scanner: ScannerInit, parser: ParserInit }) => void} Plugin\n */\n\n/**\n * De-register all plugins and reset the internal state-machine. Used for\n * testing; not required in practice.\n * @private\n */\nfunction reset() {\n State.groups = {};\n INIT.scanner = null;\n INIT.parser = null;\n INIT.tokenQueue = [];\n INIT.pluginQueue = [];\n INIT.customSchemes = [];\n INIT.initialized = false;\n return INIT;\n}\n\n/**\n * Register a token plugin to allow the scanner to recognize additional token\n * types before the parser state machine is constructed from the results.\n * @param {string} name of plugin to register\n * @param {TokenPlugin} plugin function that accepts the scanner state machine\n * and available scanner tokens and collections and extends the state machine to\n * recognize additional tokens or groups.\n */\nfunction registerTokenPlugin(name, plugin) {\n if (typeof plugin !== 'function') {\n throw new Error(`linkifyjs: Invalid token plugin ${plugin} (expects function)`);\n }\n for (let i = 0; i < INIT.tokenQueue.length; i++) {\n if (name === INIT.tokenQueue[i][0]) {\n warn(`linkifyjs: token plugin \"${name}\" already registered - will be overwritten`);\n INIT.tokenQueue[i] = [name, plugin];\n return;\n }\n }\n INIT.tokenQueue.push([name, plugin]);\n if (INIT.initialized) {\n warn(`linkifyjs: already initialized - will not register token plugin \"${name}\" ${warnAdvice}`);\n }\n}\n\n/**\n * Register a linkify plugin\n * @param {string} name of plugin to register\n * @param {Plugin} plugin function that accepts the parser state machine and\n * extends the parser to recognize additional link types\n */\nfunction registerPlugin(name, plugin) {\n if (typeof plugin !== 'function') {\n throw new Error(`linkifyjs: Invalid plugin ${plugin} (expects function)`);\n }\n for (let i = 0; i < INIT.pluginQueue.length; i++) {\n if (name === INIT.pluginQueue[i][0]) {\n warn(`linkifyjs: plugin \"${name}\" already registered - will be overwritten`);\n INIT.pluginQueue[i] = [name, plugin];\n return;\n }\n }\n INIT.pluginQueue.push([name, plugin]);\n if (INIT.initialized) {\n warn(`linkifyjs: already initialized - will not register plugin \"${name}\" ${warnAdvice}`);\n }\n}\n\n/**\n * Detect URLs with the following additional protocol. Anything with format\n * \"protocol://...\" will be considered a link. If `optionalSlashSlash` is set to\n * `true`, anything with format \"protocol:...\" will be considered a link.\n * @param {string} scheme\n * @param {boolean} [optionalSlashSlash]\n */\nfunction registerCustomProtocol(scheme, optionalSlashSlash = false) {\n if (INIT.initialized) {\n warn(`linkifyjs: already initialized - will not register custom scheme \"${scheme}\" ${warnAdvice}`);\n }\n if (!/^[0-9a-z]+(-[0-9a-z]+)*$/.test(scheme)) {\n throw new Error(`linkifyjs: incorrect scheme format.\n1. Must only contain digits, lowercase ASCII letters or \"-\"\n2. Cannot start or end with \"-\"\n3. \"-\" cannot repeat`);\n }\n INIT.customSchemes.push([scheme, optionalSlashSlash]);\n}\n\n/**\n * Initialize the linkify state machine. Called automatically the first time\n * linkify is called on a string, but may be called manually as well.\n */\nfunction init() {\n // Initialize scanner state machine and plugins\n INIT.scanner = init$2(INIT.customSchemes);\n for (let i = 0; i < INIT.tokenQueue.length; i++) {\n INIT.tokenQueue[i][1]({\n scanner: INIT.scanner\n });\n }\n\n // Initialize parser state machine and plugins\n INIT.parser = init$1(INIT.scanner.tokens);\n for (let i = 0; i < INIT.pluginQueue.length; i++) {\n INIT.pluginQueue[i][1]({\n scanner: INIT.scanner,\n parser: INIT.parser\n });\n }\n INIT.initialized = true;\n return INIT;\n}\n\n/**\n * Parse a string into tokens that represent linkable and non-linkable sub-components\n * @param {string} str\n * @return {MultiToken[]} tokens\n */\nfunction tokenize(str) {\n if (!INIT.initialized) {\n init();\n }\n return run(INIT.parser.start, str, run$1(INIT.scanner.start, str));\n}\ntokenize.scan = run$1; // for testing\n\n/**\n * Find a list of linkable items in the given string.\n * @param {string} str string to find links in\n * @param {string | Opts} [type] either formatting options or specific type of\n * links to find, e.g., 'url' or 'email'\n * @param {Opts} [opts] formatting options for final output. Cannot be specified\n * if opts already provided in `type` argument\n */\nfunction find(str, type = null, opts = null) {\n if (type && typeof type === 'object') {\n if (opts) {\n throw Error(`linkifyjs: Invalid link type ${type}; must be a string`);\n }\n opts = type;\n type = null;\n }\n const options = new Options(opts);\n const tokens = tokenize(str);\n const filtered = [];\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n if (token.isLink && (!type || token.t === type) && options.check(token)) {\n filtered.push(token.toFormattedObject(options));\n }\n }\n return filtered;\n}\n\n/**\n * Is the given string valid linkable text of some sort. Note that this does not\n * trim the text for you.\n *\n * Optionally pass in a second `type` param, which is the type of link to test\n * for.\n *\n * For example,\n *\n * linkify.test(str, 'email');\n *\n * Returns `true` if str is a valid email.\n * @param {string} str string to test for links\n * @param {string} [type] optional specific link type to look for\n * @returns boolean true/false\n */\nfunction test(str, type = null) {\n const tokens = tokenize(str);\n return tokens.length === 1 && tokens[0].isLink && (!type || tokens[0].t === type);\n}\n\nexport { MultiToken, Options, State, createTokenClass, find, init, multi, options, regexp, registerCustomProtocol, registerPlugin, registerTokenPlugin, reset, stringToArray, test, multi as text, tokenize };\n", "import type { PasteRuleMatch } from '@tiptap/core'\nimport { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'\nimport type { Plugin } from '@tiptap/pm/state'\nimport { find, registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\nimport { UNICODE_WHITESPACE_REGEX_GLOBAL } from './helpers/whitespace.js'\n\nexport interface LinkProtocolOptions {\n /**\n * The protocol scheme to be registered.\n * @default '''\n * @example 'ftp'\n * @example 'git'\n */\n scheme: string\n\n /**\n * If enabled, it allows optional slashes after the protocol.\n * @default false\n * @example true\n */\n optionalSlashes?: boolean\n}\n\nexport const pasteRegex =\n /https?:\\/\\/(?:www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z]{2,}\\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi\n\n/**\n * @deprecated The default behavior is now to open links when the editor is not editable.\n */\ntype DeprecatedOpenWhenNotEditable = 'whenNotEditable'\n\nexport interface LinkOptions {\n /**\n * If enabled, the extension will automatically add links as you type.\n * @default true\n * @example false\n */\n autolink: boolean\n\n /**\n * An array of custom protocols to be registered with linkifyjs.\n * @default []\n * @example ['ftp', 'git']\n */\n protocols: Array\n\n /**\n * Default protocol to use when no protocol is specified.\n * @default 'http'\n */\n defaultProtocol: string\n /**\n * If enabled, links will be opened on click.\n * @default true\n * @example false\n */\n openOnClick: boolean | DeprecatedOpenWhenNotEditable\n /**\n * If enabled, the link will be selected when clicked.\n * @default false\n * @example true\n */\n enableClickSelection: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n * @default true\n * @example false\n */\n linkOnPaste: boolean\n\n /**\n * HTML attributes to add to the link element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n\n /**\n * @deprecated Use the `shouldAutoLink` option instead.\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate: (url: string) => boolean\n\n /**\n * A validation function which is used for configuring link verification for preventing XSS attacks.\n * Only modify this if you know what you're doing.\n *\n * @returns {boolean} `true` if the URL is valid, `false` otherwise.\n *\n * @example\n * isAllowedUri: (url, { defaultValidate, protocols, defaultProtocol }) => {\n * return url.startsWith('./') || defaultValidate(url)\n * }\n */\n isAllowedUri: (\n /**\n * The URL to be validated.\n */\n url: string,\n ctx: {\n /**\n * The default validation function.\n */\n defaultValidate: (url: string) => boolean\n /**\n * An array of allowed protocols for the URL (e.g., \"http\", \"https\"). As defined in the `protocols` option.\n */\n protocols: Array\n /**\n * A string that represents the default protocol (e.g., 'http'). As defined in the `defaultProtocol` option.\n */\n defaultProtocol: string\n },\n ) => boolean\n\n /**\n * Determines whether a valid link should be automatically linked in the content.\n *\n * @param {string} url - The URL that has already been validated.\n * @returns {boolean} - True if the link should be auto-linked; false if it should not be auto-linked.\n */\n shouldAutoLink: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n link: {\n /**\n * Set a link mark\n * @param attributes The link attributes\n * @example editor.commands.setLink({ href: 'https://tiptap.dev' })\n */\n setLink: (attributes: {\n href: string\n target?: string | null\n rel?: string | null\n class?: string | null\n title?: string | null\n }) => ReturnType\n /**\n * Toggle a link mark\n * @param attributes The link attributes\n * @example editor.commands.toggleLink({ href: 'https://tiptap.dev' })\n */\n toggleLink: (attributes?: {\n href: string\n target?: string | null\n rel?: string | null\n class?: string | null\n title?: string | null\n }) => ReturnType\n /**\n * Unset a link mark\n * @example editor.commands.unsetLink()\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport function isAllowedUri(uri: string | undefined, protocols?: LinkOptions['protocols']) {\n const allowedProtocols: string[] = ['http', 'https', 'ftp', 'ftps', 'mailto', 'tel', 'callto', 'sms', 'cid', 'xmpp']\n\n if (protocols) {\n protocols.forEach(protocol => {\n const nextProtocol = typeof protocol === 'string' ? protocol : protocol.scheme\n\n if (nextProtocol) {\n allowedProtocols.push(nextProtocol)\n }\n })\n }\n\n return (\n !uri ||\n uri.replace(UNICODE_WHITESPACE_REGEX_GLOBAL, '').match(\n new RegExp(\n // eslint-disable-next-line no-useless-escape\n `^(?:(?:${allowedProtocols.join('|')}):|[^a-z]|[a-z0-9+.\\-]+(?:[^a-z+.\\-:]|$))`,\n 'i',\n ),\n )\n )\n}\n\n/**\n * This extension allows you to create links.\n * @see https://www.tiptap.dev/api/marks/link\n */\nexport const Link = Mark.create({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n exitable: true,\n\n onCreate() {\n // TODO: v4 - remove validate option\n if (this.options.validate && !this.options.shouldAutoLink) {\n // Copy the validate function to the shouldAutoLink option\n this.options.shouldAutoLink = this.options.validate\n console.warn('The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.')\n }\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n enableClickSelection: false,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n defaultProtocol: 'http',\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n isAllowedUri: (url, ctx) => !!isAllowedUri(url, ctx.protocols),\n validate: url => !!url,\n shouldAutoLink: url => {\n // URLs with explicit protocols (e.g., https://) should be auto-linked\n // But not if @ appears before :// (that would be userinfo like user:pass@host)\n const hasProtocol = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(url)\n const hasMaybeProtocol = /^[a-z][a-z0-9+.-]*:/i.test(url)\n\n if (hasProtocol || (hasMaybeProtocol && !url.includes('@'))) {\n return true\n }\n // Strip userinfo (user:pass@) if present, then extract hostname\n const urlWithoutUserinfo = url.includes('@') ? url.split('@').pop()! : url\n const hostname = urlWithoutUserinfo.split(/[/?#:]/)[0]\n\n // Don't auto-link IP addresses without protocol\n if (/^\\d{1,3}(\\.\\d{1,3}){3}$/.test(hostname)) {\n return false\n }\n // Don't auto-link single-word hostnames without TLD (e.g., \"localhost\")\n if (!/\\./.test(hostname)) {\n return false\n }\n return true\n },\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n parseHTML(element) {\n return element.getAttribute('href')\n },\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n title: {\n default: null,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'a[href]',\n getAttrs: dom => {\n const href = (dom as HTMLElement).getAttribute('href')\n\n // prevent XSS attacks\n if (\n !href ||\n !this.options.isAllowedUri(href, {\n defaultValidate: url => !!isAllowedUri(url, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n })\n ) {\n return false\n }\n return null\n },\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n // prevent XSS attacks\n if (\n !this.options.isAllowedUri(HTMLAttributes.href, {\n defaultValidate: href => !!isAllowedUri(href, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n })\n ) {\n // strip out the href\n return ['a', mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: '' }), 0]\n }\n\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n markdownTokenName: 'link',\n\n parseMarkdown: (token, helpers) => {\n return helpers.applyMark('link', helpers.parseInline(token.tokens || []), {\n href: token.href,\n title: token.title || null,\n })\n },\n\n renderMarkdown: (node, h) => {\n const href = node.attrs?.href ?? ''\n const title = node.attrs?.title ?? ''\n const text = h.renderChildren(node)\n\n return title ? `[${text}](${href} \"${title}\")` : `[${text}](${href})`\n },\n\n addCommands() {\n return {\n setLink:\n attributes =>\n ({ chain }) => {\n const { href } = attributes\n\n if (\n !this.options.isAllowedUri(href, {\n defaultValidate: url => !!isAllowedUri(url, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n })\n ) {\n return false\n }\n\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes =>\n ({ chain }) => {\n const { href } = attributes || {}\n\n if (\n href &&\n !this.options.isAllowedUri(href, {\n defaultValidate: url => !!isAllowedUri(url, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n })\n ) {\n return false\n }\n\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () =>\n ({ chain }) => {\n return chain().unsetMark(this.name, { extendEmptyMarkRange: true }).setMeta('preventAutolink', true).run()\n },\n }\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: text => {\n const foundLinks: PasteRuleMatch[] = []\n\n if (text) {\n const { protocols, defaultProtocol } = this.options\n const links = find(text).filter(\n item =>\n item.isLink &&\n this.options.isAllowedUri(item.value, {\n defaultValidate: href => !!isAllowedUri(href, protocols),\n protocols,\n defaultProtocol,\n }),\n )\n\n if (links.length) {\n links.forEach(link => {\n if (!this.options.shouldAutoLink(link.value)) {\n return\n }\n\n foundLinks.push({\n text: link.value,\n data: {\n href: link.href,\n },\n index: link.start,\n })\n })\n }\n }\n\n return foundLinks\n },\n type: this.type,\n getAttributes: match => {\n return {\n href: match.data?.href,\n }\n },\n }),\n ]\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n const { protocols, defaultProtocol } = this.options\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n defaultProtocol: this.options.defaultProtocol,\n validate: url =>\n this.options.isAllowedUri(url, {\n defaultValidate: href => !!isAllowedUri(href, protocols),\n protocols,\n defaultProtocol,\n }),\n shouldAutoLink: this.options.shouldAutoLink,\n }),\n )\n }\n\n plugins.push(\n clickHandler({\n type: this.type,\n editor: this.editor,\n openOnClick: this.options.openOnClick === 'whenNotEditable' ? true : this.options.openOnClick,\n enableClickSelection: this.options.enableClickSelection,\n }),\n )\n\n if (this.options.linkOnPaste) {\n plugins.push(\n pasteHandler({\n editor: this.editor,\n defaultProtocol: this.options.defaultProtocol,\n type: this.type,\n shouldAutoLink: this.options.shouldAutoLink,\n }),\n )\n }\n\n return plugins\n },\n})\n", "import type { NodeWithPos } from '@tiptap/core'\nimport { combineTransactionSteps, findChildrenInRange, getChangedRanges, getMarksBetween } from '@tiptap/core'\nimport type { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { MultiToken } from 'linkifyjs'\nimport { tokenize } from 'linkifyjs'\n\nimport { UNICODE_WHITESPACE_REGEX, UNICODE_WHITESPACE_REGEX_END } from './whitespace.js'\n\n/**\n * Check if the provided tokens form a valid link structure, which can either be a single link token\n * or a link token surrounded by parentheses or square brackets.\n *\n * This ensures that only complete and valid text is hyperlinked, preventing cases where a valid\n * top-level domain (TLD) is immediately followed by an invalid character, like a number. For\n * example, with the `find` method from Linkify, entering `example.com1` would result in\n * `example.com` being linked and the trailing `1` left as plain text. By using the `tokenize`\n * method, we can perform more comprehensive validation on the input text.\n */\nfunction isValidLinkStructure(tokens: Array>) {\n if (tokens.length === 1) {\n return tokens[0].isLink\n }\n\n if (tokens.length === 3 && tokens[1].isLink) {\n return ['()', '[]'].includes(tokens[0].value + tokens[2].value)\n }\n\n return false\n}\n\ntype AutolinkOptions = {\n type: MarkType\n defaultProtocol: string\n validate: (url: string) => boolean\n shouldAutoLink: (url: string) => boolean\n}\n\n/**\n * This plugin allows you to automatically add links to your editor.\n * @param options The plugin options\n * @returns The plugin instance\n */\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n /**\n * Does the transaction change the document?\n */\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n\n /**\n * Prevent autolink if the transaction is not a document change or if the transaction has the meta `preventAutolink`.\n */\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n /**\n * Prevent autolink if the transaction is not a document change\n * or if the transaction has the meta `preventAutolink`.\n */\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, node => node.isTextblock)\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (nodesInChangedRanges.length) {\n const endText = newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ')\n if (!UNICODE_WHITESPACE_REGEX_END.test(endText)) {\n return\n }\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, undefined, ' ')\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(UNICODE_WHITESPACE_REGEX).filter(Boolean)\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject(options.defaultProtocol))\n\n if (!isValidLinkStructure(linksBeforeSpace)) {\n return false\n }\n\n linksBeforeSpace\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n if (!newState.schema.marks.code) {\n return true\n }\n\n return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code)\n })\n // validate link\n .filter(link => options.validate(link.value))\n // check whether should autolink\n .filter(link => options.shouldAutoLink(link.value))\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n", "// From DOMPurify\n// https://github.com/cure53/DOMPurify/blob/main/src/regexp.ts\nexport const UNICODE_WHITESPACE_PATTERN = '[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]'\n\nexport const UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN)\nexport const UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`)\nexport const UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, 'g')\n", "import type { Editor } from '@tiptap/core'\nimport { getAttributes } from '@tiptap/core'\nimport type { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n editor: Editor\n openOnClick?: boolean\n enableClickSelection?: boolean\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n if (!view.editable) {\n return false\n }\n\n let link: HTMLAnchorElement | null = null\n\n if (event.target instanceof HTMLAnchorElement) {\n link = event.target\n } else {\n const target = event.target as HTMLElement | null\n if (!target) {\n return false\n }\n\n const root = options.editor.view.dom\n\n // Tntentionally limit the lookup to the editor root.\n // Using tag names like DIV as boundaries breaks with custom NodeViews,\n link = target.closest('a')\n\n if (link && !root.contains(link)) {\n link = null\n }\n }\n\n if (!link) {\n return false\n }\n\n let handled = false\n\n if (options.enableClickSelection) {\n const commandResult = options.editor.commands.extendMarkRange(options.type.name)\n handled = commandResult\n }\n\n if (options.openOnClick) {\n const attrs = getAttributes(view.state, options.type.name)\n const href = link.href ?? attrs.href\n const target = link.target ?? attrs.target\n\n if (href) {\n window.open(href, target)\n handled = true\n }\n }\n\n return handled\n },\n },\n })\n}\n", "import type { Editor } from '@tiptap/core'\nimport type { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\nimport type { LinkOptions } from '../link.js'\n\ntype PasteHandlerOptions = {\n editor: Editor\n defaultProtocol: string\n type: MarkType\n shouldAutoLink?: LinkOptions['shouldAutoLink']\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, _event, slice) => {\n const { shouldAutoLink } = options\n const { state } = view\n const { selection } = state\n const { empty } = selection\n\n if (empty) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n const link = find(textContent, { defaultProtocol: options.defaultProtocol }).find(\n item => item.isLink && item.value === textContent,\n )\n\n if (!textContent || !link || (shouldAutoLink !== undefined && !shouldAutoLink(link.value))) {\n return false\n }\n\n return options.editor.commands.setMark(options.type, {\n href: link.href,\n })\n },\n },\n })\n}\n", "import { Link } from './link.js'\n\nexport * from './link.js'\n\nexport default Link\n", "import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'\n\nconst ListItemName = 'listItem'\nconst TextStyleName = 'textStyle'\n\nexport interface BulletListOptions {\n /**\n * The node name for the list items\n * @default 'listItem'\n * @example 'paragraph'\n */\n itemTypeName: string\n\n /**\n * HTML attributes to add to the bullet list element\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n\n /**\n * Keep the marks when splitting the list\n * @default false\n * @example true\n */\n keepMarks: boolean\n\n /**\n * Keep the attributes when splitting the list\n * @default false\n * @example true\n */\n keepAttributes: boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n bulletList: {\n /**\n * Toggle a bullet list\n */\n toggleBulletList: () => ReturnType\n }\n }\n}\n\n/**\n * Matches a bullet list to a dash or asterisk.\n */\nexport const bulletListInputRegex = /^\\s*([-+*])\\s$/\n\n/**\n * This extension allows you to create bullet lists.\n * This requires the ListItem extension\n * @see https://tiptap.dev/api/nodes/bullet-list\n * @see https://tiptap.dev/api/nodes/list-item.\n */\nexport const BulletList = Node.create({\n name: 'bulletList',\n\n addOptions() {\n return {\n itemTypeName: 'listItem',\n HTMLAttributes: {},\n keepMarks: false,\n keepAttributes: false,\n }\n },\n\n group: 'block list',\n\n content() {\n return `${this.options.itemTypeName}+`\n },\n\n parseHTML() {\n return [{ tag: 'ul' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['ul', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n markdownTokenName: 'list',\n\n parseMarkdown: (token, helpers) => {\n if (token.type !== 'list' || (token as any).ordered) {\n return []\n }\n\n return {\n type: 'bulletList',\n content: token.items ? helpers.parseChildren(token.items) : [],\n }\n },\n\n renderMarkdown: (node, h) => {\n if (!node.content) {\n return ''\n }\n\n return h.renderChildren(node.content, '\\n')\n },\n\n markdownOptions: {\n indentsContent: true,\n },\n\n addCommands() {\n return {\n toggleBulletList:\n () =>\n ({ commands, chain }) => {\n if (this.options.keepAttributes) {\n return chain()\n .toggleList(this.name, this.options.itemTypeName, this.options.keepMarks)\n .updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName))\n .run()\n }\n return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Shift-8': () => this.editor.commands.toggleBulletList(),\n }\n },\n\n addInputRules() {\n let inputRule = wrappingInputRule({\n find: bulletListInputRegex,\n type: this.type,\n })\n\n if (this.options.keepMarks || this.options.keepAttributes) {\n inputRule = wrappingInputRule({\n find: bulletListInputRegex,\n type: this.type,\n keepMarks: this.options.keepMarks,\n keepAttributes: this.options.keepAttributes,\n getAttributes: () => {\n return this.editor.getAttributes(TextStyleName)\n },\n editor: this.editor,\n })\n }\n return [inputRule]\n },\n})\n", "import { mergeAttributes, Node, renderNestedMarkdownContent } from '@tiptap/core'\n\nexport interface ListItemOptions {\n /**\n * The HTML attributes for a list item node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n\n /**\n * The node type for bulletList nodes\n * @default 'bulletList'\n * @example 'myCustomBulletList'\n */\n bulletListTypeName: string\n\n /**\n * The node type for orderedList nodes\n * @default 'orderedList'\n * @example 'myCustomOrderedList'\n */\n orderedListTypeName: string\n}\n\n/**\n * This extension allows you to create list items.\n * @see https://www.tiptap.dev/api/nodes/list-item\n */\nexport const ListItem = Node.create({\n name: 'listItem',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n bulletListTypeName: 'bulletList',\n orderedListTypeName: 'orderedList',\n }\n },\n\n content: 'paragraph block*',\n\n defining: true,\n\n parseHTML() {\n return [\n {\n tag: 'li',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['li', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n markdownTokenName: 'list_item',\n\n parseMarkdown: (token, helpers) => {\n if (token.type !== 'list_item') {\n return []\n }\n\n let content: any[] = []\n\n if (token.tokens && token.tokens.length > 0) {\n // Check if we have paragraph tokens (complex list items)\n const hasParagraphTokens = token.tokens.some(t => t.type === 'paragraph')\n\n if (hasParagraphTokens) {\n // If we have paragraph tokens, parse them as block elements\n content = helpers.parseChildren(token.tokens)\n } else {\n // Check if the first token is a text token with nested inline tokens\n const firstToken = token.tokens[0]\n\n if (firstToken && firstToken.type === 'text' && firstToken.tokens && firstToken.tokens.length > 0) {\n // Parse the inline content from the text token\n const inlineContent = helpers.parseInline(firstToken.tokens)\n\n // Start with the paragraph containing the inline content\n content = [\n {\n type: 'paragraph',\n content: inlineContent,\n },\n ]\n\n // If there are additional tokens after the first text token (like nested lists),\n // parse them as block elements and add them\n if (token.tokens.length > 1) {\n const remainingTokens = token.tokens.slice(1)\n const additionalContent = helpers.parseChildren(remainingTokens)\n content.push(...additionalContent)\n }\n } else {\n // Fallback: parse all tokens as block elements\n content = helpers.parseChildren(token.tokens)\n }\n }\n }\n\n // Ensure we always have at least an empty paragraph\n if (content.length === 0) {\n content = [\n {\n type: 'paragraph',\n content: [],\n },\n ]\n }\n\n return {\n type: 'listItem',\n content,\n }\n },\n\n renderMarkdown: (node, h, ctx) => {\n return renderNestedMarkdownContent(\n node,\n h,\n (context: any) => {\n if (context.parentType === 'bulletList') {\n return '- '\n }\n if (context.parentType === 'orderedList') {\n const start = context.meta?.parentAttrs?.start || 1\n return `${start + context.index}. `\n }\n // Fallback to bullet list for unknown parent types\n return '- '\n },\n ctx,\n )\n },\n\n addKeyboardShortcuts() {\n return {\n Enter: () => this.editor.commands.splitListItem(this.name),\n Tab: () => this.editor.commands.sinkListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n },\n})\n", "import { Extension } from '@tiptap/core'\n\nimport { handleBackspace, handleDelete } from './listHelpers/index.js'\n\nexport type ListKeymapOptions = {\n /**\n * An array of list types. This is used for item and wrapper list matching.\n * @default []\n * @example [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }]\n */\n listTypes: Array<{\n itemName: string\n wrapperNames: string[]\n }>\n}\n\n/**\n * This extension registers custom keymaps to change the behaviour of the backspace and delete keys.\n * By default Prosemirror keyhandling will always lift or sink items so paragraphs are joined into\n * the adjacent or previous list item. This extension will prevent this behaviour and instead will\n * try to join paragraphs from two list items into a single list item.\n * @see https://www.tiptap.dev/api/extensions/list-keymap\n */\nexport const ListKeymap = Extension.create({\n name: 'listKeymap',\n\n addOptions() {\n return {\n listTypes: [\n {\n itemName: 'listItem',\n wrapperNames: ['bulletList', 'orderedList'],\n },\n {\n itemName: 'taskItem',\n wrapperNames: ['taskList'],\n },\n ],\n }\n },\n\n addKeyboardShortcuts() {\n return {\n Delete: ({ editor }) => {\n let handled = false\n\n this.options.listTypes.forEach(({ itemName }) => {\n if (editor.state.schema.nodes[itemName] === undefined) {\n return\n }\n\n if (handleDelete(editor, itemName)) {\n handled = true\n }\n })\n\n return handled\n },\n 'Mod-Delete': ({ editor }) => {\n let handled = false\n\n this.options.listTypes.forEach(({ itemName }) => {\n if (editor.state.schema.nodes[itemName] === undefined) {\n return\n }\n\n if (handleDelete(editor, itemName)) {\n handled = true\n }\n })\n\n return handled\n },\n Backspace: ({ editor }) => {\n let handled = false\n\n this.options.listTypes.forEach(({ itemName, wrapperNames }) => {\n if (editor.state.schema.nodes[itemName] === undefined) {\n return\n }\n\n if (handleBackspace(editor, itemName, wrapperNames)) {\n handled = true\n }\n })\n\n return handled\n },\n 'Mod-Backspace': ({ editor }) => {\n let handled = false\n\n this.options.listTypes.forEach(({ itemName, wrapperNames }) => {\n if (editor.state.schema.nodes[itemName] === undefined) {\n return\n }\n\n if (handleBackspace(editor, itemName, wrapperNames)) {\n handled = true\n }\n })\n\n return handled\n },\n }\n },\n})\n", "export * from './findListItemPos.js'\nexport * from './getNextListDepth.js'\nexport * from './handleBackspace.js'\nexport * from './handleDelete.js'\nexport * from './hasListBefore.js'\nexport * from './hasListItemAfter.js'\nexport * from './hasListItemBefore.js'\nexport * from './listItemHasSubList.js'\nexport * from './nextListIsDeeper.js'\nexport * from './nextListIsHigher.js'\n", "import { getNodeType } from '@tiptap/core'\nimport type { NodeType } from '@tiptap/pm/model'\nimport type { EditorState } from '@tiptap/pm/state'\n\nexport const findListItemPos = (typeOrName: string | NodeType, state: EditorState) => {\n const { $from } = state.selection\n const nodeType = getNodeType(typeOrName, state.schema)\n\n let currentNode = null\n let currentDepth = $from.depth\n let currentPos = $from.pos\n let targetDepth: number | null = null\n\n while (currentDepth > 0 && targetDepth === null) {\n currentNode = $from.node(currentDepth)\n\n if (currentNode.type === nodeType) {\n targetDepth = currentDepth\n } else {\n currentDepth -= 1\n currentPos -= 1\n }\n }\n\n if (targetDepth === null) {\n return null\n }\n\n return { $pos: state.doc.resolve(currentPos), depth: targetDepth }\n}\n", "import { getNodeAtPosition } from '@tiptap/core'\nimport type { EditorState } from '@tiptap/pm/state'\n\nimport { findListItemPos } from './findListItemPos.js'\n\nexport const getNextListDepth = (typeOrName: string, state: EditorState) => {\n const listItemPos = findListItemPos(typeOrName, state)\n\n if (!listItemPos) {\n return false\n }\n\n const [, depth] = getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4)\n\n return depth\n}\n", "import type { Editor } from '@tiptap/core'\nimport { isAtStartOfNode, isNodeActive } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\n\nimport { findListItemPos } from './findListItemPos.js'\nimport { hasListBefore } from './hasListBefore.js'\nimport { hasListItemBefore } from './hasListItemBefore.js'\nimport { listItemHasSubList } from './listItemHasSubList.js'\n\nexport const handleBackspace = (editor: Editor, name: string, parentListTypes: string[]) => {\n // this is required to still handle the undo handling\n if (editor.commands.undoInputRule()) {\n return true\n }\n\n // if the selection is not collapsed\n // we can rely on the default backspace behavior\n if (editor.state.selection.from !== editor.state.selection.to) {\n return false\n }\n\n // if the current item is NOT inside a list item &\n // the previous item is a list (orderedList or bulletList)\n // move the cursor into the list and delete the current item\n if (!isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {\n const { $anchor } = editor.state.selection\n\n const $listPos = editor.state.doc.resolve($anchor.before() - 1)\n\n const listDescendants: Array<{ node: Node; pos: number }> = []\n\n $listPos.node().descendants((node, pos) => {\n if (node.type.name === name) {\n listDescendants.push({ node, pos })\n }\n })\n\n const lastItem = listDescendants.at(-1)\n\n if (!lastItem) {\n return false\n }\n\n const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1)\n\n return editor\n .chain()\n .cut({ from: $anchor.start() - 1, to: $anchor.end() + 1 }, $lastItemPos.end())\n .joinForward()\n .run()\n }\n\n // if the cursor is not inside the current node type\n // do nothing and proceed\n if (!isNodeActive(editor.state, name)) {\n return false\n }\n\n // if the cursor is not at the start of a node\n // do nothing and proceed\n if (!isAtStartOfNode(editor.state)) {\n return false\n }\n\n const listItemPos = findListItemPos(name, editor.state)\n\n if (!listItemPos) {\n return false\n }\n\n const $prev = editor.state.doc.resolve(listItemPos.$pos.pos - 2)\n const prevNode = $prev.node(listItemPos.depth)\n\n const previousListItemHasSubList = listItemHasSubList(name, editor.state, prevNode)\n\n // if the previous item is a list item and doesn't have a sublist, join the list items\n if (hasListItemBefore(name, editor.state) && !previousListItemHasSubList) {\n return editor.commands.joinItemBackward()\n }\n\n // otherwise in the end, a backspace should\n // always just lift the list item if\n // joining / merging is not possible\n return editor.chain().liftListItem(name).run()\n}\n", "import type { EditorState } from '@tiptap/pm/state'\n\nexport const hasListBefore = (editorState: EditorState, name: string, parentListTypes: string[]) => {\n const { $anchor } = editorState.selection\n\n const previousNodePos = Math.max(0, $anchor.pos - 2)\n\n const previousNode = editorState.doc.resolve(previousNodePos).node()\n\n if (!previousNode || !parentListTypes.includes(previousNode.type.name)) {\n return false\n }\n\n return true\n}\n", "import type { EditorState } from '@tiptap/pm/state'\n\nexport const hasListItemBefore = (typeOrName: string, state: EditorState): boolean => {\n const { $anchor } = state.selection\n\n const $targetPos = state.doc.resolve($anchor.pos - 2)\n\n if ($targetPos.index() === 0) {\n return false\n }\n\n if ($targetPos.nodeBefore?.type.name !== typeOrName) {\n return false\n }\n\n return true\n}\n", "import { getNodeType } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\nimport type { EditorState } from '@tiptap/pm/state'\n\nexport const listItemHasSubList = (typeOrName: string, state: EditorState, node?: Node) => {\n if (!node) {\n return false\n }\n\n const nodeType = getNodeType(typeOrName, state.schema)\n\n let hasSubList = false\n\n node.descendants(child => {\n if (child.type === nodeType) {\n hasSubList = true\n }\n })\n\n return hasSubList\n}\n", "import type { Editor } from '@tiptap/core'\nimport { isAtEndOfNode, isNodeActive } from '@tiptap/core'\n\nimport { nextListIsDeeper } from './nextListIsDeeper.js'\nimport { nextListIsHigher } from './nextListIsHigher.js'\n\nexport const handleDelete = (editor: Editor, name: string) => {\n // if the cursor is not inside the current node type\n // do nothing and proceed\n if (!isNodeActive(editor.state, name)) {\n return false\n }\n\n // if the cursor is not at the end of a node\n // do nothing and proceed\n if (!isAtEndOfNode(editor.state, name)) {\n return false\n }\n\n // if the selection is not collapsed, or not within a single node\n // do nothing and proceed\n const { selection } = editor.state\n const { $from, $to } = selection\n\n if (!selection.empty && $from.sameParent($to)) {\n return false\n }\n\n // check if the next node is a list with a deeper depth\n if (nextListIsDeeper(name, editor.state)) {\n return editor\n .chain()\n .focus(editor.state.selection.from + 4)\n .lift(name)\n .joinBackward()\n .run()\n }\n\n if (nextListIsHigher(name, editor.state)) {\n return editor.chain().joinForward().joinBackward().run()\n }\n\n return editor.commands.joinItemForward()\n}\n", "import type { EditorState } from '@tiptap/pm/state'\n\nimport { findListItemPos } from './findListItemPos.js'\nimport { getNextListDepth } from './getNextListDepth.js'\n\nexport const nextListIsDeeper = (typeOrName: string, state: EditorState) => {\n const listDepth = getNextListDepth(typeOrName, state)\n const listItemPos = findListItemPos(typeOrName, state)\n\n if (!listItemPos || !listDepth) {\n return false\n }\n\n if (listDepth > listItemPos.depth) {\n return true\n }\n\n return false\n}\n", "import type { EditorState } from '@tiptap/pm/state'\n\nimport { findListItemPos } from './findListItemPos.js'\nimport { getNextListDepth } from './getNextListDepth.js'\n\nexport const nextListIsHigher = (typeOrName: string, state: EditorState) => {\n const listDepth = getNextListDepth(typeOrName, state)\n const listItemPos = findListItemPos(typeOrName, state)\n\n if (!listItemPos || !listDepth) {\n return false\n }\n\n if (listDepth < listItemPos.depth) {\n return true\n }\n\n return false\n}\n", "import type { EditorState } from '@tiptap/pm/state'\n\nexport const hasListItemAfter = (typeOrName: string, state: EditorState): boolean => {\n const { $anchor } = state.selection\n\n const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2)\n\n if ($targetPos.index() === $targetPos.parent.childCount - 1) {\n return false\n }\n\n if ($targetPos.nodeAfter?.type.name !== typeOrName) {\n return false\n }\n\n return true\n}\n", "import { Extension } from '@tiptap/core'\n\nimport type { BulletListOptions } from '../bullet-list/index.js'\nimport { BulletList } from '../bullet-list/index.js'\nimport type { ListItemOptions } from '../item/index.js'\nimport { ListItem } from '../item/index.js'\nimport type { ListKeymapOptions } from '../keymap/index.js'\nimport { ListKeymap } from '../keymap/index.js'\nimport type { OrderedListOptions } from '../ordered-list/index.js'\nimport { OrderedList } from '../ordered-list/index.js'\nimport type { TaskItemOptions } from '../task-item/index.js'\nimport { TaskItem } from '../task-item/index.js'\nimport type { TaskListOptions } from '../task-list/index.js'\nimport { TaskList } from '../task-list/index.js'\n\nexport interface ListKitOptions {\n /**\n * If set to false, the bulletList extension will not be registered\n * @example table: false\n */\n bulletList: Partial | false\n /**\n * If set to false, the listItem extension will not be registered\n */\n listItem: Partial | false\n /**\n * If set to false, the listKeymap extension will not be registered\n */\n listKeymap: Partial | false\n /**\n * If set to false, the orderedList extension will not be registered\n */\n orderedList: Partial | false\n /**\n * If set to false, the taskItem extension will not be registered\n */\n taskItem: Partial | false\n /**\n * If set to false, the taskList extension will not be registered\n */\n taskList: Partial | false\n}\n\n/**\n * The table kit is a collection of table editor extensions.\n *\n * It’s a good starting point for building your own table in Tiptap.\n */\nexport const ListKit = Extension.create({\n name: 'listKit',\n\n addExtensions() {\n const extensions = []\n\n if (this.options.bulletList !== false) {\n extensions.push(BulletList.configure(this.options.bulletList))\n }\n\n if (this.options.listItem !== false) {\n extensions.push(ListItem.configure(this.options.listItem))\n }\n\n if (this.options.listKeymap !== false) {\n extensions.push(ListKeymap.configure(this.options.listKeymap))\n }\n\n if (this.options.orderedList !== false) {\n extensions.push(OrderedList.configure(this.options.orderedList))\n }\n\n if (this.options.taskItem !== false) {\n extensions.push(TaskItem.configure(this.options.taskItem))\n }\n\n if (this.options.taskList !== false) {\n extensions.push(TaskList.configure(this.options.taskList))\n }\n\n return extensions\n },\n})\n", "import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'\n\nimport { buildNestedStructure, collectOrderedListItems, parseListItems } from './utils.js'\n\nconst ListItemName = 'listItem'\nconst TextStyleName = 'textStyle'\n\nexport interface OrderedListOptions {\n /**\n * The node type name for list items.\n * @default 'listItem'\n * @example 'myListItem'\n */\n itemTypeName: string\n\n /**\n * The HTML attributes for an ordered list node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n\n /**\n * Keep the marks when splitting a list item.\n * @default false\n * @example true\n */\n keepMarks: boolean\n\n /**\n * Keep the attributes when splitting a list item.\n * @default false\n * @example true\n */\n keepAttributes: boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n orderedList: {\n /**\n * Toggle an ordered list\n * @example editor.commands.toggleOrderedList()\n */\n toggleOrderedList: () => ReturnType\n }\n }\n}\n\n/**\n * Matches an ordered list to a 1. on input (or any number followed by a dot).\n */\nexport const orderedListInputRegex = /^(\\d+)\\.\\s$/\n\n/**\n * This extension allows you to create ordered lists.\n * This requires the ListItem extension\n * @see https://www.tiptap.dev/api/nodes/ordered-list\n * @see https://www.tiptap.dev/api/nodes/list-item\n */\nexport const OrderedList = Node.create({\n name: 'orderedList',\n\n addOptions() {\n return {\n itemTypeName: 'listItem',\n HTMLAttributes: {},\n keepMarks: false,\n keepAttributes: false,\n }\n },\n\n group: 'block list',\n\n content() {\n return `${this.options.itemTypeName}+`\n },\n\n addAttributes() {\n return {\n start: {\n default: 1,\n parseHTML: element => {\n return element.hasAttribute('start') ? parseInt(element.getAttribute('start') || '', 10) : 1\n },\n },\n type: {\n default: null,\n parseHTML: element => element.getAttribute('type'),\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'ol',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n const { start, ...attributesWithoutStart } = HTMLAttributes\n\n return start === 1\n ? ['ol', mergeAttributes(this.options.HTMLAttributes, attributesWithoutStart), 0]\n : ['ol', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n markdownTokenName: 'list',\n\n parseMarkdown: (token, helpers) => {\n if (token.type !== 'list' || !token.ordered) {\n return []\n }\n\n const startValue = token.start || 1\n const content = token.items ? parseListItems(token.items, helpers) : []\n\n if (startValue !== 1) {\n return {\n type: 'orderedList',\n attrs: { start: startValue },\n content,\n }\n }\n\n return {\n type: 'orderedList',\n content,\n }\n },\n\n renderMarkdown: (node, h) => {\n if (!node.content) {\n return ''\n }\n\n return h.renderChildren(node.content, '\\n')\n },\n\n markdownTokenizer: {\n name: 'orderedList',\n level: 'block',\n start: (src: string) => {\n const match = src.match(/^(\\s*)(\\d+)\\.\\s+/)\n const index = match?.index\n return index !== undefined ? index : -1\n },\n tokenize: (src: string, _tokens, lexer) => {\n const lines = src.split('\\n')\n const [listItems, consumed] = collectOrderedListItems(lines)\n\n if (listItems.length === 0) {\n return undefined\n }\n\n const items = buildNestedStructure(listItems, 0, lexer)\n\n if (items.length === 0) {\n return undefined\n }\n\n const startValue = listItems[0]?.number || 1\n\n return {\n type: 'list',\n ordered: true,\n start: startValue,\n items,\n raw: lines.slice(0, consumed).join('\\n'),\n } as unknown as object\n },\n },\n\n markdownOptions: {\n indentsContent: true,\n },\n\n addCommands() {\n return {\n toggleOrderedList:\n () =>\n ({ commands, chain }) => {\n if (this.options.keepAttributes) {\n return chain()\n .toggleList(this.name, this.options.itemTypeName, this.options.keepMarks)\n .updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName))\n .run()\n }\n return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Shift-7': () => this.editor.commands.toggleOrderedList(),\n }\n },\n\n addInputRules() {\n let inputRule = wrappingInputRule({\n find: orderedListInputRegex,\n type: this.type,\n getAttributes: match => ({ start: +match[1] }),\n joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],\n })\n\n if (this.options.keepMarks || this.options.keepAttributes) {\n inputRule = wrappingInputRule({\n find: orderedListInputRegex,\n type: this.type,\n keepMarks: this.options.keepMarks,\n keepAttributes: this.options.keepAttributes,\n getAttributes: match => ({ start: +match[1], ...this.editor.getAttributes(TextStyleName) }),\n joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],\n editor: this.editor,\n })\n }\n return [inputRule]\n },\n})\n", "import type { JSONContent, MarkdownLexerConfiguration, MarkdownParseHelpers, MarkdownToken } from '@tiptap/core'\n\n/**\n * Matches an ordered list item line with optional leading whitespace.\n * Captures: (1) indentation spaces, (2) item number, (3) content after marker\n * Example matches: \"1. Item\", \" 2. Nested item\", \" 3. Deeply nested\"\n */\nconst ORDERED_LIST_ITEM_REGEX = /^(\\s*)(\\d+)\\.\\s+(.*)$/\n\n/**\n * Matches any line that starts with whitespace (indented content).\n * Used to identify continuation content that belongs to a list item.\n */\nconst INDENTED_LINE_REGEX = /^\\s/\n\n/**\n * Represents a parsed ordered list item with indentation information\n */\nexport interface OrderedListItem {\n indent: number\n number: number\n content: string\n raw: string\n}\n\n/**\n * Collects all ordered list items from lines, parsing them into a flat array\n * with indentation information. Stops collecting continuation content when\n * encountering nested list items, allowing them to be processed separately.\n *\n * @param lines - Array of source lines to parse\n * @returns Tuple of [listItems array, number of lines consumed]\n */\nexport function collectOrderedListItems(lines: string[]): [OrderedListItem[], number] {\n const listItems: OrderedListItem[] = []\n let currentLineIndex = 0\n let consumed = 0\n\n while (currentLineIndex < lines.length) {\n const line = lines[currentLineIndex]\n const match = line.match(ORDERED_LIST_ITEM_REGEX)\n\n if (!match) {\n break\n }\n\n const [, indent, number, content] = match\n const indentLevel = indent.length\n let itemContent = content\n let nextLineIndex = currentLineIndex + 1\n const itemLines = [line]\n\n // Collect continuation lines for this item (but NOT nested list items)\n while (nextLineIndex < lines.length) {\n const nextLine = lines[nextLineIndex]\n const nextMatch = nextLine.match(ORDERED_LIST_ITEM_REGEX)\n\n // If it's another list item (nested or not), stop collecting\n if (nextMatch) {\n break\n }\n\n // Check for continuation content (non-list content)\n if (nextLine.trim() === '') {\n // Empty line\n itemLines.push(nextLine)\n itemContent += '\\n'\n nextLineIndex += 1\n } else if (nextLine.match(INDENTED_LINE_REGEX)) {\n // Indented content - part of this item (but not a list item)\n itemLines.push(nextLine)\n itemContent += `\\n${nextLine.slice(indentLevel + 2)}` // Remove list marker indent\n nextLineIndex += 1\n } else {\n // Non-indented line means end of list\n break\n }\n }\n\n listItems.push({\n indent: indentLevel,\n number: parseInt(number, 10),\n content: itemContent.trim(),\n raw: itemLines.join('\\n'),\n })\n\n consumed = nextLineIndex\n currentLineIndex = nextLineIndex\n }\n\n return [listItems, consumed]\n}\n\n/**\n * Recursively builds a nested structure from a flat array of list items\n * based on their indentation levels. Creates proper markdown tokens with\n * nested lists where appropriate.\n *\n * @param items - Flat array of list items with indentation info\n * @param baseIndent - The indentation level to process at this recursion level\n * @param lexer - Markdown lexer for parsing inline and block content\n * @returns Array of list_item tokens with proper nesting\n */\nexport function buildNestedStructure(\n items: OrderedListItem[],\n baseIndent: number,\n lexer: MarkdownLexerConfiguration,\n): unknown[] {\n const result: unknown[] = []\n let currentIndex = 0\n\n while (currentIndex < items.length) {\n const item = items[currentIndex]\n\n if (item.indent === baseIndent) {\n // This item belongs at the current level\n const contentLines = item.content.split('\\n')\n const mainText = contentLines[0]?.trim() || ''\n\n const tokens = []\n\n // Always wrap the main text in a paragraph token\n if (mainText) {\n tokens.push({\n type: 'paragraph',\n raw: mainText,\n tokens: lexer.inlineTokens(mainText),\n })\n }\n\n // Handle additional content after the main text\n const additionalContent = contentLines.slice(1).join('\\n').trim()\n if (additionalContent) {\n // Parse as block tokens (handles mixed unordered lists, etc.)\n const blockTokens = lexer.blockTokens(additionalContent)\n tokens.push(...blockTokens)\n }\n\n // Look ahead to find nested items at deeper indent levels\n let lookAheadIndex = currentIndex + 1\n const nestedItems = []\n\n while (lookAheadIndex < items.length && items[lookAheadIndex].indent > baseIndent) {\n nestedItems.push(items[lookAheadIndex])\n lookAheadIndex += 1\n }\n\n // If we have nested items, recursively build their structure\n if (nestedItems.length > 0) {\n // Find the next indent level (immediate children)\n const nextIndent = Math.min(...nestedItems.map(nestedItem => nestedItem.indent))\n\n // Build the nested list recursively with all nested items\n // The recursive call will handle further nesting\n const nestedListItems = buildNestedStructure(nestedItems, nextIndent, lexer)\n\n // Create a nested list token\n tokens.push({\n type: 'list',\n ordered: true,\n start: nestedItems[0].number,\n items: nestedListItems,\n raw: nestedItems.map(nestedItem => nestedItem.raw).join('\\n'),\n })\n }\n\n result.push({\n type: 'list_item',\n raw: item.raw,\n tokens,\n })\n\n // Skip the nested items we just processed\n currentIndex = lookAheadIndex\n } else {\n // This item has deeper indent than we're currently processing\n // It should be handled by a recursive call\n currentIndex += 1\n }\n }\n\n return result\n}\n\n/**\n * Parses markdown list item tokens into Tiptap JSONContent structure,\n * ensuring text content is properly wrapped in paragraph nodes.\n *\n * @param items - Array of markdown tokens representing list items\n * @param helpers - Markdown parse helpers for recursive parsing\n * @returns Array of listItem JSONContent nodes\n */\nexport function parseListItems(items: MarkdownToken[], helpers: MarkdownParseHelpers): JSONContent[] {\n return items.map(item => {\n if (item.type !== 'list_item') {\n return helpers.parseChildren([item])[0]\n }\n\n // Parse the tokens within the list item\n const content: JSONContent[] = []\n\n if (item.tokens && item.tokens.length > 0) {\n item.tokens.forEach(itemToken => {\n // If it's already a proper block node (paragraph, list, etc.), parse it directly\n if (\n itemToken.type === 'paragraph' ||\n itemToken.type === 'list' ||\n itemToken.type === 'blockquote' ||\n itemToken.type === 'code'\n ) {\n content.push(...helpers.parseChildren([itemToken]))\n } else if (itemToken.type === 'text' && itemToken.tokens) {\n // If it's inline text tokens, wrap them in a paragraph\n const inlineContent = helpers.parseChildren([itemToken])\n content.push({\n type: 'paragraph',\n content: inlineContent,\n })\n } else {\n // For any other content, try to parse it\n const parsed = helpers.parseChildren([itemToken])\n if (parsed.length > 0) {\n content.push(...parsed)\n }\n }\n })\n }\n\n return {\n type: 'listItem',\n content,\n }\n })\n}\n", "import type { KeyboardShortcutCommand } from '@tiptap/core'\nimport {\n getRenderedAttributes,\n mergeAttributes,\n Node,\n renderNestedMarkdownContent,\n wrappingInputRule,\n} from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nexport interface TaskItemOptions {\n /**\n * A callback function that is called when the checkbox is clicked while the editor is in readonly mode.\n * @param node The prosemirror node of the task item\n * @param checked The new checked state\n * @returns boolean\n */\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n\n /**\n * Controls whether the task items can be nested or not.\n * @default false\n * @example true\n */\n nested: boolean\n\n /**\n * HTML attributes to add to the task item element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n\n /**\n * The node type for taskList nodes\n * @default 'taskList'\n * @example 'myCustomTaskList'\n */\n taskListTypeName: string\n\n /**\n * Accessibility options for the task item.\n * @default {}\n * @example\n * ```js\n * {\n * checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`\n * }\n */\n a11y?: {\n checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string\n }\n}\n\n/**\n * Matches a task item to a - [ ] on input.\n */\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\n/**\n * This extension allows you to create task items.\n * @see https://www.tiptap.dev/api/nodes/task-item\n */\nexport const TaskItem = Node.create({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\n taskListTypeName: 'taskList',\n a11y: undefined,\n }\n },\n\n content() {\n return this.options.nested ? 'paragraph block*' : 'paragraph+'\n },\n\n defining: true,\n\n addAttributes() {\n return {\n checked: {\n default: false,\n keepOnSplit: false,\n parseHTML: element => {\n const dataChecked = element.getAttribute('data-checked')\n\n return dataChecked === '' || dataChecked === 'true'\n },\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `li[data-type=\"${this.name}\"]`,\n priority: 51,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'li',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n }),\n [\n 'label',\n [\n 'input',\n {\n type: 'checkbox',\n checked: node.attrs.checked ? 'checked' : null,\n },\n ],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n parseMarkdown: (token, h) => {\n // Parse the task item's text content into paragraph content\n const content = []\n\n // First, add the main paragraph content\n if (token.tokens && token.tokens.length > 0) {\n // If we have tokens, create a paragraph with the inline content\n content.push(h.createNode('paragraph', {}, h.parseInline(token.tokens)))\n } else if (token.text) {\n // If we have raw text, create a paragraph with text node\n content.push(h.createNode('paragraph', {}, [h.createNode('text', { text: token.text })]))\n } else {\n // Fallback: empty paragraph\n content.push(h.createNode('paragraph', {}, []))\n }\n\n // Then, add any nested content (like nested task lists)\n if (token.nestedTokens && token.nestedTokens.length > 0) {\n const nestedContent = h.parseChildren(token.nestedTokens)\n content.push(...nestedContent)\n }\n\n return h.createNode('taskItem', { checked: token.checked || false }, content)\n },\n\n renderMarkdown: (node, h) => {\n const checkedChar = node.attrs?.checked ? 'x' : ' '\n const prefix = `- [${checkedChar}] `\n\n return renderNestedMarkdownContent(node, h, prefix)\n },\n\n addKeyboardShortcuts() {\n const shortcuts: {\n [key: string]: KeyboardShortcutCommand\n } = {\n Enter: () => this.editor.commands.splitListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem(this.name),\n }\n },\n\n addNodeView() {\n return ({ node, HTMLAttributes, getPos, editor }) => {\n const listItem = document.createElement('li')\n const checkboxWrapper = document.createElement('label')\n const checkboxStyler = document.createElement('span')\n const checkbox = document.createElement('input')\n const content = document.createElement('div')\n\n const updateA11Y = (currentNode: ProseMirrorNode) => {\n checkbox.ariaLabel =\n this.options.a11y?.checkboxLabel?.(currentNode, checkbox.checked) ||\n `Task item checkbox for ${currentNode.textContent || 'empty task item'}`\n }\n\n updateA11Y(node)\n\n checkboxWrapper.contentEditable = 'false'\n checkbox.type = 'checkbox'\n checkbox.addEventListener('mousedown', event => event.preventDefault())\n checkbox.addEventListener('change', event => {\n // if the editor isn’t editable and we don't have a handler for\n // readonly checks we have to undo the latest change\n if (!editor.isEditable && !this.options.onReadOnlyChecked) {\n checkbox.checked = !checkbox.checked\n\n return\n }\n\n const { checked } = event.target as any\n\n if (editor.isEditable && typeof getPos === 'function') {\n editor\n .chain()\n .focus(undefined, { scrollIntoView: false })\n .command(({ tr }) => {\n const position = getPos()\n\n if (typeof position !== 'number') {\n return false\n }\n const currentNode = tr.doc.nodeAt(position)\n\n tr.setNodeMarkup(position, undefined, {\n ...currentNode?.attrs,\n checked,\n })\n\n return true\n })\n .run()\n }\n if (!editor.isEditable && this.options.onReadOnlyChecked) {\n // Reset state if onReadOnlyChecked returns false\n if (!this.options.onReadOnlyChecked(node, checked)) {\n checkbox.checked = !checkbox.checked\n }\n }\n })\n\n Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n listItem.dataset.checked = node.attrs.checked\n checkbox.checked = node.attrs.checked\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object.entries(HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n // Track the keys of previously rendered HTML attributes for proper removal\n let prevRenderedAttributeKeys = new Set(Object.keys(HTMLAttributes))\n\n return {\n dom: listItem,\n contentDOM: content,\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n listItem.dataset.checked = updatedNode.attrs.checked\n checkbox.checked = updatedNode.attrs.checked\n updateA11Y(updatedNode)\n\n // Sync all HTML attributes from the updated node\n const extensionAttributes = editor.extensionManager.attributes\n const newHTMLAttributes = getRenderedAttributes(updatedNode, extensionAttributes)\n const newKeys = new Set(Object.keys(newHTMLAttributes))\n\n // Remove attributes that were previously rendered but are no longer present\n // If the attribute exists in static options, restore it instead of removing\n const staticAttrs = this.options.HTMLAttributes\n\n prevRenderedAttributeKeys.forEach(key => {\n if (!newKeys.has(key)) {\n if (key in staticAttrs) {\n listItem.setAttribute(key, staticAttrs[key])\n } else {\n listItem.removeAttribute(key)\n }\n }\n })\n\n // Update or add new attributes\n Object.entries(newHTMLAttributes).forEach(([key, value]) => {\n if (value === null || value === undefined) {\n // If the attribute exists in static options, restore it instead of removing\n if (key in staticAttrs) {\n listItem.setAttribute(key, staticAttrs[key])\n } else {\n listItem.removeAttribute(key)\n }\n } else {\n listItem.setAttribute(key, value)\n }\n })\n\n // Update the tracked keys for next update\n prevRenderedAttributeKeys = newKeys\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: inputRegex,\n type: this.type,\n getAttributes: match => ({\n checked: match[match.length - 1] === 'x',\n }),\n }),\n ]\n },\n})\n", "import { mergeAttributes, Node, parseIndentedBlocks } from '@tiptap/core'\n\nexport interface TaskListOptions {\n /**\n * The node type name for a task item.\n * @default 'taskItem'\n * @example 'myCustomTaskItem'\n */\n itemTypeName: string\n\n /**\n * The HTML attributes for a task list node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n taskList: {\n /**\n * Toggle a task list\n * @example editor.commands.toggleTaskList()\n */\n toggleTaskList: () => ReturnType\n }\n }\n}\n\n/**\n * This extension allows you to create task lists.\n * @see https://www.tiptap.dev/api/nodes/task-list\n */\nexport const TaskList = Node.create({\n name: 'taskList',\n\n addOptions() {\n return {\n itemTypeName: 'taskItem',\n HTMLAttributes: {},\n }\n },\n\n group: 'block list',\n\n content() {\n return `${this.options.itemTypeName}+`\n },\n\n parseHTML() {\n return [\n {\n tag: `ul[data-type=\"${this.name}\"]`,\n priority: 51,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['ul', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': this.name }), 0]\n },\n\n parseMarkdown: (token, h) => {\n return h.createNode('taskList', {}, h.parseChildren(token.items || []))\n },\n\n renderMarkdown: (node, h) => {\n if (!node.content) {\n return ''\n }\n\n return h.renderChildren(node.content, '\\n')\n },\n\n markdownTokenizer: {\n name: 'taskList',\n level: 'block',\n start(src) {\n // Look for the start of a task list item\n const index = src.match(/^\\s*[-+*]\\s+\\[([ xX])\\]\\s+/)?.index\n return index !== undefined ? index : -1\n },\n tokenize(src, tokens, lexer) {\n // Helper function to recursively parse task lists\n const parseTaskListContent = (content: string): any[] | undefined => {\n const nestedResult = parseIndentedBlocks(\n content,\n {\n itemPattern: /^(\\s*)([-+*])\\s+\\[([ xX])\\]\\s+(.*)$/,\n extractItemData: match => ({\n indentLevel: match[1].length,\n mainContent: match[4],\n checked: match[3].toLowerCase() === 'x',\n }),\n createToken: (data, nestedTokens) => ({\n type: 'taskItem',\n raw: '',\n mainContent: data.mainContent,\n indentLevel: data.indentLevel,\n checked: data.checked,\n text: data.mainContent,\n tokens: lexer.inlineTokens(data.mainContent),\n nestedTokens,\n }),\n // Allow recursive nesting\n customNestedParser: parseTaskListContent,\n },\n lexer,\n )\n\n if (nestedResult) {\n // Return as task list token\n return [\n {\n type: 'taskList',\n raw: nestedResult.raw,\n items: nestedResult.items,\n },\n ]\n }\n\n // Fall back to regular markdown parsing if not a task list\n return lexer.blockTokens(content)\n }\n\n const result = parseIndentedBlocks(\n src,\n {\n itemPattern: /^(\\s*)([-+*])\\s+\\[([ xX])\\]\\s+(.*)$/,\n extractItemData: match => ({\n indentLevel: match[1].length,\n mainContent: match[4],\n checked: match[3].toLowerCase() === 'x',\n }),\n createToken: (data, nestedTokens) => ({\n type: 'taskItem',\n raw: '',\n mainContent: data.mainContent,\n indentLevel: data.indentLevel,\n checked: data.checked,\n text: data.mainContent,\n tokens: lexer.inlineTokens(data.mainContent),\n nestedTokens,\n }),\n // Use the recursive parser for nested content\n customNestedParser: parseTaskListContent,\n },\n lexer,\n )\n\n if (!result) {\n return undefined\n }\n\n return {\n type: 'taskList',\n raw: result.raw,\n items: result.items,\n }\n },\n },\n\n markdownOptions: {\n indentsContent: true,\n },\n\n addCommands() {\n return {\n toggleTaskList:\n () =>\n ({ commands }) => {\n return commands.toggleList(this.name, this.options.itemTypeName)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Shift-9': () => this.editor.commands.toggleTaskList(),\n }\n },\n})\n", "import { mergeAttributes, Node } from '@tiptap/core'\n\nexport interface ParagraphOptions {\n /**\n * The HTML attributes for a paragraph node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n paragraph: {\n /**\n * Toggle a paragraph\n * @example editor.commands.toggleParagraph()\n */\n setParagraph: () => ReturnType\n }\n }\n}\n\n/**\n * Markdown marker for empty paragraphs to preserve blank lines.\n * Using   (non-breaking space HTML entity) ensures the paragraph\n * is not collapsed by markdown parsers while remaining human-readable.\n */\nconst EMPTY_PARAGRAPH_MARKDOWN = ' '\n\n/**\n * Unicode character for non-breaking space (U+00A0).\n * Some markdown parsers may convert   entities to this literal character.\n */\nconst NBSP_CHAR = '\\u00A0'\n\n/**\n * This extension allows you to create paragraphs.\n * @see https://www.tiptap.dev/api/nodes/paragraph\n */\nexport const Paragraph = Node.create({\n name: 'paragraph',\n\n priority: 1000,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n group: 'block',\n\n content: 'inline*',\n\n parseHTML() {\n return [{ tag: 'p' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['p', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n parseMarkdown: (token, helpers) => {\n const tokens = token.tokens || []\n\n // Special case: if paragraph contains only a single image token,\n // unwrap it to avoid nesting block elements incorrectly\n if (tokens.length === 1 && tokens[0].type === 'image') {\n // Parse the image token directly as a block element\n return helpers.parseChildren([tokens[0]])\n }\n\n // Parse the inline tokens\n const content = helpers.parseInline(tokens)\n\n // Special case: if paragraph contains only   (non-breaking space),\n // treat it as an empty paragraph to preserve blank lines\n if (\n content.length === 1 &&\n content[0].type === 'text' &&\n (content[0].text === EMPTY_PARAGRAPH_MARKDOWN || content[0].text === NBSP_CHAR)\n ) {\n return helpers.createNode('paragraph', undefined, [])\n }\n\n // Convert 'paragraph' token to paragraph node\n return helpers.createNode('paragraph', undefined, content)\n },\n\n renderMarkdown: (node, h) => {\n if (!node) {\n return ''\n }\n\n // Normalize content: treat undefined/null as empty array\n const content = Array.isArray(node.content) ? node.content : []\n\n // If the paragraph is empty, render a non-breaking space to preserve blank lines\n if (content.length === 0) {\n return EMPTY_PARAGRAPH_MARKDOWN\n }\n\n return h.renderChildren(content)\n },\n\n addCommands() {\n return {\n setParagraph:\n () =>\n ({ commands }) => {\n return commands.setNode(this.name)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Alt-0': () => this.editor.commands.setParagraph(),\n }\n },\n})\n", "import { Paragraph } from './paragraph.js'\n\nexport * from './paragraph.js'\n\nexport default Paragraph\n", "import { Mark, markInputRule, markPasteRule, mergeAttributes } from '@tiptap/core'\n\nexport interface StrikeOptions {\n /**\n * HTML attributes to add to the strike element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n strike: {\n /**\n * Set a strike mark\n * @example editor.commands.setStrike()\n */\n setStrike: () => ReturnType\n /**\n * Toggle a strike mark\n * @example editor.commands.toggleStrike()\n */\n toggleStrike: () => ReturnType\n /**\n * Unset a strike mark\n * @example editor.commands.unsetStrike()\n */\n unsetStrike: () => ReturnType\n }\n }\n}\n\n/**\n * Matches a strike to a ~~strike~~ on input.\n */\nexport const inputRegex = /(?:^|\\s)(~~(?!\\s+~~)((?:[^~]+))~~(?!\\s+~~))$/\n\n/**\n * Matches a strike to a ~~strike~~ on paste.\n */\nexport const pasteRegex = /(?:^|\\s)(~~(?!\\s+~~)((?:[^~]+))~~(?!\\s+~~))/g\n\n/**\n * This extension allows you to create strike text.\n * @see https://www.tiptap.dev/api/marks/strike\n */\nexport const Strike = Mark.create({\n name: 'strike',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 's',\n },\n {\n tag: 'del',\n },\n {\n tag: 'strike',\n },\n {\n style: 'text-decoration',\n consuming: false,\n getAttrs: style => ((style as string).includes('line-through') ? {} : false),\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['s', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n markdownTokenName: 'del',\n\n parseMarkdown: (token, helpers) => {\n // Convert 'del' token to strike mark\n return helpers.applyMark('strike', helpers.parseInline(token.tokens || []))\n },\n\n renderMarkdown: (node, h) => {\n return `~~${h.renderChildren(node)}~~`\n },\n\n addCommands() {\n return {\n setStrike:\n () =>\n ({ commands }) => {\n return commands.setMark(this.name)\n },\n toggleStrike:\n () =>\n ({ commands }) => {\n return commands.toggleMark(this.name)\n },\n unsetStrike:\n () =>\n ({ commands }) => {\n return commands.unsetMark(this.name)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Shift-s': () => this.editor.commands.toggleStrike(),\n }\n },\n\n addInputRules() {\n return [\n markInputRule({\n find: inputRegex,\n type: this.type,\n }),\n ]\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: pasteRegex,\n type: this.type,\n }),\n ]\n },\n})\n", "import { Strike } from './strike.js'\n\nexport * from './strike.js'\n\nexport default Strike\n", "import { Node } from '@tiptap/core'\n\n/**\n * This extension allows you to create text nodes.\n * @see https://www.tiptap.dev/api/nodes/text\n */\nexport const Text = Node.create({\n name: 'text',\n group: 'inline',\n\n parseMarkdown: token => {\n // Convert 'text' token to text node - text nodes are special as they store text directly\n return {\n type: 'text',\n text: token.text || '',\n }\n },\n\n renderMarkdown: node => node.text || '',\n})\n", "import { Text } from './text.js'\n\nexport * from './text.js'\n\nexport default Text\n", "import { Mark, mergeAttributes } from '@tiptap/core'\n\nexport interface UnderlineOptions {\n /**\n * HTML attributes to add to the underline element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n underline: {\n /**\n * Set an underline mark\n * @example editor.commands.setUnderline()\n */\n setUnderline: () => ReturnType\n /**\n * Toggle an underline mark\n * @example editor.commands.toggleUnderline()\n */\n toggleUnderline: () => ReturnType\n /**\n * Unset an underline mark\n * @example editor.commands.unsetUnderline()\n */\n unsetUnderline: () => ReturnType\n }\n }\n}\n\n/**\n * This extension allows you to create underline text.\n * @see https://www.tiptap.dev/api/marks/underline\n */\nexport const Underline = Mark.create({\n name: 'underline',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'u',\n },\n {\n style: 'text-decoration',\n consuming: false,\n getAttrs: style => ((style as string).includes('underline') ? {} : false),\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['u', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n parseMarkdown(token, helpers) {\n return helpers.applyMark(this.name || 'underline', helpers.parseInline(token.tokens || []))\n },\n\n renderMarkdown(node, helpers) {\n return `++${helpers.renderChildren(node)}++`\n },\n\n markdownTokenizer: {\n name: 'underline',\n level: 'inline',\n start(src) {\n return src.indexOf('++')\n },\n tokenize(src, _tokens, lexer) {\n const rule = /^(\\+\\+)([\\s\\S]+?)(\\+\\+)/\n const match = rule.exec(src)\n\n if (!match) {\n return undefined\n }\n\n const innerContent = match[2].trim()\n\n return {\n type: 'underline',\n raw: match[0],\n text: innerContent,\n tokens: lexer.inlineTokens(innerContent),\n }\n },\n },\n\n addCommands() {\n return {\n setUnderline:\n () =>\n ({ commands }) => {\n return commands.setMark(this.name)\n },\n toggleUnderline:\n () =>\n ({ commands }) => {\n return commands.toggleMark(this.name)\n },\n unsetUnderline:\n () =>\n ({ commands }) => {\n return commands.unsetMark(this.name)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-u': () => this.editor.commands.toggleUnderline(),\n 'Mod-U': () => this.editor.commands.toggleUnderline(),\n }\n },\n})\n", "import { Underline } from './underline.js'\n\nexport * from './underline.js'\n\nexport default Underline\n", "import { Plugin } from 'prosemirror-state';\nimport { dropPoint } from 'prosemirror-transform';\n\n/**\nCreate a plugin that, when added to a ProseMirror instance,\ncauses a decoration to show up at the drop position when something\nis dragged over the editor.\n\nNodes may add a `disableDropCursor` property to their spec to\ncontrol the showing of a drop cursor inside them. This may be a\nboolean or a function, which will be called with a view and a\nposition, and should return a boolean.\n*/\nfunction dropCursor(options = {}) {\n return new Plugin({\n view(editorView) { return new DropCursorView(editorView, options); }\n });\n}\nclass DropCursorView {\n constructor(editorView, options) {\n var _a;\n this.editorView = editorView;\n this.cursorPos = null;\n this.element = null;\n this.timeout = -1;\n this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;\n this.color = options.color === false ? undefined : (options.color || \"black\");\n this.class = options.class;\n this.handlers = [\"dragover\", \"dragend\", \"drop\", \"dragleave\"].map(name => {\n let handler = (e) => { this[name](e); };\n editorView.dom.addEventListener(name, handler);\n return { name, handler };\n });\n }\n destroy() {\n this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));\n }\n update(editorView, prevState) {\n if (this.cursorPos != null && prevState.doc != editorView.state.doc) {\n if (this.cursorPos > editorView.state.doc.content.size)\n this.setCursor(null);\n else\n this.updateOverlay();\n }\n }\n setCursor(pos) {\n if (pos == this.cursorPos)\n return;\n this.cursorPos = pos;\n if (pos == null) {\n this.element.parentNode.removeChild(this.element);\n this.element = null;\n }\n else {\n this.updateOverlay();\n }\n }\n updateOverlay() {\n let $pos = this.editorView.state.doc.resolve(this.cursorPos);\n let isBlock = !$pos.parent.inlineContent, rect;\n let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect();\n let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight;\n if (isBlock) {\n let before = $pos.nodeBefore, after = $pos.nodeAfter;\n if (before || after) {\n let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));\n if (node) {\n let nodeRect = node.getBoundingClientRect();\n let top = before ? nodeRect.bottom : nodeRect.top;\n if (before && after)\n top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;\n let halfWidth = (this.width / 2) * scaleY;\n rect = { left: nodeRect.left, right: nodeRect.right, top: top - halfWidth, bottom: top + halfWidth };\n }\n }\n }\n if (!rect) {\n let coords = this.editorView.coordsAtPos(this.cursorPos);\n let halfWidth = (this.width / 2) * scaleX;\n rect = { left: coords.left - halfWidth, right: coords.left + halfWidth, top: coords.top, bottom: coords.bottom };\n }\n let parent = this.editorView.dom.offsetParent;\n if (!this.element) {\n this.element = parent.appendChild(document.createElement(\"div\"));\n if (this.class)\n this.element.className = this.class;\n this.element.style.cssText = \"position: absolute; z-index: 50; pointer-events: none;\";\n if (this.color) {\n this.element.style.backgroundColor = this.color;\n }\n }\n this.element.classList.toggle(\"prosemirror-dropcursor-block\", isBlock);\n this.element.classList.toggle(\"prosemirror-dropcursor-inline\", !isBlock);\n let parentLeft, parentTop;\n if (!parent || parent == document.body && getComputedStyle(parent).position == \"static\") {\n parentLeft = -pageXOffset;\n parentTop = -pageYOffset;\n }\n else {\n let rect = parent.getBoundingClientRect();\n let parentScaleX = rect.width / parent.offsetWidth, parentScaleY = rect.height / parent.offsetHeight;\n parentLeft = rect.left - parent.scrollLeft * parentScaleX;\n parentTop = rect.top - parent.scrollTop * parentScaleY;\n }\n this.element.style.left = (rect.left - parentLeft) / scaleX + \"px\";\n this.element.style.top = (rect.top - parentTop) / scaleY + \"px\";\n this.element.style.width = (rect.right - rect.left) / scaleX + \"px\";\n this.element.style.height = (rect.bottom - rect.top) / scaleY + \"px\";\n }\n scheduleRemoval(timeout) {\n clearTimeout(this.timeout);\n this.timeout = setTimeout(() => this.setCursor(null), timeout);\n }\n dragover(event) {\n if (!this.editorView.editable)\n return;\n let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY });\n let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);\n let disableDropCursor = node && node.type.spec.disableDropCursor;\n let disabled = typeof disableDropCursor == \"function\"\n ? disableDropCursor(this.editorView, pos, event)\n : disableDropCursor;\n if (pos && !disabled) {\n let target = pos.pos;\n if (this.editorView.dragging && this.editorView.dragging.slice) {\n let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);\n if (point != null)\n target = point;\n }\n this.setCursor(target);\n this.scheduleRemoval(5000);\n }\n }\n dragend() {\n this.scheduleRemoval(20);\n }\n drop() {\n this.scheduleRemoval(20);\n }\n dragleave(event) {\n if (!this.editorView.dom.contains(event.relatedTarget))\n this.setCursor(null);\n }\n}\n\nexport { dropCursor };\n", "export * from \"prosemirror-dropcursor\";\nexport {};\n", "import { keydownHandler } from 'prosemirror-keymap';\nimport { Selection, NodeSelection, TextSelection, Plugin } from 'prosemirror-state';\nimport { Slice, Fragment } from 'prosemirror-model';\nimport { DecorationSet, Decoration } from 'prosemirror-view';\n\n/**\nGap cursor selections are represented using this class. Its\n`$anchor` and `$head` properties both point at the cursor position.\n*/\nclass GapCursor extends Selection {\n /**\n Create a gap cursor.\n */\n constructor($pos) {\n super($pos, $pos);\n }\n map(doc, mapping) {\n let $pos = doc.resolve(mapping.map(this.head));\n return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos);\n }\n content() { return Slice.empty; }\n eq(other) {\n return other instanceof GapCursor && other.head == this.head;\n }\n toJSON() {\n return { type: \"gapcursor\", pos: this.head };\n }\n /**\n @internal\n */\n static fromJSON(doc, json) {\n if (typeof json.pos != \"number\")\n throw new RangeError(\"Invalid input for GapCursor.fromJSON\");\n return new GapCursor(doc.resolve(json.pos));\n }\n /**\n @internal\n */\n getBookmark() { return new GapBookmark(this.anchor); }\n /**\n @internal\n */\n static valid($pos) {\n let parent = $pos.parent;\n if (parent.inlineContent || !closedBefore($pos) || !closedAfter($pos))\n return false;\n let override = parent.type.spec.allowGapCursor;\n if (override != null)\n return override;\n let deflt = parent.contentMatchAt($pos.index()).defaultType;\n return deflt && deflt.isTextblock;\n }\n /**\n @internal\n */\n static findGapCursorFrom($pos, dir, mustMove = false) {\n search: for (;;) {\n if (!mustMove && GapCursor.valid($pos))\n return $pos;\n let pos = $pos.pos, next = null;\n // Scan up from this position\n for (let d = $pos.depth;; d--) {\n let parent = $pos.node(d);\n if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {\n next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1);\n break;\n }\n else if (d == 0) {\n return null;\n }\n pos += dir;\n let $cur = $pos.doc.resolve(pos);\n if (GapCursor.valid($cur))\n return $cur;\n }\n // And then down into the next node\n for (;;) {\n let inside = dir > 0 ? next.firstChild : next.lastChild;\n if (!inside) {\n if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) {\n $pos = $pos.doc.resolve(pos + next.nodeSize * dir);\n mustMove = false;\n continue search;\n }\n break;\n }\n next = inside;\n pos += dir;\n let $cur = $pos.doc.resolve(pos);\n if (GapCursor.valid($cur))\n return $cur;\n }\n return null;\n }\n }\n}\nGapCursor.prototype.visible = false;\nGapCursor.findFrom = GapCursor.findGapCursorFrom;\nSelection.jsonID(\"gapcursor\", GapCursor);\nclass GapBookmark {\n constructor(pos) {\n this.pos = pos;\n }\n map(mapping) {\n return new GapBookmark(mapping.map(this.pos));\n }\n resolve(doc) {\n let $pos = doc.resolve(this.pos);\n return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos);\n }\n}\nfunction needsGap(type) {\n return type.isAtom || type.spec.isolating || type.spec.createGapCursor;\n}\nfunction closedBefore($pos) {\n for (let d = $pos.depth; d >= 0; d--) {\n let index = $pos.index(d), parent = $pos.node(d);\n // At the start of this parent, look at next one\n if (index == 0) {\n if (parent.type.spec.isolating)\n return true;\n continue;\n }\n // See if the node before (or its first ancestor) is closed\n for (let before = parent.child(index - 1);; before = before.lastChild) {\n if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type))\n return true;\n if (before.inlineContent)\n return false;\n }\n }\n // Hit start of document\n return true;\n}\nfunction closedAfter($pos) {\n for (let d = $pos.depth; d >= 0; d--) {\n let index = $pos.indexAfter(d), parent = $pos.node(d);\n if (index == parent.childCount) {\n if (parent.type.spec.isolating)\n return true;\n continue;\n }\n for (let after = parent.child(index);; after = after.firstChild) {\n if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type))\n return true;\n if (after.inlineContent)\n return false;\n }\n }\n return true;\n}\n\n/**\nCreate a gap cursor plugin. When enabled, this will capture clicks\nnear and arrow-key-motion past places that don't have a normally\nselectable position nearby, and create a gap cursor selection for\nthem. The cursor is drawn as an element with class\n`ProseMirror-gapcursor`. You can either include\n`style/gapcursor.css` from the package's directory or add your own\nstyles to make it visible.\n*/\nfunction gapCursor() {\n return new Plugin({\n props: {\n decorations: drawGapCursor,\n createSelectionBetween(_view, $anchor, $head) {\n return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null;\n },\n handleClick,\n handleKeyDown,\n handleDOMEvents: { beforeinput: beforeinput }\n }\n });\n}\nconst handleKeyDown = keydownHandler({\n \"ArrowLeft\": arrow(\"horiz\", -1),\n \"ArrowRight\": arrow(\"horiz\", 1),\n \"ArrowUp\": arrow(\"vert\", -1),\n \"ArrowDown\": arrow(\"vert\", 1)\n});\nfunction arrow(axis, dir) {\n const dirStr = axis == \"vert\" ? (dir > 0 ? \"down\" : \"up\") : (dir > 0 ? \"right\" : \"left\");\n return function (state, dispatch, view) {\n let sel = state.selection;\n let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty;\n if (sel instanceof TextSelection) {\n if (!view.endOfTextblock(dirStr) || $start.depth == 0)\n return false;\n mustMove = false;\n $start = state.doc.resolve(dir > 0 ? $start.after() : $start.before());\n }\n let $found = GapCursor.findGapCursorFrom($start, dir, mustMove);\n if (!$found)\n return false;\n if (dispatch)\n dispatch(state.tr.setSelection(new GapCursor($found)));\n return true;\n };\n}\nfunction handleClick(view, pos, event) {\n if (!view || !view.editable)\n return false;\n let $pos = view.state.doc.resolve(pos);\n if (!GapCursor.valid($pos))\n return false;\n let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY });\n if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside)))\n return false;\n view.dispatch(view.state.tr.setSelection(new GapCursor($pos)));\n return true;\n}\n// This is a hack that, when a composition starts while a gap cursor\n// is active, quickly creates an inline context for the composition to\n// happen in, to avoid it being aborted by the DOM selection being\n// moved into a valid position.\nfunction beforeinput(view, event) {\n if (event.inputType != \"insertCompositionText\" || !(view.state.selection instanceof GapCursor))\n return false;\n let { $from } = view.state.selection;\n let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text);\n if (!insert)\n return false;\n let frag = Fragment.empty;\n for (let i = insert.length - 1; i >= 0; i--)\n frag = Fragment.from(insert[i].createAndFill(null, frag));\n let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0));\n tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));\n view.dispatch(tr);\n return false;\n}\nfunction drawGapCursor(state) {\n if (!(state.selection instanceof GapCursor))\n return null;\n let node = document.createElement(\"div\");\n node.className = \"ProseMirror-gapcursor\";\n return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: \"gapcursor\" })]);\n}\n\nexport { GapCursor, gapCursor };\n", "export * from \"prosemirror-gapcursor\";\nexport {};\n", "var GOOD_LEAF_SIZE = 200;\n\n// :: class A rope sequence is a persistent sequence data structure\n// that supports appending, prepending, and slicing without doing a\n// full copy. It is represented as a mostly-balanced tree.\nvar RopeSequence = function RopeSequence () {};\n\nRopeSequence.prototype.append = function append (other) {\n if (!other.length) { return this }\n other = RopeSequence.from(other);\n\n return (!this.length && other) ||\n (other.length < GOOD_LEAF_SIZE && this.leafAppend(other)) ||\n (this.length < GOOD_LEAF_SIZE && other.leafPrepend(this)) ||\n this.appendInner(other)\n};\n\n// :: (union<[T], RopeSequence>) \u2192 RopeSequence\n// Prepend an array or other rope to this one, returning a new rope.\nRopeSequence.prototype.prepend = function prepend (other) {\n if (!other.length) { return this }\n return RopeSequence.from(other).append(this)\n};\n\nRopeSequence.prototype.appendInner = function appendInner (other) {\n return new Append(this, other)\n};\n\n// :: (?number, ?number) \u2192 RopeSequence\n// Create a rope repesenting a sub-sequence of this rope.\nRopeSequence.prototype.slice = function slice (from, to) {\n if ( from === void 0 ) from = 0;\n if ( to === void 0 ) to = this.length;\n\n if (from >= to) { return RopeSequence.empty }\n return this.sliceInner(Math.max(0, from), Math.min(this.length, to))\n};\n\n// :: (number) \u2192 T\n// Retrieve the element at the given position from this rope.\nRopeSequence.prototype.get = function get (i) {\n if (i < 0 || i >= this.length) { return undefined }\n return this.getInner(i)\n};\n\n// :: ((element: T, index: number) \u2192 ?bool, ?number, ?number)\n// Call the given function for each element between the given\n// indices. This tends to be more efficient than looping over the\n// indices and calling `get`, because it doesn't have to descend the\n// tree for every element.\nRopeSequence.prototype.forEach = function forEach (f, from, to) {\n if ( from === void 0 ) from = 0;\n if ( to === void 0 ) to = this.length;\n\n if (from <= to)\n { this.forEachInner(f, from, to, 0); }\n else\n { this.forEachInvertedInner(f, from, to, 0); }\n};\n\n// :: ((element: T, index: number) \u2192 U, ?number, ?number) \u2192 [U]\n// Map the given functions over the elements of the rope, producing\n// a flat array.\nRopeSequence.prototype.map = function map (f, from, to) {\n if ( from === void 0 ) from = 0;\n if ( to === void 0 ) to = this.length;\n\n var result = [];\n this.forEach(function (elt, i) { return result.push(f(elt, i)); }, from, to);\n return result\n};\n\n// :: (?union<[T], RopeSequence>) \u2192 RopeSequence\n// Create a rope representing the given array, or return the rope\n// itself if a rope was given.\nRopeSequence.from = function from (values) {\n if (values instanceof RopeSequence) { return values }\n return values && values.length ? new Leaf(values) : RopeSequence.empty\n};\n\nvar Leaf = /*@__PURE__*/(function (RopeSequence) {\n function Leaf(values) {\n RopeSequence.call(this);\n this.values = values;\n }\n\n if ( RopeSequence ) Leaf.__proto__ = RopeSequence;\n Leaf.prototype = Object.create( RopeSequence && RopeSequence.prototype );\n Leaf.prototype.constructor = Leaf;\n\n var prototypeAccessors = { length: { configurable: true },depth: { configurable: true } };\n\n Leaf.prototype.flatten = function flatten () {\n return this.values\n };\n\n Leaf.prototype.sliceInner = function sliceInner (from, to) {\n if (from == 0 && to == this.length) { return this }\n return new Leaf(this.values.slice(from, to))\n };\n\n Leaf.prototype.getInner = function getInner (i) {\n return this.values[i]\n };\n\n Leaf.prototype.forEachInner = function forEachInner (f, from, to, start) {\n for (var i = from; i < to; i++)\n { if (f(this.values[i], start + i) === false) { return false } }\n };\n\n Leaf.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {\n for (var i = from - 1; i >= to; i--)\n { if (f(this.values[i], start + i) === false) { return false } }\n };\n\n Leaf.prototype.leafAppend = function leafAppend (other) {\n if (this.length + other.length <= GOOD_LEAF_SIZE)\n { return new Leaf(this.values.concat(other.flatten())) }\n };\n\n Leaf.prototype.leafPrepend = function leafPrepend (other) {\n if (this.length + other.length <= GOOD_LEAF_SIZE)\n { return new Leaf(other.flatten().concat(this.values)) }\n };\n\n prototypeAccessors.length.get = function () { return this.values.length };\n\n prototypeAccessors.depth.get = function () { return 0 };\n\n Object.defineProperties( Leaf.prototype, prototypeAccessors );\n\n return Leaf;\n}(RopeSequence));\n\n// :: RopeSequence\n// The empty rope sequence.\nRopeSequence.empty = new Leaf([]);\n\nvar Append = /*@__PURE__*/(function (RopeSequence) {\n function Append(left, right) {\n RopeSequence.call(this);\n this.left = left;\n this.right = right;\n this.length = left.length + right.length;\n this.depth = Math.max(left.depth, right.depth) + 1;\n }\n\n if ( RopeSequence ) Append.__proto__ = RopeSequence;\n Append.prototype = Object.create( RopeSequence && RopeSequence.prototype );\n Append.prototype.constructor = Append;\n\n Append.prototype.flatten = function flatten () {\n return this.left.flatten().concat(this.right.flatten())\n };\n\n Append.prototype.getInner = function getInner (i) {\n return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length)\n };\n\n Append.prototype.forEachInner = function forEachInner (f, from, to, start) {\n var leftLen = this.left.length;\n if (from < leftLen &&\n this.left.forEachInner(f, from, Math.min(to, leftLen), start) === false)\n { return false }\n if (to > leftLen &&\n this.right.forEachInner(f, Math.max(from - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false)\n { return false }\n };\n\n Append.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {\n var leftLen = this.left.length;\n if (from > leftLen &&\n this.right.forEachInvertedInner(f, from - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false)\n { return false }\n if (to < leftLen &&\n this.left.forEachInvertedInner(f, Math.min(from, leftLen), to, start) === false)\n { return false }\n };\n\n Append.prototype.sliceInner = function sliceInner (from, to) {\n if (from == 0 && to == this.length) { return this }\n var leftLen = this.left.length;\n if (to <= leftLen) { return this.left.slice(from, to) }\n if (from >= leftLen) { return this.right.slice(from - leftLen, to - leftLen) }\n return this.left.slice(from, leftLen).append(this.right.slice(0, to - leftLen))\n };\n\n Append.prototype.leafAppend = function leafAppend (other) {\n var inner = this.right.leafAppend(other);\n if (inner) { return new Append(this.left, inner) }\n };\n\n Append.prototype.leafPrepend = function leafPrepend (other) {\n var inner = this.left.leafPrepend(other);\n if (inner) { return new Append(inner, this.right) }\n };\n\n Append.prototype.appendInner = function appendInner (other) {\n if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1)\n { return new Append(this.left, new Append(this.right, other)) }\n return new Append(this, other)\n };\n\n return Append;\n}(RopeSequence));\n\nexport default RopeSequence;\n", "import RopeSequence from 'rope-sequence';\nimport { Mapping } from 'prosemirror-transform';\nimport { PluginKey, Plugin } from 'prosemirror-state';\n\n// ProseMirror's history isn't simply a way to roll back to a previous\n// state, because ProseMirror supports applying changes without adding\n// them to the history (for example during collaboration).\n//\n// To this end, each 'Branch' (one for the undo history and one for\n// the redo history) keeps an array of 'Items', which can optionally\n// hold a step (an actual undoable change), and always hold a position\n// map (which is needed to move changes below them to apply to the\n// current document).\n//\n// An item that has both a step and a selection bookmark is the start\n// of an 'event' \u2014 a group of changes that will be undone or redone at\n// once. (It stores only the bookmark, since that way we don't have to\n// provide a document until the selection is actually applied, which\n// is useful when compressing.)\n// Used to schedule history compression\nconst max_empty_items = 500;\nclass Branch {\n constructor(items, eventCount) {\n this.items = items;\n this.eventCount = eventCount;\n }\n // Pop the latest event off the branch's history and apply it\n // to a document transform.\n popEvent(state, preserveItems) {\n if (this.eventCount == 0)\n return null;\n let end = this.items.length;\n for (;; end--) {\n let next = this.items.get(end - 1);\n if (next.selection) {\n --end;\n break;\n }\n }\n let remap, mapFrom;\n if (preserveItems) {\n remap = this.remapping(end, this.items.length);\n mapFrom = remap.maps.length;\n }\n let transform = state.tr;\n let selection, remaining;\n let addAfter = [], addBefore = [];\n this.items.forEach((item, i) => {\n if (!item.step) {\n if (!remap) {\n remap = this.remapping(end, i + 1);\n mapFrom = remap.maps.length;\n }\n mapFrom--;\n addBefore.push(item);\n return;\n }\n if (remap) {\n addBefore.push(new Item(item.map));\n let step = item.step.map(remap.slice(mapFrom)), map;\n if (step && transform.maybeStep(step).doc) {\n map = transform.mapping.maps[transform.mapping.maps.length - 1];\n addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));\n }\n mapFrom--;\n if (map)\n remap.appendMap(map, mapFrom);\n }\n else {\n transform.maybeStep(item.step);\n }\n if (item.selection) {\n selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;\n remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);\n return false;\n }\n }, this.items.length, 0);\n return { remaining: remaining, transform, selection: selection };\n }\n // Create a new branch with the given transform added.\n addTransform(transform, selection, histOptions, preserveItems) {\n let newItems = [], eventCount = this.eventCount;\n let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;\n for (let i = 0; i < transform.steps.length; i++) {\n let step = transform.steps[i].invert(transform.docs[i]);\n let item = new Item(transform.mapping.maps[i], step, selection), merged;\n if (merged = lastItem && lastItem.merge(item)) {\n item = merged;\n if (i)\n newItems.pop();\n else\n oldItems = oldItems.slice(0, oldItems.length - 1);\n }\n newItems.push(item);\n if (selection) {\n eventCount++;\n selection = undefined;\n }\n if (!preserveItems)\n lastItem = item;\n }\n let overflow = eventCount - histOptions.depth;\n if (overflow > DEPTH_OVERFLOW) {\n oldItems = cutOffEvents(oldItems, overflow);\n eventCount -= overflow;\n }\n return new Branch(oldItems.append(newItems), eventCount);\n }\n remapping(from, to) {\n let maps = new Mapping;\n this.items.forEach((item, i) => {\n let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from\n ? maps.maps.length - item.mirrorOffset : undefined;\n maps.appendMap(item.map, mirrorPos);\n }, from, to);\n return maps;\n }\n addMaps(array) {\n if (this.eventCount == 0)\n return this;\n return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);\n }\n // When the collab module receives remote changes, the history has\n // to know about those, so that it can adjust the steps that were\n // rebased on top of the remote changes, and include the position\n // maps for the remote changes in its array of items.\n rebased(rebasedTransform, rebasedCount) {\n if (!this.eventCount)\n return this;\n let rebasedItems = [], start = Math.max(0, this.items.length - rebasedCount);\n let mapping = rebasedTransform.mapping;\n let newUntil = rebasedTransform.steps.length;\n let eventCount = this.eventCount;\n this.items.forEach(item => { if (item.selection)\n eventCount--; }, start);\n let iRebased = rebasedCount;\n this.items.forEach(item => {\n let pos = mapping.getMirror(--iRebased);\n if (pos == null)\n return;\n newUntil = Math.min(newUntil, pos);\n let map = mapping.maps[pos];\n if (item.step) {\n let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);\n let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));\n if (selection)\n eventCount++;\n rebasedItems.push(new Item(map, step, selection));\n }\n else {\n rebasedItems.push(new Item(map));\n }\n }, start);\n let newMaps = [];\n for (let i = rebasedCount; i < newUntil; i++)\n newMaps.push(new Item(mapping.maps[i]));\n let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);\n let branch = new Branch(items, eventCount);\n if (branch.emptyItemCount() > max_empty_items)\n branch = branch.compress(this.items.length - rebasedItems.length);\n return branch;\n }\n emptyItemCount() {\n let count = 0;\n this.items.forEach(item => { if (!item.step)\n count++; });\n return count;\n }\n // Compressing a branch means rewriting it to push the air (map-only\n // items) out. During collaboration, these naturally accumulate\n // because each remote change adds one. The `upto` argument is used\n // to ensure that only the items below a given level are compressed,\n // because `rebased` relies on a clean, untouched set of items in\n // order to associate old items with rebased steps.\n compress(upto = this.items.length) {\n let remap = this.remapping(0, upto), mapFrom = remap.maps.length;\n let items = [], events = 0;\n this.items.forEach((item, i) => {\n if (i >= upto) {\n items.push(item);\n if (item.selection)\n events++;\n }\n else if (item.step) {\n let step = item.step.map(remap.slice(mapFrom)), map = step && step.getMap();\n mapFrom--;\n if (map)\n remap.appendMap(map, mapFrom);\n if (step) {\n let selection = item.selection && item.selection.map(remap.slice(mapFrom));\n if (selection)\n events++;\n let newItem = new Item(map.invert(), step, selection), merged, last = items.length - 1;\n if (merged = items.length && items[last].merge(newItem))\n items[last] = merged;\n else\n items.push(newItem);\n }\n }\n else if (item.map) {\n mapFrom--;\n }\n }, this.items.length, 0);\n return new Branch(RopeSequence.from(items.reverse()), events);\n }\n}\nBranch.empty = new Branch(RopeSequence.empty, 0);\nfunction cutOffEvents(items, n) {\n let cutPoint;\n items.forEach((item, i) => {\n if (item.selection && (n-- == 0)) {\n cutPoint = i;\n return false;\n }\n });\n return items.slice(cutPoint);\n}\nclass Item {\n constructor(\n // The (forward) step map for this item.\n map, \n // The inverted step\n step, \n // If this is non-null, this item is the start of a group, and\n // this selection is the starting selection for the group (the one\n // that was active before the first step was applied)\n selection, \n // If this item is the inverse of a previous mapping on the stack,\n // this points at the inverse's offset\n mirrorOffset) {\n this.map = map;\n this.step = step;\n this.selection = selection;\n this.mirrorOffset = mirrorOffset;\n }\n merge(other) {\n if (this.step && other.step && !other.selection) {\n let step = other.step.merge(this.step);\n if (step)\n return new Item(step.getMap().invert(), step, this.selection);\n }\n }\n}\n// The value of the state field that tracks undo/redo history for that\n// state. Will be stored in the plugin state when the history plugin\n// is active.\nclass HistoryState {\n constructor(done, undone, prevRanges, prevTime, prevComposition) {\n this.done = done;\n this.undone = undone;\n this.prevRanges = prevRanges;\n this.prevTime = prevTime;\n this.prevComposition = prevComposition;\n }\n}\nconst DEPTH_OVERFLOW = 20;\n// Record a transformation in undo history.\nfunction applyTransaction(history, state, tr, options) {\n let historyTr = tr.getMeta(historyKey), rebased;\n if (historyTr)\n return historyTr.historyState;\n if (tr.getMeta(closeHistoryKey))\n history = new HistoryState(history.done, history.undone, null, 0, -1);\n let appended = tr.getMeta(\"appendedTransaction\");\n if (tr.steps.length == 0) {\n return history;\n }\n else if (appended && appended.getMeta(historyKey)) {\n if (appended.getMeta(historyKey).redo)\n return new HistoryState(history.done.addTransform(tr, undefined, options, mustPreserveItems(state)), history.undone, rangesFor(tr.mapping.maps), history.prevTime, history.prevComposition);\n else\n return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);\n }\n else if (tr.getMeta(\"addToHistory\") !== false && !(appended && appended.getMeta(\"addToHistory\") === false)) {\n // Group transforms that occur in quick succession into one event.\n let composition = tr.getMeta(\"composition\");\n let newGroup = history.prevTime == 0 ||\n (!appended && history.prevComposition != composition &&\n (history.prevTime < (tr.time || 0) - options.newGroupDelay || !isAdjacentTo(tr, history.prevRanges)));\n let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps);\n return new HistoryState(history.done.addTransform(tr, newGroup ? state.selection.getBookmark() : undefined, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr.time, composition == null ? history.prevComposition : composition);\n }\n else if (rebased = tr.getMeta(\"rebased\")) {\n // Used by the collab module to tell the history that some of its\n // content has been rebased.\n return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);\n }\n else {\n return new HistoryState(history.done.addMaps(tr.mapping.maps), history.undone.addMaps(tr.mapping.maps), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);\n }\n}\nfunction isAdjacentTo(transform, prevRanges) {\n if (!prevRanges)\n return false;\n if (!transform.docChanged)\n return true;\n let adjacent = false;\n transform.mapping.maps[0].forEach((start, end) => {\n for (let i = 0; i < prevRanges.length; i += 2)\n if (start <= prevRanges[i + 1] && end >= prevRanges[i])\n adjacent = true;\n });\n return adjacent;\n}\nfunction rangesFor(maps) {\n let result = [];\n for (let i = maps.length - 1; i >= 0 && result.length == 0; i--)\n maps[i].forEach((_from, _to, from, to) => result.push(from, to));\n return result;\n}\nfunction mapRanges(ranges, mapping) {\n if (!ranges)\n return null;\n let result = [];\n for (let i = 0; i < ranges.length; i += 2) {\n let from = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1);\n if (from <= to)\n result.push(from, to);\n }\n return result;\n}\n// Apply the latest event from one branch to the document and shift the event\n// onto the other branch.\nfunction histTransaction(history, state, redo) {\n let preserveItems = mustPreserveItems(state);\n let histOptions = historyKey.get(state).spec.config;\n let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);\n if (!pop)\n return null;\n let selection = pop.selection.resolve(pop.transform.doc);\n let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);\n let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);\n return pop.transform.setSelection(selection).setMeta(historyKey, { redo, historyState: newHist });\n}\nlet cachedPreserveItems = false, cachedPreserveItemsPlugins = null;\n// Check whether any plugin in the given state has a\n// `historyPreserveItems` property in its spec, in which case we must\n// preserve steps exactly as they came in, so that they can be\n// rebased.\nfunction mustPreserveItems(state) {\n let plugins = state.plugins;\n if (cachedPreserveItemsPlugins != plugins) {\n cachedPreserveItems = false;\n cachedPreserveItemsPlugins = plugins;\n for (let i = 0; i < plugins.length; i++)\n if (plugins[i].spec.historyPreserveItems) {\n cachedPreserveItems = true;\n break;\n }\n }\n return cachedPreserveItems;\n}\n/**\nSet a flag on the given transaction that will prevent further steps\nfrom being appended to an existing history event (so that they\nrequire a separate undo command to undo).\n*/\nfunction closeHistory(tr) {\n return tr.setMeta(closeHistoryKey, true);\n}\nconst historyKey = new PluginKey(\"history\");\nconst closeHistoryKey = new PluginKey(\"closeHistory\");\n/**\nReturns a plugin that enables the undo history for an editor. The\nplugin will track undo and redo stacks, which can be used with the\n[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.\n\nYou can set an `\"addToHistory\"` [metadata\nproperty](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction\nto prevent it from being rolled back by undo.\n*/\nfunction history(config = {}) {\n config = { depth: config.depth || 100,\n newGroupDelay: config.newGroupDelay || 500 };\n return new Plugin({\n key: historyKey,\n state: {\n init() {\n return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);\n },\n apply(tr, hist, state) {\n return applyTransaction(hist, state, tr, config);\n }\n },\n config,\n props: {\n handleDOMEvents: {\n beforeinput(view, e) {\n let inputType = e.inputType;\n let command = inputType == \"historyUndo\" ? undo : inputType == \"historyRedo\" ? redo : null;\n if (!command || !view.editable)\n return false;\n e.preventDefault();\n return command(view.state, view.dispatch);\n }\n }\n }\n });\n}\nfunction buildCommand(redo, scroll) {\n return (state, dispatch) => {\n let hist = historyKey.getState(state);\n if (!hist || (redo ? hist.undone : hist.done).eventCount == 0)\n return false;\n if (dispatch) {\n let tr = histTransaction(hist, state, redo);\n if (tr)\n dispatch(scroll ? tr.scrollIntoView() : tr);\n }\n return true;\n };\n}\n/**\nA command function that undoes the last change, if any.\n*/\nconst undo = buildCommand(false, true);\n/**\nA command function that redoes the last undone change, if any.\n*/\nconst redo = buildCommand(true, true);\n/**\nA command function that undoes the last change. Don't scroll the\nselection into view.\n*/\nconst undoNoScroll = buildCommand(false, false);\n/**\nA command function that redoes the last undone change. Don't\nscroll the selection into view.\n*/\nconst redoNoScroll = buildCommand(true, false);\n/**\nThe amount of undoable events available in a given state.\n*/\nfunction undoDepth(state) {\n let hist = historyKey.getState(state);\n return hist ? hist.done.eventCount : 0;\n}\n/**\nThe amount of redoable events available in a given editor state.\n*/\nfunction redoDepth(state) {\n let hist = historyKey.getState(state);\n return hist ? hist.undone.eventCount : 0;\n}\n/**\nReturns true if the given transaction was generated by the history\nplugin.\n*/\nfunction isHistoryTransaction(tr) {\n return tr.getMeta(historyKey) != null;\n}\n\nexport { closeHistory, history, isHistoryTransaction, redo, redoDepth, redoNoScroll, undo, undoDepth, undoNoScroll };\n", "export * from \"prosemirror-history\";\nexport {};\n", "import { Extension } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\nexport interface CharacterCountOptions {\n /**\n * The maximum number of characters that should be allowed. Defaults to `0`.\n * @default null\n * @example 180\n */\n limit: number | null | undefined\n /**\n * The mode by which the size is calculated. If set to `textSize`, the textContent of the document is used.\n * If set to `nodeSize`, the nodeSize of the document is used.\n * @default 'textSize'\n * @example 'textSize'\n */\n mode: 'textSize' | 'nodeSize'\n /**\n * The text counter function to use. Defaults to a simple character count.\n * @default (text) => text.length\n * @example (text) => [...new Intl.Segmenter().segment(text)].length\n */\n textCounter: (text: string) => number\n /**\n * The word counter function to use. Defaults to a simple word count.\n * @default (text) => text.split(' ').filter(word => word !== '').length\n * @example (text) => text.split(/\\s+/).filter(word => word !== '').length\n */\n wordCounter: (text: string) => number\n}\n\nexport interface CharacterCountStorage {\n /**\n * Get the number of characters for the current document.\n * @param options The options for the character count. (optional)\n * @param options.node The node to get the characters from. Defaults to the current document.\n * @param options.mode The mode by which the size is calculated. If set to `textSize`, the textContent of the document is used.\n */\n characters: (options?: { node?: ProseMirrorNode; mode?: 'textSize' | 'nodeSize' }) => number\n\n /**\n * Get the number of words for the current document.\n * @param options The options for the character count. (optional)\n * @param options.node The node to get the words from. Defaults to the current document.\n */\n words: (options?: { node?: ProseMirrorNode }) => number\n}\n\ndeclare module '@tiptap/core' {\n interface Storage {\n characterCount: CharacterCountStorage\n }\n}\n\n/**\n * This extension allows you to count the characters and words of your document.\n * @see https://tiptap.dev/api/extensions/character-count\n */\nexport const CharacterCount = Extension.create({\n name: 'characterCount',\n\n addOptions() {\n return {\n limit: null,\n mode: 'textSize',\n textCounter: text => text.length,\n wordCounter: text => text.split(' ').filter(word => word !== '').length,\n }\n },\n\n addStorage() {\n return {\n characters: () => 0,\n words: () => 0,\n }\n },\n\n onBeforeCreate() {\n this.storage.characters = options => {\n const node = options?.node || this.editor.state.doc\n const mode = options?.mode || this.options.mode\n\n if (mode === 'textSize') {\n const text = node.textBetween(0, node.content.size, undefined, ' ')\n\n return this.options.textCounter(text)\n }\n\n return node.nodeSize\n }\n\n this.storage.words = options => {\n const node = options?.node || this.editor.state.doc\n const text = node.textBetween(0, node.content.size, ' ', ' ')\n\n return this.options.wordCounter(text)\n }\n },\n\n addProseMirrorPlugins() {\n let initialEvaluationDone = false\n\n return [\n new Plugin({\n key: new PluginKey('characterCount'),\n appendTransaction: (transactions, oldState, newState) => {\n if (initialEvaluationDone) {\n return\n }\n\n const limit = this.options.limit\n\n if (limit === null || limit === undefined || limit === 0) {\n initialEvaluationDone = true\n return\n }\n\n const initialContentSize = this.storage.characters({ node: newState.doc })\n\n if (initialContentSize > limit) {\n const over = initialContentSize - limit\n const from = 0\n const to = over\n\n console.warn(\n `[CharacterCount] Initial content exceeded limit of ${limit} characters. Content was automatically trimmed.`,\n )\n const tr = newState.tr.deleteRange(from, to)\n\n initialEvaluationDone = true\n return tr\n }\n\n initialEvaluationDone = true\n },\n filterTransaction: (transaction, state) => {\n const limit = this.options.limit\n\n // Nothing has changed or no limit is defined. Ignore it.\n if (!transaction.docChanged || limit === 0 || limit === null || limit === undefined) {\n return true\n }\n\n const oldSize = this.storage.characters({ node: state.doc })\n const newSize = this.storage.characters({ node: transaction.doc })\n\n // Everything is in the limit. Good.\n if (newSize <= limit) {\n return true\n }\n\n // The limit has already been exceeded but will be reduced.\n if (oldSize > limit && newSize > limit && newSize <= oldSize) {\n return true\n }\n\n // The limit has already been exceeded and will be increased further.\n if (oldSize > limit && newSize > limit && newSize > oldSize) {\n return false\n }\n\n const isPaste = transaction.getMeta('paste')\n\n // Block all exceeding transactions that were not pasted.\n if (!isPaste) {\n return false\n }\n\n // For pasted content, we try to remove the exceeding content.\n const pos = transaction.selection.$head.pos\n const over = newSize - limit\n const from = pos - over\n const to = pos\n\n // It’s probably a bad idea to mutate transactions within `filterTransaction`\n // but for now this is working fine.\n transaction.deleteRange(from, to)\n\n // In some situations, the limit will continue to be exceeded after trimming.\n // This happens e.g. when truncating within a complex node (e.g. table)\n // and ProseMirror has to close this node again.\n // If this is the case, we prevent the transaction completely.\n const updatedSize = this.storage.characters({ node: transaction.doc })\n\n if (updatedSize > limit) {\n return false\n }\n\n return true\n },\n }),\n ]\n },\n})\n", "import { Extension } from '@tiptap/core'\nimport { dropCursor } from '@tiptap/pm/dropcursor'\n\nexport interface DropcursorOptions {\n /**\n * The color of the drop cursor. Use `false` to apply no color and rely only on class.\n * @default 'currentColor'\n * @example 'red'\n */\n color?: string | false\n\n /**\n * The width of the drop cursor\n * @default 1\n * @example 2\n */\n width: number | undefined\n\n /**\n * The class of the drop cursor\n * @default undefined\n * @example 'drop-cursor'\n */\n class: string | undefined\n}\n\n/**\n * This extension allows you to add a drop cursor to your editor.\n * A drop cursor is a line that appears when you drag and drop content\n * in-between nodes.\n * @see https://tiptap.dev/api/extensions/dropcursor\n */\nexport const Dropcursor = Extension.create({\n name: 'dropCursor',\n\n addOptions() {\n return {\n color: 'currentColor',\n width: 1,\n class: undefined,\n }\n },\n\n addProseMirrorPlugins() {\n return [dropCursor(this.options)]\n },\n})\n", "import { Extension } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\n\nexport interface FocusOptions {\n /**\n * The class name that should be added to the focused node.\n * @default 'has-focus'\n * @example 'is-focused'\n */\n className: string\n\n /**\n * The mode by which the focused node is determined.\n * - All: All nodes are marked as focused.\n * - Deepest: Only the deepest node is marked as focused.\n * - Shallowest: Only the shallowest node is marked as focused.\n *\n * @default 'all'\n * @example 'deepest'\n * @example 'shallowest'\n */\n mode: 'all' | 'deepest' | 'shallowest'\n}\n\n/**\n * This extension allows you to add a class to the focused node.\n * @see https://www.tiptap.dev/api/extensions/focus\n */\nexport const Focus = Extension.create({\n name: 'focus',\n\n addOptions() {\n return {\n className: 'has-focus',\n mode: 'all',\n }\n },\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: new PluginKey('focus'),\n props: {\n decorations: ({ doc, selection }) => {\n const { isEditable, isFocused } = this.editor\n const { anchor } = selection\n const decorations: Decoration[] = []\n\n if (!isEditable || !isFocused) {\n return DecorationSet.create(doc, [])\n }\n\n // Maximum Levels\n let maxLevels = 0\n\n if (this.options.mode === 'deepest') {\n doc.descendants((node, pos) => {\n if (node.isText) {\n return\n }\n\n const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1\n\n if (!isCurrent) {\n return false\n }\n\n maxLevels += 1\n })\n }\n\n // Loop through current\n let currentLevel = 0\n\n doc.descendants((node, pos) => {\n if (node.isText) {\n return false\n }\n\n const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1\n\n if (!isCurrent) {\n return false\n }\n\n currentLevel += 1\n\n const outOfScope =\n (this.options.mode === 'deepest' && maxLevels - currentLevel > 0) ||\n (this.options.mode === 'shallowest' && currentLevel > 1)\n\n if (outOfScope) {\n return this.options.mode === 'deepest'\n }\n\n decorations.push(\n Decoration.node(pos, pos + node.nodeSize, {\n class: this.options.className,\n }),\n )\n })\n\n return DecorationSet.create(doc, decorations)\n },\n },\n }),\n ]\n },\n})\n", "import type { ParentConfig } from '@tiptap/core'\nimport { callOrReturn, Extension, getExtensionField } from '@tiptap/core'\nimport { gapCursor } from '@tiptap/pm/gapcursor'\n\ndeclare module '@tiptap/core' {\n interface NodeConfig {\n /**\n * A function to determine whether the gap cursor is allowed at the current position. Must return `true` or `false`.\n * @default null\n */\n allowGapCursor?:\n | boolean\n | null\n | ((this: {\n name: string\n options: Options\n storage: Storage\n parent: ParentConfig>['allowGapCursor']\n }) => boolean | null)\n }\n}\n\n/**\n * This extension allows you to add a gap cursor to your editor.\n * A gap cursor is a cursor that appears when you click on a place\n * where no content is present, for example inbetween nodes.\n * @see https://tiptap.dev/api/extensions/gapcursor\n */\nexport const Gapcursor = Extension.create({\n name: 'gapCursor',\n\n addProseMirrorPlugins() {\n return [gapCursor()]\n },\n\n extendNodeSchema(extension) {\n const context = {\n name: extension.name,\n options: extension.options,\n storage: extension.storage,\n }\n\n return {\n allowGapCursor: callOrReturn(getExtensionField(extension, 'allowGapCursor', context)) ?? null,\n }\n },\n})\n", "import type { Editor } from '@tiptap/core'\nimport { Extension, isNodeEmpty } from '@tiptap/core'\nimport type { Node as ProsemirrorNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\n\n/**\n * The default data attribute label\n */\nconst DEFAULT_DATA_ATTRIBUTE = 'placeholder'\n\n/**\n * Prepares the placeholder attribute by ensuring it is properly formatted.\n * @param attr - The placeholder attribute string.\n * @returns The prepared placeholder attribute string.\n */\nexport function preparePlaceholderAttribute(attr: string): string {\n return (\n attr\n // replace whitespace with dashes\n .replace(/\\s+/g, '-')\n // replace non-alphanumeric characters\n // or special chars like $, %, &, etc.\n // but not dashes\n .replace(/[^a-zA-Z0-9-]/g, '')\n // and replace any numeric character at the start\n .replace(/^[0-9-]+/, '')\n // and finally replace any stray, leading dashes\n .replace(/^-+/, '')\n .toLowerCase()\n )\n}\n\nexport interface PlaceholderOptions {\n /**\n * **The class name for the empty editor**\n * @default 'is-editor-empty'\n */\n emptyEditorClass: string\n\n /**\n * **The class name for empty nodes**\n * @default 'is-empty'\n */\n emptyNodeClass: string\n\n /**\n * **The data-attribute used for the placeholder label**\n * Will be prepended with `data-` and converted to kebab-case and cleaned of special characters.\n * @default 'placeholder'\n */\n dataAttribute: string\n\n /**\n * **The placeholder content**\n *\n * You can use a function to return a dynamic placeholder or a string.\n * @default 'Write something …'\n */\n placeholder:\n | ((PlaceholderProps: { editor: Editor; node: ProsemirrorNode; pos: number; hasAnchor: boolean }) => string)\n | string\n\n /**\n * **Checks if the placeholder should be only shown when the editor is editable.**\n *\n * If true, the placeholder will only be shown when the editor is editable.\n * If false, the placeholder will always be shown.\n * @default true\n */\n showOnlyWhenEditable: boolean\n\n /**\n * **Checks if the placeholder should be only shown when the current node is empty.**\n *\n * If true, the placeholder will only be shown when the current node is empty.\n * If false, the placeholder will be shown when any node is empty.\n * @default true\n */\n showOnlyCurrent: boolean\n\n /**\n * **Controls if the placeholder should be shown for all descendents.**\n *\n * If true, the placeholder will be shown for all descendents.\n * If false, the placeholder will only be shown for the current node.\n * @default false\n */\n includeChildren: boolean\n}\n\n/**\n * This extension allows you to add a placeholder to your editor.\n * A placeholder is a text that appears when the editor or a node is empty.\n * @see https://www.tiptap.dev/api/extensions/placeholder\n */\nexport const Placeholder = Extension.create({\n name: 'placeholder',\n\n addOptions() {\n return {\n emptyEditorClass: 'is-editor-empty',\n emptyNodeClass: 'is-empty',\n dataAttribute: DEFAULT_DATA_ATTRIBUTE,\n placeholder: 'Write something …',\n showOnlyWhenEditable: true,\n showOnlyCurrent: true,\n includeChildren: false,\n }\n },\n\n addProseMirrorPlugins() {\n const dataAttribute = this.options.dataAttribute\n ? `data-${preparePlaceholderAttribute(this.options.dataAttribute)}`\n : `data-${DEFAULT_DATA_ATTRIBUTE}`\n\n return [\n new Plugin({\n key: new PluginKey('placeholder'),\n props: {\n decorations: ({ doc, selection }) => {\n const active = this.editor.isEditable || !this.options.showOnlyWhenEditable\n const { anchor } = selection\n const decorations: Decoration[] = []\n\n if (!active) {\n return null\n }\n\n const isEmptyDoc = this.editor.isEmpty\n\n doc.descendants((node, pos) => {\n const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize\n const isEmpty = !node.isLeaf && isNodeEmpty(node)\n\n if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {\n const classes = [this.options.emptyNodeClass]\n\n if (isEmptyDoc) {\n classes.push(this.options.emptyEditorClass)\n }\n\n const decoration = Decoration.node(pos, pos + node.nodeSize, {\n class: classes.join(' '),\n [dataAttribute]:\n typeof this.options.placeholder === 'function'\n ? this.options.placeholder({\n editor: this.editor,\n node,\n pos,\n hasAnchor,\n })\n : this.options.placeholder,\n })\n\n decorations.push(decoration)\n }\n\n return this.options.includeChildren\n })\n\n return DecorationSet.create(doc, decorations)\n },\n },\n }),\n ]\n },\n})\n", "import { Extension, isNodeSelection } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\n\nexport type SelectionOptions = {\n /**\n * The class name that should be added to the selected text.\n * @default 'selection'\n * @example 'is-selected'\n */\n className: string\n}\n\n/**\n * This extension allows you to add a class to the selected text.\n * @see https://www.tiptap.dev/api/extensions/selection\n */\nexport const Selection = Extension.create({\n name: 'selection',\n\n addOptions() {\n return {\n className: 'selection',\n }\n },\n\n addProseMirrorPlugins() {\n const { editor, options } = this\n\n return [\n new Plugin({\n key: new PluginKey('selection'),\n props: {\n decorations(state) {\n if (\n state.selection.empty ||\n editor.isFocused ||\n !editor.isEditable ||\n isNodeSelection(state.selection) ||\n editor.view.dragging\n ) {\n return null\n }\n\n return DecorationSet.create(state.doc, [\n Decoration.inline(state.selection.from, state.selection.to, {\n class: options.className,\n }),\n ])\n },\n },\n }),\n ]\n },\n})\n\nexport default Selection\n", "import { Extension } from '@tiptap/core'\nimport type { Node, NodeType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\nfunction nodeEqualsType({ types, node }: { types: NodeType | NodeType[]; node: Node | null | undefined }) {\n return (node && Array.isArray(types) && types.includes(node.type)) || node?.type === types\n}\n\n/**\n * Extension based on:\n * - https://github.com/ueberdosis/tiptap/blob/v1/packages/tiptap-extensions/src/extensions/TrailingNode.js\n * - https://github.com/remirror/remirror/blob/e0f1bec4a1e8073ce8f5500d62193e52321155b9/packages/prosemirror-trailing-node/src/trailing-node-plugin.ts\n */\n\nexport interface TrailingNodeOptions {\n /**\n * The node type that should be inserted at the end of the document.\n * @note the node will always be added to the `notAfter` lists to\n * prevent an infinite loop.\n * @default undefined\n */\n node?: string\n /**\n * The node types after which the trailing node should not be inserted.\n * @default ['paragraph']\n */\n notAfter?: string | string[]\n}\n\n/**\n * This extension allows you to add an extra node at the end of the document.\n * @see https://www.tiptap.dev/api/extensions/trailing-node\n */\nexport const TrailingNode = Extension.create({\n name: 'trailingNode',\n\n addOptions() {\n return {\n node: undefined,\n notAfter: [],\n }\n },\n\n addProseMirrorPlugins() {\n const plugin = new PluginKey(this.name)\n const defaultNode =\n this.options.node || this.editor.schema.topNodeType.contentMatch.defaultType?.name || 'paragraph'\n\n const disabledNodes = Object.entries(this.editor.schema.nodes)\n .map(([, value]) => value)\n .filter(node => (this.options.notAfter || []).concat(defaultNode).includes(node.name))\n\n return [\n new Plugin({\n key: plugin,\n appendTransaction: (_, __, state) => {\n const { doc, tr, schema } = state\n const shouldInsertNodeAtEnd = plugin.getState(state)\n const endPosition = doc.content.size\n const type = schema.nodes[defaultNode]\n\n if (!shouldInsertNodeAtEnd) {\n return\n }\n\n return tr.insert(endPosition, type.create())\n },\n state: {\n init: (_, state) => {\n const lastNode = state.tr.doc.lastChild\n\n return !nodeEqualsType({ node: lastNode, types: disabledNodes })\n },\n apply: (tr, value) => {\n if (!tr.docChanged) {\n return value\n }\n\n // Ignore transactions from UniqueID extension to prevent infinite loops\n // when UniqueID adds IDs to newly inserted trailing nodes\n if (tr.getMeta('__uniqueIDTransaction')) {\n return value\n }\n\n const lastNode = tr.doc.lastChild\n\n return !nodeEqualsType({ node: lastNode, types: disabledNodes })\n },\n },\n }),\n ]\n },\n})\n", "import { Extension } from '@tiptap/core'\nimport { history, redo, undo } from '@tiptap/pm/history'\n\nexport interface UndoRedoOptions {\n /**\n * The amount of history events that are collected before the oldest events are discarded.\n * @default 100\n * @example 50\n */\n depth: number\n\n /**\n * The delay (in milliseconds) between changes after which a new group should be started.\n * @default 500\n * @example 1000\n */\n newGroupDelay: number\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n undoRedo: {\n /**\n * Undo recent changes\n * @example editor.commands.undo()\n */\n undo: () => ReturnType\n /**\n * Reapply reverted changes\n * @example editor.commands.redo()\n */\n redo: () => ReturnType\n }\n }\n}\n\n/**\n * This extension allows you to undo and redo recent changes.\n * @see https://www.tiptap.dev/api/extensions/undo-redo\n *\n * **Important**: If the `@tiptap/extension-collaboration` package is used, make sure to remove\n * the `undo-redo` extension, as it is not compatible with the `collaboration` extension.\n *\n * `@tiptap/extension-collaboration` uses its own history implementation.\n */\nexport const UndoRedo = Extension.create({\n name: 'undoRedo',\n\n addOptions() {\n return {\n depth: 100,\n newGroupDelay: 500,\n }\n },\n\n addCommands() {\n return {\n undo:\n () =>\n ({ state, dispatch }) => {\n return undo(state, dispatch)\n },\n redo:\n () =>\n ({ state, dispatch }) => {\n return redo(state, dispatch)\n },\n }\n },\n\n addProseMirrorPlugins() {\n return [history(this.options)]\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-z': () => this.editor.commands.undo(),\n 'Shift-Mod-z': () => this.editor.commands.redo(),\n 'Mod-y': () => this.editor.commands.redo(),\n\n // Russian keyboard layouts\n 'Mod-я': () => this.editor.commands.undo(),\n 'Shift-Mod-я': () => this.editor.commands.redo(),\n }\n },\n})\n", "import { Extension } from '@tiptap/core'\nimport type { BlockquoteOptions } from '@tiptap/extension-blockquote'\nimport { Blockquote } from '@tiptap/extension-blockquote'\nimport type { BoldOptions } from '@tiptap/extension-bold'\nimport { Bold } from '@tiptap/extension-bold'\nimport type { CodeOptions } from '@tiptap/extension-code'\nimport { Code } from '@tiptap/extension-code'\nimport type { CodeBlockOptions } from '@tiptap/extension-code-block'\nimport { CodeBlock } from '@tiptap/extension-code-block'\nimport { Document } from '@tiptap/extension-document'\nimport type { HardBreakOptions } from '@tiptap/extension-hard-break'\nimport { HardBreak } from '@tiptap/extension-hard-break'\nimport type { HeadingOptions } from '@tiptap/extension-heading'\nimport { Heading } from '@tiptap/extension-heading'\nimport type { HorizontalRuleOptions } from '@tiptap/extension-horizontal-rule'\nimport { HorizontalRule } from '@tiptap/extension-horizontal-rule'\nimport type { ItalicOptions } from '@tiptap/extension-italic'\nimport { Italic } from '@tiptap/extension-italic'\nimport type { LinkOptions } from '@tiptap/extension-link'\nimport { Link } from '@tiptap/extension-link'\nimport type { BulletListOptions, ListItemOptions, ListKeymapOptions, OrderedListOptions } from '@tiptap/extension-list'\nimport { BulletList, ListItem, ListKeymap, OrderedList } from '@tiptap/extension-list'\nimport type { ParagraphOptions } from '@tiptap/extension-paragraph'\nimport { Paragraph } from '@tiptap/extension-paragraph'\nimport type { StrikeOptions } from '@tiptap/extension-strike'\nimport { Strike } from '@tiptap/extension-strike'\nimport { Text } from '@tiptap/extension-text'\nimport type { UnderlineOptions } from '@tiptap/extension-underline'\nimport { Underline } from '@tiptap/extension-underline'\nimport type { DropcursorOptions, TrailingNodeOptions, UndoRedoOptions } from '@tiptap/extensions'\nimport { Dropcursor, Gapcursor, TrailingNode, UndoRedo } from '@tiptap/extensions'\n\nexport interface StarterKitOptions {\n /**\n * If set to false, the blockquote extension will not be registered\n * @example blockquote: false\n */\n blockquote: Partial | false\n\n /**\n * If set to false, the bold extension will not be registered\n * @example bold: false\n */\n bold: Partial | false\n\n /**\n * If set to false, the bulletList extension will not be registered\n * @example bulletList: false\n */\n bulletList: Partial | false\n\n /**\n * If set to false, the code extension will not be registered\n * @example code: false\n */\n code: Partial | false\n\n /**\n * If set to false, the codeBlock extension will not be registered\n * @example codeBlock: false\n */\n codeBlock: Partial | false\n\n /**\n * If set to false, the document extension will not be registered\n * @example document: false\n */\n document: false\n\n /**\n * If set to false, the dropcursor extension will not be registered\n * @example dropcursor: false\n */\n dropcursor: Partial | false\n\n /**\n * If set to false, the gapcursor extension will not be registered\n * @example gapcursor: false\n */\n gapcursor: false\n\n /**\n * If set to false, the hardBreak extension will not be registered\n * @example hardBreak: false\n */\n hardBreak: Partial | false\n\n /**\n * If set to false, the heading extension will not be registered\n * @example heading: false\n */\n heading: Partial | false\n\n /**\n * If set to false, the undo-redo extension will not be registered\n * @example undoRedo: false\n */\n undoRedo: Partial | false\n\n /**\n * If set to false, the horizontalRule extension will not be registered\n * @example horizontalRule: false\n */\n horizontalRule: Partial | false\n\n /**\n * If set to false, the italic extension will not be registered\n * @example italic: false\n */\n italic: Partial | false\n\n /**\n * If set to false, the listItem extension will not be registered\n * @example listItem: false\n */\n listItem: Partial | false\n\n /**\n * If set to false, the listItemKeymap extension will not be registered\n * @example listKeymap: false\n */\n listKeymap: Partial | false\n\n /**\n * If set to false, the link extension will not be registered\n * @example link: false\n */\n link: Partial | false\n\n /**\n * If set to false, the orderedList extension will not be registered\n * @example orderedList: false\n */\n orderedList: Partial | false\n\n /**\n * If set to false, the paragraph extension will not be registered\n * @example paragraph: false\n */\n paragraph: Partial | false\n\n /**\n * If set to false, the strike extension will not be registered\n * @example strike: false\n */\n strike: Partial | false\n\n /**\n * If set to false, the text extension will not be registered\n * @example text: false\n */\n text: false\n\n /**\n * If set to false, the underline extension will not be registered\n * @example underline: false\n */\n underline: Partial | false\n\n /**\n * If set to false, the trailingNode extension will not be registered\n * @example trailingNode: false\n */\n trailingNode: Partial | false\n}\n\n/**\n * The starter kit is a collection of essential editor extensions.\n *\n * It’s a good starting point for building your own editor.\n */\nexport const StarterKit = Extension.create({\n name: 'starterKit',\n\n addExtensions() {\n const extensions = []\n\n if (this.options.bold !== false) {\n extensions.push(Bold.configure(this.options.bold))\n }\n\n if (this.options.blockquote !== false) {\n extensions.push(Blockquote.configure(this.options.blockquote))\n }\n\n if (this.options.bulletList !== false) {\n extensions.push(BulletList.configure(this.options.bulletList))\n }\n\n if (this.options.code !== false) {\n extensions.push(Code.configure(this.options.code))\n }\n\n if (this.options.codeBlock !== false) {\n extensions.push(CodeBlock.configure(this.options.codeBlock))\n }\n\n if (this.options.document !== false) {\n extensions.push(Document.configure(this.options.document))\n }\n\n if (this.options.dropcursor !== false) {\n extensions.push(Dropcursor.configure(this.options.dropcursor))\n }\n\n if (this.options.gapcursor !== false) {\n extensions.push(Gapcursor.configure(this.options.gapcursor))\n }\n\n if (this.options.hardBreak !== false) {\n extensions.push(HardBreak.configure(this.options.hardBreak))\n }\n\n if (this.options.heading !== false) {\n extensions.push(Heading.configure(this.options.heading))\n }\n\n if (this.options.undoRedo !== false) {\n extensions.push(UndoRedo.configure(this.options.undoRedo))\n }\n\n if (this.options.horizontalRule !== false) {\n extensions.push(HorizontalRule.configure(this.options.horizontalRule))\n }\n\n if (this.options.italic !== false) {\n extensions.push(Italic.configure(this.options.italic))\n }\n\n if (this.options.listItem !== false) {\n extensions.push(ListItem.configure(this.options.listItem))\n }\n\n if (this.options.listKeymap !== false) {\n extensions.push(ListKeymap.configure(this.options?.listKeymap))\n }\n\n if (this.options.link !== false) {\n extensions.push(Link.configure(this.options?.link))\n }\n\n if (this.options.orderedList !== false) {\n extensions.push(OrderedList.configure(this.options.orderedList))\n }\n\n if (this.options.paragraph !== false) {\n extensions.push(Paragraph.configure(this.options.paragraph))\n }\n\n if (this.options.strike !== false) {\n extensions.push(Strike.configure(this.options.strike))\n }\n\n if (this.options.text !== false) {\n extensions.push(Text.configure(this.options.text))\n }\n\n if (this.options.underline !== false) {\n extensions.push(Underline.configure(this.options?.underline))\n }\n\n if (this.options.trailingNode !== false) {\n extensions.push(TrailingNode.configure(this.options?.trailingNode))\n }\n\n return extensions\n },\n})\n", "import { StarterKit } from './starter-kit.js'\n\nexport type { StarterKitOptions } from './starter-kit.js'\nexport * from './starter-kit.js'\n\nexport default StarterKit\n", "import type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Gets the original marked default options.\n */\nexport function _getDefaults(): MarkedOptions {\n return {\n async: false,\n breaks: false,\n extensions: null,\n gfm: true,\n hooks: null,\n pedantic: false,\n renderer: null,\n silent: false,\n tokenizer: null,\n walkTokens: null,\n };\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport let _defaults: MarkedOptions = _getDefaults();\n\nexport function changeDefaults(newDefaults: MarkedOptions) {\n _defaults = newDefaults;\n}\n", "const noopTest = { exec: () => null } as unknown as RegExp;\n\nfunction edit(regex: string | RegExp, opt = '') {\n let source = typeof regex === 'string' ? regex : regex.source;\n const obj = {\n replace: (name: string | RegExp, val: string | RegExp) => {\n let valSource = typeof val === 'string' ? val : val.source;\n valSource = valSource.replace(other.caret, '$1');\n source = source.replace(name, valSource);\n return obj;\n },\n getRegex: () => {\n return new RegExp(source, opt);\n },\n };\n return obj;\n}\n\nconst supportsLookbehind = (() => {\ntry {\n // eslint-disable-next-line prefer-regex-literals\n return !!new RegExp('(?<=1)(?/,\n blockquoteSetextReplace: /\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,\n blockquoteSetextReplace2: /^ {0,3}>[ \\t]?/gm,\n listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g,\n listIsTask: /^\\[[ xX]\\] +\\S/,\n listReplaceTask: /^\\[[ xX]\\] +/,\n listTaskCheckbox: /\\[[ xX]\\]/,\n anyLine: /\\n.*\\n/,\n hrefBrackets: /^<(.*)>$/,\n tableDelimiter: /[:|]/,\n tableAlignChars: /^\\||\\| *$/g,\n tableRowBlankLine: /\\n[ \\t]*$/,\n tableAlignRight: /^ *-+: *$/,\n tableAlignCenter: /^ *:-+: *$/,\n tableAlignLeft: /^ *:-+ *$/,\n startATag: /^
/i,\n startPreScriptTag: /^<(pre|code|kbd|script)(\\s|>)/i,\n endPreScriptTag: /^<\\/(pre|code|kbd|script)(\\s|>)/i,\n startAngleBracket: /^$/,\n pedanticHrefTitle: /^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/,\n unicodeAlphaNumeric: /[\\p{L}\\p{N}]/u,\n escapeTest: /[&<>\"']/,\n escapeReplace: /[&<>\"']/g,\n escapeTestNoEncode: /[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,\n escapeReplaceNoEncode: /[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,\n caret: /(^|[^\\[])\\^/g,\n percentDecode: /%25/g,\n findPipe: /\\|/g,\n splitPipe: / \\|/,\n slashPipe: /\\\\\\|/g,\n carriageReturn: /\\r\\n|\\r/g,\n spaceLine: /^ +$/gm,\n notSpaceStart: /^\\S*/,\n endingNewline: /\\n$/,\n listItemRegex: (bull: string) => new RegExp(`^( {0,3}${bull})((?:[\\t ][^\\\\n]*)?(?:\\\\n|$))`),\n nextBulletRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \\t][^\\\\n]*)?(?:\\\\n|$))`),\n hrRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`),\n fencesBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\\`\\`\\`|~~~)`),\n headingBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`),\n htmlBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, 'i'),\n blockquoteBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}>`),\n};\n\n/**\n * Block-Level Grammar\n */\n\nconst newline = /^(?:[ \\t]*(?:\\n|$))+/;\nconst blockCode = /^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/;\nconst fences = /^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/;\nconst hr = /^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/;\nconst heading = /^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/;\nconst bullet = / {0,3}(?:[*+-]|\\d{1,9}[.)])/;\nconst lheadingCore = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/;\nconst lheading = edit(lheadingCore)\n .replace(/bull/g, bullet) // lists can interrupt\n .replace(/blockCode/g, /(?: {4}| {0,3}\\t)/) // indented code blocks can interrupt\n .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt\n .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt\n .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt\n .replace(/html/g, / {0,3}<[^\\n>]+>\\n/) // block html can interrupt\n .replace(/\\|table/g, '') // table not in commonmark\n .getRegex();\nconst lheadingGfm = edit(lheadingCore)\n .replace(/bull/g, bullet) // lists can interrupt\n .replace(/blockCode/g, /(?: {4}| {0,3}\\t)/) // indented code blocks can interrupt\n .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt\n .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt\n .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt\n .replace(/html/g, / {0,3}<[^\\n>]+>\\n/) // block html can interrupt\n .replace(/table/g, / {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/) // table can interrupt\n .getRegex();\nconst _paragraph = /^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\\n)[^\\n]+)*)/;\nconst blockText = /^[^\\n]+/;\nconst _blockLabel = /(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/;\nconst def = edit(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/)\n .replace('label', _blockLabel)\n .replace('title', /(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/)\n .getRegex();\n\nconst list = edit(/^(bull)([ \\t][^\\n]+?)?(?:\\n|$)/)\n .replace(/bull/g, bullet)\n .getRegex();\n\nconst _tag = 'address|article|aside|base|basefont|blockquote|body|caption'\n + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'\n + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'\n + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'\n + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title'\n + '|tr|track|ul';\nconst _comment = /|$))/;\nconst html = edit(\n '^ {0,3}(?:' // optional indentation\n+ '<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:[^\\\\n]*\\\\n+|$)' // (1)\n+ '|comment[^\\\\n]*(\\\\n+|$)' // (2)\n+ '|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>\\\\n*|$)' // (3)\n+ '|\\\\n*|$)' // (4)\n+ '|\\\\n*|$)' // (5)\n+ '|)[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (6)\n+ '|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (7) open tag\n+ '|(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (7) closing tag\n+ ')', 'i')\n .replace('comment', _comment)\n .replace('tag', _tag)\n .replace('attribute', / +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/)\n .getRegex();\n\nconst paragraph = edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs\n .replace('|table', '')\n .replace('blockquote', ' {0,3}>')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)])[ \\\\t]') // only lists starting from 1 can interrupt\n .replace('html', ')|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // pars can be interrupted by type (6) html blocks\n .getRegex();\n\nconst blockquote = edit(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/)\n .replace('paragraph', paragraph)\n .getRegex();\n\n/**\n * Normal Block Grammar\n */\n\nconst blockNormal = {\n blockquote,\n code: blockCode,\n def,\n fences,\n heading,\n hr,\n html,\n lheading,\n list,\n newline,\n paragraph,\n table: noopTest,\n text: blockText,\n};\n\ntype BlockKeys = keyof typeof blockNormal;\n\n/**\n * GFM Block Grammar\n */\n\nconst gfmTable = edit(\n '^ *([^\\\\n ].*)\\\\n' // Header\n+ ' {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)' // Align\n+ '(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)') // Cells\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('blockquote', ' {0,3}>')\n .replace('code', '(?: {4}| {0,3}\\t)[^\\\\n]')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)])[ \\\\t]') // only lists starting from 1 can interrupt\n .replace('html', ')|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // tables can be interrupted by type (6) html blocks\n .getRegex();\n\nconst blockGfm: Record = {\n ...blockNormal,\n lheading: lheadingGfm,\n table: gfmTable,\n paragraph: edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs\n .replace('table', gfmTable) // interrupt paragraphs with table\n .replace('blockquote', ' {0,3}>')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)])[ \\\\t]') // only lists starting from 1 can interrupt\n .replace('html', ')|<(?:script|pre|style|textarea|!--)')\n .replace('tag', _tag) // pars can be interrupted by type (6) html blocks\n .getRegex(),\n};\n\n/**\n * Pedantic grammar (original John Gruber's loose markdown specification)\n */\n\nconst blockPedantic: Record = {\n ...blockNormal,\n html: edit(\n '^ *(?:comment *(?:\\\\n|\\\\s*$)'\n + '|<(tag)[\\\\s\\\\S]+? *(?:\\\\n{2,}|\\\\s*$)' // closed tag\n + '|\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))')\n .replace('comment', _comment)\n .replace(/tag/g, '(?!(?:'\n + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'\n + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'\n + '\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b')\n .getRegex(),\n def: /^ *\\[([^\\]]+)\\]: *]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,\n heading: /^(#{1,6})(.*)(?:\\n+|$)/,\n fences: noopTest, // fences not supported\n lheading: /^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,\n paragraph: edit(_paragraph)\n .replace('hr', hr)\n .replace('heading', ' *#{1,6} *[^\\n]')\n .replace('lheading', lheading)\n .replace('|table', '')\n .replace('blockquote', ' {0,3}>')\n .replace('|fences', '')\n .replace('|list', '')\n .replace('|html', '')\n .replace('|tag', '')\n .getRegex(),\n};\n\n/**\n * Inline-Level Grammar\n */\n\nconst escape = /^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/;\nconst inlineCode = /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/;\nconst br = /^( {2,}|\\\\)\\n(?!\\s*$)/;\nconst inlineText = /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\\nconst blockSkip = edit(/link|precode-code|html/, 'g')\n .replace('link', /\\[(?:[^\\[\\]`]|(?`+)[^`]+\\k(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/)\n .replace('precode-', supportsLookbehind ? '(?`+)[^`]+\\k(?!`)/)\n .replace('html', /<(?! )[^<>]*?>/)\n .getRegex();\n\nconst emStrongLDelimCore = /^(?:\\*+(?:((?!\\*)punct)|[^\\s*]))|^_+(?:((?!_)punct)|([^\\s_]))/;\n\nconst emStrongLDelim = edit(emStrongLDelimCore, 'u')\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst emStrongLDelimGfm = edit(emStrongLDelimCore, 'u')\n .replace(/punct/g, _punctuationGfmStrongEm)\n .getRegex();\n\nconst emStrongRDelimAstCore =\n '^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)' // Skip orphan inside strong\n+ '|[^*]+(?=[^*])' // Consume to delim\n+ '|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)' // (1) #*** can only be a Right Delimiter\n+ '|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter\n+ '|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)' // (3) #***a, ***a can only be Left Delimiter\n+ '|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)' // (4) ***# can only be Left Delimiter\n+ '|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter\n+ '|notPunctSpace(\\\\*+)(?=notPunctSpace)'; // (6) a***a can be either Left or Right Delimiter\n\nconst emStrongRDelimAst = edit(emStrongRDelimAstCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst emStrongRDelimAstGfm = edit(emStrongRDelimAstCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpaceGfmStrongEm)\n .replace(/punctSpace/g, _punctuationOrSpaceGfmStrongEm)\n .replace(/punct/g, _punctuationGfmStrongEm)\n .getRegex();\n\n// (6) Not allowed for _\nconst emStrongRDelimUnd = edit(\n '^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)' // Skip orphan inside strong\n+ '|[^_]+(?=[^_])' // Consume to delim\n+ '|(?!_)punct(_+)(?=[\\\\s]|$)' // (1) #___ can only be a Right Delimiter\n+ '|notPunctSpace(_+)(?!_)(?=punctSpace|$)' // (2) a___#, a___ can only be a Right Delimiter\n+ '|(?!_)punctSpace(_+)(?=notPunctSpace)' // (3) #___a, ___a can only be Left Delimiter\n+ '|[\\\\s](_+)(?!_)(?=punct)' // (4) ___# can only be Left Delimiter\n+ '|(?!_)punct(_+)(?!_)(?=punct)', 'gu') // (5) #___# can be either Left or Right Delimiter\n .replace(/notPunctSpace/g, _notPunctuationOrSpace)\n .replace(/punctSpace/g, _punctuationOrSpace)\n .replace(/punct/g, _punctuation)\n .getRegex();\n\n// Tilde left delimiter for strikethrough (similar to emStrongLDelim for asterisk)\nconst delLDelim = edit(/^~~?(?:((?!~)punct)|[^\\s~])/, 'u')\n .replace(/punct/g, _punctuationGfmDel)\n .getRegex();\n\n// Tilde delimiter patterns for strikethrough (similar to asterisk)\nconst delRDelimCore =\n '^[^~]+(?=[^~])' // Consume to delim\n+ '|(?!~)punct(~~?)(?=[\\\\s]|$)' // (1) #~~ can only be a Right Delimiter\n+ '|notPunctSpace(~~?)(?!~)(?=punctSpace|$)' // (2) a~~#, a~~ can only be a Right Delimiter\n+ '|(?!~)punctSpace(~~?)(?=notPunctSpace)' // (3) #~~a, ~~a can only be Left Delimiter\n+ '|[\\\\s](~~?)(?!~)(?=punct)' // (4) ~~# can only be Left Delimiter\n+ '|(?!~)punct(~~?)(?!~)(?=punct)' // (5) #~~# can be either Left or Right Delimiter\n+ '|notPunctSpace(~~?)(?=notPunctSpace)'; // (6) a~~a can be either Left or Right Delimiter\n\nconst delRDelim = edit(delRDelimCore, 'gu')\n .replace(/notPunctSpace/g, _notPunctuationOrSpaceGfmDel)\n .replace(/punctSpace/g, _punctuationOrSpaceGfmDel)\n .replace(/punct/g, _punctuationGfmDel)\n .getRegex();\n\nconst anyPunctuation = edit(/\\\\(punct)/, 'gu')\n .replace(/punct/g, _punctuation)\n .getRegex();\n\nconst autolink = edit(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/)\n .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)\n .replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/)\n .getRegex();\n\nconst _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();\nconst tag = edit(\n '^comment'\n + '|^' // self-closing tag\n + '|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>' // open tag\n + '|^<\\\\?[\\\\s\\\\S]*?\\\\?>' // processing instruction, e.g. \n + '|^' // declaration, e.g. \n + '|^') // CDATA section\n .replace('comment', _inlineComment)\n .replace('attribute', /\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/)\n .getRegex();\n\nconst _inlineLabel = /(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+[^`]*?`+(?!`)|[^\\[\\]\\\\`])*?/;\n\nconst link = edit(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/)\n .replace('label', _inlineLabel)\n .replace('href', /<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]*/)\n .replace('title', /\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/)\n .getRegex();\n\nconst reflink = edit(/^!?\\[(label)\\]\\[(ref)\\]/)\n .replace('label', _inlineLabel)\n .replace('ref', _blockLabel)\n .getRegex();\n\nconst nolink = edit(/^!?\\[(ref)\\](?:\\[\\])?/)\n .replace('ref', _blockLabel)\n .getRegex();\n\nconst reflinkSearch = edit('reflink|nolink(?!\\\\()', 'g')\n .replace('reflink', reflink)\n .replace('nolink', nolink)\n .getRegex();\n\nconst _caseInsensitiveProtocol = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;\n\n/**\n * Normal Inline Grammar\n */\n\nconst inlineNormal = {\n _backpedal: noopTest, // only used for GFM url\n anyPunctuation,\n autolink,\n blockSkip,\n br,\n code: inlineCode,\n del: noopTest,\n delLDelim: noopTest,\n delRDelim: noopTest,\n emStrongLDelim,\n emStrongRDelimAst,\n emStrongRDelimUnd,\n escape,\n link,\n nolink,\n punctuation,\n reflink,\n reflinkSearch,\n tag,\n text: inlineText,\n url: noopTest,\n};\n\ntype InlineKeys = keyof typeof inlineNormal;\n\n/**\n * Pedantic Inline Grammar\n */\n\nconst inlinePedantic: Record = {\n ...inlineNormal,\n link: edit(/^!?\\[(label)\\]\\((.*?)\\)/)\n .replace('label', _inlineLabel)\n .getRegex(),\n reflink: edit(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/)\n .replace('label', _inlineLabel)\n .getRegex(),\n};\n\n/**\n * GFM Inline Grammar\n */\n\nconst inlineGfm: Record = {\n ...inlineNormal,\n emStrongRDelimAst: emStrongRDelimAstGfm,\n emStrongLDelim: emStrongLDelimGfm,\n delLDelim,\n delRDelim,\n url: edit(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/)\n .replace('protocol', _caseInsensitiveProtocol)\n .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)\n .getRegex(),\n _backpedal: /(?:[^?!.,:;*_'\"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'\"~)]+(?!$))+/,\n del: /^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,\n text: edit(/^([`~]+|[^`~])(?:(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\ = {\n ...inlineGfm,\n br: edit(br).replace('{2,}', '*').getRegex(),\n text: edit(inlineGfm.text)\n .replace('\\\\b_', '\\\\b_| {2,}\\\\n')\n .replace(/\\{2,\\}/g, '*')\n .getRegex(),\n};\n\n/**\n * exports\n */\n\nexport const block = {\n normal: blockNormal,\n gfm: blockGfm,\n pedantic: blockPedantic,\n};\n\nexport const inline = {\n normal: inlineNormal,\n gfm: inlineGfm,\n breaks: inlineBreaks,\n pedantic: inlinePedantic,\n};\n\nexport interface Rules {\n other: typeof other\n block: Record\n inline: Record\n}\n", "import { other } from './rules.ts';\n\n/**\n * Helpers\n */\nconst escapeReplacements: { [index: string]: string } = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n};\nconst getEscapeReplacement = (ch: string) => escapeReplacements[ch];\n\nexport function escapeHtmlEntities(html: string, encode?: boolean) {\n if (encode) {\n if (other.escapeTest.test(html)) {\n return html.replace(other.escapeReplace, getEscapeReplacement);\n }\n } else {\n if (other.escapeTestNoEncode.test(html)) {\n return html.replace(other.escapeReplaceNoEncode, getEscapeReplacement);\n }\n }\n\n return html;\n}\n\nexport function cleanUrl(href: string) {\n try {\n href = encodeURI(href).replace(other.percentDecode, '%');\n } catch {\n return null;\n }\n return href;\n}\n\nexport function splitCells(tableRow: string, count?: number) {\n // ensure that every cell-delimiting pipe has a space\n // before it to distinguish it from an escaped pipe\n const row = tableRow.replace(other.findPipe, (match, offset, str) => {\n let escaped = false;\n let curr = offset;\n while (--curr >= 0 && str[curr] === '\\\\') escaped = !escaped;\n if (escaped) {\n // odd number of slashes means | is escaped\n // so we leave it alone\n return '|';\n } else {\n // add space before unescaped |\n return ' |';\n }\n }),\n cells = row.split(other.splitPipe);\n let i = 0;\n\n // First/last cell in a row cannot be empty if it has no leading/trailing pipe\n if (!cells[0].trim()) {\n cells.shift();\n }\n if (cells.length > 0 && !cells.at(-1)?.trim()) {\n cells.pop();\n }\n\n if (count) {\n if (cells.length > count) {\n cells.splice(count);\n } else {\n while (cells.length < count) cells.push('');\n }\n }\n\n for (; i < cells.length; i++) {\n // leading or trailing whitespace is ignored per the gfm spec\n cells[i] = cells[i].trim().replace(other.slashPipe, '|');\n }\n return cells;\n}\n\n/**\n * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').\n * /c*$/ is vulnerable to REDOS.\n *\n * @param str\n * @param c\n * @param invert Remove suffix of non-c chars instead. Default falsey.\n */\nexport function rtrim(str: string, c: string, invert?: boolean) {\n const l = str.length;\n if (l === 0) {\n return '';\n }\n\n // Length of suffix matching the invert condition.\n let suffLen = 0;\n\n // Step left until we fail to match the invert condition.\n while (suffLen < l) {\n const currChar = str.charAt(l - suffLen - 1);\n if (currChar === c && !invert) {\n suffLen++;\n } else if (currChar !== c && invert) {\n suffLen++;\n } else {\n break;\n }\n }\n\n return str.slice(0, l - suffLen);\n}\n\nexport function findClosingBracket(str: string, b: string) {\n if (str.indexOf(b[1]) === -1) {\n return -1;\n }\n\n let level = 0;\n for (let i = 0; i < str.length; i++) {\n if (str[i] === '\\\\') {\n i++;\n } else if (str[i] === b[0]) {\n level++;\n } else if (str[i] === b[1]) {\n level--;\n if (level < 0) {\n return i;\n }\n }\n }\n if (level > 0) {\n return -2;\n }\n\n return -1;\n}\n\nexport function expandTabs(line: string, indent = 0) {\n let col = indent;\n let expanded = '';\n for (const char of line) {\n if (char === '\\t') {\n const added = 4 - (col % 4);\n expanded += ' '.repeat(added);\n col += added;\n } else {\n expanded += char;\n col++;\n }\n }\n\n return expanded;\n}\n", "import { _defaults } from './defaults.ts';\nimport {\n rtrim,\n splitCells,\n findClosingBracket,\n expandTabs,\n} from './helpers.ts';\nimport type { Rules } from './rules.ts';\nimport type { _Lexer } from './Lexer.ts';\nimport type { Links, Tokens, Token } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\nfunction outputLink(cap: string[], link: Pick, raw: string, lexer: _Lexer, rules: Rules): Tokens.Link | Tokens.Image {\n const href = link.href;\n const title = link.title || null;\n const text = cap[1].replace(rules.other.outputLinkReplace, '$1');\n\n lexer.state.inLink = true;\n const token: Tokens.Link | Tokens.Image = {\n type: cap[0].charAt(0) === '!' ? 'image' : 'link',\n raw,\n href,\n title,\n text,\n tokens: lexer.inlineTokens(text),\n };\n lexer.state.inLink = false;\n return token;\n}\n\nfunction indentCodeCompensation(raw: string, text: string, rules: Rules) {\n const matchIndentToCode = raw.match(rules.other.indentCodeCompensation);\n\n if (matchIndentToCode === null) {\n return text;\n }\n\n const indentToCode = matchIndentToCode[1];\n\n return text\n .split('\\n')\n .map(node => {\n const matchIndentInNode = node.match(rules.other.beginningSpace);\n if (matchIndentInNode === null) {\n return node;\n }\n\n const [indentInNode] = matchIndentInNode;\n\n if (indentInNode.length >= indentToCode.length) {\n return node.slice(indentToCode.length);\n }\n\n return node;\n })\n .join('\\n');\n}\n\n/**\n * Tokenizer\n */\nexport class _Tokenizer {\n options: MarkedOptions;\n rules!: Rules; // set by the lexer\n lexer!: _Lexer; // set by the lexer\n\n constructor(options?: MarkedOptions) {\n this.options = options || _defaults;\n }\n\n space(src: string): Tokens.Space | undefined {\n const cap = this.rules.block.newline.exec(src);\n if (cap && cap[0].length > 0) {\n return {\n type: 'space',\n raw: cap[0],\n };\n }\n }\n\n code(src: string): Tokens.Code | undefined {\n const cap = this.rules.block.code.exec(src);\n if (cap) {\n const text = cap[0].replace(this.rules.other.codeRemoveIndent, '');\n return {\n type: 'code',\n raw: cap[0],\n codeBlockStyle: 'indented',\n text: !this.options.pedantic\n ? rtrim(text, '\\n')\n : text,\n };\n }\n }\n\n fences(src: string): Tokens.Code | undefined {\n const cap = this.rules.block.fences.exec(src);\n if (cap) {\n const raw = cap[0];\n const text = indentCodeCompensation(raw, cap[3] || '', this.rules);\n\n return {\n type: 'code',\n raw,\n lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],\n text,\n };\n }\n }\n\n heading(src: string): Tokens.Heading | undefined {\n const cap = this.rules.block.heading.exec(src);\n if (cap) {\n let text = cap[2].trim();\n\n // remove trailing #s\n if (this.rules.other.endingHash.test(text)) {\n const trimmed = rtrim(text, '#');\n if (this.options.pedantic) {\n text = trimmed.trim();\n } else if (!trimmed || this.rules.other.endingSpaceChar.test(trimmed)) {\n // CommonMark requires space before trailing #s\n text = trimmed.trim();\n }\n }\n\n return {\n type: 'heading',\n raw: cap[0],\n depth: cap[1].length,\n text,\n tokens: this.lexer.inline(text),\n };\n }\n }\n\n hr(src: string): Tokens.Hr | undefined {\n const cap = this.rules.block.hr.exec(src);\n if (cap) {\n return {\n type: 'hr',\n raw: rtrim(cap[0], '\\n'),\n };\n }\n }\n\n blockquote(src: string): Tokens.Blockquote | undefined {\n const cap = this.rules.block.blockquote.exec(src);\n if (cap) {\n let lines = rtrim(cap[0], '\\n').split('\\n');\n let raw = '';\n let text = '';\n const tokens: Token[] = [];\n\n while (lines.length > 0) {\n let inBlockquote = false;\n const currentLines = [];\n\n let i;\n for (i = 0; i < lines.length; i++) {\n // get lines up to a continuation\n if (this.rules.other.blockquoteStart.test(lines[i])) {\n currentLines.push(lines[i]);\n inBlockquote = true;\n } else if (!inBlockquote) {\n currentLines.push(lines[i]);\n } else {\n break;\n }\n }\n lines = lines.slice(i);\n\n const currentRaw = currentLines.join('\\n');\n const currentText = currentRaw\n // precede setext continuation with 4 spaces so it isn't a setext\n .replace(this.rules.other.blockquoteSetextReplace, '\\n $1')\n .replace(this.rules.other.blockquoteSetextReplace2, '');\n raw = raw ? `${raw}\\n${currentRaw}` : currentRaw;\n text = text ? `${text}\\n${currentText}` : currentText;\n\n // parse blockquote lines as top level tokens\n // merge paragraphs if this is a continuation\n const top = this.lexer.state.top;\n this.lexer.state.top = true;\n this.lexer.blockTokens(currentText, tokens, true);\n this.lexer.state.top = top;\n\n // if there is no continuation then we are done\n if (lines.length === 0) {\n break;\n }\n\n const lastToken = tokens.at(-1);\n\n if (lastToken?.type === 'code') {\n // blockquote continuation cannot be preceded by a code block\n break;\n } else if (lastToken?.type === 'blockquote') {\n // include continuation in nested blockquote\n const oldToken = lastToken as Tokens.Blockquote;\n const newText = oldToken.raw + '\\n' + lines.join('\\n');\n const newToken = this.blockquote(newText)!;\n tokens[tokens.length - 1] = newToken;\n\n raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw;\n text = text.substring(0, text.length - oldToken.text.length) + newToken.text;\n break;\n } else if (lastToken?.type === 'list') {\n // include continuation in nested list\n const oldToken = lastToken as Tokens.List;\n const newText = oldToken.raw + '\\n' + lines.join('\\n');\n const newToken = this.list(newText)!;\n tokens[tokens.length - 1] = newToken;\n\n raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;\n text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;\n lines = newText.substring(tokens.at(-1)!.raw.length).split('\\n');\n continue;\n }\n }\n\n return {\n type: 'blockquote',\n raw,\n tokens,\n text,\n };\n }\n }\n\n list(src: string): Tokens.List | undefined {\n let cap = this.rules.block.list.exec(src);\n if (cap) {\n let bull = cap[1].trim();\n const isordered = bull.length > 1;\n\n const list: Tokens.List = {\n type: 'list',\n raw: '',\n ordered: isordered,\n start: isordered ? +bull.slice(0, -1) : '',\n loose: false,\n items: [],\n };\n\n bull = isordered ? `\\\\d{1,9}\\\\${bull.slice(-1)}` : `\\\\${bull}`;\n\n if (this.options.pedantic) {\n bull = isordered ? bull : '[*+-]';\n }\n\n // Get next list item\n const itemRegex = this.rules.other.listItemRegex(bull);\n let endsWithBlankLine = false;\n // Check if current bullet point can start a new List Item\n while (src) {\n let endEarly = false;\n let raw = '';\n let itemContents = '';\n if (!(cap = itemRegex.exec(src))) {\n break;\n }\n\n if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)\n break;\n }\n\n raw = cap[0];\n src = src.substring(raw.length);\n\n let line = expandTabs(cap[2].split('\\n', 1)[0], cap[1].length);\n let nextLine = src.split('\\n', 1)[0];\n let blankLine = !line.trim();\n\n let indent = 0;\n if (this.options.pedantic) {\n indent = 2;\n itemContents = line.trimStart();\n } else if (blankLine) {\n indent = cap[1].length + 1;\n } else {\n indent = line.search(this.rules.other.nonSpaceChar); // Find first non-space char\n indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent\n itemContents = line.slice(indent);\n indent += cap[1].length;\n }\n\n if (blankLine && this.rules.other.blankLine.test(nextLine)) { // Items begin with at most one blank line\n raw += nextLine + '\\n';\n src = src.substring(nextLine.length + 1);\n endEarly = true;\n }\n\n if (!endEarly) {\n const nextBulletRegex = this.rules.other.nextBulletRegex(indent);\n const hrRegex = this.rules.other.hrRegex(indent);\n const fencesBeginRegex = this.rules.other.fencesBeginRegex(indent);\n const headingBeginRegex = this.rules.other.headingBeginRegex(indent);\n const htmlBeginRegex = this.rules.other.htmlBeginRegex(indent);\n const blockquoteBeginRegex = this.rules.other.blockquoteBeginRegex(indent);\n\n // Check if following lines should be included in List Item\n while (src) {\n const rawLine = src.split('\\n', 1)[0];\n let nextLineWithoutTabs;\n nextLine = rawLine;\n\n // Re-align to follow commonmark nesting rules\n if (this.options.pedantic) {\n nextLine = nextLine.replace(this.rules.other.listReplaceNesting, ' ');\n nextLineWithoutTabs = nextLine;\n } else {\n nextLineWithoutTabs = nextLine.replace(this.rules.other.tabCharGlobal, ' ');\n }\n\n // End list item if found code fences\n if (fencesBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of new heading\n if (headingBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of html block\n if (htmlBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of blockquote\n if (blockquoteBeginRegex.test(nextLine)) {\n break;\n }\n\n // End list item if found start of new bullet\n if (nextBulletRegex.test(nextLine)) {\n break;\n }\n\n // Horizontal rule found\n if (hrRegex.test(nextLine)) {\n break;\n }\n\n if (nextLineWithoutTabs.search(this.rules.other.nonSpaceChar) >= indent || !nextLine.trim()) { // Dedent if possible\n itemContents += '\\n' + nextLineWithoutTabs.slice(indent);\n } else {\n // not enough indentation\n if (blankLine) {\n break;\n }\n\n // paragraph continuation unless last line was a different block level element\n if (line.replace(this.rules.other.tabCharGlobal, ' ').search(this.rules.other.nonSpaceChar) >= 4) { // indented code block\n break;\n }\n if (fencesBeginRegex.test(line)) {\n break;\n }\n if (headingBeginRegex.test(line)) {\n break;\n }\n if (hrRegex.test(line)) {\n break;\n }\n\n itemContents += '\\n' + nextLine;\n }\n\n blankLine = !nextLine.trim();\n\n raw += rawLine + '\\n';\n src = src.substring(rawLine.length + 1);\n line = nextLineWithoutTabs.slice(indent);\n }\n }\n\n if (!list.loose) {\n // If the previous item ended with a blank line, the list is loose\n if (endsWithBlankLine) {\n list.loose = true;\n } else if (this.rules.other.doubleBlankLine.test(raw)) {\n endsWithBlankLine = true;\n }\n }\n\n list.items.push({\n type: 'list_item',\n raw,\n task: !!this.options.gfm && this.rules.other.listIsTask.test(itemContents),\n loose: false,\n text: itemContents,\n tokens: [],\n });\n\n list.raw += raw;\n }\n\n // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic\n const lastItem = list.items.at(-1);\n if (lastItem) {\n lastItem.raw = lastItem.raw.trimEnd();\n lastItem.text = lastItem.text.trimEnd();\n } else {\n // not a list since there were no items\n return;\n }\n list.raw = list.raw.trimEnd();\n\n // Item child tokens handled here at end because we needed to have the final item to trim it first\n for (const item of list.items) {\n this.lexer.state.top = false;\n item.tokens = this.lexer.blockTokens(item.text, []);\n if (item.task) {\n // Remove checkbox markdown from item tokens\n item.text = item.text.replace(this.rules.other.listReplaceTask, '');\n if (item.tokens[0]?.type === 'text' || item.tokens[0]?.type === 'paragraph') {\n item.tokens[0].raw = item.tokens[0].raw.replace(this.rules.other.listReplaceTask, '');\n item.tokens[0].text = item.tokens[0].text.replace(this.rules.other.listReplaceTask, '');\n for (let i = this.lexer.inlineQueue.length - 1; i >= 0; i--) {\n if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[i].src)) {\n this.lexer.inlineQueue[i].src = this.lexer.inlineQueue[i].src.replace(this.rules.other.listReplaceTask, '');\n break;\n }\n }\n }\n\n const taskRaw = this.rules.other.listTaskCheckbox.exec(item.raw);\n if (taskRaw) {\n const checkboxToken: Tokens.Checkbox = {\n type: 'checkbox',\n raw: taskRaw[0] + ' ',\n checked: taskRaw[0] !== '[ ]',\n };\n item.checked = checkboxToken.checked;\n if (list.loose) {\n if (item.tokens[0] && ['paragraph', 'text'].includes(item.tokens[0].type) && 'tokens' in item.tokens[0] && item.tokens[0].tokens) {\n item.tokens[0].raw = checkboxToken.raw + item.tokens[0].raw;\n item.tokens[0].text = checkboxToken.raw + item.tokens[0].text;\n item.tokens[0].tokens.unshift(checkboxToken);\n } else {\n item.tokens.unshift({\n type: 'paragraph',\n raw: checkboxToken.raw,\n text: checkboxToken.raw,\n tokens: [checkboxToken],\n });\n }\n } else {\n item.tokens.unshift(checkboxToken);\n }\n }\n }\n\n if (!list.loose) {\n // Check if list should be loose\n const spacers = item.tokens.filter(t => t.type === 'space');\n const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => this.rules.other.anyLine.test(t.raw));\n\n list.loose = hasMultipleLineBreaks;\n }\n }\n\n // Set all items to loose if list is loose\n if (list.loose) {\n for (const item of list.items) {\n item.loose = true;\n for (const token of item.tokens) {\n if (token.type === 'text') {\n token.type = 'paragraph';\n }\n }\n }\n }\n\n return list;\n }\n }\n\n html(src: string): Tokens.HTML | undefined {\n const cap = this.rules.block.html.exec(src);\n if (cap) {\n const token: Tokens.HTML = {\n type: 'html',\n block: true,\n raw: cap[0],\n pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',\n text: cap[0],\n };\n return token;\n }\n }\n\n def(src: string): Tokens.Def | undefined {\n const cap = this.rules.block.def.exec(src);\n if (cap) {\n const tag = cap[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, ' ');\n const href = cap[2] ? cap[2].replace(this.rules.other.hrefBrackets, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';\n const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];\n return {\n type: 'def',\n tag,\n raw: cap[0],\n href,\n title,\n };\n }\n }\n\n table(src: string): Tokens.Table | undefined {\n const cap = this.rules.block.table.exec(src);\n if (!cap) {\n return;\n }\n\n if (!this.rules.other.tableDelimiter.test(cap[2])) {\n // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading\n return;\n }\n\n const headers = splitCells(cap[1]);\n const aligns = cap[2].replace(this.rules.other.tableAlignChars, '').split('|');\n const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\\n') : [];\n\n const item: Tokens.Table = {\n type: 'table',\n raw: cap[0],\n header: [],\n align: [],\n rows: [],\n };\n\n if (headers.length !== aligns.length) {\n // header and align columns must be equal, rows can be different.\n return;\n }\n\n for (const align of aligns) {\n if (this.rules.other.tableAlignRight.test(align)) {\n item.align.push('right');\n } else if (this.rules.other.tableAlignCenter.test(align)) {\n item.align.push('center');\n } else if (this.rules.other.tableAlignLeft.test(align)) {\n item.align.push('left');\n } else {\n item.align.push(null);\n }\n }\n\n for (let i = 0; i < headers.length; i++) {\n item.header.push({\n text: headers[i],\n tokens: this.lexer.inline(headers[i]),\n header: true,\n align: item.align[i],\n });\n }\n\n for (const row of rows) {\n item.rows.push(splitCells(row, item.header.length).map((cell, i) => {\n return {\n text: cell,\n tokens: this.lexer.inline(cell),\n header: false,\n align: item.align[i],\n };\n }));\n }\n\n return item;\n }\n\n lheading(src: string): Tokens.Heading | undefined {\n const cap = this.rules.block.lheading.exec(src);\n if (cap) {\n return {\n type: 'heading',\n raw: cap[0],\n depth: cap[2].charAt(0) === '=' ? 1 : 2,\n text: cap[1],\n tokens: this.lexer.inline(cap[1]),\n };\n }\n }\n\n paragraph(src: string): Tokens.Paragraph | undefined {\n const cap = this.rules.block.paragraph.exec(src);\n if (cap) {\n const text = cap[1].charAt(cap[1].length - 1) === '\\n'\n ? cap[1].slice(0, -1)\n : cap[1];\n return {\n type: 'paragraph',\n raw: cap[0],\n text,\n tokens: this.lexer.inline(text),\n };\n }\n }\n\n text(src: string): Tokens.Text | undefined {\n const cap = this.rules.block.text.exec(src);\n if (cap) {\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n tokens: this.lexer.inline(cap[0]),\n };\n }\n }\n\n escape(src: string): Tokens.Escape | undefined {\n const cap = this.rules.inline.escape.exec(src);\n if (cap) {\n return {\n type: 'escape',\n raw: cap[0],\n text: cap[1],\n };\n }\n }\n\n tag(src: string): Tokens.Tag | undefined {\n const cap = this.rules.inline.tag.exec(src);\n if (cap) {\n if (!this.lexer.state.inLink && this.rules.other.startATag.test(cap[0])) {\n this.lexer.state.inLink = true;\n } else if (this.lexer.state.inLink && this.rules.other.endATag.test(cap[0])) {\n this.lexer.state.inLink = false;\n }\n if (!this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(cap[0])) {\n this.lexer.state.inRawBlock = true;\n } else if (this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(cap[0])) {\n this.lexer.state.inRawBlock = false;\n }\n\n return {\n type: 'html',\n raw: cap[0],\n inLink: this.lexer.state.inLink,\n inRawBlock: this.lexer.state.inRawBlock,\n block: false,\n text: cap[0],\n };\n }\n }\n\n link(src: string): Tokens.Link | Tokens.Image | undefined {\n const cap = this.rules.inline.link.exec(src);\n if (cap) {\n const trimmedUrl = cap[2].trim();\n if (!this.options.pedantic && this.rules.other.startAngleBracket.test(trimmedUrl)) {\n // commonmark requires matching angle brackets\n if (!(this.rules.other.endAngleBracket.test(trimmedUrl))) {\n return;\n }\n\n // ending angle bracket cannot be escaped\n const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\\\');\n if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {\n return;\n }\n } else {\n // find closing parenthesis\n const lastParenIndex = findClosingBracket(cap[2], '()');\n if (lastParenIndex === -2) {\n // more open parens than closed\n return;\n }\n\n if (lastParenIndex > -1) {\n const start = cap[0].indexOf('!') === 0 ? 5 : 4;\n const linkLen = start + cap[1].length + lastParenIndex;\n cap[2] = cap[2].substring(0, lastParenIndex);\n cap[0] = cap[0].substring(0, linkLen).trim();\n cap[3] = '';\n }\n }\n let href = cap[2];\n let title = '';\n if (this.options.pedantic) {\n // split pedantic href and title\n const link = this.rules.other.pedanticHrefTitle.exec(href);\n\n if (link) {\n href = link[1];\n title = link[3];\n }\n } else {\n title = cap[3] ? cap[3].slice(1, -1) : '';\n }\n\n href = href.trim();\n if (this.rules.other.startAngleBracket.test(href)) {\n if (this.options.pedantic && !(this.rules.other.endAngleBracket.test(trimmedUrl))) {\n // pedantic allows starting angle bracket without ending angle bracket\n href = href.slice(1);\n } else {\n href = href.slice(1, -1);\n }\n }\n return outputLink(cap, {\n href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,\n title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title,\n }, cap[0], this.lexer, this.rules);\n }\n }\n\n reflink(src: string, links: Links): Tokens.Link | Tokens.Image | Tokens.Text | undefined {\n let cap;\n if ((cap = this.rules.inline.reflink.exec(src))\n || (cap = this.rules.inline.nolink.exec(src))) {\n const linkString = (cap[2] || cap[1]).replace(this.rules.other.multipleSpaceGlobal, ' ');\n const link = links[linkString.toLowerCase()];\n if (!link) {\n const text = cap[0].charAt(0);\n return {\n type: 'text',\n raw: text,\n text,\n };\n }\n return outputLink(cap, link, cap[0], this.lexer, this.rules);\n }\n }\n\n emStrong(src: string, maskedSrc: string, prevChar = ''): Tokens.Em | Tokens.Strong | undefined {\n let match = this.rules.inline.emStrongLDelim.exec(src);\n if (!match) return;\n\n // _ can't be between two alphanumerics. \\p{L}\\p{N} includes non-english alphabet/numbers as well\n if (match[3] && prevChar.match(this.rules.other.unicodeAlphaNumeric)) return;\n\n const nextChar = match[1] || match[2] || '';\n\n if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {\n // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)\n const lLength = [...match[0]].length - 1;\n let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;\n\n const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;\n endReg.lastIndex = 0;\n\n // Clip maskedSrc to same section of string as src (move to lexer?)\n maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n\n while ((match = endReg.exec(maskedSrc)) != null) {\n rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n\n if (!rDelim) continue; // skip single * in __abc*abc__\n\n rLength = [...rDelim].length;\n\n if (match[3] || match[4]) { // found another Left Delim\n delimTotal += rLength;\n continue;\n } else if (match[5] || match[6]) { // either Left or Right Delim\n if (lLength % 3 && !((lLength + rLength) % 3)) {\n midDelimTotal += rLength;\n continue; // CommonMark Emphasis Rules 9-10\n }\n }\n\n delimTotal -= rLength;\n\n if (delimTotal > 0) continue; // Haven't found enough closing delimiters\n\n // Remove extra characters. *a*** -> *a*\n rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);\n // char length can be >1 for unicode characters;\n const lastCharLength = [...match[0]][0].length;\n const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);\n\n // Create `em` if smallest delimiter has odd char count. *a***\n if (Math.min(lLength, rLength) % 2) {\n const text = raw.slice(1, -1);\n return {\n type: 'em',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n\n // Create 'strong' if smallest delimiter has even char count. **a***\n const text = raw.slice(2, -2);\n return {\n type: 'strong',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n }\n }\n\n codespan(src: string): Tokens.Codespan | undefined {\n const cap = this.rules.inline.code.exec(src);\n if (cap) {\n let text = cap[2].replace(this.rules.other.newLineCharGlobal, ' ');\n const hasNonSpaceChars = this.rules.other.nonSpaceChar.test(text);\n const hasSpaceCharsOnBothEnds = this.rules.other.startingSpaceChar.test(text) && this.rules.other.endingSpaceChar.test(text);\n if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n text = text.substring(1, text.length - 1);\n }\n return {\n type: 'codespan',\n raw: cap[0],\n text,\n };\n }\n }\n\n br(src: string): Tokens.Br | undefined {\n const cap = this.rules.inline.br.exec(src);\n if (cap) {\n return {\n type: 'br',\n raw: cap[0],\n };\n }\n }\n\n del(src: string, maskedSrc: string, prevChar = ''): Tokens.Del | undefined {\n let match = this.rules.inline.delLDelim.exec(src);\n if (!match) return;\n\n const nextChar = match[1] || '';\n\n if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {\n // unicode Regex counts emoji as 1 char; spread into array for proper count\n const lLength = [...match[0]].length - 1;\n let rDelim, rLength, delimTotal = lLength;\n\n const endReg = this.rules.inline.delRDelim;\n endReg.lastIndex = 0;\n\n // Clip maskedSrc to same section of string as src\n maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n\n while ((match = endReg.exec(maskedSrc)) != null) {\n rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n\n if (!rDelim) continue;\n\n rLength = [...rDelim].length;\n\n if (rLength !== lLength) continue;\n\n if (match[3] || match[4]) { // found another Left Delim\n delimTotal += rLength;\n continue;\n }\n\n delimTotal -= rLength;\n\n if (delimTotal > 0) continue; // Haven't found enough closing delimiters\n\n // Remove extra characters\n rLength = Math.min(rLength, rLength + delimTotal);\n // char length can be >1 for unicode characters\n const lastCharLength = [...match[0]][0].length;\n const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);\n\n // Create del token - only single ~ or double ~~ supported\n const text = raw.slice(lLength, -lLength);\n return {\n type: 'del',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text),\n };\n }\n }\n }\n\n autolink(src: string): Tokens.Link | undefined {\n const cap = this.rules.inline.autolink.exec(src);\n if (cap) {\n let text, href;\n if (cap[2] === '@') {\n text = cap[1];\n href = 'mailto:' + text;\n } else {\n text = cap[1];\n href = text;\n }\n\n return {\n type: 'link',\n raw: cap[0],\n text,\n href,\n tokens: [\n {\n type: 'text',\n raw: text,\n text,\n },\n ],\n };\n }\n }\n\n url(src: string): Tokens.Link | undefined {\n let cap;\n if (cap = this.rules.inline.url.exec(src)) {\n let text, href;\n if (cap[2] === '@') {\n text = cap[0];\n href = 'mailto:' + text;\n } else {\n // do extended autolink path validation\n let prevCapZero;\n do {\n prevCapZero = cap[0];\n cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';\n } while (prevCapZero !== cap[0]);\n text = cap[0];\n if (cap[1] === 'www.') {\n href = 'http://' + cap[0];\n } else {\n href = cap[0];\n }\n }\n return {\n type: 'link',\n raw: cap[0],\n text,\n href,\n tokens: [\n {\n type: 'text',\n raw: text,\n text,\n },\n ],\n };\n }\n }\n\n inlineText(src: string): Tokens.Text | undefined {\n const cap = this.rules.inline.text.exec(src);\n if (cap) {\n const escaped = this.lexer.state.inRawBlock;\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n escaped,\n };\n }\n }\n}\n", "import { _Tokenizer } from './Tokenizer.ts';\nimport { _defaults } from './defaults.ts';\nimport { other, block, inline } from './rules.ts';\nimport type { Token, TokensList, Tokens } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Block Lexer\n */\nexport class _Lexer {\n tokens: TokensList;\n options: MarkedOptions;\n state: {\n inLink: boolean;\n inRawBlock: boolean;\n top: boolean;\n };\n\n public inlineQueue: { src: string, tokens: Token[] }[];\n\n private tokenizer: _Tokenizer;\n\n constructor(options?: MarkedOptions) {\n // TokenList cannot be created in one go\n this.tokens = [] as unknown as TokensList;\n this.tokens.links = Object.create(null);\n this.options = options || _defaults;\n this.options.tokenizer = this.options.tokenizer || new _Tokenizer();\n this.tokenizer = this.options.tokenizer;\n this.tokenizer.options = this.options;\n this.tokenizer.lexer = this;\n this.inlineQueue = [];\n this.state = {\n inLink: false,\n inRawBlock: false,\n top: true,\n };\n\n const rules = {\n other,\n block: block.normal,\n inline: inline.normal,\n };\n\n if (this.options.pedantic) {\n rules.block = block.pedantic;\n rules.inline = inline.pedantic;\n } else if (this.options.gfm) {\n rules.block = block.gfm;\n if (this.options.breaks) {\n rules.inline = inline.breaks;\n } else {\n rules.inline = inline.gfm;\n }\n }\n this.tokenizer.rules = rules;\n }\n\n /**\n * Expose Rules\n */\n static get rules() {\n return {\n block,\n inline,\n };\n }\n\n /**\n * Static Lex Method\n */\n static lex(src: string, options?: MarkedOptions) {\n const lexer = new _Lexer(options);\n return lexer.lex(src);\n }\n\n /**\n * Static Lex Inline Method\n */\n static lexInline(src: string, options?: MarkedOptions) {\n const lexer = new _Lexer(options);\n return lexer.inlineTokens(src);\n }\n\n /**\n * Preprocessing\n */\n lex(src: string) {\n src = src.replace(other.carriageReturn, '\\n');\n\n this.blockTokens(src, this.tokens);\n\n for (let i = 0; i < this.inlineQueue.length; i++) {\n const next = this.inlineQueue[i];\n this.inlineTokens(next.src, next.tokens);\n }\n this.inlineQueue = [];\n\n return this.tokens;\n }\n\n /**\n * Lexing\n */\n blockTokens(src: string, tokens?: Token[], lastParagraphClipped?: boolean): Token[];\n blockTokens(src: string, tokens?: TokensList, lastParagraphClipped?: boolean): TokensList;\n blockTokens(src: string, tokens: Token[] = [], lastParagraphClipped = false) {\n if (this.options.pedantic) {\n src = src.replace(other.tabCharGlobal, ' ').replace(other.spaceLine, '');\n }\n\n while (src) {\n let token: Tokens.Generic | undefined;\n\n if (this.options.extensions?.block?.some((extTokenizer) => {\n if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n return true;\n }\n return false;\n })) {\n continue;\n }\n\n // newline\n if (token = this.tokenizer.space(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (token.raw.length === 1 && lastToken !== undefined) {\n // if there's a single \\n as a spacer, it's terminating the last line,\n // so move it there so that we don't get unnecessary paragraph tags\n lastToken.raw += '\\n';\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // code\n if (token = this.tokenizer.code(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n // An indented code block cannot interrupt a paragraph.\n if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // fences\n if (token = this.tokenizer.fences(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // heading\n if (token = this.tokenizer.heading(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // hr\n if (token = this.tokenizer.hr(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // blockquote\n if (token = this.tokenizer.blockquote(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // list\n if (token = this.tokenizer.list(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // html\n if (token = this.tokenizer.html(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // def\n if (token = this.tokenizer.def(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.raw;\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else if (!this.tokens.links[token.tag]) {\n this.tokens.links[token.tag] = {\n href: token.href,\n title: token.title,\n };\n tokens.push(token);\n }\n continue;\n }\n\n // table (gfm)\n if (token = this.tokenizer.table(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // lheading\n if (token = this.tokenizer.lheading(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // top-level paragraph\n // prevent paragraph consuming extensions by clipping 'src' to extension start\n let cutSrc = src;\n if (this.options.extensions?.startBlock) {\n let startIndex = Infinity;\n const tempSrc = src.slice(1);\n let tempStart;\n this.options.extensions.startBlock.forEach((getStartIndex) => {\n tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n if (typeof tempStart === 'number' && tempStart >= 0) {\n startIndex = Math.min(startIndex, tempStart);\n }\n });\n if (startIndex < Infinity && startIndex >= 0) {\n cutSrc = src.substring(0, startIndex + 1);\n }\n }\n if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {\n const lastToken = tokens.at(-1);\n if (lastParagraphClipped && lastToken?.type === 'paragraph') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.pop();\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n lastParagraphClipped = cutSrc.length !== src.length;\n src = src.substring(token.raw.length);\n continue;\n }\n\n // text\n if (token = this.tokenizer.text(src)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'text') {\n lastToken.raw += (lastToken.raw.endsWith('\\n') ? '' : '\\n') + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.pop();\n this.inlineQueue.at(-1)!.src = lastToken.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n if (src) {\n const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);\n if (this.options.silent) {\n console.error(errMsg);\n break;\n } else {\n throw new Error(errMsg);\n }\n }\n }\n\n this.state.top = true;\n return tokens;\n }\n\n inline(src: string, tokens: Token[] = []) {\n this.inlineQueue.push({ src, tokens });\n return tokens;\n }\n\n /**\n * Lexing/Compiling\n */\n inlineTokens(src: string, tokens: Token[] = []): Token[] {\n // String with links masked to avoid interference with em and strong\n let maskedSrc = src;\n let match: RegExpExecArray | null = null;\n\n // Mask out reflinks\n if (this.tokens.links) {\n const links = Object.keys(this.tokens.links);\n if (links.length > 0) {\n while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {\n if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {\n maskedSrc = maskedSrc.slice(0, match.index)\n + '[' + 'a'.repeat(match[0].length - 2) + ']'\n + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);\n }\n }\n }\n }\n\n // Mask out escaped characters\n while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {\n maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);\n }\n\n // Mask out other blocks\n let offset;\n while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {\n offset = match[2] ? match[2].length : 0;\n maskedSrc = maskedSrc.slice(0, match.index + offset) + '[' + 'a'.repeat(match[0].length - offset - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);\n }\n\n // Mask out blocks from extensions\n maskedSrc = this.options.hooks?.emStrongMask?.call({ lexer: this }, maskedSrc) ?? maskedSrc;\n\n let keepPrevChar = false;\n let prevChar = '';\n while (src) {\n if (!keepPrevChar) {\n prevChar = '';\n }\n keepPrevChar = false;\n\n let token: Tokens.Generic | undefined;\n\n // extensions\n if (this.options.extensions?.inline?.some((extTokenizer) => {\n if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n return true;\n }\n return false;\n })) {\n continue;\n }\n\n // escape\n if (token = this.tokenizer.escape(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // tag\n if (token = this.tokenizer.tag(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // link\n if (token = this.tokenizer.link(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // reflink, nolink\n if (token = this.tokenizer.reflink(src, this.tokens.links)) {\n src = src.substring(token.raw.length);\n const lastToken = tokens.at(-1);\n if (token.type === 'text' && lastToken?.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n // em & strong\n if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // code\n if (token = this.tokenizer.codespan(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // br\n if (token = this.tokenizer.br(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // del (gfm)\n if (token = this.tokenizer.del(src, maskedSrc, prevChar)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // autolink\n if (token = this.tokenizer.autolink(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // url (gfm)\n if (!this.state.inLink && (token = this.tokenizer.url(src))) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n\n // text\n // prevent inlineText consuming extensions by clipping 'src' to extension start\n let cutSrc = src;\n if (this.options.extensions?.startInline) {\n let startIndex = Infinity;\n const tempSrc = src.slice(1);\n let tempStart;\n this.options.extensions.startInline.forEach((getStartIndex) => {\n tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n if (typeof tempStart === 'number' && tempStart >= 0) {\n startIndex = Math.min(startIndex, tempStart);\n }\n });\n if (startIndex < Infinity && startIndex >= 0) {\n cutSrc = src.substring(0, startIndex + 1);\n }\n }\n if (token = this.tokenizer.inlineText(cutSrc)) {\n src = src.substring(token.raw.length);\n if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started\n prevChar = token.raw.slice(-1);\n }\n keepPrevChar = true;\n const lastToken = tokens.at(-1);\n if (lastToken?.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n } else {\n tokens.push(token);\n }\n continue;\n }\n\n if (src) {\n const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);\n if (this.options.silent) {\n console.error(errMsg);\n break;\n } else {\n throw new Error(errMsg);\n }\n }\n }\n\n return tokens;\n }\n}\n", "import { _defaults } from './defaults.ts';\nimport {\n cleanUrl,\n escapeHtmlEntities,\n} from './helpers.ts';\nimport { other } from './rules.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\nimport type { Tokens } from './Tokens.ts';\nimport type { _Parser } from './Parser.ts';\n\n/**\n * Renderer\n */\nexport class _Renderer {\n options: MarkedOptions;\n parser!: _Parser; // set by the parser\n constructor(options?: MarkedOptions) {\n this.options = options || _defaults;\n }\n\n space(token: Tokens.Space): RendererOutput {\n return '' as RendererOutput;\n }\n\n code({ text, lang, escaped }: Tokens.Code): RendererOutput {\n const langString = (lang || '').match(other.notSpaceStart)?.[0];\n\n const code = text.replace(other.endingNewline, '') + '\\n';\n\n if (!langString) {\n return '
'\n        + (escaped ? code : escapeHtmlEntities(code, true))\n        + '
\\n' as RendererOutput;\n }\n\n return '
'\n      + (escaped ? code : escapeHtmlEntities(code, true))\n      + '
\\n' as RendererOutput;\n }\n\n blockquote({ tokens }: Tokens.Blockquote): RendererOutput {\n const body = this.parser.parse(tokens);\n return `
\\n${body}
\\n` as RendererOutput;\n }\n\n html({ text }: Tokens.HTML | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n def(token: Tokens.Def): RendererOutput {\n return '' as RendererOutput;\n }\n\n heading({ tokens, depth }: Tokens.Heading): RendererOutput {\n return `${this.parser.parseInline(tokens)}\\n` as RendererOutput;\n }\n\n hr(token: Tokens.Hr): RendererOutput {\n return '
\\n' as RendererOutput;\n }\n\n list(token: Tokens.List): RendererOutput {\n const ordered = token.ordered;\n const start = token.start;\n\n let body = '';\n for (let j = 0; j < token.items.length; j++) {\n const item = token.items[j];\n body += this.listitem(item);\n }\n\n const type = ordered ? 'ol' : 'ul';\n const startAttr = (ordered && start !== 1) ? (' start=\"' + start + '\"') : '';\n return '<' + type + startAttr + '>\\n' + body + '\\n' as RendererOutput;\n }\n\n listitem(item: Tokens.ListItem): RendererOutput {\n return `
  • ${this.parser.parse(item.tokens)}
  • \\n` as RendererOutput;\n }\n\n checkbox({ checked }: Tokens.Checkbox): RendererOutput {\n return ' ' as RendererOutput;\n }\n\n paragraph({ tokens }: Tokens.Paragraph): RendererOutput {\n return `

    ${this.parser.parseInline(tokens)}

    \\n` as RendererOutput;\n }\n\n table(token: Tokens.Table): RendererOutput {\n let header = '';\n\n // header\n let cell = '';\n for (let j = 0; j < token.header.length; j++) {\n cell += this.tablecell(token.header[j]);\n }\n header += this.tablerow({ text: cell as ParserOutput });\n\n let body = '';\n for (let j = 0; j < token.rows.length; j++) {\n const row = token.rows[j];\n\n cell = '';\n for (let k = 0; k < row.length; k++) {\n cell += this.tablecell(row[k]);\n }\n\n body += this.tablerow({ text: cell as ParserOutput });\n }\n if (body) body = `${body}`;\n\n return '\\n'\n + '\\n'\n + header\n + '\\n'\n + body\n + '
    \\n' as RendererOutput;\n }\n\n tablerow({ text }: Tokens.TableRow): RendererOutput {\n return `\\n${text}\\n` as RendererOutput;\n }\n\n tablecell(token: Tokens.TableCell): RendererOutput {\n const content = this.parser.parseInline(token.tokens);\n const type = token.header ? 'th' : 'td';\n const tag = token.align\n ? `<${type} align=\"${token.align}\">`\n : `<${type}>`;\n return tag + content + `\\n` as RendererOutput;\n }\n\n /**\n * span level renderer\n */\n strong({ tokens }: Tokens.Strong): RendererOutput {\n return `${this.parser.parseInline(tokens)}` as RendererOutput;\n }\n\n em({ tokens }: Tokens.Em): RendererOutput {\n return `${this.parser.parseInline(tokens)}` as RendererOutput;\n }\n\n codespan({ text }: Tokens.Codespan): RendererOutput {\n return `${escapeHtmlEntities(text, true)}` as RendererOutput;\n }\n\n br(token: Tokens.Br): RendererOutput {\n return '
    ' as RendererOutput;\n }\n\n del({ tokens }: Tokens.Del): RendererOutput {\n return `${this.parser.parseInline(tokens)}` as RendererOutput;\n }\n\n link({ href, title, tokens }: Tokens.Link): RendererOutput {\n const text = this.parser.parseInline(tokens) as string;\n const cleanHref = cleanUrl(href);\n if (cleanHref === null) {\n return text as RendererOutput;\n }\n href = cleanHref;\n let out = '
    ';\n return out as RendererOutput;\n }\n\n image({ href, title, text, tokens }: Tokens.Image): RendererOutput {\n if (tokens) {\n text = this.parser.parseInline(tokens, this.parser.textRenderer) as string;\n }\n const cleanHref = cleanUrl(href);\n if (cleanHref === null) {\n return escapeHtmlEntities(text) as RendererOutput;\n }\n href = cleanHref;\n\n let out = `\"${escapeHtmlEntities(text)}\"`;\n {\n // no need for block level renderers\n strong({ text }: Tokens.Strong): RendererOutput {\n return text as RendererOutput;\n }\n\n em({ text }: Tokens.Em): RendererOutput {\n return text as RendererOutput;\n }\n\n codespan({ text }: Tokens.Codespan): RendererOutput {\n return text as RendererOutput;\n }\n\n del({ text }: Tokens.Del): RendererOutput {\n return text as RendererOutput;\n }\n\n html({ text }: Tokens.HTML | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n text({ text }: Tokens.Text | Tokens.Escape | Tokens.Tag): RendererOutput {\n return text as RendererOutput;\n }\n\n link({ text }: Tokens.Link): RendererOutput {\n return '' + text as RendererOutput;\n }\n\n image({ text }: Tokens.Image): RendererOutput {\n return '' + text as RendererOutput;\n }\n\n br(): RendererOutput {\n return '' as RendererOutput;\n }\n\n checkbox({ raw }: Tokens.Checkbox): RendererOutput {\n return raw as RendererOutput;\n }\n}\n", "import { _Renderer } from './Renderer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { _defaults } from './defaults.ts';\nimport type { MarkedToken, Token, Tokens } from './Tokens.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\n\n/**\n * Parsing & Compiling\n */\nexport class _Parser {\n options: MarkedOptions;\n renderer: _Renderer;\n textRenderer: _TextRenderer;\n constructor(options?: MarkedOptions) {\n this.options = options || _defaults;\n this.options.renderer = this.options.renderer || new _Renderer();\n this.renderer = this.options.renderer;\n this.renderer.options = this.options;\n this.renderer.parser = this;\n this.textRenderer = new _TextRenderer();\n }\n\n /**\n * Static Parse Method\n */\n static parse(tokens: Token[], options?: MarkedOptions) {\n const parser = new _Parser(options);\n return parser.parse(tokens);\n }\n\n /**\n * Static Parse Inline Method\n */\n static parseInline(tokens: Token[], options?: MarkedOptions) {\n const parser = new _Parser(options);\n return parser.parseInline(tokens);\n }\n\n /**\n * Parse Loop\n */\n parse(tokens: Token[]): ParserOutput {\n let out = '';\n\n for (let i = 0; i < tokens.length; i++) {\n const anyToken = tokens[i];\n\n // Run any renderer extensions\n if (this.options.extensions?.renderers?.[anyToken.type]) {\n const genericToken = anyToken as Tokens.Generic;\n const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);\n if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'def', 'paragraph', 'text'].includes(genericToken.type)) {\n out += ret || '';\n continue;\n }\n }\n\n const token = anyToken as MarkedToken;\n\n switch (token.type) {\n case 'space': {\n out += this.renderer.space(token);\n break;\n }\n case 'hr': {\n out += this.renderer.hr(token);\n break;\n }\n case 'heading': {\n out += this.renderer.heading(token);\n break;\n }\n case 'code': {\n out += this.renderer.code(token);\n break;\n }\n case 'table': {\n out += this.renderer.table(token);\n break;\n }\n case 'blockquote': {\n out += this.renderer.blockquote(token);\n break;\n }\n case 'list': {\n out += this.renderer.list(token);\n break;\n }\n case 'checkbox': {\n out += this.renderer.checkbox(token);\n break;\n }\n case 'html': {\n out += this.renderer.html(token);\n break;\n }\n case 'def': {\n out += this.renderer.def(token);\n break;\n }\n case 'paragraph': {\n out += this.renderer.paragraph(token);\n break;\n }\n case 'text': {\n out += this.renderer.text(token);\n break;\n }\n\n default: {\n const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n if (this.options.silent) {\n console.error(errMsg);\n return '' as ParserOutput;\n } else {\n throw new Error(errMsg);\n }\n }\n }\n }\n\n return out as ParserOutput;\n }\n\n /**\n * Parse Inline Tokens\n */\n parseInline(tokens: Token[], renderer: _Renderer | _TextRenderer = this.renderer): ParserOutput {\n let out = '';\n\n for (let i = 0; i < tokens.length; i++) {\n const anyToken = tokens[i];\n\n // Run any renderer extensions\n if (this.options.extensions?.renderers?.[anyToken.type]) {\n const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);\n if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {\n out += ret || '';\n continue;\n }\n }\n\n const token = anyToken as MarkedToken;\n\n switch (token.type) {\n case 'escape': {\n out += renderer.text(token);\n break;\n }\n case 'html': {\n out += renderer.html(token);\n break;\n }\n case 'link': {\n out += renderer.link(token);\n break;\n }\n case 'image': {\n out += renderer.image(token);\n break;\n }\n case 'checkbox': {\n out += renderer.checkbox(token);\n break;\n }\n case 'strong': {\n out += renderer.strong(token);\n break;\n }\n case 'em': {\n out += renderer.em(token);\n break;\n }\n case 'codespan': {\n out += renderer.codespan(token);\n break;\n }\n case 'br': {\n out += renderer.br(token);\n break;\n }\n case 'del': {\n out += renderer.del(token);\n break;\n }\n case 'text': {\n out += renderer.text(token);\n break;\n }\n default: {\n const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n if (this.options.silent) {\n console.error(errMsg);\n return '' as ParserOutput;\n } else {\n throw new Error(errMsg);\n }\n }\n }\n }\n return out as ParserOutput;\n }\n}\n", "import { _defaults } from './defaults.ts';\nimport { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport type { MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, TokensList } from './Tokens.ts';\n\nexport class _Hooks {\n options: MarkedOptions;\n block?: boolean;\n\n constructor(options?: MarkedOptions) {\n this.options = options || _defaults;\n }\n\n static passThroughHooks = new Set([\n 'preprocess',\n 'postprocess',\n 'processAllTokens',\n 'emStrongMask',\n ]);\n\n static passThroughHooksRespectAsync = new Set([\n 'preprocess',\n 'postprocess',\n 'processAllTokens',\n ]);\n\n /**\n * Process markdown before marked\n */\n preprocess(markdown: string) {\n return markdown;\n }\n\n /**\n * Process HTML after marked is finished\n */\n postprocess(html: ParserOutput) {\n return html;\n }\n\n /**\n * Process all tokens before walk tokens\n */\n processAllTokens(tokens: Token[] | TokensList) {\n return tokens;\n }\n\n /**\n * Mask contents that should not be interpreted as em/strong delimiters\n */\n emStrongMask(src: string) {\n return src;\n }\n\n /**\n * Provide function to tokenize markdown\n */\n provideLexer() {\n return this.block ? _Lexer.lex : _Lexer.lexInline;\n }\n\n /**\n * Provide function to parse tokens\n */\n provideParser() {\n return this.block ? _Parser.parse : _Parser.parseInline;\n }\n}\n", "import { _getDefaults } from './defaults.ts';\nimport { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport { _Hooks } from './Hooks.ts';\nimport { _Renderer } from './Renderer.ts';\nimport { _Tokenizer } from './Tokenizer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { escapeHtmlEntities } from './helpers.ts';\nimport type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, Tokens, TokensList } from './Tokens.ts';\n\nexport type MaybePromise = void | Promise;\n\ntype UnknownFunction = (...args: unknown[]) => unknown;\ntype GenericRendererFunction = (...args: unknown[]) => string | false;\n\nexport class Marked {\n defaults = _getDefaults();\n options = this.setOptions;\n\n parse = this.parseMarkdown(true);\n parseInline = this.parseMarkdown(false);\n\n Parser = _Parser;\n Renderer = _Renderer;\n TextRenderer = _TextRenderer;\n Lexer = _Lexer;\n Tokenizer = _Tokenizer;\n Hooks = _Hooks;\n\n constructor(...args: MarkedExtension[]) {\n this.use(...args);\n }\n\n /**\n * Run callback for every token\n */\n walkTokens(tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) {\n let values: MaybePromise[] = [];\n for (const token of tokens) {\n values = values.concat(callback.call(this, token));\n switch (token.type) {\n case 'table': {\n const tableToken = token as Tokens.Table;\n for (const cell of tableToken.header) {\n values = values.concat(this.walkTokens(cell.tokens, callback));\n }\n for (const row of tableToken.rows) {\n for (const cell of row) {\n values = values.concat(this.walkTokens(cell.tokens, callback));\n }\n }\n break;\n }\n case 'list': {\n const listToken = token as Tokens.List;\n values = values.concat(this.walkTokens(listToken.items, callback));\n break;\n }\n default: {\n const genericToken = token as Tokens.Generic;\n if (this.defaults.extensions?.childTokens?.[genericToken.type]) {\n this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {\n const tokens = genericToken[childTokens].flat(Infinity) as Token[] | TokensList;\n values = values.concat(this.walkTokens(tokens, callback));\n });\n } else if (genericToken.tokens) {\n values = values.concat(this.walkTokens(genericToken.tokens, callback));\n }\n }\n }\n }\n return values;\n }\n\n use(...args: MarkedExtension[]) {\n const extensions: MarkedOptions['extensions'] = this.defaults.extensions || { renderers: {}, childTokens: {} };\n\n args.forEach((pack) => {\n // copy options to new object\n const opts = { ...pack } as MarkedOptions;\n\n // set async to true if it was set to true before\n opts.async = this.defaults.async || opts.async || false;\n\n // ==-- Parse \"addon\" extensions --== //\n if (pack.extensions) {\n pack.extensions.forEach((ext) => {\n if (!ext.name) {\n throw new Error('extension name required');\n }\n if ('renderer' in ext) { // Renderer extensions\n const prevRenderer = extensions.renderers[ext.name];\n if (prevRenderer) {\n // Replace extension with func to run new extension but fall back if false\n extensions.renderers[ext.name] = function(...args) {\n let ret = ext.renderer.apply(this, args);\n if (ret === false) {\n ret = prevRenderer.apply(this, args);\n }\n return ret;\n };\n } else {\n extensions.renderers[ext.name] = ext.renderer;\n }\n }\n if ('tokenizer' in ext) { // Tokenizer Extensions\n if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {\n throw new Error(\"extension level must be 'block' or 'inline'\");\n }\n const extLevel = extensions[ext.level];\n if (extLevel) {\n extLevel.unshift(ext.tokenizer);\n } else {\n extensions[ext.level] = [ext.tokenizer];\n }\n if (ext.start) { // Function to check for start of token\n if (ext.level === 'block') {\n if (extensions.startBlock) {\n extensions.startBlock.push(ext.start);\n } else {\n extensions.startBlock = [ext.start];\n }\n } else if (ext.level === 'inline') {\n if (extensions.startInline) {\n extensions.startInline.push(ext.start);\n } else {\n extensions.startInline = [ext.start];\n }\n }\n }\n }\n if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens\n extensions.childTokens[ext.name] = ext.childTokens;\n }\n });\n opts.extensions = extensions;\n }\n\n // ==-- Parse \"overwrite\" extensions --== //\n if (pack.renderer) {\n const renderer = this.defaults.renderer || new _Renderer(this.defaults);\n for (const prop in pack.renderer) {\n if (!(prop in renderer)) {\n throw new Error(`renderer '${prop}' does not exist`);\n }\n if (['options', 'parser'].includes(prop)) {\n // ignore options property\n continue;\n }\n const rendererProp = prop as Exclude, 'options' | 'parser'>;\n const rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction;\n const prevRenderer = renderer[rendererProp] as GenericRendererFunction;\n // Replace renderer with func to run extension, but fall back if false\n renderer[rendererProp] = (...args: unknown[]) => {\n let ret = rendererFunc.apply(renderer, args);\n if (ret === false) {\n ret = prevRenderer.apply(renderer, args);\n }\n return (ret || '') as RendererOutput;\n };\n }\n opts.renderer = renderer;\n }\n if (pack.tokenizer) {\n const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);\n for (const prop in pack.tokenizer) {\n if (!(prop in tokenizer)) {\n throw new Error(`tokenizer '${prop}' does not exist`);\n }\n if (['options', 'rules', 'lexer'].includes(prop)) {\n // ignore options, rules, and lexer properties\n continue;\n }\n const tokenizerProp = prop as Exclude, 'options' | 'rules' | 'lexer'>;\n const tokenizerFunc = pack.tokenizer[tokenizerProp] as UnknownFunction;\n const prevTokenizer = tokenizer[tokenizerProp] as UnknownFunction;\n // Replace tokenizer with func to run extension, but fall back if false\n // @ts-expect-error cannot type tokenizer function dynamically\n tokenizer[tokenizerProp] = (...args: unknown[]) => {\n let ret = tokenizerFunc.apply(tokenizer, args);\n if (ret === false) {\n ret = prevTokenizer.apply(tokenizer, args);\n }\n return ret;\n };\n }\n opts.tokenizer = tokenizer;\n }\n\n // ==-- Parse Hooks extensions --== //\n if (pack.hooks) {\n const hooks = this.defaults.hooks || new _Hooks();\n for (const prop in pack.hooks) {\n if (!(prop in hooks)) {\n throw new Error(`hook '${prop}' does not exist`);\n }\n if (['options', 'block'].includes(prop)) {\n // ignore options and block properties\n continue;\n }\n const hooksProp = prop as Exclude, 'options' | 'block'>;\n const hooksFunc = pack.hooks[hooksProp] as UnknownFunction;\n const prevHook = hooks[hooksProp] as UnknownFunction;\n if (_Hooks.passThroughHooks.has(prop)) {\n // @ts-expect-error cannot type hook function dynamically\n hooks[hooksProp] = (arg: unknown) => {\n if (this.defaults.async && _Hooks.passThroughHooksRespectAsync.has(prop)) {\n return (async() => {\n const ret = await hooksFunc.call(hooks, arg);\n return prevHook.call(hooks, ret);\n })();\n }\n\n const ret = hooksFunc.call(hooks, arg);\n return prevHook.call(hooks, ret);\n };\n } else {\n // @ts-expect-error cannot type hook function dynamically\n hooks[hooksProp] = (...args: unknown[]) => {\n if (this.defaults.async) {\n return (async() => {\n let ret = await hooksFunc.apply(hooks, args);\n if (ret === false) {\n ret = await prevHook.apply(hooks, args);\n }\n return ret;\n })();\n }\n\n let ret = hooksFunc.apply(hooks, args);\n if (ret === false) {\n ret = prevHook.apply(hooks, args);\n }\n return ret;\n };\n }\n }\n opts.hooks = hooks;\n }\n\n // ==-- Parse WalkTokens extensions --== //\n if (pack.walkTokens) {\n const walkTokens = this.defaults.walkTokens;\n const packWalktokens = pack.walkTokens;\n opts.walkTokens = function(token) {\n let values: MaybePromise[] = [];\n values.push(packWalktokens.call(this, token));\n if (walkTokens) {\n values = values.concat(walkTokens.call(this, token));\n }\n return values;\n };\n }\n\n this.defaults = { ...this.defaults, ...opts };\n });\n\n return this;\n }\n\n setOptions(opt: MarkedOptions) {\n this.defaults = { ...this.defaults, ...opt };\n return this;\n }\n\n lexer(src: string, options?: MarkedOptions) {\n return _Lexer.lex(src, options ?? this.defaults);\n }\n\n parser(tokens: Token[], options?: MarkedOptions) {\n return _Parser.parse(tokens, options ?? this.defaults);\n }\n\n private parseMarkdown(blockType: boolean) {\n type overloadedParse = {\n (src: string, options: MarkedOptions & { async: true }): Promise;\n (src: string, options: MarkedOptions & { async: false }): ParserOutput;\n (src: string, options?: MarkedOptions | null): ParserOutput | Promise;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const parse: overloadedParse = (src: string, options?: MarkedOptions | null): any => {\n const origOpt = { ...options };\n const opt = { ...this.defaults, ...origOpt };\n\n const throwError = this.onError(!!opt.silent, !!opt.async);\n\n // throw error if an extension set async to true but parse was called with async: false\n if (this.defaults.async === true && origOpt.async === false) {\n return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));\n }\n\n // throw error in case of non string input\n if (typeof src === 'undefined' || src === null) {\n return throwError(new Error('marked(): input parameter is undefined or null'));\n }\n if (typeof src !== 'string') {\n return throwError(new Error('marked(): input parameter is of type '\n + Object.prototype.toString.call(src) + ', string expected'));\n }\n\n if (opt.hooks) {\n opt.hooks.options = opt;\n opt.hooks.block = blockType;\n }\n\n if (opt.async) {\n return (async() => {\n const processedSrc = opt.hooks ? await opt.hooks.preprocess(src) : src;\n const lexer = opt.hooks ? await opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);\n const tokens = await lexer(processedSrc, opt);\n const processedTokens = opt.hooks ? await opt.hooks.processAllTokens(tokens) : tokens;\n if (opt.walkTokens) {\n await Promise.all(this.walkTokens(processedTokens, opt.walkTokens));\n }\n const parser = opt.hooks ? await opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);\n const html = await parser(processedTokens, opt);\n return opt.hooks ? await opt.hooks.postprocess(html) : html;\n })().catch(throwError);\n }\n\n try {\n if (opt.hooks) {\n src = opt.hooks.preprocess(src) as string;\n }\n const lexer = opt.hooks ? opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);\n let tokens = lexer(src, opt);\n if (opt.hooks) {\n tokens = opt.hooks.processAllTokens(tokens);\n }\n if (opt.walkTokens) {\n this.walkTokens(tokens, opt.walkTokens);\n }\n const parser = opt.hooks ? opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);\n let html = parser(tokens, opt);\n if (opt.hooks) {\n html = opt.hooks.postprocess(html);\n }\n return html;\n } catch(e) {\n return throwError(e as Error);\n }\n };\n\n return parse;\n }\n\n private onError(silent: boolean, async: boolean) {\n return (e: Error): string | Promise => {\n e.message += '\\nPlease report this to https://github.com/markedjs/marked.';\n\n if (silent) {\n const msg = '

    An error occurred:

    '\n          + escapeHtmlEntities(e.message + '', true)\n          + '
    ';\n if (async) {\n return Promise.resolve(msg);\n }\n return msg;\n }\n\n if (async) {\n return Promise.reject(e);\n }\n throw e;\n };\n }\n}\n", "import { _Lexer } from './Lexer.ts';\nimport { _Parser } from './Parser.ts';\nimport { _Tokenizer } from './Tokenizer.ts';\nimport { _Renderer } from './Renderer.ts';\nimport { _TextRenderer } from './TextRenderer.ts';\nimport { _Hooks } from './Hooks.ts';\nimport { Marked } from './Instance.ts';\nimport {\n _getDefaults,\n changeDefaults,\n _defaults,\n} from './defaults.ts';\nimport type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';\nimport type { Token, TokensList } from './Tokens.ts';\nimport type { MaybePromise } from './Instance.ts';\n\nconst markedInstance = new Marked();\n\n/**\n * Compiles markdown to HTML asynchronously.\n *\n * @param src String of markdown source to be compiled\n * @param options Hash of options, having async: true\n * @return Promise of string of compiled HTML\n */\nexport function marked(src: string, options: MarkedOptions & { async: true }): Promise;\n\n/**\n * Compiles markdown to HTML.\n *\n * @param src String of markdown source to be compiled\n * @param options Optional hash of options\n * @return String of compiled HTML. Will be a Promise of string if async is set to true by any extensions.\n */\nexport function marked(src: string, options: MarkedOptions & { async: false }): string;\nexport function marked(src: string, options: MarkedOptions & { async: true }): Promise;\nexport function marked(src: string, options?: MarkedOptions | null): string | Promise;\nexport function marked(src: string, opt?: MarkedOptions | null): string | Promise {\n return markedInstance.parse(src, opt);\n}\n\n/**\n * Sets the default options.\n *\n * @param options Hash of options\n */\nmarked.options =\n marked.setOptions = function(options: MarkedOptions) {\n markedInstance.setOptions(options);\n marked.defaults = markedInstance.defaults;\n changeDefaults(marked.defaults);\n return marked;\n };\n\n/**\n * Gets the original marked default options.\n */\nmarked.getDefaults = _getDefaults;\n\nmarked.defaults = _defaults;\n\n/**\n * Use Extension\n */\n\nmarked.use = function(...args: MarkedExtension[]) {\n markedInstance.use(...args);\n marked.defaults = markedInstance.defaults;\n changeDefaults(marked.defaults);\n return marked;\n};\n\n/**\n * Run callback for every token\n */\n\nmarked.walkTokens = function(tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) {\n return markedInstance.walkTokens(tokens, callback);\n};\n\n/**\n * Compiles markdown to HTML without enclosing `p` tag.\n *\n * @param src String of markdown source to be compiled\n * @param options Hash of options\n * @return String of compiled HTML\n */\nmarked.parseInline = markedInstance.parseInline;\n\n/**\n * Expose\n */\nmarked.Parser = _Parser;\nmarked.parser = _Parser.parse;\nmarked.Renderer = _Renderer;\nmarked.TextRenderer = _TextRenderer;\nmarked.Lexer = _Lexer;\nmarked.lexer = _Lexer.lex;\nmarked.Tokenizer = _Tokenizer;\nmarked.Hooks = _Hooks;\nmarked.parse = marked;\n\nexport const options = marked.options;\nexport const setOptions = marked.setOptions;\nexport const use = marked.use;\nexport const walkTokens = marked.walkTokens;\nexport const parseInline = marked.parseInline;\nexport const parse = marked;\nexport const parser = _Parser.parse;\nexport const lexer = _Lexer.lex;\nexport { _defaults as defaults, _getDefaults as getDefaults } from './defaults.ts';\nexport { _Lexer as Lexer } from './Lexer.ts';\nexport { _Parser as Parser } from './Parser.ts';\nexport { _Tokenizer as Tokenizer } from './Tokenizer.ts';\nexport { _Renderer as Renderer } from './Renderer.ts';\nexport { _TextRenderer as TextRenderer } from './TextRenderer.ts';\nexport { _Hooks as Hooks } from './Hooks.ts';\nexport { Marked } from './Instance.ts';\nexport type * from './MarkedOptions.ts';\nexport type * from './Tokens.ts';\n", "import {\n type InsertContentAtOptions as MarkdownInsertContentAtOptions,\n type InsertContentOptions as MarkdownInsertContentOptions,\n type SetContentOptions as MarkdownSetContentOptions,\n commands,\n Extension,\n} from '@tiptap/core'\nimport type { marked } from 'marked'\n\nimport MarkdownManager from './MarkdownManager.js'\nimport type { ContentType } from './types.js'\nimport { assumeContentType } from './utils.js'\n\ndeclare module '@tiptap/core' {\n interface Editor {\n /**\n * Get the content of the editor as markdown.\n */\n getMarkdown: () => string\n\n /**\n * The markdown manager instance.\n */\n markdown?: MarkdownManager\n }\n\n interface EditorOptions {\n /**\n * The content type the content is provided as.\n *\n * @default 'json'\n */\n contentType?: ContentType\n }\n\n interface Storage {\n markdown: MarkdownExtensionStorage\n }\n\n interface InsertContentOptions {\n /**\n * The content type the content is provided as.\n *\n * @default 'json'\n */\n contentType?: ContentType\n }\n\n interface InsertContentAtOptions {\n /**\n * The content type the content is provided as.\n *\n * @default 'json'\n */\n contentType?: ContentType\n }\n\n interface SetContentOptions {\n /**\n * The content type the content is provided as.\n *\n * @default 'json'\n */\n contentType?: ContentType\n }\n}\n\nexport type MarkdownExtensionOptions = {\n /**\n * Configure the indentation style and size for lists and code blocks.\n * - `style`: Choose between spaces or tabs. Default is 'space'.\n * - `size`: Number of spaces or tabs for indentation. Default is 2.\n */\n indentation?: { style?: 'space' | 'tab'; size?: number }\n\n /**\n * Use a custom version of `marked` for markdown parsing and serialization.\n * If not provided, the default `marked` instance will be used.\n */\n marked?: typeof marked\n\n /**\n * Options to pass to `marked.setOptions()`.\n * See the [marked documentation](https://marked.js.org/using_advanced#options) for available options.\n */\n markedOptions?: Parameters[0]\n}\n\nexport type MarkdownExtensionStorage = {\n manager: MarkdownManager\n}\n\nexport const Markdown = Extension.create({\n name: 'markdown',\n\n addOptions() {\n return {\n indentation: { style: 'space', size: 2 },\n marked: undefined,\n markedOptions: {},\n }\n },\n\n addCommands() {\n return {\n setContent: (content, options?: MarkdownSetContentOptions) => {\n // if no contentType is specified, we assume the content is in JSON format OR HTML format\n if (!options?.contentType) {\n return commands.setContent(content, options)\n }\n\n const actualContentType = assumeContentType(content, options?.contentType)\n\n if (actualContentType !== 'markdown' || !this.editor.markdown) {\n return commands.setContent(content, options)\n }\n\n const mdContent = this.editor.markdown.parse(content as string)\n return commands.setContent(mdContent, options)\n },\n\n insertContent: (value, options?: MarkdownInsertContentOptions) => {\n // if no contentType is specified, we assume the content is in JSON format OR HTML format\n if (!options?.contentType) {\n return commands.insertContent(value, options)\n }\n\n const actualContentType = assumeContentType(value, options?.contentType)\n\n if (actualContentType !== 'markdown' || !this.editor.markdown) {\n return commands.insertContent(value, options)\n }\n\n const mdContent = this.editor.markdown.parse(value as string)\n return commands.insertContent(mdContent, options)\n },\n\n insertContentAt: (position, value, options?: MarkdownInsertContentAtOptions) => {\n // if no contentType is specified, we assume the content is in JSON format OR HTML format\n if (!options?.contentType) {\n return commands.insertContentAt(position, value, options)\n }\n\n const actualContentType = assumeContentType(value, options?.contentType)\n\n if (actualContentType !== 'markdown' || !this.editor.markdown) {\n return commands.insertContentAt(position, value, options)\n }\n\n const mdContent = this.editor.markdown.parse(value as string)\n return commands.insertContentAt(position, mdContent, options)\n },\n }\n },\n\n addStorage() {\n return {\n manager: new MarkdownManager({\n indentation: this.options.indentation,\n marked: this.options.marked,\n markedOptions: this.options.markedOptions,\n extensions: [],\n }),\n }\n },\n\n onBeforeCreate() {\n if (this.editor.markdown) {\n console.error(\n '[tiptap][markdown]: There is already a `markdown` property on the editor instance. This might lead to unexpected behavior.',\n )\n return\n }\n\n this.storage.manager = new MarkdownManager({\n indentation: this.options.indentation,\n marked: this.options.marked,\n markedOptions: this.options.markedOptions,\n extensions: this.editor.extensionManager.baseExtensions,\n })\n\n this.editor.markdown = this.storage.manager\n\n // add a `getMarkdown()` method to the editor\n this.editor.getMarkdown = () => {\n return this.storage.manager.serialize(this.editor.getJSON())\n }\n\n if (!this.editor.options.contentType) {\n return\n }\n\n const assumedType = assumeContentType(this.editor.options.content, this.editor.options.contentType)\n if (assumedType !== 'markdown') {\n return\n }\n\n if (!this.editor.markdown) {\n throw new Error(\n '[tiptap][markdown]: The `contentType` option is set to \"markdown\", but the Markdown extension is not added to the editor. Please add the Markdown extension to use this feature.',\n )\n }\n\n if (this.editor.options.content === undefined || typeof this.editor.options.content !== 'string') {\n throw new Error(\n '[tiptap][markdown]: The `contentType` option is set to \"markdown\", but the initial content is not a string. Please provide the initial content as a markdown string.',\n )\n }\n\n const json = this.editor.markdown.parse(this.editor.options.content as string)\n this.editor.options.content = json\n },\n})\n", "import {\n type AnyExtension,\n type ExtendableConfig,\n type JSONContent,\n type MarkdownExtensionSpec,\n type MarkdownParseHelpers,\n type MarkdownParseResult,\n type MarkdownRendererHelpers,\n type MarkdownToken,\n type MarkdownTokenizer,\n type RenderContext,\n flattenExtensions,\n generateJSON,\n getExtensionField,\n} from '@tiptap/core'\nimport { type Lexer, type Token, type TokenizerExtension, marked } from 'marked'\n\nimport {\n closeMarksBeforeNode,\n findMarksToClose,\n findMarksToCloseAtEnd,\n findMarksToOpen,\n isTaskItem,\n reopenMarksAfterNode,\n wrapInMarkdownBlock,\n} from './utils.js'\n\nexport class MarkdownManager {\n private markedInstance: typeof marked\n private lexer: Lexer\n private registry: Map\n private nodeTypeRegistry: Map\n private indentStyle: 'space' | 'tab'\n private indentSize: number\n private baseExtensions: AnyExtension[] = []\n private extensions: AnyExtension[] = []\n\n /**\n * Create a MarkdownManager.\n * @param options.marked Optional marked instance to use (injected).\n * @param options.markedOptions Optional options to pass to marked.setOptions\n * @param options.indentation Indentation settings (style and size).\n * @param options.extensions An array of Tiptap extensions to register for markdown parsing and rendering.\n */\n constructor(options?: {\n marked?: typeof marked\n markedOptions?: Parameters[0]\n indentation?: { style?: 'space' | 'tab'; size?: number }\n extensions: AnyExtension[]\n }) {\n this.markedInstance = options?.marked ?? marked\n this.lexer = new this.markedInstance.Lexer()\n this.indentStyle = options?.indentation?.style ?? 'space'\n this.indentSize = options?.indentation?.size ?? 2\n this.baseExtensions = options?.extensions || []\n\n if (options?.markedOptions && typeof this.markedInstance.setOptions === 'function') {\n this.markedInstance.setOptions(options.markedOptions)\n }\n\n this.registry = new Map()\n this.nodeTypeRegistry = new Map()\n\n // If extensions were provided, register them now\n if (options?.extensions) {\n this.baseExtensions = options.extensions\n const flattened = flattenExtensions(options.extensions)\n flattened.forEach(ext => this.registerExtension(ext, false))\n }\n this.lexer = new this.markedInstance.Lexer() // Reset lexer to include all tokenizers\n }\n\n /** Returns the underlying marked instance. */\n get instance(): typeof marked {\n return this.markedInstance\n }\n\n /** Returns the correct indentCharacter (space or tab) */\n get indentCharacter(): string {\n return this.indentStyle === 'space' ? ' ' : '\\t'\n }\n\n /** Returns the correct indentString repeated X times */\n get indentString(): string {\n return this.indentCharacter.repeat(this.indentSize)\n }\n\n /** Helper to quickly check whether a marked instance is available. */\n hasMarked(): boolean {\n return !!this.markedInstance\n }\n\n /**\n * Register a Tiptap extension (Node/Mark/Extension). This will read\n * `markdownName`, `parseMarkdown`, `renderMarkdown` and `priority` from the\n * extension config (using the same resolution used across the codebase).\n */\n registerExtension(extension: AnyExtension, recreateLexer: boolean = true): void {\n // Keep track of all extensions for HTML parsing\n this.extensions.push(extension)\n\n const name = extension.name\n const tokenName =\n (getExtensionField(extension, 'markdownTokenName') as ExtendableConfig['markdownTokenName']) || name\n const parseMarkdown = getExtensionField(extension, 'parseMarkdown') as ExtendableConfig['parseMarkdown'] | undefined\n const renderMarkdown = getExtensionField(extension, 'renderMarkdown') as\n | ExtendableConfig['renderMarkdown']\n | undefined\n const tokenizer = getExtensionField(extension, 'markdownTokenizer') as\n | ExtendableConfig['markdownTokenizer']\n | undefined\n\n // Read the `markdown` object from the extension config. This allows\n // extensions to provide `markdown: { name?, parseName?, renderName?, parse?, render?, match? }`.\n const markdownCfg = (getExtensionField(extension, 'markdownOptions') ?? null) as ExtendableConfig['markdownOptions']\n const isIndenting = markdownCfg?.indentsContent ?? false\n\n const spec: MarkdownExtensionSpec = {\n tokenName,\n nodeName: name,\n parseMarkdown,\n renderMarkdown,\n isIndenting,\n tokenizer,\n }\n\n // Add to parse registry using parseName\n if (tokenName && parseMarkdown) {\n const parseExisting = this.registry.get(tokenName) || []\n parseExisting.push(spec)\n this.registry.set(tokenName, parseExisting)\n }\n\n // Add to render registry using renderName (node type)\n if (renderMarkdown) {\n const renderExisting = this.nodeTypeRegistry.get(name) || []\n renderExisting.push(spec)\n this.nodeTypeRegistry.set(name, renderExisting)\n }\n\n // Register custom tokenizer with marked.js\n if (tokenizer && this.hasMarked()) {\n this.registerTokenizer(tokenizer)\n\n if (recreateLexer) {\n this.lexer = new this.markedInstance.Lexer() // Reset lexer to include new tokenizer\n }\n }\n }\n\n /**\n * Register a custom tokenizer with marked.js for parsing non-standard markdown syntax.\n */\n private registerTokenizer(tokenizer: MarkdownTokenizer): void {\n if (!this.hasMarked()) {\n return\n }\n\n const { name, start, level = 'inline', tokenize } = tokenizer\n\n // Helper functions that use a fresh lexer instance with all registered extensions\n const tokenizeInline = (src: string) => {\n return this.lexer.inlineTokens(src)\n }\n\n const tokenizeBlock = (src: string) => {\n return this.lexer.blockTokens(src)\n }\n\n const helper = {\n inlineTokens: tokenizeInline,\n blockTokens: tokenizeBlock,\n }\n\n let startCb: (src: string) => number\n\n if (!start) {\n startCb = (src: string) => {\n // For other tokenizers, try to find a match and return its position\n const result = tokenize(src, [], helper)\n if (result && result.raw) {\n const index = src.indexOf(result.raw)\n return index\n }\n return -1\n }\n } else {\n startCb = typeof start === 'function' ? start : (src: string) => src.indexOf(start)\n }\n\n // Create marked.js extension with proper types\n const markedExtension: TokenizerExtension = {\n name,\n level,\n start: startCb,\n tokenizer: (src, tokens) => {\n const result = tokenize(src, tokens, helper)\n\n if (result && result.type) {\n return {\n ...result,\n type: result.type || name,\n raw: result.raw || '',\n tokens: (result.tokens || []) as Token[],\n }\n }\n\n return undefined\n },\n childTokens: [],\n }\n\n // Register with marked.js - use extensions array to control priority\n this.markedInstance.use({\n extensions: [markedExtension],\n })\n }\n\n /** Get registered handlers for a token type and try each until one succeeds. */\n private getHandlersForToken(type: string): MarkdownExtensionSpec[] {\n try {\n return this.registry.get(type) || []\n } catch {\n return []\n }\n }\n\n /** Get the first handler for a token type (for backwards compatibility). */\n private getHandlerForToken(type: string): MarkdownExtensionSpec | undefined {\n // First try the markdown token registry (for parsing)\n const markdownHandlers = this.getHandlersForToken(type)\n if (markdownHandlers.length > 0) {\n return markdownHandlers[0]\n }\n\n // Then try the node type registry (for rendering)\n const nodeTypeHandlers = this.getHandlersForNodeType(type)\n return nodeTypeHandlers.length > 0 ? nodeTypeHandlers[0] : undefined\n }\n\n /** Get registered handlers for a node type (for rendering). */\n private getHandlersForNodeType(type: string): MarkdownExtensionSpec[] {\n try {\n return this.nodeTypeRegistry.get(type) || []\n } catch {\n return []\n }\n }\n\n /**\n * Serialize a ProseMirror-like JSON document (or node array) to a Markdown string\n * using registered renderers and fallback renderers.\n */\n serialize(docOrContent: JSONContent): string {\n if (!docOrContent) {\n return ''\n }\n\n const result = this.renderNodes(docOrContent, docOrContent)\n // Return empty string if result is only whitespace entities or non-breaking spaces\n return this.isEmptyOutput(result) ? '' : result\n }\n\n /**\n * Check if the markdown output represents an empty document.\n * Empty documents may contain only   entities or non-breaking space characters\n * which are used by the Paragraph extension to preserve blank lines.\n */\n private isEmptyOutput(markdown: string): boolean {\n if (!markdown || markdown.trim() === '') {\n return true\n }\n\n // Check if the output is only   entities or non-breaking space characters\n const cleanedOutput = markdown\n .replace(/ /g, '')\n .replace(/\\u00A0/g, '')\n .trim()\n return cleanedOutput === ''\n }\n\n /**\n * Parse markdown string into Tiptap JSON document using registered extension handlers.\n */\n parse(markdown: string): JSONContent {\n if (!this.hasMarked()) {\n throw new Error('No marked instance available for parsing')\n }\n\n // Use marked to tokenize the markdown\n const tokens = this.markedInstance.lexer(markdown)\n\n // Convert tokens to Tiptap JSON\n const content = this.parseTokens(tokens)\n\n // Return a document node containing the parsed content\n return {\n type: 'doc',\n content,\n }\n }\n\n /**\n * Convert an array of marked tokens into Tiptap JSON nodes using registered extension handlers.\n */\n private parseTokens(tokens: MarkdownToken[]): JSONContent[] {\n return tokens\n .map(token => this.parseToken(token))\n .filter((parsed): parsed is JSONContent | JSONContent[] => parsed !== null)\n .flatMap(parsed => (Array.isArray(parsed) ? parsed : [parsed]))\n }\n\n /**\n * Parse a single token into Tiptap JSON using the appropriate registered handler.\n */\n private parseToken(token: MarkdownToken): JSONContent | JSONContent[] | null {\n if (!token.type) {\n return null\n }\n\n // Special handling for 'list' tokens that may contain mixed bullet/task items\n if (token.type === 'list') {\n return this.parseListToken(token)\n }\n\n const handlers = this.getHandlersForToken(token.type)\n const helpers = this.createParseHelpers()\n\n // Try each handler until one returns a valid result\n const result = handlers.find(handler => {\n if (!handler.parseMarkdown) {\n return false\n }\n\n const parseResult = handler.parseMarkdown(token, helpers)\n const normalized = this.normalizeParseResult(parseResult)\n\n // Check if this handler returned a valid result (not null/empty array)\n if (normalized && (!Array.isArray(normalized) || normalized.length > 0)) {\n // Store result for return\n this.lastParseResult = normalized\n return true\n }\n\n return false\n })\n\n // If a handler worked, return its result\n if (result && this.lastParseResult) {\n const toReturn = this.lastParseResult\n this.lastParseResult = null // Clean up\n return toReturn\n }\n\n // If no handler worked, try fallback parsing\n return this.parseFallbackToken(token)\n }\n\n private lastParseResult: JSONContent | JSONContent[] | null = null\n\n /**\n * Parse a list token, handling mixed bullet and task list items by splitting them into separate lists.\n * This ensures that consecutive task items and bullet items are grouped and parsed as separate list nodes.\n *\n * @param token The list token to parse\n * @returns Array of parsed list nodes, or null if parsing fails\n */\n private parseListToken(token: MarkdownToken): JSONContent | JSONContent[] | null {\n if (!token.items || token.items.length === 0) {\n // No items, parse normally\n return this.parseTokenWithHandlers(token)\n }\n\n const hasTask = token.items.some(item => isTaskItem(item).isTask)\n const hasNonTask = token.items.some(item => !isTaskItem(item).isTask)\n\n if (!hasTask || !hasNonTask || this.getHandlersForToken('taskList').length === 0) {\n // Not mixed or no taskList extension, parse normally\n return this.parseTokenWithHandlers(token)\n }\n\n // Mixed list with taskList extension available: split into separate lists\n type TaskListItemToken = MarkdownToken & { type: 'taskItem'; checked?: boolean; indentLevel?: number }\n const groups: { type: 'list' | 'taskList'; items: (MarkdownToken | TaskListItemToken)[] }[] = []\n let currentGroup: (MarkdownToken | TaskListItemToken)[] = []\n let currentType: 'list' | 'taskList' | null = null\n\n for (let i = 0; i < token.items.length; i += 1) {\n const item = token.items[i]\n const { isTask, checked, indentLevel } = isTaskItem(item)\n let processedItem = item\n\n if (isTask) {\n // Transform list_item into taskItem token\n const raw = item.raw || item.text || ''\n\n // Split raw content by lines to separate main content from nested\n const lines = raw.split('\\n')\n\n // Extract main content from the first line\n const firstLineMatch = lines[0].match(/^\\s*[-+*]\\s+\\[([ xX])\\]\\s+(.*)$/)\n const mainContent = firstLineMatch ? firstLineMatch[2] : ''\n\n // Parse nested content from remaining lines\n let nestedTokens: MarkdownToken[] = []\n if (lines.length > 1) {\n // Join all lines after the first\n const nestedRaw = lines.slice(1).join('\\n')\n\n // Only parse if there's actual content\n if (nestedRaw.trim()) {\n // Find minimum indentation of non-empty lines\n const nestedLines = lines.slice(1)\n const nonEmptyLines = nestedLines.filter(line => line.trim())\n if (nonEmptyLines.length > 0) {\n const minIndent = Math.min(...nonEmptyLines.map(line => line.length - line.trimStart().length))\n // Remove common indentation while preserving structure\n const trimmedLines = nestedLines.map(line => {\n if (!line.trim()) {\n return '' // Keep empty lines\n }\n return line.slice(minIndent)\n })\n const nestedContent = trimmedLines.join('\\n').trim()\n // Use the lexer to parse nested content\n if (nestedContent) {\n // Use the full lexer pipeline to ensure inline tokens are populated\n nestedTokens = this.markedInstance.lexer(`${nestedContent}\\n`)\n }\n }\n }\n }\n\n processedItem = {\n type: 'taskItem',\n raw: '',\n mainContent,\n indentLevel,\n checked: checked ?? false,\n text: mainContent,\n tokens: this.lexer.inlineTokens(mainContent),\n nestedTokens,\n }\n }\n\n const itemType: 'list' | 'taskList' = isTask ? 'taskList' : 'list'\n\n if (currentType !== itemType) {\n if (currentGroup.length > 0) {\n groups.push({ type: currentType!, items: currentGroup })\n }\n currentGroup = [processedItem]\n currentType = itemType\n } else {\n currentGroup.push(processedItem)\n }\n }\n\n if (currentGroup.length > 0) {\n groups.push({ type: currentType!, items: currentGroup })\n }\n\n // Parse each group as a separate token\n const results: JSONContent[] = []\n for (let i = 0; i < groups.length; i += 1) {\n const group = groups[i]\n const subToken = { ...token, type: group.type, items: group.items }\n const parsed = this.parseToken(subToken)\n if (parsed) {\n if (Array.isArray(parsed)) {\n results.push(...parsed)\n } else {\n results.push(parsed)\n }\n }\n }\n\n return results.length > 0 ? results : null\n }\n\n /**\n * Parse a token using registered handlers (extracted for reuse).\n */\n private parseTokenWithHandlers(token: MarkdownToken): JSONContent | JSONContent[] | null {\n if (!token.type) {\n return null\n }\n\n const handlers = this.getHandlersForToken(token.type)\n const helpers = this.createParseHelpers()\n\n // Try each handler until one returns a valid result\n const result = handlers.find(handler => {\n if (!handler.parseMarkdown) {\n return false\n }\n\n const parseResult = handler.parseMarkdown(token, helpers)\n const normalized = this.normalizeParseResult(parseResult)\n\n // Check if this handler returned a valid result (not null/empty array)\n if (normalized && (!Array.isArray(normalized) || normalized.length > 0)) {\n // Store result for return\n this.lastParseResult = normalized\n return true\n }\n\n return false\n })\n\n // If a handler worked, return its result\n if (result && this.lastParseResult) {\n const toReturn = this.lastParseResult\n this.lastParseResult = null // Clean up\n return toReturn\n }\n\n // If no handler worked, try fallback parsing\n return this.parseFallbackToken(token)\n }\n\n /**\n * Creates helper functions for parsing markdown tokens.\n * @returns An object containing helper functions for parsing.\n */\n private createParseHelpers(): MarkdownParseHelpers {\n return {\n parseInline: (tokens: MarkdownToken[]) => this.parseInlineTokens(tokens),\n parseChildren: (tokens: MarkdownToken[]) => this.parseTokens(tokens),\n createTextNode: (text: string, marks?: Array<{ type: string; attrs?: any }>) => {\n const node = {\n type: 'text',\n text,\n marks: marks || undefined,\n }\n\n return node\n },\n createNode: (type: string, attrs?: any, content?: JSONContent[]) => {\n const node = {\n type,\n attrs: attrs || undefined,\n content: content || undefined,\n }\n\n if (!attrs || Object.keys(attrs).length === 0) {\n delete node.attrs\n }\n\n return node\n },\n applyMark: (markType: string, content: JSONContent[], attrs?: any) => ({\n mark: markType,\n content,\n attrs: attrs && Object.keys(attrs).length > 0 ? attrs : undefined,\n }),\n }\n }\n\n /**\n * Escape special regex characters in a string.\n */\n private escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n }\n\n /**\n * Parse inline tokens (bold, italic, links, etc.) into text nodes with marks.\n * This is the complex part that handles mark nesting and boundaries.\n */\n private parseInlineTokens(tokens: MarkdownToken[]): JSONContent[] {\n const result: JSONContent[] = []\n\n // Process tokens sequentially using an index so we can lookahead and\n // merge split inline HTML fragments like: text / / inner / / text\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i]\n\n if (token.type === 'text') {\n // Create text node\n result.push({\n type: 'text',\n text: token.text || '',\n })\n } else if (token.type === 'html') {\n // Handle possible split inline HTML by attempting to detect an\n // opening tag and searching forward for a matching closing tag.\n const raw = (token.raw ?? token.text ?? '').toString()\n\n // Quick checks for opening vs. closing tag\n const isClosing = /^<\\/[\\s]*[\\w-]+/i.test(raw)\n const openMatch = raw.match(/^<[\\s]*([\\w-]+)(\\s|>|\\/|$)/i)\n\n if (!isClosing && openMatch && !/\\/>$/.test(raw)) {\n // Try to find the corresponding closing html token for this tag\n const tagName = openMatch[1]\n const escapedTagName = this.escapeRegex(tagName)\n const closingRegex = new RegExp(`^<\\\\/\\\\s*${escapedTagName}\\\\b`, 'i')\n let foundIndex = -1\n\n // Collect intermediate raw parts to reconstruct full HTML fragment\n const parts: string[] = [raw]\n for (let j = i + 1; j < tokens.length; j += 1) {\n const t = tokens[j]\n const tRaw = (t.raw ?? t.text ?? '').toString()\n parts.push(tRaw)\n if (t.type === 'html' && closingRegex.test(tRaw)) {\n foundIndex = j\n break\n }\n }\n\n if (foundIndex !== -1) {\n // Merge opening + inner + closing into one html fragment and parse\n const mergedRaw = parts.join('')\n const mergedToken = {\n type: 'html',\n raw: mergedRaw,\n text: mergedRaw,\n block: false,\n } as unknown as MarkdownToken\n\n const parsed = this.parseHTMLToken(mergedToken)\n if (parsed) {\n const normalized = this.normalizeParseResult(parsed as any)\n if (Array.isArray(normalized)) {\n result.push(...normalized)\n } else if (normalized) {\n result.push(normalized)\n }\n }\n\n // Advance i to the closing token\n i = foundIndex\n continue\n }\n }\n\n // Fallback: single html token parse\n const parsedSingle = this.parseHTMLToken(token)\n if (parsedSingle) {\n const normalized = this.normalizeParseResult(parsedSingle as any)\n if (Array.isArray(normalized)) {\n result.push(...normalized)\n } else if (normalized) {\n result.push(normalized)\n }\n }\n } else if (token.type) {\n // Handle inline marks (bold, italic, etc.)\n const markHandler = this.getHandlerForToken(token.type)\n if (markHandler && markHandler.parseMarkdown) {\n const helpers = this.createParseHelpers()\n const parsed = markHandler.parseMarkdown(token, helpers)\n\n if (this.isMarkResult(parsed)) {\n // This is a mark result - apply the mark to the content\n const markedContent = this.applyMarkToContent(parsed.mark, parsed.content, parsed.attrs)\n result.push(...markedContent)\n } else {\n // Regular inline node\n const normalized = this.normalizeParseResult(parsed)\n if (Array.isArray(normalized)) {\n result.push(...normalized)\n } else if (normalized) {\n result.push(normalized)\n }\n }\n } else if (token.tokens) {\n // Fallback: try to parse children if they exist\n result.push(...this.parseInlineTokens(token.tokens))\n }\n }\n }\n\n return result\n }\n\n /**\n * Apply a mark to content nodes.\n */\n private applyMarkToContent(markType: string, content: JSONContent[], attrs?: any): JSONContent[] {\n return content.map(node => {\n if (node.type === 'text') {\n // Add the mark to existing marks or create new marks array\n const existingMarks = node.marks || []\n const newMark = attrs ? { type: markType, attrs } : { type: markType }\n return {\n ...node,\n marks: [...existingMarks, newMark],\n }\n }\n\n // For non-text nodes, recursively apply to content\n return {\n ...node,\n content: node.content ? this.applyMarkToContent(markType, node.content, attrs) : undefined,\n }\n })\n } /**\n * Check if a parse result represents a mark to be applied.\n */\n private isMarkResult(result: any): result is { mark: string; content: JSONContent[]; attrs?: any } {\n return result && typeof result === 'object' && 'mark' in result\n }\n\n /**\n * Normalize parse results to ensure they're valid JSONContent.\n */\n private normalizeParseResult(result: MarkdownParseResult): JSONContent | JSONContent[] | null {\n if (!result) {\n return null\n }\n\n if (this.isMarkResult(result)) {\n // This shouldn't happen at the top level, but handle it gracefully\n return result.content\n }\n\n return result as JSONContent | JSONContent[]\n }\n\n /**\n * Fallback parsing for common tokens when no specific handler is registered.\n */\n private parseFallbackToken(token: MarkdownToken): JSONContent | JSONContent[] | null {\n switch (token.type) {\n case 'paragraph':\n return {\n type: 'paragraph',\n content: token.tokens ? this.parseInlineTokens(token.tokens) : [],\n }\n\n case 'heading':\n return {\n type: 'heading',\n attrs: { level: token.depth || 1 },\n content: token.tokens ? this.parseInlineTokens(token.tokens) : [],\n }\n\n case 'text':\n return {\n type: 'text',\n text: token.text || '',\n }\n\n case 'html':\n // Parse HTML using extensions' parseHTML methods\n return this.parseHTMLToken(token)\n\n case 'space':\n return null\n\n default:\n // Unknown token type - try to parse children if they exist\n if (token.tokens) {\n return this.parseTokens(token.tokens)\n }\n return null\n }\n }\n\n /**\n * Parse HTML tokens using extensions' parseHTML methods.\n * This allows HTML within markdown to be parsed according to extension rules.\n */\n private parseHTMLToken(token: MarkdownToken): JSONContent | JSONContent[] | null {\n const html = token.text || token.raw || ''\n\n if (!html.trim()) {\n return null\n }\n\n // Check if we're in a server-side environment (no window object)\n // If so, fall back to treating HTML as plain text to avoid runtime errors\n if (typeof window === 'undefined') {\n // For block-level HTML, wrap in a paragraph to maintain valid document structure\n if (token.block) {\n return {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: html,\n },\n ],\n }\n }\n // For inline HTML, return plain text\n return {\n type: 'text',\n text: html,\n }\n }\n\n // Use generateJSON to parse the HTML using extensions' parseHTML rules\n try {\n const parsed = generateJSON(html, this.baseExtensions)\n\n // If the result is a doc node, extract its content\n if (parsed.type === 'doc' && parsed.content) {\n // For block-level HTML, return the content array\n if (token.block) {\n return parsed.content\n }\n\n // For inline HTML, we need to flatten the content appropriately\n // If there's only one paragraph with content, unwrap it\n if (parsed.content.length === 1 && parsed.content[0].type === 'paragraph' && parsed.content[0].content) {\n return parsed.content[0].content\n }\n\n return parsed.content\n }\n\n return parsed as JSONContent\n } catch (error) {\n throw new Error(`Failed to parse HTML in markdown: ${error}`)\n }\n }\n\n renderNodeToMarkdown(node: JSONContent, parentNode?: JSONContent, index = 0, level = 0): string {\n // if node is a text node, we simply return it's text content\n // marks are handled at the array level in renderNodesWithMarkBoundaries\n if (node.type === 'text') {\n return node.text || ''\n }\n\n if (!node.type) {\n return ''\n }\n\n const handler = this.getHandlerForToken(node.type)\n if (!handler) {\n return ''\n }\n\n const helpers: MarkdownRendererHelpers = {\n renderChildren: (nodes, separator) => {\n const childLevel = handler.isIndenting ? level + 1 : level\n\n if (!Array.isArray(nodes) && (nodes as any).content) {\n return this.renderNodes((nodes as any).content as JSONContent[], node, separator || '', index, childLevel)\n }\n\n return this.renderNodes(nodes, node, separator || '', index, childLevel)\n },\n indent: content => {\n return this.indentString + content\n },\n wrapInBlock: wrapInMarkdownBlock,\n }\n\n const context: RenderContext = {\n index,\n level,\n parentType: parentNode?.type,\n meta: {\n parentAttrs: parentNode?.attrs,\n },\n }\n\n // First render the node itself (this will render children recursively)\n const rendered = handler.renderMarkdown?.(node, helpers, context) || ''\n\n return rendered\n }\n\n /**\n * Render a node or an array of nodes. Parent type controls how children\n * are joined (which determines newline insertion between children).\n */\n renderNodes(\n nodeOrNodes: JSONContent | JSONContent[],\n parentNode?: JSONContent,\n separator = '',\n index = 0,\n level = 0,\n ): string {\n // if we have just one node, call renderNodeToMarkdown directly\n if (!Array.isArray(nodeOrNodes)) {\n if (!nodeOrNodes.type) {\n return ''\n }\n\n return this.renderNodeToMarkdown(nodeOrNodes, parentNode, index, level)\n }\n\n return this.renderNodesWithMarkBoundaries(nodeOrNodes, parentNode, separator, level)\n }\n\n /**\n * Render an array of nodes while properly tracking mark boundaries.\n * This handles cases where marks span across multiple text nodes.\n */\n private renderNodesWithMarkBoundaries(\n nodes: JSONContent[],\n parentNode?: JSONContent,\n separator = '',\n level = 0,\n ): string {\n const result: string[] = []\n const activeMarks: Map = new Map()\n nodes.forEach((node, i) => {\n // Lookahead to the next node to determine if marks need to be closed\n const nextNode = i < nodes.length - 1 ? nodes[i + 1] : null\n\n if (!node.type) {\n return\n }\n\n if (node.type === 'text') {\n let textContent = node.text || ''\n const currentMarks = new Map((node.marks || []).map(mark => [mark.type, mark]))\n\n // Find marks that need to be closed and opened\n const marksToOpen = findMarksToOpen(activeMarks, currentMarks)\n const marksToClose = findMarksToClose(currentMarks, nextNode)\n\n let middleTrailingWhitespace = ''\n\n if (marksToClose.length > 0) {\n // Extract trailing whitespace before closing marks to prevent invalid markdown like \"**text **\"\n const middleTrailingMatch = textContent.match(/(\\s+)$/)\n if (middleTrailingMatch) {\n middleTrailingWhitespace = middleTrailingMatch[1]\n textContent = textContent.slice(0, -middleTrailingWhitespace.length)\n }\n }\n // Close marks that are ending here\n marksToClose.forEach(markType => {\n const mark = currentMarks.get(markType)\n const closeMarkdown = this.getMarkClosing(markType, mark)\n if (closeMarkdown) {\n textContent += closeMarkdown\n }\n // deleting closed marks from active marks\n if (activeMarks.has(markType)) {\n activeMarks.delete(markType)\n }\n })\n\n // Open new marks (should be at the beginning)\n // Extract leading whitespace before opening marks to prevent invalid markdown like \"** text**\"\n let leadingWhitespace = ''\n if (marksToOpen.length > 0) {\n const leadingMatch = textContent.match(/^(\\s+)/)\n if (leadingMatch) {\n leadingWhitespace = leadingMatch[1]\n textContent = textContent.slice(leadingWhitespace.length)\n }\n }\n\n marksToOpen.forEach(({ type, mark }) => {\n const openMarkdown = this.getMarkOpening(type, mark)\n if (openMarkdown) {\n textContent = openMarkdown + textContent\n }\n if (!marksToClose.includes(type)) {\n activeMarks.set(type, mark)\n }\n })\n\n // Add leading whitespace before the mark opening\n textContent = leadingWhitespace + textContent\n\n // Close marks at the end of this node if needed\n const marksToCloseAtEnd = findMarksToCloseAtEnd(\n activeMarks,\n currentMarks,\n nextNode,\n this.markSetsEqual.bind(this),\n )\n\n // Extract trailing whitespace before closing marks to prevent invalid markdown like \"**text **\"\n let trailingWhitespace = ''\n if (marksToCloseAtEnd.length > 0) {\n const trailingMatch = textContent.match(/(\\s+)$/)\n if (trailingMatch) {\n trailingWhitespace = trailingMatch[1]\n textContent = textContent.slice(0, -trailingWhitespace.length)\n }\n }\n\n marksToCloseAtEnd.forEach(markType => {\n const mark = activeMarks.get(markType)\n const closeMarkdown = this.getMarkClosing(markType, mark)\n if (closeMarkdown) {\n textContent += closeMarkdown\n }\n activeMarks.delete(markType)\n })\n\n // Add trailing whitespace after the mark closing\n textContent += trailingWhitespace\n textContent += middleTrailingWhitespace\n\n result.push(textContent)\n } else {\n // For non-text nodes, close all active marks before rendering, then reopen after\n const marksToReopen = new Map(activeMarks)\n\n // Close all marks before the node\n const beforeMarkdown = closeMarksBeforeNode(activeMarks, this.getMarkClosing.bind(this))\n\n // Render the node\n const nodeContent = this.renderNodeToMarkdown(node, parentNode, i, level)\n\n // Reopen marks after the node, but NOT after a hard break\n // Hard breaks should terminate marks (they create a line break where marks don't continue)\n const afterMarkdown =\n node.type === 'hardBreak'\n ? ''\n : reopenMarksAfterNode(marksToReopen, activeMarks, this.getMarkOpening.bind(this))\n\n result.push(beforeMarkdown + nodeContent + afterMarkdown)\n }\n })\n\n return result.join(separator)\n }\n\n /**\n * Get the opening markdown syntax for a mark type.\n */\n private getMarkOpening(markType: string, mark: any): string {\n const handlers = this.getHandlersForNodeType(markType)\n const handler = handlers.length > 0 ? handlers[0] : undefined\n if (!handler || !handler.renderMarkdown) {\n return ''\n }\n\n // Use a unique placeholder that's extremely unlikely to appear in real content\n const placeholder = '\\uE000__TIPTAP_MARKDOWN_PLACEHOLDER__\\uE001'\n\n // For most marks, we can extract the opening syntax by rendering a simple case\n const syntheticNode: JSONContent = {\n type: markType,\n attrs: mark.attrs || {},\n content: [{ type: 'text', text: placeholder }],\n }\n\n try {\n const rendered = handler.renderMarkdown(\n syntheticNode,\n {\n renderChildren: () => placeholder,\n indent: (content: string) => content,\n wrapInBlock: (prefix: string, content: string) => prefix + content,\n },\n { index: 0, level: 0, parentType: 'text', meta: {} },\n )\n\n // Extract the opening part (everything before placeholder)\n const placeholderIndex = rendered.indexOf(placeholder)\n return placeholderIndex >= 0 ? rendered.substring(0, placeholderIndex) : ''\n } catch (err) {\n throw new Error(`Failed to get mark opening for ${markType}: ${err}`)\n }\n }\n\n /**\n * Get the closing markdown syntax for a mark type.\n */\n private getMarkClosing(markType: string, mark: any): string {\n const handlers = this.getHandlersForNodeType(markType)\n const handler = handlers.length > 0 ? handlers[0] : undefined\n if (!handler || !handler.renderMarkdown) {\n return ''\n }\n\n // Use a unique placeholder that's extremely unlikely to appear in real content\n const placeholder = '\\uE000__TIPTAP_MARKDOWN_PLACEHOLDER__\\uE001'\n\n const syntheticNode: JSONContent = {\n type: markType,\n attrs: mark.attrs || {},\n content: [{ type: 'text', text: placeholder }],\n }\n\n try {\n const rendered = handler.renderMarkdown(\n syntheticNode,\n {\n renderChildren: () => placeholder,\n indent: (content: string) => content,\n wrapInBlock: (prefix: string, content: string) => prefix + content,\n },\n { index: 0, level: 0, parentType: 'text', meta: {} },\n )\n\n // Extract the closing part (everything after placeholder)\n const placeholderIndex = rendered.indexOf(placeholder)\n const placeholderEnd = placeholderIndex + placeholder.length\n return placeholderIndex >= 0 ? rendered.substring(placeholderEnd) : ''\n } catch (err) {\n throw new Error(`Failed to get mark closing for ${markType}: ${err}`)\n }\n }\n\n /**\n * Check if two mark sets are equal.\n */\n private markSetsEqual(marks1: Map, marks2: Map): boolean {\n if (marks1.size !== marks2.size) {\n return false\n }\n\n return Array.from(marks1.keys()).every(type => marks2.has(type))\n }\n}\n\nexport default MarkdownManager\n", "import type { Content, MarkdownToken } from '@tiptap/core'\nimport type { Fragment, Node } from '@tiptap/pm/model'\n\nimport type { ContentType } from './types.js'\n\n/**\n * Wraps each line of the content with the given prefix.\n * @param prefix The prefix to wrap each line with.\n * @param content The content to wrap.\n * @returns The content with each line wrapped with the prefix.\n */\nexport function wrapInMarkdownBlock(prefix: string, content: string) {\n // split content lines\n const lines = content.split('\\n')\n\n // add empty strings between every line\n const output = lines\n // add empty lines between each block\n .flatMap(line => [line, ''])\n // add the prefix to each line\n .map(line => `${prefix}${line}`)\n .join('\\n')\n\n return output.slice(0, output.length - 1)\n}\n\n/**\n * Identifies marks that need to be closed, based on the marks in the next node.\n */\nexport function findMarksToClose(currentMarks: Map, nextNode: any): string[] {\n const marksToClose: string[] = []\n\n Array.from(currentMarks.keys()).forEach(markType => {\n if (!nextNode || !nextNode.marks || !nextNode.marks.map((mark: any) => mark.type).includes(markType)) {\n marksToClose.push(markType)\n }\n })\n return marksToClose\n}\n\n/**\n * Identifies marks that need to be opened (in current node but not active).\n */\nexport function findMarksToOpen(\n activeMarks: Map,\n currentMarks: Map,\n): Array<{ type: string; mark: any }> {\n const marksToOpen: Array<{ type: string; mark: any }> = []\n Array.from(currentMarks.entries()).forEach(([markType, mark]) => {\n if (!activeMarks.has(markType)) {\n marksToOpen.push({ type: markType, mark })\n }\n })\n return marksToOpen\n}\n\n/**\n * Determines which marks need to be closed at the end of the current text node.\n * This handles cases where marks end at node boundaries or when transitioning\n * to nodes with different mark sets.\n */\nexport function findMarksToCloseAtEnd(\n activeMarks: Map,\n currentMarks: Map,\n nextNode: any,\n markSetsEqual: (a: Map, b: Map) => boolean,\n): string[] {\n const isLastNode = !nextNode\n const nextNodeHasNoMarks = nextNode && nextNode.type === 'text' && (!nextNode.marks || nextNode.marks.length === 0)\n const nextNodeHasDifferentMarks =\n nextNode &&\n nextNode.type === 'text' &&\n nextNode.marks &&\n !markSetsEqual(currentMarks, new Map(nextNode.marks.map((mark: any) => [mark.type, mark])))\n\n const marksToCloseAtEnd: string[] = []\n if (isLastNode || nextNodeHasNoMarks || nextNodeHasDifferentMarks) {\n if (nextNode && nextNode.type === 'text' && nextNode.marks) {\n const nextMarks = new Map(nextNode.marks.map((mark: any) => [mark.type, mark]))\n Array.from(activeMarks.keys()).forEach(markType => {\n if (!nextMarks.has(markType)) {\n marksToCloseAtEnd.push(markType)\n }\n })\n } else if (isLastNode || nextNodeHasNoMarks) {\n // Close all active marks\n marksToCloseAtEnd.push(...Array.from(activeMarks.keys()))\n }\n }\n\n return marksToCloseAtEnd\n}\n\n/**\n * Closes active marks before rendering a non-text node.\n * Returns the closing markdown syntax and clears the active marks.\n */\nexport function closeMarksBeforeNode(\n activeMarks: Map,\n getMarkClosing: (markType: string, mark: any) => string,\n): string {\n let beforeMarkdown = ''\n Array.from(activeMarks.keys())\n .reverse()\n .forEach(markType => {\n const mark = activeMarks.get(markType)\n const closeMarkdown = getMarkClosing(markType, mark)\n if (closeMarkdown) {\n beforeMarkdown = closeMarkdown + beforeMarkdown\n }\n })\n activeMarks.clear()\n return beforeMarkdown\n}\n\n/**\n * Reopens marks after rendering a non-text node.\n * Returns the opening markdown syntax and updates the active marks.\n */\nexport function reopenMarksAfterNode(\n marksToReopen: Map,\n activeMarks: Map,\n getMarkOpening: (markType: string, mark: any) => string,\n): string {\n let afterMarkdown = ''\n Array.from(marksToReopen.entries()).forEach(([markType, mark]) => {\n const openMarkdown = getMarkOpening(markType, mark)\n if (openMarkdown) {\n afterMarkdown += openMarkdown\n }\n activeMarks.set(markType, mark)\n })\n return afterMarkdown\n}\n\n/**\n * Check if a markdown list item token is a task item and extract its state.\n *\n * @param item The list item token to check\n * @returns Object containing isTask flag, checked state, and indentation level\n *\n * @example\n * ```ts\n * isTaskItem({ raw: '- [ ] Task' }) // { isTask: true, checked: false, indentLevel: 0 }\n * isTaskItem({ raw: ' - [x] Done' }) // { isTask: true, checked: true, indentLevel: 2 }\n * isTaskItem({ raw: '- Regular' }) // { isTask: false, indentLevel: 0 }\n * ```\n */\nexport function isTaskItem(item: MarkdownToken): { isTask: boolean; checked?: boolean; indentLevel: number } {\n const raw = item.raw || item.text || ''\n\n // Match patterns like \"- [ ] \" or \" - [x] \"\n const match = raw.match(/^(\\s*)[-+*]\\s+\\[([ xX])\\]\\s+/)\n\n if (match) {\n return { isTask: true, checked: match[2].toLowerCase() === 'x', indentLevel: match[1].length }\n }\n return { isTask: false, indentLevel: 0 }\n}\n\n/**\n * Assumes the content type based off the content.\n * @param content The content to assume the type for.\n * @param contentType The content type that should be prioritized.\n */\nexport function assumeContentType(\n content: (Content | Fragment | Node) | string,\n contentType: ContentType,\n): ContentType {\n // if not a string, we assume it will be a json content object\n if (typeof content !== 'string') {\n return 'json'\n }\n\n // otherwise we let the content type be what it is\n return contentType\n}\n", "import { Placeholder } from '@tiptap/extensions'\n\nexport type { PlaceholderOptions } from '@tiptap/extensions'\nexport { Placeholder } from '@tiptap/extensions'\n\nexport default Placeholder\n", "export const CLERK_ERROR_COPY = {\n genericRetry: \"Something went wrong. Try again.\",\n planningOfferInactive: \"This Plan offer is no longer active\",\n activeRunInProgress: \"Your last message is still being processed. Please wait a moment and try again.\",\n clerkUnavailable: \"AI research isn't enabled in this workspace. Ask your admin for access.\",\n contextWindowReached: \"Something went wrong. Start a new conversation to continue your research.\",\n timeout:\n \"This is taking longer than expected. Try again in a moment. If the issue persists, contact Bench IQ Support.\",\n costLimitReached:\n \"Your latest request in this conversation reached its spending limit. Try asking a more focused question.\",\n outputLimitExceeded: \"The response was too long to complete. Try asking for a shorter or more focused answer.\",\n searchUnavailable: \"We couldn't search transcripts right now. Please try again.\",\n transcriptUnavailable: \"We couldn't open that transcript right now. Please try again.\",\n transcriptBootstrapFailure: \"We couldn't open that transcript. You can still start a new conversation.\",\n conversationLoadFailure: \"We couldn't load this conversation right now. Please try again.\",\n conversationHistoryPageFailure: \"We couldn\u2019t load earlier messages. Refresh the conversation and try again.\",\n emptyConversationRecoveryHeading: \"We couldn't load this conversation yet.\",\n emptyConversationRecoveryBody: \"This conversation is taking longer than expected to load. Please try again.\",\n historyLoadFailure: \"We couldn't load your conversation history. Please try again.\",\n clarifyingAnswerSubmitFailure: \"We couldn't send your reply. Please try sending it again.\",\n clarifyingAnswerUncertainDelivery: \"We saved your reply, but may not have received it. Please try sending it again.\",\n clarifyingAnswerNoLongerAccepted: \"This question timed out, so the agent continued using its best judgment.\",\n clarifyingAnswerConflict: \"Another reply was already saved for this question, so this reply was not used.\",\n monthlyUsageLimit: \"You have reached your usage limit this month. Try again next month.\",\n monthlyCreditLimit: \"Your account has reached its monthly credit limit. Contact Bench IQ support to increase it.\",\n creditAccessExpired: \"Your account's Bench IQ credits have expired. Contact Bench IQ support to restore access.\",\n shareConversationUnavailable:\n \"This shared conversation is no longer available. Please ask the sender for a new link.\",\n shareLinkUpdateFailure: \"We couldn't update the share link right now. Please try again.\",\n shareLinkCopyFailure: \"We couldn't copy the link. Please copy it manually.\",\n shareLinkDeleteUnauthorized:\n \"Only the person who shared this conversation can delete this link. Please ask them to remove it.\",\n tooManyFiles: \"You can upload up to 5 files at a time. Remove a file and try again.\",\n fileTooLarge: \"That file is too large. Please upload a smaller file.\",\n unsupportedFileType: \"We can\u2019t read this file type. Upload a PDF, DOCX, TXT, MD, or RTF file.\",\n fileUnreadable: \"We couldn\u2019t read this file. Try uploading it again or choose another copy.\",\n pdfUnreadable: \"We couldn\u2019t read this file. Try uploading it again or choose another copy.\",\n creditBillingUnavailable:\n \"We couldn\u2019t start your request right now. Try again in a few minutes. If the issue persists, contact Bench IQ Support.\",\n creditRequestUnavailable: \"We couldn\u2019t start this request. Refresh the page and try again.\",\n matterNumberRequired: \"Enter a matter number to continue.\",\n matterNumberInvalid: \"Enter a valid matter number.\",\n originalMatterMissing:\n \"We couldn\u2019t retry this response because its matter number is missing. Start a new conversation.\",\n conversationMatterConflict:\n \"This conversation belongs to a different matter. Return to that matter or start a new conversation.\",\n matterValidationUnavailable: \"We couldn\u2019t verify this matter number right now. Try again.\",\n streamInterruptedWithContent: \"The connection was interrupted. The response above may be incomplete.\",\n responseDetailsLoadFailure: \"We couldn\u2019t load the complete response. Please try again.\",\n recoveryHydrationFailure: \"Your response is ready, but we couldn't load it. Please refresh the page.\",\n citationGenerationFailure: \"Some citation details couldn\u2019t be generated for this response.\",\n} as const;\n\nexport const CLERK_ERROR_COPY_BANNED_TERMS = [\n /backend/i,\n /\\bocr\\b/i,\n /working memory/i,\n /context limit/i,\n /\\btoken\\b/i,\n /\\bhttp\\b/i,\n /per-question processing budget/i,\n /per-run processing limit/i,\n /narrow (the )?request/i,\n /narrow your question/i,\n] as const;\n\nexport type ClerkErrorCopyKey = keyof typeof CLERK_ERROR_COPY;\n\nconst APPROVED_STATIC_COPY = new Set(Object.values(CLERK_ERROR_COPY));\n\nconst RAW_ERROR_MESSAGE_MAP = new Map([\n [\"Connection lost after multiple attempts. Please try again.\", CLERK_ERROR_COPY.genericRetry],\n [\"Failed to recover run. Please refresh and try again.\", CLERK_ERROR_COPY.genericRetry],\n [\"A message is already being processed\", CLERK_ERROR_COPY.activeRunInProgress],\n [\"Monthly usage limit reached. Your limit resets at the start of next month.\", CLERK_ERROR_COPY.monthlyUsageLimit],\n [\"This share link is expired or revoked.\", CLERK_ERROR_COPY.shareConversationUnavailable],\n [\"Share link not found\", CLERK_ERROR_COPY.shareConversationUnavailable],\n [\"Only the sender can revoke this share link.\", CLERK_ERROR_COPY.shareLinkDeleteUnauthorized],\n [\"Session not found\", CLERK_ERROR_COPY.conversationLoadFailure],\n [\"Run not found\", CLERK_ERROR_COPY.genericRetry],\n [\"Missing question_id or answer\", CLERK_ERROR_COPY.clarifyingAnswerSubmitFailure],\n [\"Too many files. Maximum 5 files per message.\", CLERK_ERROR_COPY.tooManyFiles],\n [\"Unsupported file type.\", CLERK_ERROR_COPY.unsupportedFileType],\n [\"Transcript content temporarily unavailable\", CLERK_ERROR_COPY.transcriptUnavailable],\n [\"OCR temporarily unavailable. Please try again.\", CLERK_ERROR_COPY.pdfUnreadable],\n [\"OCR failed. Please try again.\", CLERK_ERROR_COPY.pdfUnreadable],\n [\"Failed to submit answer\", CLERK_ERROR_COPY.clarifyingAnswerSubmitFailure],\n [\"Failed to cancel run\", CLERK_ERROR_COPY.genericRetry],\n [\"This request was interrupted before completion. Please retry.\", CLERK_ERROR_COPY.genericRetry],\n [\n \"The conversation has grown too long. Please start a new session or narrow the request.\",\n CLERK_ERROR_COPY.contextWindowReached,\n ],\n [\"This run timed out. Please try again.\", CLERK_ERROR_COPY.timeout],\n [\"This run hit the turn limit. Please try again with a narrower question.\", CLERK_ERROR_COPY.genericRetry],\n [\"This request exceeded the per-question processing budget. Please try again.\", CLERK_ERROR_COPY.costLimitReached],\n [\n \"The transcript search service is temporarily unavailable. Please try again with a judge, case name, or rough date range.\",\n CLERK_ERROR_COPY.searchUnavailable,\n ],\n [\"The research agent encountered an error. Please try again.\", CLERK_ERROR_COPY.genericRetry],\n [\"A backend service is temporarily unavailable. Please try again.\", CLERK_ERROR_COPY.genericRetry],\n [\"Something went wrong. Please try again.\", CLERK_ERROR_COPY.genericRetry],\n]);\n\nconst ERROR_CODE_MAP = new Map([\n [\"active_run_in_progress\", CLERK_ERROR_COPY.activeRunInProgress],\n [\"agent_connection_failed\", CLERK_ERROR_COPY.genericRetry],\n [\"agent_http_error\", CLERK_ERROR_COPY.genericRetry],\n [\"capacity\", CLERK_ERROR_COPY.genericRetry],\n [\"clerk_unavailable\", CLERK_ERROR_COPY.clerkUnavailable],\n [\"connection_timeout\", CLERK_ERROR_COPY.genericRetry],\n [\"context_limit\", CLERK_ERROR_COPY.contextWindowReached],\n [\"cost_limit\", CLERK_ERROR_COPY.costLimitReached],\n [\"monthly_usage_limit\", CLERK_ERROR_COPY.monthlyUsageLimit],\n [\"monthly_usage_unavailable\", CLERK_ERROR_COPY.genericRetry],\n [\"output_limit_exceeded\", CLERK_ERROR_COPY.outputLimitExceeded],\n [\"deployment_interrupted\", CLERK_ERROR_COPY.genericRetry],\n [\"enqueue_failed\", CLERK_ERROR_COPY.genericRetry],\n [\"missing_tool_output\", CLERK_ERROR_COPY.genericRetry],\n [\"monthly_credit_limit_reached\", CLERK_ERROR_COPY.monthlyCreditLimit],\n [\"credit_access_expired\", CLERK_ERROR_COPY.creditAccessExpired],\n [\"conversation_cursor_invalid\", CLERK_ERROR_COPY.conversationHistoryPageFailure],\n [\"credit_billing_temporarily_unavailable\", CLERK_ERROR_COPY.creditBillingUnavailable],\n [\"credit_usage_conflict\", CLERK_ERROR_COPY.genericRetry],\n [\"credit_request_id_required\", CLERK_ERROR_COPY.creditRequestUnavailable],\n [\"client_matter_code_required\", CLERK_ERROR_COPY.matterNumberRequired],\n [\"client_matter_code_invalid\", CLERK_ERROR_COPY.matterNumberInvalid],\n [\"credit_original_matter_missing\", CLERK_ERROR_COPY.originalMatterMissing],\n [\"credit_session_matter_conflict\", CLERK_ERROR_COPY.conversationMatterConflict],\n [\"credit_speed_bump_request_invalid\", CLERK_ERROR_COPY.genericRetry],\n [\"credit_speed_bump_confirmation_invalid\", CLERK_ERROR_COPY.genericRetry],\n [\"rate_limit\", CLERK_ERROR_COPY.genericRetry],\n [\"search_unavailable\", CLERK_ERROR_COPY.searchUnavailable],\n [\"service_unavailable\", CLERK_ERROR_COPY.genericRetry],\n [\"stream_terminated\", CLERK_ERROR_COPY.genericRetry],\n [\"startup_stall\", CLERK_ERROR_COPY.genericRetry],\n [\"timeout\", CLERK_ERROR_COPY.timeout],\n [\"turn_limit\", CLERK_ERROR_COPY.genericRetry],\n [\"unknown\", CLERK_ERROR_COPY.genericRetry],\n [\"worker_interrupted\", CLERK_ERROR_COPY.genericRetry],\n]);\n\nfunction mappedRawErrorMessage(rawError: string): string | null {\n const directMatch = RAW_ERROR_MESSAGE_MAP.get(rawError);\n if (directMatch) return directMatch;\n\n if (/\\bclerk\\b/i.test(rawError)) {\n return CLERK_ERROR_COPY.genericRetry;\n }\n\n if (/context.length|token.limit|maximum.context/i.test(rawError)) {\n return CLERK_ERROR_COPY.contextWindowReached;\n }\n if (/search.*temporarily unavailable|search failed/i.test(rawError)) {\n return CLERK_ERROR_COPY.searchUnavailable;\n }\n if (/transcript content temporarily unavailable|transcript not found/i.test(rawError)) {\n return CLERK_ERROR_COPY.transcriptUnavailable;\n }\n if (/share link/i.test(rawError) && /(expired|revoked|not found|no longer available)/i.test(rawError)) {\n return CLERK_ERROR_COPY.shareConversationUnavailable;\n }\n if (/sender can revoke/i.test(rawError)) {\n return CLERK_ERROR_COPY.shareLinkDeleteUnauthorized;\n }\n if (/maximum 5 files|max 5 files|too many files/i.test(rawError)) {\n return CLERK_ERROR_COPY.tooManyFiles;\n }\n if (/10 MB limit|25 MB|too large/i.test(rawError)) {\n return CLERK_ERROR_COPY.fileTooLarge;\n }\n if (/unsupported file type/i.test(rawError)) {\n return CLERK_ERROR_COPY.unsupportedFileType;\n }\n if (/ocr|did not return readable text/i.test(rawError)) {\n return CLERK_ERROR_COPY.pdfUnreadable;\n }\n if (/could not process file|failed to read .*file|file may be corrupt|file storage failed/i.test(rawError)) {\n return CLERK_ERROR_COPY.fileUnreadable;\n }\n\n return null;\n}\n\nexport function normalizeClerkErrorMessage(\n rawError: string | null | undefined,\n options: {\n code?: string | null;\n fallbackKey?: ClerkErrorCopyKey;\n } = {},\n): string {\n if (options.code === \"cost_limit\") {\n const costLimitMessage = rawError?.trim();\n if (\n /^Your latest request in this conversation reached its \\$[\\d,.]+ spending limit\\./.test(costLimitMessage || \"\")\n ) {\n return costLimitMessage!;\n }\n return CLERK_ERROR_COPY.costLimitReached;\n }\n\n const trimmedError = rawError?.trim();\n if (trimmedError && APPROVED_STATIC_COPY.has(trimmedError)) return trimmedError;\n\n if (options.code) {\n const mappedByCode = ERROR_CODE_MAP.get(options.code);\n if (mappedByCode) return mappedByCode;\n }\n\n if (trimmedError) {\n const mapped = mappedRawErrorMessage(trimmedError);\n if (mapped) return mapped;\n }\n\n return CLERK_ERROR_COPY[options.fallbackKey || \"genericRetry\"];\n}\n", "import { planningSubmitSx } from \"./planningSubmitSx\";\nimport React, { useState, useRef, useCallback, useEffect, useLayoutEffect, useSyncExternalStore } from \"react\";\nimport {\n Alert,\n Box,\n Stack,\n Typography,\n Menu,\n MenuItem,\n ListItemText,\n ListSubheader,\n Chip,\n Tooltip,\n} from \"@mui/material\";\nimport { alpha } from \"@mui/material/styles\";\nimport { visuallyHidden } from \"@mui/utils\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport {\n ArrowUp,\n Square,\n Check,\n ChevronDown,\n CircleStop,\n ListChecks,\n Paperclip,\n Signal,\n SignalHigh,\n SignalLow,\n SignalMedium,\n SignalZero,\n X,\n type LucideIcon,\n} from \"lucide-react\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { spacing } from \"@/components/theme/tokens/spacing\";\nimport { colors } from \"@/components/theme/tokens/colors\";\nimport { Icon } from \"@/components/icons\";\nimport { ConversationDrafts } from \"./conversationDrafts\";\nimport { DEFAULT_REASONING_EFFORT } from \"./constants\";\nimport { canonicalizeModelConfig, isReasoningEffortAvailable } from \"./modelConfig\";\nimport { useEditor, EditorContent } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport { Markdown } from \"@tiptap/markdown\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport type { AttachedFile, ModelConfig } from \"../../api/queries/agentPrototype.types\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { CLERK_ERROR_COPY } from \"../../utils/clerkErrorCopy\";\nimport { featureEnabled, isClerkAvailable } from \"../../utils/featureFlags\";\n\nconst ACCEPTED_EXTENSIONS = \".docx,.txt,.md,.rtf,.pdf\";\nconst ACCEPTED_SET = new Set(ACCEPTED_EXTENSIONS.split(\",\"));\nconst MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB\n\nfunction hasAcceptedExtension(name: string): boolean {\n const dot = name.lastIndexOf(\".\");\n if (dot === -1) return false;\n return ACCEPTED_SET.has(name.slice(dot).toLowerCase());\n}\n\nfunction readFileAsBase64(file: File): Promise {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result as string;\n const base64 = result.split(\",\")[1] || \"\";\n resolve(base64);\n };\n reader.onerror = () => reject(new Error(`Failed to read ${file.name}`));\n reader.readAsDataURL(file);\n });\n}\n\n// Keep copy for every supported level; model availability controls which options appear.\nconst EFFORT_OPTIONS: Array<{\n label: string;\n value: NonNullable;\n description: string;\n icon: LucideIcon;\n}> = [\n {\n label: \"None\",\n value: \"none\",\n icon: SignalZero,\n description: \"No reasoning, for simple and straightforward requests.\",\n },\n {\n label: \"Low\",\n value: \"low\",\n icon: SignalLow,\n description: \"Light reasoning for short, direct questions.\",\n },\n {\n label: \"Medium\",\n value: \"medium\",\n icon: SignalMedium,\n description: \"Balances speed and depth. Suits most research questions.\",\n },\n {\n label: \"High\",\n value: \"high\",\n icon: SignalHigh,\n description: \"Carefully works through multi-step questions before answering.\",\n },\n {\n label: \"Extra High\",\n value: \"xhigh\",\n icon: Signal,\n description: \"Extended reasoning for complex, open-ended analysis.\",\n },\n {\n label: \"Maximum\",\n value: \"max\",\n icon: Signal,\n description: \"The most reasoning available, for the most demanding questions.\",\n },\n];\n\n// When the button row can't keep its gap between the left and right groups, it\n// turns compact and Draft Plan becomes icon-only. Its label is visually hidden,\n// so it stays the button's accessible name.\nconst DRAFT_PLAN_LABEL_CLASS = \"AgentComposer-draftPlanLabel\";\n\n// Measures the row with Draft Plan labelled and marks it compact if it doesn't fit.\n// Writes to the DOM directly so measuring needs no re-render.\nexport function fitButtonRow(row: HTMLElement) {\n if (!row.clientWidth) return;\n row.removeAttribute(\"data-compact\");\n const [left, right] = Array.from(row.children);\n const gap = parseFloat(getComputedStyle(row).columnGap) || 0;\n const needed = left.getBoundingClientRect().width + gap + right.getBoundingClientRect().width;\n row.toggleAttribute(\"data-compact\", needed > row.clientWidth);\n}\n\nexport const PlanningModeToggle: React.FC<{ selected: boolean; disabled?: boolean; onToggle?: () => void }> = ({\n selected,\n disabled,\n onToggle,\n}) => (\n \n \n }\n onClick={onToggle}\n disabled={disabled}\n aria-pressed={selected}\n sx={{\n px: 1,\n height: 36,\n border: \"1px solid\",\n borderColor: selected ? colors.indigo[100] : \"transparent\",\n backgroundColor: selected ? colors.indigo[50] : \"transparent\",\n \"&:hover\": { backgroundColor: selected ? colors.indigo[100] : \"action.hover\" },\n }}\n >\n Plan\n \n \n \n);\n\ninterface AgentPrototypeInputProps {\n onSend: (message: string, files?: AttachedFile[]) => boolean | \"stopped\" | void | Promise;\n onCancel: () => void;\n allowQueueing?: boolean;\n conversationKey?: string;\n conversationDrafts?: ConversationDrafts;\n restoreDraft?: { id: string; sessionToken?: string; text: string; files?: AttachedFile[] };\n onRestoreDraftConsumed?: (id: string) => void;\n isStreaming: boolean;\n isStopping?: boolean;\n disabled?: boolean;\n placeholder?: string;\n prefill?: string;\n onPrefillConsumed?: () => void;\n modelConfig: ModelConfig;\n onModelConfigChange: (config: ModelConfig) => void;\n planningAvailable?: boolean;\n planningEnabled?: boolean;\n planningActive?: boolean;\n planningModePending?: boolean;\n draftValue?: string;\n onDraftChange?: (value: string) => void;\n onPlanningToggle?: () => void;\n}\n\nconst AgentPrototypeInput: React.FC = ({\n onSend,\n onCancel,\n allowQueueing = false,\n conversationKey = \"composer\",\n conversationDrafts,\n restoreDraft,\n onRestoreDraftConsumed,\n isStreaming,\n isStopping = false,\n disabled = false,\n placeholder,\n prefill = \"\",\n onPrefillConsumed,\n modelConfig,\n onModelConfigChange,\n planningAvailable = false,\n planningEnabled = false,\n planningActive = false,\n planningModePending = false,\n draftValue,\n onDraftChange,\n onPlanningToggle,\n}) => {\n // Locked accounts (disable_generative_ai / incognito_queries) can't run\n // document analysis \u2014 it's an AI feature \u2014 and their Home submit carries only\n // the question text (not files), so don't offer the attach affordance at all.\n // Reuses the existing uploads-disabled gate (hides the button, input + drop).\n const uploadsDisabled = featureEnabled(\"agent_prototype_document_uploads_disabled\") || !isClerkAvailable();\n const effortOptions = EFFORT_OPTIONS.filter((option) => isReasoningEffortAvailable(option.value));\n useEffect(() => {\n if (isStreaming) return;\n const normalized = canonicalizeModelConfig(modelConfig);\n if (modelConfig.reasoning_effort && normalized.reasoning_effort !== modelConfig.reasoning_effort) {\n onModelConfigChange(normalized);\n }\n }, [isStreaming, modelConfig, onModelConfigChange]);\n const [localDrafts] = useState(() => new ConversationDrafts());\n const drafts = conversationDrafts ?? localDrafts;\n const getDraft = useCallback(() => drafts.get(conversationKey), [drafts, conversationKey]);\n const draft = useSyncExternalStore(drafts.subscribe, getDraft);\n const files = draft.files;\n const setFiles = useCallback(\n (update: AttachedFile[] | ((current: AttachedFile[]) => AttachedFile[])) => {\n drafts.update(conversationKey, (current) => ({\n ...current,\n files: typeof update === \"function\" ? update(current.files) : update,\n }));\n },\n [drafts, conversationKey],\n );\n const [fileError, setFileError] = useState(null);\n const [editorEmpty, setEditorEmpty] = useState(true);\n const [submissionPending, setSubmissionPending] = useState(false);\n const submissionPendingRef = useRef(false);\n const [isDragging, setIsDragging] = useState(false);\n const [effortAnchor, setEffortAnchor] = useState(null);\n const fileInputRef = useRef(null);\n const buttonRowRef = useRef(null);\n const effortButtonRef = useRef(null);\n const dragCounter = useRef(0);\n const restoredDraftId = useRef();\n const handleSendRef = useRef<() => void>(() => {});\n const editorRef = useRef | null>(null);\n const resolvedPlaceholder =\n placeholder ??\n (planningEnabled || planningActive\n ? \"Describe what you\u2019re looking for. Bench IQ will ask clarifying questions to draft your prompt.\"\n : \"Ask a question\");\n const placeholderRef = useRef(resolvedPlaceholder);\n placeholderRef.current = resolvedPlaceholder;\n\n const onDraftChangeRef = useRef(onDraftChange);\n onDraftChangeRef.current = onDraftChange;\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n heading: { levels: [1, 2, 3] },\n dropcursor: false,\n }),\n Markdown,\n Placeholder.configure({\n placeholder: () => placeholderRef.current,\n // Show the placeholder even when the editor is set non-editable\n // (during status=\"creating\", when `disabled` is true). Without\n // this, TipTap hides the placeholder while editing is locked,\n // which collapses the empty

    below the container's minHeight\n // and produces a visible height shift the moment streaming\n // starts and the editor becomes editable again.\n showOnlyWhenEditable: false,\n }),\n ],\n content: draft.text,\n contentType: \"markdown\",\n onUpdate: ({ editor: e }) => {\n setEditorEmpty(e.isEmpty);\n drafts.update(conversationKey, (current) => ({ ...current, text: e.getMarkdown() }));\n onDraftChangeRef.current?.(e.getMarkdown());\n },\n editorProps: {\n attributes: {\n class: \"agent-tiptap-editor\",\n },\n handleKeyDown: (_view, event) => {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSendRef.current();\n return true;\n }\n // Shift+Enter: split list item or split block (new paragraph)\n if (event.key === \"Enter\" && event.shiftKey) {\n const ed = editorRef.current;\n if (ed && ed.isActive(\"listItem\")) {\n event.preventDefault();\n // Empty list item \u2192 exit list\n const { $from } = _view.state.selection;\n const listItem = $from.node($from.depth - 1);\n if (listItem && listItem.textContent === \"\") {\n ed.commands.liftListItem(\"listItem\");\n } else {\n ed.commands.splitListItem(\"listItem\");\n }\n return true;\n }\n if (ed) {\n event.preventDefault();\n ed.commands.splitBlock();\n return true;\n }\n }\n return false;\n },\n },\n });\n\n useEffect(() => {\n if (editor && !editor.isDestroyed) {\n editor.view.dispatch(editor.state.tr);\n }\n }, [editor, resolvedPlaceholder]);\n\n // Reconcile only externally changed drafts; ordinary typing keeps its selection.\n useLayoutEffect(() => {\n if (!conversationDrafts || !editor || editor.isDestroyed) return;\n if (editor.getMarkdown() !== draft.text) {\n editor.commands.setContent(draft.text, { contentType: \"markdown\", emitUpdate: false });\n }\n setEditorEmpty(!draft.text.trim());\n }, [conversationDrafts, draft.text, editor]);\n\n const handleSend = useCallback(() => {\n if (!editor || submissionPendingRef.current) return;\n const markdown = editor.getMarkdown().trim();\n if (!markdown || (isStreaming && (!allowQueueing || planningEnabled || planningActive)) || disabled) return;\n const submittedFiles = files;\n submissionPendingRef.current = true;\n setSubmissionPending(true);\n // Capture this submission once while cancellation or sending is in flight.\n let sendResult: Promise;\n try {\n sendResult = Promise.resolve(onSend(markdown, files.length > 0 ? files : undefined));\n } catch (error) {\n sendResult = Promise.reject(error);\n }\n drafts.update(conversationKey, () => ({ text: \"\", files: [] }));\n editor.commands.clearContent(true);\n setFiles([]);\n setFileError(null);\n setEditorEmpty(true);\n editor.commands.focus();\n\n const restoreUnsent = () => {\n if (conversationDrafts) {\n drafts.append(conversationKey, { text: markdown, files: submittedFiles });\n return;\n }\n if (editor.isDestroyed) return;\n const current = editor.isEmpty ? \"\" : editor.getMarkdown().trim();\n editor.commands.setContent([current, markdown].filter(Boolean).join(\"\\n\\n\"), { contentType: \"markdown\" });\n setFiles((currentFiles) => [...currentFiles, ...submittedFiles]);\n setEditorEmpty(false);\n editor.commands.focus();\n };\n void sendResult\n .then((sent) => {\n if (sent === false) restoreUnsent();\n }, restoreUnsent)\n .finally(() => {\n submissionPendingRef.current = false;\n setSubmissionPending(false);\n });\n }, [\n editor,\n isStreaming,\n allowQueueing,\n planningEnabled,\n planningActive,\n disabled,\n onSend,\n files,\n drafts,\n conversationKey,\n conversationDrafts,\n setFiles,\n ]);\n\n useEffect(() => {\n handleSendRef.current = handleSend;\n }, [handleSend]);\n\n useEffect(() => {\n editorRef.current = editor;\n }, [editor]);\n\n useEffect(() => {\n if (editor && draftValue !== undefined && editor.getMarkdown() !== draftValue) {\n drafts.update(conversationKey, (current) => ({ ...current, text: draftValue }));\n editor.commands.setContent(draftValue, { contentType: \"markdown\", emitUpdate: false });\n setEditorEmpty(editor.isEmpty);\n }\n }, [editor, draftValue, drafts, conversationKey]);\n\n // Prefill\n useEffect(() => {\n if (prefill && editor) {\n drafts.update(conversationKey, (current) => ({ ...current, text: prefill }));\n editor.commands.setContent(prefill, { contentType: \"markdown\" });\n setEditorEmpty(false);\n onPrefillConsumed?.();\n setTimeout(() => editor.commands.focus(\"start\"), 0);\n }\n }, [prefill, editor, onPrefillConsumed, drafts, conversationKey]);\n\n // A cancelled queue entry or fork draft must not overwrite work already typed.\n useEffect(() => {\n if (!restoreDraft || !editor || restoredDraftId.current === restoreDraft.id) return;\n if (restoreDraft.sessionToken && restoreDraft.sessionToken !== conversationKey) return;\n restoredDraftId.current = restoreDraft.id;\n if (conversationDrafts) {\n drafts.restore(conversationKey, restoreDraft.id, { text: restoreDraft.text, files: restoreDraft.files ?? [] });\n onRestoreDraftConsumed?.(restoreDraft.id);\n editor.commands.focus(\"end\");\n return;\n }\n const current = editor.getMarkdown().trim();\n const text = [current, restoreDraft.text].filter(Boolean).join(\"\\n\\n\");\n editor.commands.setContent(text, { contentType: \"markdown\" });\n setEditorEmpty(!text.trim());\n setFiles((currentFiles) => [...currentFiles, ...(restoreDraft.files ?? [])]);\n editor.commands.focus(\"end\");\n onRestoreDraftConsumed?.(restoreDraft.id);\n }, [restoreDraft, editor, onRestoreDraftConsumed, conversationDrafts, drafts, conversationKey, setFiles]);\n\n // Disabled state\n useEffect(() => {\n if (editor) {\n // Editability is not a text edit. Its default update event can overwrite\n // a just-restored draft before the editor has reconciled that content.\n editor.setEditable(!disabled, false);\n }\n }, [editor, disabled]);\n\n const handleFileSelect = useCallback(\n async (e: React.ChangeEvent) => {\n const selected = e.target.files;\n if (!selected) return;\n\n const newFiles: AttachedFile[] = [];\n let nextFileError: string | null = null;\n for (let i = 0; i < selected.length; i++) {\n const file = selected[i];\n if (file.size > MAX_FILE_SIZE) {\n nextFileError ||= CLERK_ERROR_COPY.fileTooLarge;\n continue;\n }\n try {\n const data = await readFileAsBase64(file);\n newFiles.push({ name: file.name, type: file.type, size: file.size, data });\n } catch {\n nextFileError ||= CLERK_ERROR_COPY.fileUnreadable;\n }\n }\n\n setFiles((prev) => [...prev, ...newFiles]);\n setFileError(nextFileError);\n if (fileInputRef.current) {\n fileInputRef.current.value = \"\";\n }\n },\n [setFiles],\n );\n\n const removeFile = useCallback(\n (index: number) => {\n setFiles((prev) => prev.filter((_, i) => i !== index));\n },\n [setFiles],\n );\n\n const handleDragEnter = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter.current++;\n if (e.dataTransfer.types.includes(\"Files\")) {\n setIsDragging(true);\n }\n }, []);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter.current--;\n if (dragCounter.current === 0) {\n setIsDragging(false);\n }\n }, []);\n\n const handleDrop = useCallback(\n async (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter.current = 0;\n setIsDragging(false);\n\n const dropped = e.dataTransfer.files;\n if (!dropped || dropped.length === 0) return;\n\n const newFiles: AttachedFile[] = [];\n let nextFileError: string | null = null;\n for (let i = 0; i < dropped.length; i++) {\n const file = dropped[i];\n if (!hasAcceptedExtension(file.name)) {\n nextFileError ||= CLERK_ERROR_COPY.unsupportedFileType;\n continue;\n }\n if (file.size > MAX_FILE_SIZE) {\n nextFileError ||= CLERK_ERROR_COPY.fileTooLarge;\n continue;\n }\n try {\n const data = await readFileAsBase64(file);\n newFiles.push({ name: file.name, type: file.type, size: file.size, data });\n } catch {\n nextFileError ||= CLERK_ERROR_COPY.fileUnreadable;\n }\n }\n\n if (newFiles.length > 0) {\n setFiles((prev) => [...prev, ...newFiles]);\n }\n setFileError(nextFileError);\n },\n [setFiles],\n );\n\n const effortLabel =\n (isStreaming ? EFFORT_OPTIONS : effortOptions).find(\n (o) => o.value === (modelConfig.reasoning_effort || DEFAULT_REASONING_EFFORT),\n )?.label || \"Medium\";\n\n // Refit when the row resizes or its labels change. Only the row is observed:\n // fitting resizes the button groups but never the (non-wrapping) row, so the\n // observer can't trip the browser's \"ResizeObserver loop\" error.\n useLayoutEffect(() => {\n const row = buttonRowRef.current;\n if (!row) return;\n fitButtonRow(row);\n const observer = new ResizeObserver(() => fitButtonRow(row));\n observer.observe(row);\n return () => observer.disconnect();\n }, [effortLabel, planningAvailable, planningEnabled, planningActive, isStreaming, isStopping, allowQueueing]);\n\n return (\n \n {/* Drop zone overlay */}\n {isDragging && (\n ({\n position: \"absolute\",\n inset: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: alpha(theme.palette.background.paper, 0.95),\n border: `2px dashed ${theme.palette.primary.main}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n pointerEvents: \"none\",\n })}\n >\n Drop files here\n \n )}\n\n {/* SearchCard-style wrapper */}\n ({\n border: `1px solid ${planningAvailable ? theme.palette.divider : theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n p: `${planningAvailable ? spacing[4] - 1 : spacing[4]}px`,\n ...(planningAvailable ? { \"& .MuiButton-sizeMedium\": { height: 36 } } : {}),\n backgroundColor: \"common.white\",\n })}\n >\n {/* TipTap editor */}\n ({\n \"& .ProseMirror\": {\n ...theme.typography.body1,\n ...(planningAvailable ? { lineHeight: \"24px\", letterSpacing: \"0.15px\" } : {}),\n outline: \"none\",\n minHeight: 56,\n boxSizing: \"border-box\",\n // Figma's 56px BenchTextField insets its 24px text line by\n // 16px vertically and 12px horizontally, inside the card padding.\n // Apply this to the editor so typed text and its placeholder align.\n padding: planningAvailable ? `${spacing[4]}px ${spacing[3]}px` : spacing[0],\n maxHeight: \"calc(1.6em * 6 + 16px)\",\n overflowY: \"auto\",\n \"& p\": { margin: 0 },\n \"& p + p\": { marginTop: \"0.25em\" },\n \"& h1, & h2, & h3\": {\n margin: \"0.25em 0\",\n fontSize: \"0.95rem\",\n fontWeight: 600,\n },\n \"& ul, & ol\": {\n paddingLeft: \"1.5em\",\n margin: \"0.25em 0\",\n },\n \"& blockquote\": {\n borderLeft: `3px solid ${alpha(theme.palette.primary.main, 0.3)}`,\n paddingLeft: \"0.75em\",\n margin: \"0.25em 0\",\n color: \"text.secondary\",\n },\n \"& code\": {\n // TODO Phase 2 review: non-text rgba(0,0,0,X) background \u2014 leave hardcoded per C5 / chunk 1.5 review\n backgroundColor: \"rgba(0, 0, 0, 0.06)\",\n borderRadius: \"3px\",\n padding: \"0.1em 0.3em\",\n fontSize: \"0.85em\",\n fontFamily: \"monospace\",\n },\n \"& pre\": {\n // TODO Phase 2 review: non-text rgba(0,0,0,X) background \u2014 leave hardcoded per C5 / chunk 1.5 review\n backgroundColor: \"rgba(0, 0, 0, 0.04)\",\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n padding: \"0.5em\",\n margin: \"0.25em 0\",\n \"& code\": {\n backgroundColor: \"transparent\",\n padding: 0,\n },\n },\n },\n // Contain the placeholder float so a wrapped placeholder grows the\n // editor instead of overflowing it into a scrollbar on narrow screens.\n \"& .ProseMirror p.is-editor-empty:first-of-type\": { display: \"flow-root\" },\n \"& .ProseMirror p.is-editor-empty:first-of-type::before\": {\n ...theme.typography.body1,\n ...(planningAvailable ? { lineHeight: \"24px\", letterSpacing: \"0.15px\" } : {}),\n color: theme.palette.text.tertiary,\n content: \"attr(data-placeholder)\",\n float: \"left\",\n // Full-width text with a zero-width margin box, so the caret\n // still sits on the placeholder's first line.\n width: \"100%\",\n marginRight: \"-100%\",\n pointerEvents: \"none\",\n },\n })}\n >\n \n \n\n {/* Attached files chips */}\n {files.length > 0 && (\n \n {files.map((file, i) => (\n removeFile(i)}\n deleteIcon={}\n sx={(theme) => ({\n height: 24,\n fontSize: \"0.75rem\",\n backgroundColor: theme.palette.primary._states.selected,\n color: \"primary.main\",\n \"& .MuiChip-deleteIcon\": {\n color: alpha(theme.palette.primary.main, 0.5),\n \"&:hover\": { color: \"primary.main\" },\n },\n })}\n />\n ))}\n \n )}\n\n {fileError && (\n setFileError(null)}>\n {fileError}\n \n )}\n\n {/* Hidden file input */}\n {!uploadsDisabled && (\n \n )}\n\n {/* Button row: Add files pinned left, effort + Send pinned right. It never wraps, so\n collapsing labels can't change its height mid-ResizeObserver callback. */}\n \n \n {!uploadsDisabled && (\n 0 ? `Add Files (${files.length} attached)` : \"Add Files\"}\n onClick={() => fileInputRef.current?.click()}\n disabled={(isStreaming && (!allowQueueing || planningEnabled || planningActive)) || disabled}\n />\n )}\n\n {planningAvailable && (\n \n )}\n \n\n \n }\n onClick={() => setEffortAnchor(effortButtonRef.current)}\n disabled={isStreaming || disabled}\n sx={{ whiteSpace: \"nowrap\" }}\n >\n {effortLabel}\n \n\n setEffortAnchor(null)}\n anchorOrigin={{ vertical: \"bottom\", horizontal: \"right\" }}\n transformOrigin={{ vertical: \"top\", horizontal: \"right\" }}\n sx={{ mt: `${spacing[1]}px` }}\n slotProps={{\n paper: {\n sx: (theme) => ({\n width: 286,\n border: `1px solid ${theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n backgroundColor: \"background.paper\",\n }),\n },\n }}\n MenuListProps={{\n \"aria-label\": \"Reasoning effort\",\n sx: {\n px: `${spacing[3]}px`,\n py: `${spacing[2]}px`,\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${spacing[1]}px`,\n },\n }}\n >\n \n \n Reasoning effort\n \n \n {effortOptions.map((option) => {\n const selected =\n modelConfig.reasoning_effort === option.value ||\n (!modelConfig.reasoning_effort && option.value === DEFAULT_REASONING_EFFORT);\n return (\n ({\n px: `${spacing[3]}px`,\n py: `${spacing[2]}px`,\n minHeight: 0,\n alignItems: \"center\",\n gap: `${spacing[3]}px`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n \"&.Mui-selected\": { bgcolor: \"transparent\" },\n \"&:hover, &.Mui-selected:hover, &:active, &.Mui-focusVisible, &.Mui-selected.Mui-focusVisible\": {\n bgcolor: \"primary._states.hover\",\n },\n \"&.Mui-focusVisible\": { outline: \"1px solid\", outlineColor: \"primary.main\", outlineOffset: -1 },\n })}\n selected={selected}\n onClick={() => {\n const previousReasoningEffort = modelConfig.reasoning_effort || DEFAULT_REASONING_EFFORT;\n if (previousReasoningEffort !== option.value) {\n void recordUserEvent({\n event_name: \"select_clerk_reasoning_effort\",\n event_properties: {\n previous_reasoning_effort: previousReasoningEffort,\n selected_reasoning_effort: option.value,\n model: modelConfig.model,\n },\n });\n }\n onModelConfigChange({ ...modelConfig, reasoning_effort: option.value });\n setEffortAnchor(null);\n }}\n >\n \n \n \n ({\n color: \"text.primary\",\n fontSize: theme.typography.caption.fontSize,\n fontWeight: theme.typography.button.fontWeight,\n lineHeight: theme.typography.body2.fontSize,\n letterSpacing: \"0.17px\",\n }),\n }}\n secondaryTypographyProps={{\n variant: \"caption\",\n color: \"text.secondary\",\n sx: { whiteSpace: \"normal\" },\n }}\n />\n ({\n display: \"flex\",\n flexShrink: 0,\n visibility: selected ? \"visible\" : \"hidden\",\n color: colors.indigo[600],\n \"& svg\": { width: theme.typography.body2.fontSize, height: theme.typography.body2.fontSize },\n })}\n >\n \n \n \n );\n })}\n ({\n mx: `-${spacing[3]}px`,\n mb: `-${spacing[2]}px`,\n mt: `${spacing[1]}px`,\n px: `${spacing[4]}px`,\n py: `${spacing[2]}px`,\n borderTop: `1px solid ${theme.border.default}`,\n bgcolor: \"background.paper\",\n lineHeight: \"normal\",\n })}\n >\n \n Higher levels take longer to respond.\n \n \n \n\n {allowQueueing && !planningEnabled && !planningActive ? (\n isStreaming && editorEmpty && !submissionPending ? (\n \n ) : (\n ({\n width: 36,\n height: 36,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n bgcolor: \"primary.main\",\n \"&&[data-biq-type]\": { color: \"primary.contrastText\" },\n \"&:hover\": { bgcolor: \"primary.dark\" },\n \"&&[data-biq-type].Mui-disabled\": {\n bgcolor: \"action.disabledBackground\",\n color: \"primary.contrastText\",\n },\n })}\n />\n )\n ) : isStreaming ? (\n \n {isStopping ? \"Stopping\u2026\" : \"Stop\"}\n \n ) : planningEnabled ? (\n \n Draft Plan\n \n ) : (\n \n )}\n \n \n \n\n {/* Hint */}\n \n Shift + Enter for new line\n \n \n );\n};\n\nexport default AgentPrototypeInput;\n", "import React from \"react\";\nimport { MessageSquare as FeedbackOutlinedIcon } from \"lucide-react\";\nimport DialogActions from \"@mui/material/DialogActions\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\n\nexport default function DialogDefaultActions({ onClose }: { onClose: () => void }) {\n return (\n \n \n Share feedback\n \n \n OK\n \n \n );\n}\n", "import React from \"react\";\nimport Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\n\nexport default function DialogDisclaimer() {\n return (\n \n \n AI can make mistakes. Confirm key data by referencing raw transcripts.\n \n \n );\n}\n", "import { layout } from \"../components/theme/tokens/layout\";\n\n// LocalStorage keys with expiry configuration\nexport const LOCAL_STORAGE_KEYS = {\n CLERK_NOTIFICATION_DISMISSED: {\n key: \"clerk_notif_dismissed\",\n // No expiryDays \u2014 dismissal is permanent\n },\n} as const;\n\n// Layout constants \u2014 re-exported from tokens for backward compatibility\n\nexport const PAGE_CONTENT_MAX_WIDTH = layout.pageContentMaxWidth;\nexport const MODAL_WIDTH = layout.modalWidth;\nexport const RESULTS_PANEL_MIN_WIDTH = layout.resultsPanelMinWidth;\nexport const RESULTS_CARD_MAX_WIDTH = layout.resultsCardMaxWidth;\nexport const RESULTS_CARD_MIN_WIDTH = layout.resultsCardMinWidth;\n", "export function canRequestJudge(): boolean {\n return window.currentAccount?.billing_type !== \"educational\";\n}\n", "import React from \"react\";\nimport Dialog from \"@mui/material/Dialog\";\nimport { X as CloseIcon } from \"lucide-react\";\nimport Typography from \"@mui/material/Typography\";\nimport Link from \"@mui/material/Link\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport DialogDefaultActions from \"../atoms/DialogDefaultActions\";\nimport DialogDisclaimer from \"../atoms/DialogDisclaimer\";\nimport { Stack } from \"@mui/material\";\nimport { MODAL_WIDTH } from \"../../utils/constants\";\nimport { canRequestJudge } from \"../../utils/canRequestJudge\";\n\ninterface DataCoverageModalProps {\n open: boolean;\n onClose: () => void;\n onRequestJudge?: () => void;\n}\n\nconst DataCoverageModal: React.FC = ({ open, onClose, onRequestJudge }) => {\n const requestJudgeAvailable = canRequestJudge();\n\n return (\n ({ borderRadius: `${theme.tokens.radii.smallRadius}px`, maxWidth: MODAL_WIDTH }) }}\n >\n \n \n \n Data Coverage\n \n \n \n \n Bench IQ's database contains published Chapter 11 and Chapter 15 hearing transcripts from 2014 for active\n judges in DE, SDNY, SDTX, NJ, EDMO, NDGA, and more.\n \n {requestJudgeAvailable && (\n \n Don't see a judge?{\" \"}\n \n Request them here.\n {\" \"}\n We'll add their data within 24\u201348 hours.\n \n )}\n \n \n \n \n );\n};\n\nexport default DataCoverageModal;\n", "import React, { forwardRef, type ReactNode } from \"react\";\nimport {\n TextField as MuiTextField,\n type TextFieldProps as MuiTextFieldProps,\n InputAdornment,\n Stack,\n Typography,\n FormHelperText,\n} from \"@mui/material\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { renderLucideOrNode } from \"@/components/icons\";\nimport type { SxProps, Theme } from \"@mui/material/styles\";\n\n/**\n * Branded text input. Wraps MUI `TextField` (outlined variant) with the\n * Phase 2 brand patterns:\n *\n * - Label is rendered ABOVE the input as a separate Typography (NOT MUI's\n * floating label).\n * - Helper text uses MUI's helperText with error coloring.\n * - startIcon / endIcon accept lucide components directly or pre-rendered\n * ReactNodes (icon adornments size to sm / 16px by default).\n *\n * If a callsite has special input behavior (smart-quotes, ghost text,\n * autocomplete), keep using the specialized wrapper for now \u2014 those can\n * migrate to compose BIQInputField in a follow-up.\n */\nexport interface BIQInputFieldProps extends Omit {\n /** Label rendered above the input (not floating). */\n label?: ReactNode;\n /** Helper / error text rendered below the input. */\n helper?: ReactNode;\n /** Icon at the start of the input. Lucide component auto-wraps in . */\n startIcon?: LucideIcon | ReactNode;\n /** Icon at the end of the input. Lucide component auto-wraps in . */\n endIcon?: LucideIcon | ReactNode;\n /** Pass through to MUI's inputProps (DOM input element attributes). */\n inputProps?: MuiTextFieldProps[\"inputProps\"];\n /** Pass through to MUI's InputProps (the InputBase wrapper props). */\n InputProps?: MuiTextFieldProps[\"InputProps\"];\n /** Optional styling for the wrapper and separate label. */\n containerSx?: SxProps;\n labelSx?: SxProps;\n}\n\nexport const BIQInputField = forwardRef(\n ({ label, helper, startIcon, endIcon, error, InputProps, inputProps, containerSx, labelSx, id, ...rest }, ref) => {\n const startAdornment = startIcon ? (\n {renderLucideOrNode(startIcon, \"sm\")}\n ) : undefined;\n const endAdornment = endIcon ? (\n {renderLucideOrNode(endIcon, \"sm\")}\n ) : undefined;\n\n return (\n \n {label && (\n \n {label}\n \n )}\n \n {helper && (\n \n {helper}\n \n )}\n \n );\n },\n);\n\nBIQInputField.displayName = \"BIQInputField\";\n", "import { fetchHelper } from \"../utils/fetchHelpers\";\n\ninterface JudgeRequest {\n judge_name: string;\n additional_feedback?: string;\n}\n\nexport const sendJudgeRequest = async (judgeRequest: JudgeRequest): Promise => {\n const response = await fetchHelper(\"/api/judge-requests\", {\n method: \"POST\",\n body: { judge_request: judgeRequest },\n });\n\n if (!response.ok) {\n throw new Error(\"Failed to submit judge request\");\n }\n\n return response;\n};\n", "import { X } from \"lucide-react\";\nimport { Alert, Dialog, Stack, Typography } from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { BIQInputField } from \"@/components/atoms/BIQInputField\";\nimport React, { useEffect, useState } from \"react\";\nimport { sendJudgeRequest } from \"../../api/judgeRequests\";\nimport { featureEnabled } from \"../../utils/featureFlags\";\nimport { MODAL_WIDTH } from \"../../utils/constants\";\n\ninterface RequestJudgeModalProps {\n open: boolean;\n onClose: () => void;\n query: string;\n onSubmit?: (judgeName: string) => void;\n}\n\n/**\n * A modal that allows the user to request support for a judge.\n */\nexport function RequestJudgeModal(props: RequestJudgeModalProps) {\n const [judgeName, setJudgeName] = useState(\"\");\n const [feedback, setFeedback] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [error, setError] = useState();\n\n /**\n * Submits the judge request.\n */\n async function submit() {\n const trimmedJudgeName = judgeName.trim();\n const additionalFeedback = feedback.trim() || undefined;\n\n setError(undefined);\n if (!trimmedJudgeName) {\n setError(\"Please enter a judge name.\");\n return;\n }\n\n setIsSubmitting(true);\n\n try {\n if (featureEnabled(\"incognito_queries\")) {\n const SUPPORT_EMAIL = \"support@benchiq.com\";\n const CC_EMAILS = [\"maxim@benchiq.com\", \"jeffrey@benchiq.com\", \"alex.hevia@benchiq.com\"];\n const params = new URLSearchParams({\n cc: CC_EMAILS.join(\",\"),\n subject: \"Request to add judge\",\n body: `To whom it may concern:\n\nI'd like to request that you add the judge: ${trimmedJudgeName}\n\n${additionalFeedback ? `Additional feedback: ${additionalFeedback}\\n\\n` : \"\"}Best regards,`,\n });\n window.open(`mailto:${SUPPORT_EMAIL}?${params.toString()}`);\n } else {\n await sendJudgeRequest({\n judge_name: trimmedJudgeName,\n additional_feedback: additionalFeedback,\n });\n }\n props.onSubmit?.(trimmedJudgeName);\n props.onClose();\n setIsSubmitting(false);\n } catch (e) {\n console.error(\"Failed to submit judge request:\", e);\n setError(\"Failed to submit your request. Please try again.\");\n setIsSubmitting(false);\n }\n }\n\n /**\n * Populate the judge name field using the current query and clear\n * other fields when the query changes.\n */\n useEffect(() => {\n if (props.query) {\n setJudgeName(props.query);\n setFeedback(\"\");\n setError(undefined);\n }\n }, [props.query]);\n\n return (\n ({\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n width: MODAL_WIDTH,\n }),\n }}\n >\n \n \n Request judge\n \n \n\n {error && (\n setError(undefined)}>\n {error}\n \n )}\n\n \n Don't see a judge in Bench IQ? Request them here. We'll add their data within 24\u201348 hours.\n \n\n \n setJudgeName(e.target.value)}\n fullWidth\n />\n\n setFeedback(e.target.value)}\n minRows={3}\n />\n \n\n \n \n Cancel\n \n \n Submit\n \n \n \n \n );\n}\n", "import React, { createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport { fetchHelper } from \"@/utils/fetchHelpers\";\nimport { CLERK_ERROR_COPY } from \"@/utils/clerkErrorCopy\";\n\nconst STORAGE_KEY_PREFIX = \"creditActiveMatter\";\nexport const CLIENT_MATTER_IDLE_TIMEOUT_MS = 30 * 60 * 1000;\nconst ACTIVITY_PERSIST_THROTTLE_MS = 30 * 1000;\n\ninterface StoredMatter {\n code: string;\n lastActivityAt: number;\n}\n\ntype PromptMode = \"add\" | \"confirm_agent\" | \"update_search\" | \"expired\";\n\ninterface PromptState {\n mode: PromptMode;\n initialCode: string;\n lockedMatterCode?: string;\n resolve: (matterCode: string | null) => void;\n}\n\ninterface EnsureMatterOptions {\n confirm?: boolean;\n mode?: Exclude;\n lockedMatterCode?: string;\n promptOnExpired?: boolean;\n}\n\ninterface LockedAgentMatter {\n matterCode: string;\n startNewSession: () => void;\n}\n\ninterface ClientMatterContextValue {\n activeMatterCode: string | null;\n expired: boolean;\n prompt: PromptState | null;\n lockedAgentMatter: LockedAgentMatter | null;\n setActiveMatter: (matterCode: string) => Promise;\n clearActiveMatter: () => void;\n ensureMatter: (options?: EnsureMatterOptions) => Promise;\n isMatterExpired: () => boolean;\n markCreditActivity: () => void;\n resolvePrompt: (matterCode: string | null) => void;\n continueExpiredMatter: (matterCode: string) => Promise;\n setLockedAgentMatter: (lockedMatter: LockedAgentMatter | null) => void;\n}\n\nconst ClientMatterContext = createContext(null);\n\nexport const getClientMatterStorageKey = () =>\n `${STORAGE_KEY_PREFIX}:${window.currentAccount?.id || \"unknown\"}:${window.currentUser?.id || \"unknown\"}`;\n\nconst readStoredMatter = (): StoredMatter | null => {\n try {\n const parsed = JSON.parse(\n window.localStorage.getItem(getClientMatterStorageKey()) || \"null\",\n ) as Partial | null;\n if (!parsed || typeof parsed.code !== \"string\" || typeof parsed.lastActivityAt !== \"number\") return null;\n return { code: parsed.code, lastActivityAt: parsed.lastActivityAt };\n } catch {\n return null;\n }\n};\n\nexport const getStoredActiveMatterCode = (): string | null => readStoredMatter()?.code || null;\n\nconst writeStoredMatter = (matter: StoredMatter | null) => {\n const storageKey = getClientMatterStorageKey();\n if (matter) {\n window.localStorage.setItem(storageKey, JSON.stringify(matter));\n } else {\n window.localStorage.removeItem(storageKey);\n }\n};\n\nclass MatterValidationError extends Error {}\n\nconst validateMatter = async (matterCode: string): Promise => {\n try {\n const response = await fetchHelper(\"/api/client-matter-codes/validate\", {\n method: \"POST\",\n body: { matter_code: matterCode },\n });\n const payload = await response.json();\n if (!response.ok) {\n throw new MatterValidationError(payload.error || \"Enter a valid matter number.\");\n }\n return payload.matter_code;\n } catch (cause) {\n if (cause instanceof MatterValidationError) throw cause;\n throw new MatterValidationError(CLERK_ERROR_COPY.matterValidationUnavailable);\n }\n};\n\nexport const ClientMatterProvider = ({ children }: { children: ReactNode }) => {\n const initial = useMemo(readStoredMatter, []);\n const [storedMatter, setStoredMatter] = useState(initial);\n const [expired, setExpired] = useState(\n Boolean(initial && Date.now() - initial.lastActivityAt >= CLIENT_MATTER_IDLE_TIMEOUT_MS),\n );\n const [prompt, setPrompt] = useState(null);\n const [lockedAgentMatter, setLockedAgentMatter] = useState(null);\n const storedMatterRef = useRef(storedMatter);\n const expiredRef = useRef(expired);\n const lastObservedActivityAtRef = useRef(initial?.lastActivityAt || 0);\n const lastPersistedActivityAtRef = useRef(initial?.lastActivityAt || 0);\n const promptPendingRef = useRef(false);\n const pendingPromptResolveRef = useRef<((matterCode: string | null) => void) | null>(null);\n\n useEffect(() => {\n storedMatterRef.current = storedMatter;\n }, [storedMatter]);\n useEffect(() => {\n expiredRef.current = expired;\n }, [expired]);\n\n const syncStoredMatter = useCallback((matter: StoredMatter | null) => {\n storedMatterRef.current = matter;\n lastPersistedActivityAtRef.current = matter?.lastActivityAt || 0;\n setStoredMatter(matter);\n writeStoredMatter(matter);\n }, []);\n\n const checkExpiration = useCallback(() => {\n const matter = storedMatterRef.current;\n const lastActivityAt = lastObservedActivityAtRef.current || matter?.lastActivityAt;\n if (matter && lastActivityAt && Date.now() - lastActivityAt >= CLIENT_MATTER_IDLE_TIMEOUT_MS) {\n expiredRef.current = true;\n setExpired(true);\n return true;\n }\n return false;\n }, []);\n\n const isMatterExpired = useCallback(() => expiredRef.current || checkExpiration(), [checkExpiration]);\n\n const markCreditActivity = useCallback(() => {\n const matter = storedMatterRef.current;\n if (!matter || expiredRef.current) return;\n\n const now = Date.now();\n const lastActivityAt = lastObservedActivityAtRef.current || matter.lastActivityAt;\n if (now - lastActivityAt >= CLIENT_MATTER_IDLE_TIMEOUT_MS) {\n expiredRef.current = true;\n setExpired(true);\n return;\n }\n\n lastObservedActivityAtRef.current = now;\n if (now - lastPersistedActivityAtRef.current >= ACTIVITY_PERSIST_THROTTLE_MS) {\n syncStoredMatter({ ...matter, lastActivityAt: now });\n }\n }, [syncStoredMatter]);\n\n const persistLatestActivity = useCallback(() => {\n const matter = storedMatterRef.current;\n const lastActivityAt = lastObservedActivityAtRef.current;\n if (!matter || expiredRef.current || lastActivityAt <= matter.lastActivityAt) return;\n\n syncStoredMatter({ ...matter, lastActivityAt });\n }, [syncStoredMatter]);\n\n useEffect(() => {\n const storage = (event: StorageEvent) => {\n if (event.key !== getClientMatterStorageKey()) return;\n const next = readStoredMatter();\n storedMatterRef.current = next;\n lastObservedActivityAtRef.current = next?.lastActivityAt || 0;\n lastPersistedActivityAtRef.current = next?.lastActivityAt || 0;\n setStoredMatter(next);\n const nextExpired = Boolean(next && Date.now() - next.lastActivityAt >= CLIENT_MATTER_IDLE_TIMEOUT_MS);\n expiredRef.current = nextExpired;\n setExpired(nextExpired);\n };\n const resumeActivity = () => {\n if (!checkExpiration()) markCreditActivity();\n };\n const visibility = () => {\n if (document.visibilityState === \"visible\") resumeActivity();\n else persistLatestActivity();\n };\n const interval = window.setInterval(checkExpiration, 5_000);\n checkExpiration();\n window.addEventListener(\"pointerdown\", markCreditActivity);\n window.addEventListener(\"keydown\", markCreditActivity);\n window.addEventListener(\"scroll\", markCreditActivity, { passive: true });\n window.addEventListener(\"touchstart\", markCreditActivity, { passive: true });\n window.addEventListener(\"focus\", resumeActivity);\n window.addEventListener(\"pagehide\", persistLatestActivity);\n window.addEventListener(\"storage\", storage);\n document.addEventListener(\"visibilitychange\", visibility);\n return () => {\n window.clearInterval(interval);\n window.removeEventListener(\"pointerdown\", markCreditActivity);\n window.removeEventListener(\"keydown\", markCreditActivity);\n window.removeEventListener(\"scroll\", markCreditActivity);\n window.removeEventListener(\"touchstart\", markCreditActivity);\n window.removeEventListener(\"focus\", resumeActivity);\n window.removeEventListener(\"pagehide\", persistLatestActivity);\n window.removeEventListener(\"storage\", storage);\n document.removeEventListener(\"visibilitychange\", visibility);\n };\n }, [checkExpiration, markCreditActivity, persistLatestActivity]);\n\n const setActiveMatter = useCallback(\n async (matterCode: string) => {\n const normalized = await validateMatter(matterCode);\n const now = Date.now();\n lastObservedActivityAtRef.current = now;\n syncStoredMatter({ code: normalized, lastActivityAt: now });\n expiredRef.current = false;\n setExpired(false);\n return normalized;\n },\n [syncStoredMatter],\n );\n\n const clearActiveMatter = useCallback(() => {\n syncStoredMatter(null);\n lastObservedActivityAtRef.current = 0;\n expiredRef.current = false;\n setExpired(false);\n }, [syncStoredMatter]);\n\n const openPrompt = useCallback((state: Omit) => {\n if (promptPendingRef.current) return Promise.resolve(null);\n\n promptPendingRef.current = true;\n return new Promise((resolve) => {\n const finish = (matterCode: string | null) => {\n promptPendingRef.current = false;\n pendingPromptResolveRef.current = null;\n resolve(matterCode);\n };\n pendingPromptResolveRef.current = finish;\n setPrompt({ ...state, resolve: finish });\n });\n }, []);\n\n useEffect(\n () => () => {\n pendingPromptResolveRef.current?.(null);\n },\n [],\n );\n\n const ensureMatter = useCallback(\n ({\n confirm = false,\n mode = \"update_search\",\n lockedMatterCode,\n promptOnExpired = true,\n }: EnsureMatterOptions = {}) => {\n const active = storedMatterRef.current?.code || null;\n if (isMatterExpired() && promptOnExpired) {\n return openPrompt({\n mode: \"expired\",\n initialCode: lockedMatterCode || active || \"\",\n lockedMatterCode,\n });\n }\n if (lockedMatterCode) return Promise.resolve(lockedMatterCode);\n if (active && !confirm) return Promise.resolve(active);\n\n return openPrompt({ mode: active ? mode : \"add\", initialCode: active || \"\" });\n },\n [isMatterExpired, openPrompt],\n );\n\n const resolvePrompt = useCallback((matterCode: string | null) => {\n setPrompt((current) => {\n current?.resolve(matterCode);\n return null;\n });\n }, []);\n\n const continueExpiredMatter = useCallback(\n async (matterCode: string) => {\n const normalized = matterCode.trim();\n if (!normalized) throw new Error(\"Enter a valid matter number.\");\n\n const now = Date.now();\n lastObservedActivityAtRef.current = now;\n syncStoredMatter({ code: normalized, lastActivityAt: now });\n expiredRef.current = false;\n setExpired(false);\n return normalized;\n },\n [syncStoredMatter],\n );\n\n const value = useMemo(\n () => ({\n activeMatterCode: storedMatter?.code || null,\n expired,\n prompt,\n lockedAgentMatter,\n setActiveMatter,\n clearActiveMatter,\n ensureMatter,\n isMatterExpired,\n markCreditActivity,\n resolvePrompt,\n continueExpiredMatter,\n setLockedAgentMatter,\n }),\n [\n storedMatter,\n expired,\n prompt,\n lockedAgentMatter,\n setActiveMatter,\n clearActiveMatter,\n ensureMatter,\n isMatterExpired,\n markCreditActivity,\n resolvePrompt,\n continueExpiredMatter,\n setLockedAgentMatter,\n ],\n );\n\n return {children};\n};\n\nexport const useClientMatter = () => {\n const context = useContext(ClientMatterContext);\n if (!context) throw new Error(\"useClientMatter must be used inside ClientMatterProvider\");\n return context;\n};\n\nexport const useOptionalClientMatter = () => useContext(ClientMatterContext);\n", "import { Gavel, Landmark, Search, Brain, UserSearch, FileSearch, FileText } from \"lucide-react\";\nimport type { UsecaseCardItem } from \"../atoms/UsecaseCard\";\nimport { colors } from \"../theme/tokens/colors\";\n\nexport const DEFAULT_EXAMPLE_PROMPTS: UsecaseCardItem[] = [\n {\n label: \"Judge Insight\",\n icon: Gavel,\n iconColor: colors.teal[700],\n iconBgColor: colors.teal[50],\n description: \"Review transcripts from similar cases, get a research memo and a redlined version of your filing.\",\n prompt: `I'll attach a draft filing. Review all available relevant transcripts from **[JUDGE NAME]** and provide:\\n\\n1. A research memo with insights from similar cases before this judge. Prioritize insights that are both unpredictable \u2014 patterns I, an attorney, wouldn't anticipate from the rules or general experience alone \u2014 and actionable enough to change how I'd frame my filing, what arguments I'd lead with, or whether I'd file at all. If nothing rises to that bar, say so.\\n\\n2. A redlined version of my filing with your suggested changes and comments explaining each.`,\n },\n {\n label: \"Judge Personality\",\n icon: Brain,\n iconColor: colors.lime[700],\n iconBgColor: colors.lime[50],\n description: \"MBTI & Enneagram assessment with advice on communication style and courtroom approach.\",\n prompt: `Build a behavioral profile of **[JUDGE NAME]**.`,\n },\n {\n label: \"Attorney Insights\",\n icon: UserSearch,\n iconColor: colors.cyan[700],\n iconBgColor: colors.cyan[50],\n description: \"Evaluate courtroom strengths, weaknesses, and tendencies \u2014 for self-review and more.\",\n prompt: `Analyze **[ATTORNEY NAME]**'s courtroom performance based on all available hearing transcripts.`,\n },\n {\n label: \"Issue Analysis\",\n icon: Search,\n iconColor: colors.indigo[700],\n iconBgColor: colors.indigo[50],\n description: \"Find patterns in how a judge handles a specific motion type or issue.\",\n prompt: `When ruling on **[MOTION OR OBJECTION]** on the basis of **[ARGUMENT]**, what specific factors has **[JUDGE NAME]** cited that differentiate their rulings granting versus denying? Conduct an exhaustive review of all available relevant transcripts. Factors could include, but not be limited to, different facts, different case law precedent, or different interpretation of case law precedent. Prioritize insights that are both unpredictable \u2014 patterns I, an attorney, wouldn't anticipate from the rules or general experience alone \u2014 and actionable enough to change how I'd frame my motion, what arguments I'd lead with, or whether I'd file one at all.`,\n },\n {\n label: \"Topic Lookup\",\n icon: FileSearch,\n iconColor: colors.purple[700],\n iconBgColor: colors.purple[50],\n description: \"Surface every instance a judge discussed a topic \u2014 case names, dates, and rulings.\",\n prompt: `Search all available transcripts from **[JUDGE NAME]**'s cases and identify every instance where **[TOPIC OR EVENT]** was discussed or occurred. For each hit, provide the case name, date, and relevant excerpt with enough surrounding context to be useful. Where the transcript captures the judge's reaction or ruling on the matter, include that as well.`,\n },\n {\n label: \"Transcript Lookup\",\n icon: FileText,\n iconColor: colors.taupe[800],\n iconBgColor: colors.taupe[50],\n description: \"Locate and provide the full transcript from a specific hearing by case name and date.\",\n prompt: `Locate and provide the full transcript from **[CASE NAME]**, hearing on **[DATE OR DESCRIPTION OF HEARING]**.`,\n },\n];\n\n// New-feature examples lead the six-card homepage selection.\nexport const EXAMPLE_PROMPTS: UsecaseCardItem[] = [\n {\n label: \"Motion Preparation\",\n cardType: \"new\",\n icon: Landmark,\n description: \"Find relevant examples of motions, supporting evidence, and orders to help prepare your filing.\",\n prompt: `I\u2019m preparing **[MOTION OR REQUEST]** in **[COURT]** involving **[KEY FACTS OR CIRCUMSTANCES]**. Search court dockets for comparable motions. Download and read the relevant motions, supporting declarations, exhibits, objections, and resulting orders, including substantive attachments. Read available hearing transcripts to explain what influenced the court\u2019s decision.\\n\\nIdentify the most useful examples for my filing and explain how their facts compare with mine. Recommend which arguments to lead with, what evidence to provide, and how to address likely objections. Distinguish parties\u2019 arguments, negotiated changes, and the court\u2019s reasoning.`,\n },\n {\n label: \"Case Developments\",\n cardType: \"new\",\n icon: Landmark,\n description: \"Trace an issue through a case\u2019s filings, hearings, and orders to understand what changed and why.\",\n prompt: `Trace the development of **[ISSUE OR DISPUTE]** in **[CASE NAME AND COURT]**. Search the docket, then download and read the relevant filings and their substantive attachments, including motions, supporting evidence, responses, and orders. Read available hearing transcripts alongside those documents.\\n\\nCreate a chronology showing what each party requested or argued, the evidence presented, how positions or proposed terms changed, and what the court decided. Explain what drove the significant developments, distinguishing negotiated resolutions from judicial rulings. Conclude with the latest established status, what remains unresolved, and any upcoming deadlines identified in the record.`,\n },\n ...DEFAULT_EXAMPLE_PROMPTS.filter((item) => ![\"Attorney Insights\", \"Judge Personality\"].includes(item.label)),\n];\n\n// Match the server-side tool access decision; do not infer access from flag presence.\nexport const getExamplePrompts = (): UsecaseCardItem[] =>\n window.docketConnectEnabled === true ? EXAMPLE_PROMPTS : DEFAULT_EXAMPLE_PROMPTS;\n", "import { createContext, useContext } from \"react\";\nimport type { useAgentPrototypeSession } from \"../../hooks/useAgentPrototypeSession\";\n\ntype AgentPrototypeContextValue = ReturnType;\n\nexport const AgentPrototypeContext = createContext(null);\n\nexport function useAgentPrototype(): AgentPrototypeContextValue {\n const ctx = useContext(AgentPrototypeContext);\n if (!ctx) throw new Error(\"useAgentPrototype must be used within AgentPrototypeLayout\");\n return ctx;\n}\n", "export const TRANSCRIPT_SCROLL_ANCHOR_MAX_LENGTH = 150;\n\nconst TRANSCRIPT_SCROLL_ANCHOR_PREFIX_FALLBACK_LENGTHS = [80, 40];\nconst TRANSCRIPT_SCROLL_TOP_OFFSET_PX = 24;\n\ninterface TextNodeEntry {\n node: Text;\n start: number;\n end: number;\n}\n\ninterface TextPosition {\n node: Text;\n offset: number;\n}\n\ninterface CaretPositionFromPointLike {\n offsetNode: Node;\n offset: number;\n}\n\ntype DocumentWithCaretApis = Document & {\n caretPositionFromPoint?: (x: number, y: number) => CaretPositionFromPointLike | null;\n caretRangeFromPoint?: (x: number, y: number) => Range | null;\n};\n\nconst buildTextNodeIndex = (root: Node): { text: string; entries: TextNodeEntry[] } => {\n const document = root.ownerDocument ?? window.document;\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n const entries: TextNodeEntry[] = [];\n let combinedText = \"\";\n let currentNode = walker.nextNode();\n\n while (currentNode) {\n const node = currentNode as Text;\n const text = node.textContent ?? \"\";\n\n if (text.length > 0) {\n entries.push({\n node,\n start: combinedText.length,\n end: combinedText.length + text.length,\n });\n combinedText += text;\n }\n\n currentNode = walker.nextNode();\n }\n\n return { text: combinedText, entries };\n};\n\nconst resolveGlobalOffset = (entries: TextNodeEntry[], position: TextPosition): number | null => {\n const entry = entries.find((candidate) => candidate.node === position.node);\n if (!entry) return null;\n\n return Math.min(entry.end, entry.start + Math.max(0, position.offset));\n};\n\nconst resolvePositionAtGlobalOffset = (entries: TextNodeEntry[], globalOffset: number): TextPosition | null => {\n if (entries.length === 0) return null;\n\n const safeOffset = Math.max(0, globalOffset);\n const entry = entries.find((candidate) => safeOffset < candidate.end) ?? entries[entries.length - 1];\n\n return {\n node: entry.node,\n offset: Math.min(entry.end - entry.start, Math.max(0, safeOffset - entry.start)),\n };\n};\n\nconst firstTextDescendant = (root: Node | null): Text | null => {\n if (!root) return null;\n if (root.nodeType === Node.TEXT_NODE) {\n return root as Text;\n }\n\n const document = root.ownerDocument ?? window.document;\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n const currentNode = walker.nextNode();\n return currentNode ? (currentNode as Text) : null;\n};\n\nconst resolveTextPosition = (root: Node, node: Node, offset: number): TextPosition | null => {\n if (node.nodeType === Node.TEXT_NODE) {\n const textNode = node as Text;\n return {\n node: textNode,\n offset: Math.min(textNode.textContent?.length ?? 0, Math.max(0, offset)),\n };\n }\n\n const preferredChildren = [node.childNodes[offset] ?? null, node.childNodes[Math.max(0, offset - 1)] ?? null, node];\n\n for (const candidate of preferredChildren) {\n const textNode = firstTextDescendant(candidate);\n if (textNode && root.contains(textNode)) {\n return { node: textNode, offset: 0 };\n }\n }\n\n return null;\n};\n\nconst getCaretTextPositionFromPoint = (root: HTMLElement, x: number, y: number): TextPosition | null => {\n const document = (root.ownerDocument ?? window.document) as DocumentWithCaretApis;\n\n if (typeof document.caretPositionFromPoint === \"function\") {\n const caretPosition = document.caretPositionFromPoint(x, y);\n if (caretPosition) {\n return resolveTextPosition(root, caretPosition.offsetNode, caretPosition.offset);\n }\n }\n\n if (typeof document.caretRangeFromPoint === \"function\") {\n const range = document.caretRangeFromPoint(x, y);\n if (range) {\n return resolveTextPosition(root, range.startContainer, range.startOffset);\n }\n }\n\n return null;\n};\n\nconst buildAnchorCandidates = (anchor: string): string[] => {\n const trimmedAnchor = anchor.trim();\n if (!trimmedAnchor) return [];\n\n const candidates = [trimmedAnchor];\n for (const prefixLength of TRANSCRIPT_SCROLL_ANCHOR_PREFIX_FALLBACK_LENGTHS) {\n if (trimmedAnchor.length > prefixLength) {\n candidates.push(trimmedAnchor.slice(0, prefixLength));\n }\n }\n\n return Array.from(new Set(candidates.map((candidate) => candidate.trim()).filter(Boolean)));\n};\n\nconst findAnchorMatch = (bodyText: string, anchor: string): { index: number; matchedAnchor: string } | null => {\n for (const candidate of buildAnchorCandidates(anchor)) {\n const index = bodyText.indexOf(candidate);\n if (index !== -1) {\n return { index, matchedAnchor: candidate };\n }\n }\n\n return null;\n};\n\nexport const extractVisibleTranscriptTextAnchor = (\n root: HTMLElement,\n scrollContainer: HTMLElement,\n maxLength = TRANSCRIPT_SCROLL_ANCHOR_MAX_LENGTH,\n): string | null => {\n const contentRect = root.getBoundingClientRect();\n const containerRect = scrollContainer.getBoundingClientRect();\n if (contentRect.width <= 0 || contentRect.height <= 0 || containerRect.height <= 0) {\n return null;\n }\n\n const x = Math.max(contentRect.left + 1, Math.min(contentRect.left + 48, contentRect.right - 1));\n const minY = Math.max(containerRect.top + 24, contentRect.top + 1);\n const maxY = Math.min(containerRect.bottom - 1, contentRect.bottom - 1);\n if (maxY <= minY) {\n return null;\n }\n\n const { text, entries } = buildTextNodeIndex(root);\n if (entries.length === 0) return null;\n\n const ySamples = Array.from(new Set([minY, minY + 24, minY + 48].filter((sample) => sample <= maxY)));\n\n for (const y of ySamples) {\n const position = getCaretTextPositionFromPoint(root, x, y);\n if (!position) continue;\n\n const globalOffset = resolveGlobalOffset(entries, position);\n if (globalOffset === null) continue;\n\n const anchor = text\n .slice(globalOffset, globalOffset + maxLength)\n .replace(/^\\s+/u, \"\")\n .trim();\n if (anchor) {\n return anchor;\n }\n }\n\n return null;\n};\n\nexport const findTranscriptTextAnchorScrollTop = (\n root: HTMLElement,\n scrollContainer: HTMLElement,\n anchor: string,\n topOffsetPx = TRANSCRIPT_SCROLL_TOP_OFFSET_PX,\n): number | null => {\n const trimmedAnchor = anchor.trim();\n if (!trimmedAnchor) return null;\n\n const { text, entries } = buildTextNodeIndex(root);\n if (entries.length === 0) return null;\n\n const match = findAnchorMatch(text, trimmedAnchor);\n if (!match) return null;\n\n const startPosition = resolvePositionAtGlobalOffset(entries, match.index);\n const endPosition = resolvePositionAtGlobalOffset(entries, Math.min(match.index + 1, text.length));\n if (!startPosition || !endPosition) return null;\n\n const document = root.ownerDocument ?? window.document;\n const range = document.createRange();\n range.setStart(startPosition.node, startPosition.offset);\n range.setEnd(endPosition.node, endPosition.offset);\n\n const rect = range.getClientRects()[0] ?? range.getBoundingClientRect();\n const containerRect = scrollContainer.getBoundingClientRect();\n\n return Math.max(scrollContainer.scrollTop + rect.top - containerRect.top - topOffsetPx, 0);\n};\n", "import { isClerkAvailable } from \"../../utils/featureFlags\";\nimport { TRANSCRIPT_SCROLL_ANCHOR_MAX_LENGTH } from \"../../utils/transcriptScrollAnchor\";\n\nexport const ACTIVE_TRANSCRIPT_ID_QUERY_PARAM = \"activeTranscriptId\";\nexport const ACTIVE_TRANSCRIPT_TEXT_ANCHOR_QUERY_PARAM = \"activeTranscriptTextAnchor\";\n\nexport function openFreshClerkTab(\n activeTranscriptId?: number | null,\n activeTranscriptTextAnchor?: string | null,\n): boolean {\n if (!isClerkAvailable()) {\n return false;\n }\n\n const params = new URLSearchParams();\n if (activeTranscriptId && activeTranscriptId > 0) {\n params.set(ACTIVE_TRANSCRIPT_ID_QUERY_PARAM, String(activeTranscriptId));\n }\n if (activeTranscriptTextAnchor?.trim()) {\n params.set(\n ACTIVE_TRANSCRIPT_TEXT_ANCHOR_QUERY_PARAM,\n activeTranscriptTextAnchor.trim().slice(0, TRANSCRIPT_SCROLL_ANCHOR_MAX_LENGTH),\n );\n }\n const path = params.toString().length > 0 ? `/agent?${params.toString()}` : \"/agent\";\n window.open(path, \"_blank\", \"noopener,noreferrer\");\n return true;\n}\n", "import type { AttachedFile, ModelConfig } from \"../../api/queries/agentPrototype.types\";\nimport { canonicalizeModelConfig } from \"./modelConfig\";\n\nexport interface PendingClerkDraft {\n message: string;\n files?: AttachedFile[];\n modelConfig: ModelConfig;\n promptSource: \"typed\" | \"example_prompt\";\n planningMode?: \"manual\";\n}\n\nlet pendingClerkDraft: PendingClerkDraft | null = null;\n\nexport function storePendingClerkDraft(draft: PendingClerkDraft) {\n pendingClerkDraft = {\n ...draft,\n modelConfig: canonicalizeModelConfig(draft.modelConfig),\n };\n}\n\nexport function consumePendingClerkDraft(): PendingClerkDraft | null {\n const draft = pendingClerkDraft;\n pendingClerkDraft = null;\n return draft;\n}\n\n/**\n * Non-consuming check \u2014 returns whether a draft is currently stashed\n * without clearing it. Used by route-level dispatchers (e.g. the\n * `/agent` welcome / locked-landing dispatch) that need to\n * choose which component to render based on whether a Home submission\n * is pending, while leaving the draft intact for the eventual\n * `consumePendingClerkDraft` call inside the rendered component.\n */\nexport function hasPendingClerkDraft(): boolean {\n return pendingClerkDraft !== null;\n}\n\nexport function clearPendingClerkDraft() {\n pendingClerkDraft = null;\n}\n", "// Like the effort preference, this is a default for new conversations in this\n// browser. Existing conversations retain their server-owned planning mode.\nconst STORAGE_KEY = \"agent_planning_mode\";\n\nexport function loadStoredPlanningMode(): boolean {\n try {\n return window.localStorage.getItem(STORAGE_KEY) === \"true\";\n } catch {\n return false;\n }\n}\n\nexport function saveStoredPlanningMode(enabled: boolean): boolean {\n try {\n window.localStorage.setItem(STORAGE_KEY, String(enabled));\n } catch {\n // Storage availability must not prevent changing the current mode.\n }\n return enabled;\n}\n", "import { recordPlanningEvent } from \"./planningAnalytics\";\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useOptionalClientMatter } from \"@/contexts/ClientMatterContext\";\nimport { isCreditBillingLive } from \"@/utils/creditBilling\";\nimport { Alert, Box, CircularProgress, Typography } from \"@mui/material\";\nimport { UsecaseCard } from \"../atoms/UsecaseCard\";\nimport { getExamplePrompts } from \"./examplePrompts\";\nimport { UseCaseBlock } from \"../molecules/UseCaseBlock\";\nimport { EntryBlock } from \"../molecules/EntryBlock\";\nimport { EntryLayout } from \"../layouts/EntryLayout\";\nimport AgentPrototypeInput from \"./AgentPrototypeInput\";\nimport { useAgentPrototype } from \"./AgentPrototypeContext\";\nimport DataCoverageModal from \"./DataCoverageModal\";\nimport { RequestJudgeModal } from \"../molecules/RequestJudgeModal\";\nimport { useNavigate, useSearchParams } from \"../../utils/urlHelpers\";\nimport { ACTIVE_TRANSCRIPT_ID_QUERY_PARAM, ACTIVE_TRANSCRIPT_TEXT_ANCHOR_QUERY_PARAM } from \"./openFreshClerkTab\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { CLERK_ERROR_COPY } from \"../../utils/clerkErrorCopy\";\nimport { clearPendingClerkDraft, consumePendingClerkDraft, hasPendingClerkDraft } from \"./pendingClerkDraft\";\nimport { AGENT_HELP_CENTER_URL } from \"./constants\";\nimport { loadStoredModelConfig, saveStoredModelConfig } from \"./modelConfig\";\nimport { loadStoredPlanningMode, saveStoredPlanningMode } from \"./planningModePreference\";\nimport { featureEnabled } from \"../../utils/featureFlags\";\nimport type { AttachedFile, ModelConfig } from \"../../api/queries/agentPrototype.types\";\n\nexport { EXAMPLE_PROMPTS, getExamplePrompts } from \"./examplePrompts\";\n\n/**\n * Centered spinner + caption shown during async transitions on the\n * `/agent` welcome page. Exported so the Home page can render\n * the SAME loading state during the brief window between \"user clicked\n * submit\" and \"Welcome page mounted\" \u2014 without this, Home would show its\n * cards-laden EntryLayout for one extra render before navigation,\n * producing a visible flash even though Welcome's first frame is correct.\n */\nexport const AgentPrototypeLoadingState: React.FC<{ copy: string }> = ({ copy }) => (\n \n \n \n {copy}\n \n \n);\n\nconst AgentPrototypeWelcome: React.FC = () => {\n const navigate = useNavigate();\n const examplePrompts = getExamplePrompts();\n const [searchParams] = useSearchParams();\n const { token, isStreaming, reset, bootstrapSession, sendMessage, setPlanningMode, status, messages } =\n useAgentPrototype();\n const clientMatter = useOptionalClientMatter();\n const [dataCoverageOpen, setDataCoverageOpen] = useState(false);\n const [requestJudgeOpen, setRequestJudgeOpen] = useState(false);\n const [isBootstrapping, setIsBootstrapping] = useState(false);\n // Lazy-init from the pending-draft peek so Welcome's first render\n // already shows the loading state on Home \u2192 submit. Welcome \u2192 submit\n // (typing into Welcome's own input) is covered by handleSend below.\n const [isLaunchingConversation, setIsLaunchingConversation] = useState(() => hasPendingClerkDraft());\n const [bootstrapError, setBootstrapError] = useState(null);\n const [prefillText, setPrefillText] = useState(\"\");\n const [nextPromptSource, setNextPromptSource] = useState<\"typed\" | \"example_prompt\">(\"typed\");\n const [modelConfig, setModelConfig] = useState(loadStoredModelConfig);\n const [planEnabled, setPlanEnabled] = useState(loadStoredPlanningMode);\n\n const sendWithMatter = useCallback(\n async (\n message: string,\n files: AttachedFile[] | undefined,\n selectedModelConfig: ModelConfig,\n promptSource: \"typed\" | \"example_prompt\",\n planningMode = false,\n ) => {\n let creditRequest: { clientRequestId: string; clientMatterCode: string } | undefined;\n if (isCreditBillingLive()) {\n const matterCode = await clientMatter?.ensureMatter();\n if (!matterCode) return false;\n creditRequest = { clientRequestId: crypto.randomUUID(), clientMatterCode: matterCode };\n }\n const sent = planningMode\n ? await sendMessage(message, files, selectedModelConfig, undefined, promptSource, creditRequest, true)\n : creditRequest\n ? await sendMessage(message, files, selectedModelConfig, undefined, promptSource, creditRequest)\n : await sendMessage(message, files, selectedModelConfig, undefined, promptSource);\n if (sent === false) return false;\n\n return true;\n },\n [clientMatter, sendMessage],\n );\n\n // Track the token at mount time so we only navigate for *new* tokens\n const initialToken = useRef(token);\n const bootstrapTriggeredRef = useRef(false);\n const suppressTokenNavigationRef = useRef(false);\n const pendingDraftConsumedRef = useRef(false);\n const bootstrapTranscriptId = useMemo(() => {\n const rawValue = searchParams.get(ACTIVE_TRANSCRIPT_ID_QUERY_PARAM);\n if (!rawValue) return null;\n\n const parsedValue = Number.parseInt(rawValue, 10);\n return Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : null;\n }, [searchParams]);\n const bootstrapSearch = useMemo(() => {\n const params = new URLSearchParams();\n if (bootstrapTranscriptId) {\n params.set(ACTIVE_TRANSCRIPT_ID_QUERY_PARAM, String(bootstrapTranscriptId));\n }\n const anchorText = searchParams.get(ACTIVE_TRANSCRIPT_TEXT_ANCHOR_QUERY_PARAM);\n if (anchorText?.trim()) {\n params.set(ACTIVE_TRANSCRIPT_TEXT_ANCHOR_QUERY_PARAM, anchorText.trim());\n }\n\n const query = params.toString();\n return query ? `?${query}` : undefined;\n }, [bootstrapTranscriptId, searchParams]);\n\n // StrictMode replays mount effects in development. Reset only once so\n // the replay cannot invalidate a pending Home draft's submission.\n const initialResetDoneRef = useRef(false);\n useEffect(() => {\n if (initialResetDoneRef.current) return;\n initialResetDoneRef.current = true;\n reset();\n }, [reset]);\n\n useEffect(() => {\n if (!bootstrapTranscriptId || bootstrapTriggeredRef.current || token) return;\n\n bootstrapTriggeredRef.current = true;\n suppressTokenNavigationRef.current = true;\n setIsBootstrapping(true);\n setBootstrapError(null);\n\n void bootstrapSession({ transcript_id: bootstrapTranscriptId })\n .then(async (session) => {\n if (session?.token && (session.messages.length > 0 || session.active_transcript)) {\n if (featureEnabled(\"planning_mode\") && loadStoredPlanningMode()) await setPlanningMode(true);\n navigate({ pathname: `/agent/${session.token}`, search: bootstrapSearch }, { replace: true });\n return;\n }\n\n reset();\n suppressTokenNavigationRef.current = false;\n setBootstrapError(CLERK_ERROR_COPY.transcriptBootstrapFailure);\n navigate({ pathname: \"/agent\" }, { replace: true });\n })\n .finally(() => {\n setIsBootstrapping(false);\n });\n }, [bootstrapSearch, bootstrapSession, bootstrapTranscriptId, navigate, reset, setPlanningMode, token]);\n\n useEffect(() => {\n if (token || pendingDraftConsumedRef.current) return;\n\n // Bootstrap supersedes any pending draft \u2014 the user navigated here\n // with a transcript-id param, so drop a stale draft instead of\n // leaving it in module memory to silently fire on the next mount.\n if (bootstrapTranscriptId) {\n clearPendingClerkDraft();\n return;\n }\n\n const draft = consumePendingClerkDraft();\n if (!draft) return;\n\n // `isLaunchingConversation` is already true from the lazy-init \u2014\n // setting it again here would be a no-op state update.\n pendingDraftConsumedRef.current = true;\n void sendWithMatter(\n draft.message,\n draft.files,\n draft.modelConfig,\n draft.promptSource,\n draft.planningMode === \"manual\",\n ).then((sent) => {\n if (!sent) setIsLaunchingConversation(false);\n });\n }, [bootstrapTranscriptId, sendWithMatter, token]);\n\n useEffect(() => {\n if (suppressTokenNavigationRef.current) {\n return;\n }\n\n if (token && token !== initialToken.current) {\n navigate({ pathname: `/agent/${token}` }, { replace: true });\n }\n }, [token, navigate]);\n\n // Clear launching only on error so the user can retry from the welcome\n // UI. On the success path the token-navigate effect unmounts us, so\n // clearing here would just create a one-frame flash of the welcome JSX\n // between token arrival and unmount.\n useEffect(() => {\n if (status === \"error\" && isLaunchingConversation) {\n setIsLaunchingConversation(false);\n }\n }, [isLaunchingConversation, status]);\n\n const handleSend = useCallback(\n async (message: string, files?: AttachedFile[]) => {\n // Welcome \u2192 submit: flip launching true synchronously so the next\n // render keeps the loading state visible until unmount.\n setIsLaunchingConversation(true);\n const sent = await sendWithMatter(\n message,\n files,\n modelConfig,\n nextPromptSource,\n featureEnabled(\"planning_mode\") && planEnabled,\n );\n if (!sent) setIsLaunchingConversation(false);\n if (sent) {\n setNextPromptSource(\"typed\");\n setPlanEnabled(false);\n }\n return sent;\n },\n [sendWithMatter, modelConfig, nextPromptSource, planEnabled],\n );\n\n const handleModelChange = useCallback((config: ModelConfig) => {\n setModelConfig(saveStoredModelConfig(config));\n }, []);\n\n const handleExampleClick = (prompt: string) => {\n if (isStreaming) return;\n void recordUserEvent({\n event_name: \"click_clerk_example_prompt\",\n event_properties: {\n example_label: examplePrompts.find((item) => item.prompt === prompt)?.label || \"unknown\",\n },\n });\n setNextPromptSource(\"example_prompt\");\n setPrefillText(prompt);\n };\n\n const handleDataCoverageClick = () => {\n void recordUserEvent({\n event_name: \"click_clerk_data_coverage\",\n event_properties: {\n surface: \"welcome\",\n },\n });\n setDataCoverageOpen(true);\n };\n\n const handleAgentHelpClick = () => {\n window.open(AGENT_HELP_CENTER_URL, \"_blank\", \"noopener,noreferrer\");\n };\n\n // Show loading whenever we're actively launching (covers the moment\n // between token arrival and the token-navigate effect's unmount \u2014\n // gating on `!token` here would flash the welcome JSX for one frame).\n // The `!token` branch handles back-navigation onto /agent\n // while a session is still creating/streaming elsewhere.\n const showConversationStartLoading =\n !isBootstrapping &&\n (isLaunchingConversation || (!token && (status === \"creating\" || (status === \"streaming\" && messages.length > 0))));\n\n if (isBootstrapping) {\n return ;\n }\n\n // Spinner only \u2014 Layout renders the input at its bottom slot\n // throughout the entire launching phase (see `hasInputContent` gate\n // there), keeping the input in one fixed DOM position.\n if (showConversationStartLoading) {\n return ;\n }\n\n return (\n <>\n \n {bootstrapError && (\n \n {bootstrapError}\n \n )}\n \n {}}\n isStreaming={isStreaming}\n disabled={status === \"creating\"}\n prefill={prefillText}\n onPrefillConsumed={() => setPrefillText(\"\")}\n modelConfig={modelConfig}\n onModelConfigChange={handleModelChange}\n planningAvailable={featureEnabled(\"planning_mode\")}\n planningEnabled={featureEnabled(\"planning_mode\") && planEnabled}\n onPlanningToggle={() => {\n const next = !planEnabled;\n recordPlanningEvent({\n event_name: \"select_clerk_planning_mode\",\n event_properties: { planning_enabled: next, surface: \"welcome\" },\n });\n setPlanEnabled(saveStoredPlanningMode(next));\n }}\n />\n \n \n }\n secondary={\n (\n handleExampleClick(item.prompt)} />\n ))}\n />\n }\n />\n setDataCoverageOpen(false)}\n onRequestJudge={() => {\n setDataCoverageOpen(false);\n setRequestJudgeOpen(true);\n }}\n />\n setRequestJudgeOpen(false)} query=\"\" />\n \n );\n};\n\nexport default AgentPrototypeWelcome;\n", "import { recordPlanningEvent } from \"./agent_prototype/planningAnalytics\";\nimport React, { useCallback, useState } from \"react\";\nimport { useNavigate } from \"../utils/urlHelpers\";\nimport { EntryBlock } from \"./molecules/EntryBlock\";\nimport { EntryLayout } from \"./layouts/EntryLayout\";\nimport { UseCaseBlock } from \"./molecules/UseCaseBlock\";\nimport { UsecaseCard } from \"./atoms/UsecaseCard\";\nimport AgentPrototypeInput from \"./agent_prototype/AgentPrototypeInput\";\nimport DataCoverageModal from \"./agent_prototype/DataCoverageModal\";\nimport { RequestJudgeModal } from \"./molecules/RequestJudgeModal\";\nimport { AgentPrototypeLoadingState, getExamplePrompts } from \"./agent_prototype/AgentPrototypeWelcome\";\nimport { loadStoredModelConfig, saveStoredModelConfig } from \"./agent_prototype/modelConfig\";\nimport { loadStoredPlanningMode, saveStoredPlanningMode } from \"./agent_prototype/planningModePreference\";\nimport { storePendingClerkDraft } from \"./agent_prototype/pendingClerkDraft\";\nimport type { AttachedFile, ModelConfig } from \"../api/queries/agentPrototype.types\";\nimport { recordUserEvent } from \"../api/userEvents\";\nimport { featureEnabled, isClerkAvailable, isGenerativeAIDisabled } from \"../utils/featureFlags\";\nimport { AGENT_HELP_CENTER_URL } from \"./agent_prototype/constants\";\n\n/**\n * Home \u2014 `/` route. Single Clerk-focused surface inside AppShell.\n *\n * Composes the Step 4 EntryBlock (H1 + section header + Clerk input slot)\n * and the Step 3 UseCaseBlock (example prompts grid) inside the PR 2\n * EntryLayout primitive. Boolean-search transcript discovery is reached\n * via the topbar SearchOverlay (Step 6) \u2014 Home no longer hosts a search\n * tab or the legacy BooleanSearchBar / AdvancedSearchModal.\n *\n * Submission and UsecaseCard click handlers mirror today's\n * AgentPrototypeHomeTab \u2014 they store the pending Clerk draft and\n * navigate to /agent.\n */\nconst Home: React.FC = () => {\n const navigate = useNavigate();\n const examplePrompts = getExamplePrompts();\n const [prefillText, setPrefillText] = useState(\"\");\n const [nextPromptSource, setNextPromptSource] = useState<\"typed\" | \"example_prompt\">(\"typed\");\n const [dataCoverageOpen, setDataCoverageOpen] = useState(false);\n const [requestJudgeOpen, setRequestJudgeOpen] = useState(false);\n const [modelConfig, setModelConfig] = useState(loadStoredModelConfig);\n const [isLaunching, setIsLaunching] = useState(false);\n const [planEnabled, setPlanEnabled] = useState(loadStoredPlanningMode);\n const planningAvailable = isClerkAvailable() && featureEnabled(\"planning_mode\");\n\n const handleSend = useCallback(\n (message: string, files?: AttachedFile[]) => {\n // Locked accounts (disable_generative_ai / incognito_queries) can't run a\n // real Clerk session \u2014 the backend rejects session creation for them, and\n // the route shell always renders `LockedClerkLanding`. Carry the typed\n // question in the URL (`?q=...`) instead of module memory: it survives\n // refresh, reliably shows in the user bubble (no StrictMode double-consume\n // surprise), and prefills the \"Search transcripts\" popover. The wrapped\n // navigate makes this incognito-safe (becomes a `#` param when incognito\n // is on). No spinner \u2014 there's no session to start.\n if (!isClerkAvailable()) {\n if (isGenerativeAIDisabled()) {\n void recordUserEvent({\n event_name: \"submit_disabled_clerk_query\",\n event_properties: {\n prompt_length_chars: message.length,\n prompt_line_count: message.split(/\\r\\n|\\r|\\n/).length,\n prompt_source: nextPromptSource,\n },\n });\n }\n navigate({ pathname: \"/agent\", search: `?${new URLSearchParams({ q: message }).toString()}` });\n return;\n }\n setIsLaunching(true);\n storePendingClerkDraft({\n message,\n files,\n modelConfig,\n promptSource: nextPromptSource,\n planningMode: planningAvailable && planEnabled ? \"manual\" : undefined,\n });\n navigate({ pathname: \"/agent\" });\n setNextPromptSource(\"typed\");\n },\n [modelConfig, navigate, nextPromptSource, planningAvailable, planEnabled],\n );\n\n const handleModelChange = useCallback((config: ModelConfig) => {\n setModelConfig(saveStoredModelConfig(config));\n }, []);\n\n const handleDataCoverageClick = () => {\n void recordUserEvent({\n event_name: \"click_clerk_data_coverage\",\n event_properties: { surface: \"home_tab\" },\n });\n setDataCoverageOpen(true);\n };\n\n const handleAgentHelpClick = () => {\n window.open(AGENT_HELP_CENTER_URL, \"_blank\", \"noopener,noreferrer\");\n };\n\n // Show the same loading state Welcome shows during conversation start,\n // so the / \u2192 /agent navigation reads as one continuous\n // spinner instead of \"Home cards \u2192 spinner\".\n if (isLaunching) {\n return ;\n }\n\n return (\n <>\n \n {}}\n isStreaming={false}\n disabled={isLaunching}\n prefill={prefillText}\n onPrefillConsumed={() => setPrefillText(\"\")}\n modelConfig={modelConfig}\n onModelConfigChange={handleModelChange}\n planningAvailable={planningAvailable}\n planningEnabled={planningAvailable && planEnabled}\n onPlanningToggle={() => {\n const next = !planEnabled;\n recordPlanningEvent({\n event_name: \"select_clerk_planning_mode\",\n event_properties: { planning_enabled: next, surface: \"home\" },\n });\n setPlanEnabled(saveStoredPlanningMode(next));\n }}\n />\n \n }\n secondary={\n (\n {\n if (isLaunching) return;\n void recordUserEvent({\n event_name: \"click_clerk_example_prompt\",\n event_properties: { example_label: item.label },\n });\n setNextPromptSource(\"example_prompt\");\n setPrefillText(item.prompt);\n }}\n />\n ))}\n />\n }\n />\n setDataCoverageOpen(false)}\n onRequestJudge={() => {\n setDataCoverageOpen(false);\n setRequestJudgeOpen(true);\n }}\n />\n setRequestJudgeOpen(false)} query=\"\" />\n \n );\n};\n\nexport default Home;\n", "import type { NextStepSelection } from \"../components/agent_prototype/nextSteps\";\nimport { fetchHelper } from \"../utils/fetchHelpers\";\nimport { normalizeClerkErrorMessage, type ClerkErrorCopyKey } from \"../utils/clerkErrorCopy\";\nimport type {\n ActiveTranscriptReference,\n AttachedFile,\n FileMetadata,\n ClarifyingQuestionResponse,\n ConsumeShareLinkResponse,\n CreateShareLinkResponse,\n CreateSessionResponse,\n CreateSessionRunResponse,\n CreatedSessionRunResponse,\n ModelConfig,\n RunStatusResponse,\n SessionListResponse,\n SessionWithMessages,\n DocketConnectRetrievalRequestPayload,\n ActiveRun,\n QueueDispatchState,\n CancelSessionResponse,\n SteerMessageIntent,\n SteerMessageResponse,\n PlanningActionResponse,\n PlanningCycle,\n PlanningQuestionResponse,\n PlanningModeState,\n} from \"./queries/agentPrototype.types\";\n\nconst BASE = \"/api/agent-prototype\";\n\nfunction clerkError(rawError: unknown, fallbackKey: ClerkErrorCopyKey, rawCode?: unknown): Error {\n const code = typeof rawCode === \"string\" ? rawCode : null;\n return new Error(normalizeClerkErrorMessage(typeof rawError === \"string\" ? rawError : null, { code, fallbackKey }));\n}\n\nexport interface CreditAgentSpeedBumpRequest {\n sessionToken: string;\n requestKind: \"message\" | \"retry\" | \"docket_connect_approval_continuation\";\n clientRequestId: string;\n message?: string;\n modelConfig?: ModelConfig;\n activeTranscript?: ActiveTranscriptReference;\n files?: AttachedFile[] | PlanningNewQuestion[\"files\"];\n clientMatterCode?: string;\n parentRunToken?: string;\n}\n\nexport interface PlanningNewQuestion {\n message: string;\n files: { name: string; type?: string; size?: number; content?: string }[];\n model_config?: Partial | null;\n client_request_id: string;\n client_matter_code?: string;\n}\n\nexport interface CreditAgentSpeedBumpRequirement {\n required: boolean;\n thresholdUsd?: string | number;\n warningLevelUsd?: string | number;\n nextWarningLevelUsd?: string | number;\n conversationUsageUsd?: string | number;\n clientMatterCode?: string;\n confirmationToken?: string;\n}\n\ninterface CreditAgentSpeedBumpPayload {\n queue_dispatch?: QueueDispatchState | null;\n required?: boolean;\n threshold_usd?: string | number;\n warning_level_usd?: string | number;\n next_warning_level_usd?: string | number;\n conversation_usage_usd?: string | number;\n client_matter_code?: string;\n challenge?: string;\n confirmation_token?: string;\n error?: string;\n code?: string;\n}\n\nexport class AgentPrototypeApiError extends Error {\n status: number;\n code?: string;\n speedBumpRequirement?: CreditAgentSpeedBumpRequirement;\n queueDispatch?: QueueDispatchState | null;\n\n constructor(\n message: string,\n {\n status,\n code,\n speedBumpRequirement,\n queueDispatch,\n }: {\n queueDispatch?: QueueDispatchState | null;\n status: number;\n code?: string;\n speedBumpRequirement?: CreditAgentSpeedBumpRequirement;\n },\n ) {\n super(message);\n this.name = \"AgentPrototypeApiError\";\n this.status = status;\n this.code = code;\n this.speedBumpRequirement = speedBumpRequirement;\n this.queueDispatch = queueDispatch;\n }\n}\n\nexport class PlanningActionError extends Error {\n status?: number;\n code?: string;\n planningCycle?: PlanningCycle;\n speedBumpRequirement?: CreditAgentSpeedBumpRequirement;\n newQuestion?: PlanningNewQuestion;\n\n constructor(\n message: string,\n planningCycle?: PlanningCycle,\n continuation?: { speedBumpRequirement: CreditAgentSpeedBumpRequirement; newQuestion: PlanningNewQuestion },\n details?: { status: number; code?: string },\n ) {\n super(message);\n this.name = \"PlanningActionError\";\n this.status = details?.status;\n this.code = details?.code;\n this.planningCycle = planningCycle;\n this.speedBumpRequirement = continuation?.speedBumpRequirement;\n this.newQuestion = continuation?.newQuestion;\n }\n}\n\nfunction monthlyCreditLimitApiError(response: Response, body: unknown): AgentPrototypeApiError | null {\n const payload = typeof body === \"object\" && body !== null ? (body as Record) : {};\n const code = typeof payload.code === \"string\" ? payload.code : undefined;\n if (code !== \"monthly_credit_limit_reached\") return null;\n\n return new AgentPrototypeApiError(\n normalizeClerkErrorMessage(typeof payload.error === \"string\" ? payload.error : null, {\n code,\n fallbackKey: \"genericRetry\",\n }),\n { status: response.status, code },\n );\n}\n\nfunction normalizeSpeedBumpRequirement(payload: CreditAgentSpeedBumpPayload): CreditAgentSpeedBumpRequirement {\n return {\n required: Boolean(payload.required),\n thresholdUsd: payload.threshold_usd,\n warningLevelUsd: payload.warning_level_usd,\n nextWarningLevelUsd: payload.next_warning_level_usd,\n conversationUsageUsd: payload.conversation_usage_usd,\n clientMatterCode: payload.client_matter_code,\n confirmationToken: payload.challenge || payload.confirmation_token,\n };\n}\n\nexport function isCreditSpeedBumpRequiredError(\n error: unknown,\n): error is AgentPrototypeApiError & { speedBumpRequirement: CreditAgentSpeedBumpRequirement } {\n return (\n error instanceof AgentPrototypeApiError &&\n error.status === 428 &&\n error.code === \"agent_conversation_speed_bump_required\" &&\n Boolean(error.speedBumpRequirement)\n );\n}\n\nasync function throwAgentRunError(response: Response, payload: CreditAgentSpeedBumpPayload): Promise {\n const speedBumpRequirement =\n response.status === 428 && payload.code === \"agent_conversation_speed_bump_required\"\n ? { ...normalizeSpeedBumpRequirement(payload), required: true }\n : undefined;\n throw new AgentPrototypeApiError(\n normalizeClerkErrorMessage(payload.error || null, { code: payload.code, fallbackKey: \"genericRetry\" }),\n {\n status: response.status,\n code: payload.code,\n speedBumpRequirement,\n queueDispatch: payload.queue_dispatch,\n },\n );\n}\n\nexport async function checkCreditAgentSpeedBump(\n request: CreditAgentSpeedBumpRequest,\n): Promise {\n const response = await fetchHelper(\"/api/credit-agent-speed-bump/check\", {\n method: \"POST\",\n body: {\n session_token: request.sessionToken,\n request_kind: request.requestKind,\n client_request_id: request.clientRequestId,\n message: request.message,\n model_config: request.modelConfig,\n active_transcript: request.activeTranscript,\n files: request.files,\n client_matter_code: request.clientMatterCode,\n parent_run_token: request.parentRunToken,\n },\n });\n const payload = (await response.json().catch(() => ({}))) as CreditAgentSpeedBumpPayload;\n if (!response.ok) {\n throw new AgentPrototypeApiError(\n normalizeClerkErrorMessage(payload.error || null, {\n code: payload.code,\n fallbackKey: \"genericRetry\",\n }),\n { status: response.status, code: payload.code },\n );\n }\n return normalizeSpeedBumpRequirement(payload);\n}\n\nfunction docketConnectApprovalError(response: Response, body: unknown): Error {\n const record = typeof body === \"object\" && body !== null ? (body as Record) : {};\n const retrievalRequest = record.retrieval_request;\n if (response.status === 409 && typeof retrievalRequest === \"object\" && retrievalRequest !== null) {\n return Object.assign(clerkError(record.error, \"genericRetry\"), {\n retrievalRequest: retrievalRequest as DocketConnectRetrievalRequestPayload,\n });\n }\n const monthlyLimitError = monthlyCreditLimitApiError(response, record);\n if (monthlyLimitError) return monthlyLimitError;\n return clerkError(record.error, \"genericRetry\");\n}\n\nexport async function listSessions({\n pageParam = 1,\n pageSize,\n sortDirection,\n includeSidenav = false,\n}: {\n pageParam?: number;\n pageSize?: number;\n sortDirection?: \"asc\" | \"desc\";\n includeSidenav?: boolean;\n} = {}): Promise {\n const url = new URL(`${BASE}/sessions`, window.location.origin);\n url.searchParams.append(\"page\", String(pageParam));\n if (pageSize) {\n url.searchParams.append(\"pageSize\", String(pageSize));\n }\n if (sortDirection) {\n url.searchParams.append(\"sort\", sortDirection);\n }\n if (includeSidenav) url.searchParams.append(\"include\", \"sidenav\");\n const response = await fetchHelper(url.toString());\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"historyLoadFailure\");\n }\n return response.json();\n}\n\nexport async function markSessionRead(token: string): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/read`, { method: \"POST\" });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"genericRetry\");\n }\n}\n\nexport async function createSession(\n modelConfig?: ModelConfig,\n activeTranscript?: ActiveTranscriptReference,\n): Promise {\n const body: Record = {};\n if (modelConfig) {\n body.model_config = modelConfig;\n }\n if (activeTranscript) {\n body.active_transcript = activeTranscript;\n }\n const response = await fetchHelper(`${BASE}/sessions`, {\n method: \"POST\",\n body,\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n const monthlyLimitError = monthlyCreditLimitApiError(response, body);\n if (monthlyLimitError) throw monthlyLimitError;\n throw clerkError(body?.error, \"genericRetry\");\n }\n return response.json();\n}\n\nexport async function createShareLink(token: string): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/share-links`, {\n method: \"POST\",\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"shareLinkUpdateFailure\");\n }\n return response.json();\n}\n\nexport async function getCurrentShareLink(token: string): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/share-links/current`);\n if (response.status === 404) {\n return null;\n }\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"shareLinkUpdateFailure\");\n }\n return response.json();\n}\n\nconst shareLinkConsumptionRequests = new Map>();\n\nasync function requestShareLinkConsumption(shareToken: string): Promise {\n const response = await fetchHelper(`${BASE}/share-links/${shareToken}/consume`, {\n method: \"POST\",\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"shareConversationUnavailable\");\n }\n return response.json();\n}\n\nexport function consumeShareLink(shareToken: string): Promise {\n const existingRequest = shareLinkConsumptionRequests.get(shareToken);\n if (existingRequest) {\n return existingRequest;\n }\n\n const request = requestShareLinkConsumption(shareToken).finally(() => {\n if (shareLinkConsumptionRequests.get(shareToken) === request) {\n shareLinkConsumptionRequests.delete(shareToken);\n }\n });\n shareLinkConsumptionRequests.set(shareToken, request);\n return request;\n}\n\nexport async function revokeShareLink(shareToken: string): Promise {\n const response = await fetchHelper(`${BASE}/share-links/${shareToken}`, {\n method: \"DELETE\",\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"shareLinkUpdateFailure\");\n }\n}\n\nexport async function getSession(\n token: string,\n options?: { cursor?: string; beforeMessageId?: number; limit?: number },\n): Promise {\n const query = new URLSearchParams();\n if (options?.cursor) {\n query.set(\"cursor\", options.cursor);\n } else if (options?.beforeMessageId && options.beforeMessageId > 0) {\n query.set(\"before_message_id\", String(options.beforeMessageId));\n }\n if (options?.limit && options.limit > 0) {\n query.set(\"limit\", String(options.limit));\n }\n\n const suffix = query.toString();\n const url = suffix ? `${BASE}/sessions/${token}?${suffix}` : `${BASE}/sessions/${token}`;\n const response = await fetchHelper(url);\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"conversationLoadFailure\", body?.code);\n }\n return response.json();\n}\n\nexport async function updateSessionTitle(token: string, title: string): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}`, {\n method: \"PATCH\",\n body: { title },\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"genericRetry\");\n }\n}\n\nexport async function cancelSession(\n token: string,\n expectedRunToken?: string,\n intent?: \"queue\",\n): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/cancel`, {\n method: \"DELETE\",\n ...(expectedRunToken\n ? { body: intent === \"queue\" ? { expected_run_id: expectedRunToken } : { expected_run_token: expectedRunToken } }\n : {}),\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"genericRetry\");\n }\n return response.json();\n}\n\nexport async function submitClarifyingAnswer(\n token: string,\n runId: string,\n questionId: string,\n answer: string,\n questionText?: string,\n typedResponse?: ClarifyingQuestionResponse,\n files?: AttachedFile[],\n): Promise<{\n ok: boolean;\n reason?: \"not_waiting\" | \"conflict\";\n input_request_id?: string;\n display_messages?: Array<{ id: number; role: string; content: string; files?: FileMetadata[] | null }>;\n}> {\n const response = await fetchHelper(`${BASE}/sessions/${token}/answer`, {\n method: \"POST\",\n body: {\n run_id: runId,\n question_id: questionId,\n answer,\n question_text: questionText,\n ...(typedResponse ? { response: typedResponse } : {}),\n ...(files ? { files } : {}),\n },\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n if (response.status === 409 && body?.reason === \"conflict\") {\n return body;\n }\n const error = clerkError(body?.error, \"clarifyingAnswerSubmitFailure\", body?.code) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n return response.json();\n}\n\nexport async function acknowledgeClarifyingQuestion(\n token: string,\n runId: string,\n questionId: string,\n): Promise<{ ok: boolean; reason?: \"not_waiting\"; expires_at_ms?: number }> {\n const response = await fetchHelper(`${BASE}/sessions/${token}/runs/${runId}/clarifying-questions/${questionId}/ack`, {\n method: \"POST\",\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n if (\n response.status === 404 &&\n (body?.error === \"Run not found\" || body?.error === \"Clarifying question not found\")\n ) {\n return { ok: false, reason: \"not_waiting\" };\n }\n throw clerkError(body?.error, \"genericRetry\");\n }\n return response.json();\n}\n\nexport async function submitDocketConnectApproval(\n token: string,\n approvalRequestId: string | number,\n speedBumpConfirmationToken?: string,\n): Promise {\n const response = await fetchHelper(\n `${BASE}/sessions/${token}/docket-connect/approvals/${approvalRequestId}/approve`,\n speedBumpConfirmationToken\n ? { method: \"POST\", body: { credit_speed_bump_confirmation: speedBumpConfirmationToken } }\n : { method: \"POST\" },\n );\n const body = await response.json().catch(() => null);\n if (!response.ok) {\n throw docketConnectApprovalError(response, body);\n }\n return normalizeDocketConnectApprovalDecision(body);\n}\n\nexport async function cancelDocketConnectApproval(\n token: string,\n approvalRequestId: string | number,\n speedBumpConfirmationToken?: string,\n): Promise {\n const response = await fetchHelper(\n `${BASE}/sessions/${token}/docket-connect/approvals/${approvalRequestId}/cancel`,\n speedBumpConfirmationToken\n ? { method: \"POST\", body: { credit_speed_bump_confirmation: speedBumpConfirmationToken } }\n : { method: \"POST\" },\n );\n const body = await response.json().catch(() => null);\n if (!response.ok) {\n throw docketConnectApprovalError(response, body);\n }\n return normalizeDocketConnectApprovalDecision(body);\n}\n\nexport interface DocketConnectContinuationCreditSpeedBump extends CreditAgentSpeedBumpRequirement {\n requestKind: \"docket_connect_approval_continuation\";\n clientRequestId: string;\n}\n\nexport interface DocketConnectApprovalDecisionResponse {\n retrieval_request: DocketConnectRetrievalRequestPayload;\n event?: Record;\n continuation_run?: ActiveRun | null;\n continuation_error?: string | null;\n continuationCreditSpeedBump?: DocketConnectContinuationCreditSpeedBump | null;\n}\n\nfunction normalizeDocketConnectApprovalDecision(body: unknown): DocketConnectApprovalDecisionResponse {\n const payload = (body || {}) as DocketConnectApprovalDecisionResponse & {\n continuation_credit_speed_bump?: CreditAgentSpeedBumpPayload & {\n request_kind?: string;\n client_request_id?: string;\n };\n };\n const credit = payload.continuation_credit_speed_bump;\n if (!credit) return payload;\n\n return {\n ...payload,\n continuationCreditSpeedBump: {\n ...normalizeSpeedBumpRequirement(credit),\n required: true,\n requestKind: \"docket_connect_approval_continuation\",\n clientRequestId: String(credit.client_request_id || \"\"),\n },\n };\n}\n\nexport class PlanningModeConflictError extends Error {\n constructor(public mode: PlanningModeState) {\n super(\"Planning mode changed in another tab. Review the selected mode and try again.\");\n }\n}\n\nexport async function updatePlanningMode(\n token: string,\n planningMode: boolean,\n expectedRevision: number,\n): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/planning-mode`, {\n method: \"PATCH\",\n body: { planning_mode: planningMode, expected_revision: expectedRevision },\n });\n const payload = await response.json();\n if (response.status === 409) throw new PlanningModeConflictError(payload);\n if (!response.ok) throw new Error(payload.error || \"Unable to update planning mode.\");\n return payload;\n}\n\n// A message may already have committed even when its response is lost.\nexport class AgentAdmissionUncertainError extends Error {\n constructor(cause: unknown) {\n super(\"Unable to confirm the submitted message\", { cause });\n this.name = \"AgentAdmissionUncertainError\";\n }\n}\n\nexport async function createSessionRun(\n token: string,\n message: string,\n files?: AttachedFile[],\n modelConfig?: ModelConfig,\n activeTranscript?: ActiveTranscriptReference,\n creditRequest?: {\n clientRequestId: string;\n clientMatterCode: string;\n speedBumpConfirmationToken?: string;\n queue?: boolean;\n queueRunId?: string;\n },\n planningMode = false,\n expectedPlanningModeRevision?: number,\n nextStepSelection?: NextStepSelection,\n): Promise {\n let response: Response;\n try {\n response = await fetchHelper(`${BASE}/sessions/${token}/messages`, {\n method: \"POST\",\n body: {\n message,\n queue: creditRequest?.queue,\n queue_run_id: creditRequest?.queueRunId,\n next_step_selection: nextStepSelection,\n files: files && files.length > 0 ? files : undefined,\n model_config: modelConfig,\n active_transcript: activeTranscript,\n client_request_id: creditRequest?.clientRequestId,\n client_matter_code: creditRequest?.clientMatterCode,\n credit_speed_bump_confirmation: creditRequest?.speedBumpConfirmationToken,\n planning_mode: planningMode,\n expected_planning_mode_revision: expectedPlanningModeRevision,\n },\n });\n } catch (error) {\n if (nextStepSelection) throw new AgentAdmissionUncertainError(error);\n throw error;\n }\n if (nextStepSelection && response.status >= 500) throw new AgentAdmissionUncertainError(response.status);\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as CreditAgentSpeedBumpPayload & {\n planning_cycle?: PlanningCycle;\n planning_mode?: boolean;\n planning_mode_revision?: number;\n };\n if (response.status === 409 && typeof body.planning_mode === \"boolean\") throw new PlanningModeConflictError(body);\n if (response.status === 409 && body.planning_cycle) {\n throw new PlanningActionError(body.error || \"Unable to update Plan\", body.planning_cycle, undefined, {\n status: response.status,\n code: body.code,\n });\n }\n await throwAgentRunError(response, body);\n }\n try {\n return await response.json();\n } catch (error) {\n if (nextStepSelection) throw new AgentAdmissionUncertainError(error);\n throw error;\n }\n}\n\nasync function planningAction(url: string, method: \"POST\" | \"DELETE\", body?: Record) {\n const response = await fetchHelper(url, { method, body });\n const payload = (await response.json().catch(() => ({}))) as PlanningActionResponse &\n CreditAgentSpeedBumpPayload & {\n new_question?: PlanningNewQuestion;\n };\n if (!response.ok) {\n const continuation =\n response.status === 428 && payload.code === \"agent_conversation_speed_bump_required\" && payload.new_question\n ? {\n speedBumpRequirement: { ...normalizeSpeedBumpRequirement(payload), required: true },\n newQuestion: payload.new_question,\n }\n : undefined;\n throw new PlanningActionError(payload.error || \"Unable to update Plan\", payload.planning_cycle, continuation, {\n status: response.status,\n code: payload.code,\n });\n }\n return payload;\n}\n\nexport function respondToPlanningOffer(token: string, planToken: string, decision: \"accept\" | \"execute_without_plan\") {\n return planningAction(`${BASE}/sessions/${token}/plans/${planToken}/offer-response`, \"POST\", { decision });\n}\n\nexport function submitPlanningResponse(\n token: string,\n planToken: string,\n activeInteractionToken: string,\n message: string,\n files?: AttachedFile[],\n clientRequestId: string = crypto.randomUUID(),\n speedBumpConfirmationToken?: string,\n questionResponse?: PlanningQuestionResponse,\n expectedPlanningModeRevision?: number,\n) {\n return planningAction(`${BASE}/sessions/${token}/plans/${planToken}/responses`, \"POST\", {\n expected_planning_mode_revision: expectedPlanningModeRevision,\n active_interaction_token: activeInteractionToken,\n response: questionResponse,\n message,\n files: files && files.length > 0 ? files : undefined,\n client_request_id: clientRequestId,\n credit_speed_bump_confirmation: speedBumpConfirmationToken,\n });\n}\n\nexport function editPlanningVersion(token: string, planToken: string, versionToken: string) {\n return planningAction(`${BASE}/sessions/${token}/plans/${planToken}/versions/${versionToken}/edit`, \"POST\");\n}\n\nexport function confirmPlanningVersion(token: string, planToken: string, versionToken: string) {\n return planningAction(`${BASE}/sessions/${token}/plans/${planToken}/versions/${versionToken}/confirm`, \"POST\");\n}\n\nexport function cancelPlanningCycle(token: string, planToken: string) {\n return planningAction(`${BASE}/sessions/${token}/plans/${planToken}`, \"DELETE\");\n}\n\nexport async function retrySessionRun(\n token: string,\n runId: string,\n clientRequestId?: string,\n speedBumpConfirmationToken?: string,\n): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/runs/${runId}/retry`, {\n method: \"POST\",\n body: {\n client_request_id: clientRequestId,\n credit_speed_bump_confirmation: speedBumpConfirmationToken,\n },\n });\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as CreditAgentSpeedBumpPayload;\n await throwAgentRunError(response, body);\n }\n return response.json();\n}\n\nexport async function getRunStatus(token: string, runId: string): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/runs/${runId}`);\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"genericRetry\");\n }\n return response.json();\n}\n\nexport async function ackRun(token: string, runId: string): Promise {\n try {\n await fetchHelper(`${BASE}/sessions/${token}/runs/${runId}/ack`, { method: \"POST\" });\n } catch {\n /* best-effort */\n }\n}\n\n/**\n * Opens an SSE connection to a run stream endpoint.\n */\nexport function streamRun(\n token: string,\n runId: string,\n onEvent: (event: unknown, eventId?: number) => void,\n onError: (error: Error) => void,\n onComplete: () => void,\n lastEventId?: number,\n): AbortController {\n const controller = new AbortController();\n const headers: Record = {\n Accept: \"text/event-stream\",\n };\n if (lastEventId && lastEventId > 0) {\n headers[\"Last-Event-ID\"] = String(lastEventId);\n }\n\n fetchHelper(`${BASE}/sessions/${token}/runs/${runId}/stream`, {\n method: \"GET\",\n headers,\n signal: controller.signal,\n })\n .then(async (response) => {\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"genericRetry\");\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw clerkError(null, \"genericRetry\");\n }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n let currentEventId: number | undefined;\n let dataLines: string[] = [];\n\n const flushEvent = () => {\n if (dataLines.length === 0) {\n currentEventId = undefined;\n return;\n }\n\n const payload = dataLines.join(\"\\n\").trim();\n dataLines = [];\n if (!payload) {\n currentEventId = undefined;\n return;\n }\n\n try {\n const parsed = JSON.parse(payload);\n onEvent(parsed, currentEventId);\n } catch {\n // Skip malformed JSON\n } finally {\n currentEventId = undefined;\n }\n };\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Parse SSE events from buffer\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\"; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) {\n flushEvent();\n continue;\n }\n if (trimmed.startsWith(\":\")) {\n continue;\n }\n if (trimmed.startsWith(\"id:\")) {\n const parsedId = Number.parseInt(trimmed.slice(3).trim(), 10);\n if (!Number.isNaN(parsedId)) {\n currentEventId = parsedId;\n }\n continue;\n }\n if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(5).trim());\n }\n }\n }\n\n if (buffer.trim()) {\n const trimmed = buffer.trim();\n if (trimmed.startsWith(\"id:\")) {\n const parsedId = Number.parseInt(trimmed.slice(3).trim(), 10);\n if (!Number.isNaN(parsedId)) {\n currentEventId = parsedId;\n }\n } else if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(5).trim());\n }\n }\n flushEvent();\n\n onComplete();\n })\n .catch((err) => {\n if (err.name === \"AbortError\") {\n onComplete();\n } else {\n onError(err);\n }\n });\n\n return controller;\n}\n\nexport async function submitMessageFeedback(\n token: string,\n messageId: number,\n rating: boolean,\n comment?: string,\n): Promise<{ message_id: number; rating: boolean }> {\n const response = await fetchHelper(`${BASE}/sessions/${token}/messages/${messageId}/feedback`, {\n method: \"POST\",\n body: { rating, comment: comment || undefined },\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"genericRetry\");\n }\n return response.json();\n}\n\nexport async function deleteMessageFeedback(token: string, messageId: number): Promise<{ message_id: number }> {\n const response = await fetchHelper(`${BASE}/sessions/${token}/messages/${messageId}/feedback`, {\n method: \"DELETE\",\n });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"genericRetry\");\n }\n return response.json();\n}\n\nexport interface MessageDraft {\n message: string;\n files: AttachedFile[];\n}\nexport interface ForkMessageResult {\n session_token: string;\n draft: MessageDraft;\n}\n\nasync function mutateMessage(\n token: string,\n messageId: number,\n action: string,\n method: \"POST\" | \"DELETE\",\n): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/messages/${messageId}/${action}`, { method });\n if (!response.ok) {\n const body = await response.json().catch(() => null);\n throw clerkError(body?.error, \"genericRetry\");\n }\n return response.json();\n}\n\nexport async function steerQueuedMessage(\n token: string,\n messageId: number,\n intent: SteerMessageIntent,\n confirmation?: string,\n): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/messages/${messageId}/steer`, {\n method: \"POST\",\n body: {\n expected_run_id: intent.expectedRunId,\n ...(intent.intent === \"restart\" ? { intent: \"restart\", queue_generation: intent.queueGeneration } : {}),\n ...(confirmation ? { credit_speed_bump_confirmation: confirmation } : {}),\n },\n });\n if (!response.ok) await throwAgentRunError(response, await response.json().catch(() => ({})));\n return response.json();\n}\nexport async function resumeQueuedMessage(\n token: string,\n messageId: number,\n confirmation: string | undefined,\n queueGeneration: number,\n): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/messages/${messageId}/resume`, {\n method: \"POST\",\n body: { credit_speed_bump_confirmation: confirmation, queue_generation: queueGeneration },\n });\n if (!response.ok) await throwAgentRunError(response, await response.json().catch(() => ({})));\n return response.json();\n}\nexport async function getMessageDraft(token: string, messageId: number): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/messages/${messageId}/draft`);\n if (!response.ok) throw clerkError((await response.json().catch(() => null))?.error, \"genericRetry\");\n return response.json();\n}\n\nexport function cancelQueuedMessage(\n token: string,\n messageId: number,\n): Promise<{ user_message: NonNullable; draft: MessageDraft }> {\n return mutateMessage(token, messageId, \"queue\", \"DELETE\");\n}\nexport function forkSessionMessage(token: string, messageId: number): Promise {\n return mutateMessage(token, messageId, \"fork\", \"POST\");\n}\n\nexport async function getBranchDraft(token: string): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/branch-draft`);\n if (!response.ok) throw clerkError((await response.json().catch(() => null))?.error, \"genericRetry\");\n return response.json();\n}\n\nexport async function getNextSteps(token: string): Promise<{ next_steps: unknown }> {\n const response = await fetchHelper(`${BASE}/sessions/${token}/next_steps`);\n if (!response.ok) throw new Error(\"Unable to load suggested next steps\");\n return response.json();\n}\n\nexport async function dismissNextSteps(\n token: string,\n sourceMessageId: number,\n reason: \"typing\" | \"selected\",\n selection?: NextStepSelection,\n): Promise {\n const response = await fetchHelper(`${BASE}/sessions/${token}/next_steps/dismiss`, {\n method: \"POST\",\n body: {\n source_message_id: sourceMessageId,\n reason,\n suggestion_id: selection?.suggestion_id,\n request_id: selection?.request_id,\n },\n });\n if (!response.ok) throw new Error(\"Unable to update suggested next steps\");\n}\n", "export interface NextStepSuggestion {\n id: string;\n label: string;\n required_input: string | null;\n required_capabilities: string[];\n start_in_planning_mode?: boolean;\n clarification_topic?: string | null;\n}\nexport interface NextStepSendContext {\n startInPlanningMode: boolean;\n isCurrent: () => boolean;\n}\nexport interface NextStepSelection {\n source_message_id: number;\n suggestion_id: string;\n request_id: string;\n}\nexport interface NextStepSet {\n schema_version: 1;\n source_message_id: number;\n source_run_id?: string;\n status: string;\n suggestions: NextStepSuggestion[];\n}\nexport function parseNextSteps(value: unknown): NextStepSet | undefined {\n if (!value || typeof value !== \"object\") return;\n const set = value as NextStepSet;\n if (set.schema_version !== 1 || !Number.isInteger(set.source_message_id) || typeof set.status !== \"string\") return;\n if (!Array.isArray(set.suggestions)) return;\n if (\n !set.suggestions.every(\n (s) =>\n typeof s.id === \"string\" &&\n typeof s.label === \"string\" &&\n s.label.trim() &&\n (s.required_input == null || typeof s.required_input === \"string\") &&\n (s.start_in_planning_mode === undefined || typeof s.start_in_planning_mode === \"boolean\") &&\n (s.clarification_topic == null || typeof s.clarification_topic === \"string\") &&\n (s.start_in_planning_mode === true || s.clarification_topic == null),\n )\n )\n return;\n return {\n ...set,\n suggestions: set.suggestions.map((suggestion) => ({\n ...suggestion,\n start_in_planning_mode: suggestion.start_in_planning_mode ?? false,\n clarification_topic: suggestion.clarification_topic ?? null,\n })),\n };\n}\n", "import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { dismissNextSteps, getNextSteps } from \"../api/agentPrototype\";\nimport { recordUserEvent } from \"../api/userEvents\";\nimport type { ChatMessage } from \"./useAgentPrototypeSession\";\nimport {\n parseNextSteps,\n type NextStepSelection,\n type NextStepSendContext,\n type NextStepSet,\n type NextStepSuggestion,\n} from \"../components/agent_prototype/nextSteps\";\n\nfunction rememberDismissal(key: string) {\n try {\n sessionStorage.setItem(`clerk-next-steps-dismissed:${key}`, \"1\");\n } catch {\n /* Storage is optional. */\n }\n}\nfunction rememberedDismissal(key: string | null) {\n try {\n return key !== null && sessionStorage.getItem(`clerk-next-steps-dismissed:${key}`) === \"1\";\n } catch {\n return false;\n }\n}\nasync function persistDismissal(\n token: string,\n sourceId: number,\n reason: \"typing\" | \"selected\",\n selection?: NextStepSelection,\n) {\n // Safe retries retain the original operation identity even after an uncertain response.\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n await dismissNextSteps(token, sourceId, reason, selection);\n return;\n } catch (error) {\n if (attempt === 2) throw error;\n }\n }\n}\n\n// Optional generation never changes the answer's streaming or loading state.\nexport function useAgentNextSteps(\n token: string | null,\n messages: ChatMessage[],\n enabled: boolean,\n send: (label: string, selection: NextStepSelection, context: NextStepSendContext) => Promise,\n) {\n const last = messages[messages.length - 1];\n const sourceId = enabled && last?.role === \"assistant\" && !last.isStreaming ? last.serverMessageId : undefined;\n const canonical = sourceId ? parseNextSteps(last.metadata?.next_steps) : undefined;\n const [polled, setPolled] = useState<{ token: string; set: NextStepSet } | null>(null);\n const [dismissed, setDismissed] = useState(null);\n const sourceKey = token && sourceId ? `${token}:${sourceId}` : null;\n const hiddenRef = useRef(null);\n const polledSet = polled?.token === token && polled.set.source_message_id === sourceId ? polled.set : undefined;\n const canonicalFinished = canonical && ![\"pending\", \"generating\"].includes(canonical.status);\n const set = canonicalFinished ? canonical : (polledSet ?? canonical);\n const isHidden = sourceKey === dismissed || sourceKey === hiddenRef.current || rememberedDismissal(sourceKey);\n const active = !isHidden && set?.source_message_id === sourceId ? set : undefined;\n const currentSourceRef = useRef(null);\n currentSourceRef.current =\n token && last?.role === \"assistant\" && !last.isStreaming && last.serverMessageId\n ? `${token}:${last.serverMessageId}`\n : null;\n const mountedRef = useRef(false);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n const currentRef = useRef({ token, sourceId, sourceKey, active });\n currentRef.current = { token, sourceId, sourceKey, active };\n\n useEffect(() => {\n if (!token || !sourceId || !sourceKey || isHidden || !set || ![\"pending\", \"generating\"].includes(set.status))\n return;\n let cancelled = false;\n let timeout: ReturnType;\n let attempts = 0;\n const poll = async () => {\n try {\n const response = await getNextSteps(token);\n if (cancelled || currentRef.current.sourceKey !== sourceKey || hiddenRef.current === sourceKey) return;\n const next = parseNextSteps(response.next_steps);\n if (!next || next.source_message_id !== sourceId) {\n setPolled({\n token,\n set: { schema_version: 1, source_message_id: sourceId, status: \"dismissed\", suggestions: [] },\n });\n return;\n }\n setPolled({ token, set: next });\n if (![\"pending\", \"generating\"].includes(next.status)) return;\n } catch {\n /* The completed answer remains usable on optional refresh failure. */\n }\n if (!cancelled && ++attempts < 30) timeout = setTimeout(poll, 2000);\n };\n timeout = setTimeout(poll, 1000);\n return () => {\n cancelled = true;\n clearTimeout(timeout);\n };\n }, [token, sourceId, sourceKey, isHidden, set?.status]);\n\n const edited = useCallback(() => {\n const { token, sourceId, sourceKey, active } = currentRef.current;\n if (\n !token ||\n !sourceId ||\n !sourceKey ||\n hiddenRef.current === sourceKey ||\n rememberedDismissal(sourceKey) ||\n active?.status === \"ready\"\n )\n return;\n hiddenRef.current = sourceKey;\n rememberDismissal(sourceKey);\n setDismissed(sourceKey);\n void persistDismissal(token, sourceId, \"typing\").catch(() => undefined);\n }, []);\n\n const select = useCallback(\n (suggestion: NextStepSuggestion) => {\n const { token, sourceId, sourceKey, active } = currentRef.current;\n if (!token || !sourceId || !sourceKey || hiddenRef.current === sourceKey || active?.status !== \"ready\") return;\n if (!active.suggestions.some((item) => item.id === suggestion.id)) return;\n hiddenRef.current = sourceKey; // Synchronous latch before any dialog or request.\n rememberDismissal(sourceKey);\n setDismissed(sourceKey);\n const selection: NextStepSelection = {\n source_message_id: sourceId,\n suggestion_id: suggestion.id,\n request_id: crypto.randomUUID(),\n };\n void recordUserEvent({\n event_name: \"clerk_next_step_selected\",\n event_properties: {\n ...selection,\n start_in_planning_mode: suggestion.start_in_planning_mode === true,\n required_capabilities: suggestion.required_capabilities,\n },\n });\n void (async () => {\n try {\n await persistDismissal(token, sourceId, \"selected\", selection);\n if (currentRef.current.sourceKey !== sourceKey) return;\n await send(suggestion.label, selection, {\n startInPlanningMode: suggestion.start_in_planning_mode === true,\n isCurrent: () => mountedRef.current && currentSourceRef.current === sourceKey,\n });\n } catch {\n /* Keep consumed after cancelled/failed selection; preserve the manual draft. */\n }\n })();\n },\n [send],\n );\n\n return { nextSteps: active?.status === \"ready\" ? active : undefined, selectNextStep: select, onComposerEdit: edited };\n}\n", "import React, { useEffect, useState } from \"react\";\n\nconst AnimatedEllipsis: React.FC<{ delayMs: number; resetOverrideCtr?: number | string }> = ({\n delayMs,\n resetOverrideCtr,\n}) => {\n const [count, setCount] = useState(1);\n\n useEffect(() => {\n setCount(1);\n const id = window.setInterval(() => {\n setCount((c) => (c % 3) + 1);\n }, delayMs);\n return () => window.clearInterval(id);\n }, [delayMs, resetOverrideCtr]);\n\n return (\n \n = 1 ? \"visible\" : \"hidden\" }}>.\n = 2 ? \"visible\" : \"hidden\" }}>.\n = 3 ? \"visible\" : \"hidden\" }}>.\n \n );\n};\n\nexport default AnimatedEllipsis;\n", "import React, { useState, useEffect, useRef } from \"react\";\nimport { Box, Typography, Collapse } from \"@mui/material\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport {\n X,\n ChevronDown,\n ChevronUp,\n Brain,\n Search,\n FileText,\n ExternalLink,\n Shuffle,\n List,\n PenLine,\n MessageSquarePlus,\n Download,\n BadgeCheck,\n Rss,\n HelpCircle,\n Minimize2,\n Scissors,\n Folder,\n FolderOpen,\n History,\n MessageSquare,\n StickyNote,\n FolderPlus,\n FolderInput,\n FilePlus2,\n Scale,\n Users,\n ReceiptText,\n CircleDollarSign,\n BookOpen,\n Terminal,\n HardDrive,\n FileOutput,\n CircleAlert,\n} from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport type { ToolCallRecord, ToolResultRecord } from \"../../api/queries/agentPrototype.types\";\nimport AnimatedEllipsis from \"../atoms/AnimatedEllipsis\";\n\ninterface AgentPrototypeThinkingProps {\n thinking: string[];\n thinkingSinceLastTool?: string;\n toolCalls: ToolCallRecord[];\n toolResults: ToolResultRecord[];\n isAwaitingUserInput?: boolean;\n isStreaming?: boolean;\n isTerminalError?: boolean;\n hasContent?: boolean;\n isSegmentComplete?: boolean;\n completedWorkLabel?: string;\n sessionToken?: string;\n}\n\ninterface TimelineStep {\n type: string;\n label: string;\n resultSummary?: string;\n href: string;\n inProgress: boolean;\n icon: LucideIcon;\n isDelegate?: boolean;\n indented?: boolean;\n tone?: \"default\" | \"error\";\n callIndex?: number;\n}\n\ninterface BuildTimelineResult {\n steps: TimelineStep[];\n resultForCall: Map;\n}\n\nconst WAITING_FOR_INPUT_LABEL = \"Waiting for your input.\";\nconst TERMINAL_ERROR_STATUS_LABEL = \"Stopped due to an error\";\nconst HIDDEN_TIMELINE_TOOLS = new Set([\"list_docket_reference_values\", \"lookup_court\", \"list_transcript_courts\"]);\nconst COURT_RECORD_TOOLS = new Set([\"read_court_record\", \"view_court_record_pages\", \"recover_court_record\"]);\n\nfunction stripTrailingDots(text: string): string {\n return text.replace(/\\.+$/, \"\");\n}\n\nfunction isHiddenTimelineTool(tool: string): boolean {\n return HIDDEN_TIMELINE_TOOLS.has(tool);\n}\n\nconst TOOL_CONFIG: Record<\n string,\n {\n type: string;\n icon: LucideIcon;\n activeLabel: string;\n doneLabel: string;\n failureLabel?: string;\n activeLabelSingular?: string;\n doneLabelSingular?: string;\n }\n> = {\n boolean_search: {\n type: \"search\",\n icon: Search,\n activeLabel: \"Getting search results\",\n doneLabel: \"Got search results\",\n },\n get_transcript: { type: \"transcript\", icon: FileText, activeLabel: \"Opening\", doneLabel: \"Opened\" },\n create_word_document: {\n type: \"document\",\n icon: FilePlus2,\n activeLabel: \"Creating Word document\",\n doneLabel: \"Created Word document\",\n },\n create_pdf_document: {\n type: \"document\",\n icon: FilePlus2,\n activeLabel: \"Creating PDF\",\n doneLabel: \"Created PDF\",\n },\n convert_pdf_to_docx: {\n type: \"document\",\n icon: Shuffle,\n activeLabel: \"Converting PDF to Word\",\n doneLabel: \"Converted PDF to Word\",\n },\n get_document_paragraphs: {\n type: \"document\",\n icon: List,\n activeLabel: \"Reading document\",\n doneLabel: \"Read document\",\n },\n apply_redline: {\n type: \"document\",\n icon: PenLine,\n activeLabel: \"Marking up document\",\n doneLabel: \"Marked up document\",\n },\n add_document_comment: {\n type: \"document\",\n icon: MessageSquarePlus,\n activeLabel: \"Adding comment\",\n doneLabel: \"Added comment\",\n },\n get_document_download_url: {\n type: \"document\",\n icon: Download,\n activeLabel: \"Preparing download link\",\n doneLabel: \"Prepared download link\",\n },\n report_status: { type: \"status\", icon: Rss, activeLabel: \"Updating status\", doneLabel: \"Updated status\" },\n delegate_search: {\n type: \"search\",\n icon: Search,\n activeLabel: \"Searching transcripts\",\n doneLabel: \"Searched transcripts\",\n },\n delegate_read: {\n type: \"transcript\",\n icon: FileText,\n activeLabel: \"Reading transcripts\",\n doneLabel: \"Read transcripts\",\n activeLabelSingular: \"Reading transcript\",\n doneLabelSingular: \"Read transcript\",\n },\n delegate_verify: {\n type: \"verify\",\n icon: BadgeCheck,\n activeLabel: \"Verifying citations\",\n doneLabel: \"Verified citations\",\n activeLabelSingular: \"Verifying citation\",\n doneLabelSingular: \"Verified citation\",\n },\n delegate_docket_search: {\n type: \"docket\",\n icon: Scale,\n activeLabel: \"Gathering court materials\",\n doneLabel: \"Gathered court materials\",\n },\n delegate_court_record_read: {\n type: \"docket\",\n icon: BookOpen,\n activeLabel: \"Reading court record\",\n doneLabel: \"Read court record\",\n },\n search_dockets: {\n type: \"docket\",\n icon: Search,\n activeLabel: \"Searching dockets\",\n doneLabel: \"Searched dockets\",\n failureLabel: \"Could not search dockets\",\n },\n get_case_docket: {\n type: \"docket\",\n icon: List,\n activeLabel: \"Reading case docket\",\n doneLabel: \"Read case docket\",\n failureLabel: \"Could not read case docket\",\n },\n get_party_report: {\n type: \"docket\",\n icon: Users,\n activeLabel: \"Reading party report\",\n doneLabel: \"Read party report\",\n failureLabel: \"Could not read party report\",\n },\n quote_court_artifacts: {\n type: \"docket\",\n icon: ReceiptText,\n activeLabel: \"Quoting court materials\",\n doneLabel: \"Quoted court materials\",\n failureLabel: \"Could not quote court materials\",\n },\n request_court_artifact_approval: {\n type: \"docket\",\n icon: CircleDollarSign,\n activeLabel: \"Waiting for approval\",\n doneLabel: \"Approval received\",\n failureLabel: \"Approval not received\",\n },\n retrieve_court_artifacts: {\n type: \"docket\",\n icon: Download,\n activeLabel: \"Retrieving court materials\",\n doneLabel: \"Retrieved court materials\",\n failureLabel: \"Could not retrieve court materials\",\n },\n read_court_record: {\n type: \"docket\",\n icon: FileText,\n activeLabel: \"Opening\",\n doneLabel: \"Opened\",\n failureLabel: \"Could not read court record\",\n },\n view_court_record_pages: {\n type: \"docket\",\n icon: FileText,\n activeLabel: \"Opening court record pages\",\n doneLabel: \"Opened court record pages\",\n failureLabel: \"Could not open court record pages\",\n },\n recover_court_record: {\n type: \"docket\",\n icon: FileText,\n activeLabel: \"Recovering court record\",\n doneLabel: \"Recovered court record\",\n failureLabel: \"Court record recovery failed\",\n },\n read_party_report: {\n type: \"docket\",\n icon: Users,\n activeLabel: \"Reading party report\",\n doneLabel: \"Read party report\",\n failureLabel: \"Could not read party report\",\n },\n lookup_judge: {\n type: \"search\",\n icon: Search,\n activeLabel: \"Looking up judge\",\n doneLabel: \"Looked up judge\",\n },\n list_folders: {\n type: \"workspace\",\n icon: Folder,\n activeLabel: \"Checking folders\",\n doneLabel: \"Checked folders\",\n failureLabel: \"Could not check folders\",\n },\n read_folder: {\n type: \"workspace\",\n icon: FolderOpen,\n activeLabel: \"Reading folder\",\n doneLabel: \"Read folder\",\n failureLabel: \"Could not read folder\",\n },\n list_clerk_sessions: {\n type: \"workspace\",\n icon: History,\n activeLabel: \"Searching sessions\",\n doneLabel: \"Searched sessions\",\n failureLabel: \"Couldn't search sessions\",\n },\n read_clerk_session: {\n type: \"workspace\",\n icon: MessageSquare,\n activeLabel: \"Reading session\",\n doneLabel: \"Read session\",\n failureLabel: \"Couldn't read session\",\n },\n list_annotations: {\n type: \"workspace\",\n icon: StickyNote,\n activeLabel: \"Checking notes and highlights\",\n doneLabel: \"Checked notes and highlights\",\n failureLabel: \"Could not check notes and highlights\",\n },\n read_annotation: {\n type: \"workspace\",\n icon: StickyNote,\n activeLabel: \"Reading note\",\n doneLabel: \"Read note\",\n failureLabel: \"Could not read note\",\n },\n ensure_folder: {\n type: \"workspace\",\n icon: FolderPlus,\n activeLabel: \"Preparing folder\",\n doneLabel: \"Prepared folder\",\n failureLabel: \"Could not prepare folder\",\n },\n save_to_folder: {\n type: \"workspace\",\n icon: FolderInput,\n activeLabel: \"Saving to folder\",\n doneLabel: \"Saved to folder\",\n failureLabel: \"Could not save to folder\",\n },\n add_note: {\n type: \"workspace\",\n icon: StickyNote,\n activeLabel: \"Adding note\",\n doneLabel: \"Added note\",\n failureLabel: \"Could not add note\",\n },\n ask_clarifying_question: {\n type: \"clarify\",\n icon: HelpCircle,\n activeLabel: \"Asking a question\",\n doneLabel: \"Asked a question\",\n },\n compact_context: {\n type: \"context\",\n icon: Minimize2,\n activeLabel: \"Compacting context\",\n doneLabel: \"Compacted context\",\n },\n truncate_context: {\n type: \"context\",\n icon: Scissors,\n activeLabel: \"Truncating context\",\n doneLabel: \"Truncated context\",\n },\n materialize_session_computer: {\n type: \"computer\",\n icon: HardDrive,\n activeLabel: \"Preparing the in-app computer\",\n doneLabel: \"Prepared the in-app computer\",\n failureLabel: \"Could not prepare the in-app computer\",\n },\n run_session_computer_command: {\n type: \"computer\",\n icon: Terminal,\n activeLabel: \"Running a command on the in-app computer\",\n doneLabel: \"Ran a command on the in-app computer\",\n failureLabel: \"Command failed on the in-app computer\",\n },\n list_session_computer_files: {\n type: \"computer\",\n icon: FolderOpen,\n activeLabel: \"Listing in-app computer files\",\n doneLabel: \"Listed in-app computer files\",\n failureLabel: \"Could not list in-app computer files\",\n },\n run_session_computer_smoke_test: {\n type: \"computer\",\n icon: Terminal,\n activeLabel: \"Checking in-app computer tooling\",\n doneLabel: \"Checked in-app computer tooling\",\n failureLabel: \"Could not check in-app computer tooling\",\n },\n export_transcripts_to_session_computer: {\n type: \"computer\",\n icon: FileOutput,\n activeLabel: \"Exporting transcripts to the in-app computer\",\n doneLabel: \"Exported transcripts to the in-app computer\",\n failureLabel: \"Could not export transcripts to the in-app computer\",\n },\n publish_session_computer_artifacts: {\n type: \"computer\",\n icon: FileOutput,\n activeLabel: \"Preparing downloadable files\",\n doneLabel: \"Prepared downloadable files\",\n failureLabel: \"Could not prepare downloadable files\",\n },\n read_session_computer_output: {\n type: \"computer\",\n icon: FileText,\n activeLabel: \"Reading command output\",\n doneLabel: \"Read command output\",\n failureLabel: \"Could not read command output\",\n },\n read_session_computer_file: {\n type: \"computer\",\n icon: FileText,\n activeLabel: \"Reading an in-app computer file\",\n doneLabel: \"Read an in-app computer file\",\n failureLabel: \"Could not read an in-app computer file\",\n },\n};\n\n/** Build a link to the search results page with all filters */\nfunction searchHref(input: Record): string {\n const params = new URLSearchParams();\n if (input.query) params.set(\"queryText\", String(input.query));\n if (input.judge_names) {\n const names = input.judge_names as string[];\n if (names.length > 0) params.set(\"judgeIds\", names.join(\",\"));\n }\n const filters = input.filters as Record | undefined;\n if (filters) {\n if (filters.hearing_date_from) params.set(\"hearingDateFrom\", String(filters.hearing_date_from));\n if (filters.hearing_date_to) params.set(\"hearingDateTo\", String(filters.hearing_date_to));\n if (filters.case_number) params.set(\"caseNumber\", String(filters.case_number));\n if (filters.case_name) params.set(\"caseName\", String(filters.case_name));\n if (filters.motion_type) params.set(\"motionType\", String(filters.motion_type));\n }\n if (input.page && Number(input.page) > 1) {\n params.set(\"page\", String(input.page));\n }\n return `/transcripts?${params.toString()}`;\n}\n\n/** Build a link to the transcript reader */\nfunction transcriptHref(transcriptId: number, highlightText?: string): string {\n const params = new URLSearchParams();\n params.set(\"initialReaderTranscriptId\", String(transcriptId));\n if (highlightText) {\n params.set(\"initialReaderTranscriptTextToHighlight\", highlightText.slice(0, 150));\n }\n return `/transcripts?${params.toString()}`;\n}\n\n/** Extract a display label from a get_transcript tool result summary.\n * Format is typically \"Read: Case Name (date)\" \u2014 return \"Case Name\" */\nfunction parseCaseName(summary: string): string | null {\n const match = summary.match(/^Read:\\s*(.+?)(?:\\s*\\(|$)/);\n return match ? match[1].trim() : null;\n}\n\n/** Extract case name from structured tool_result detail payload */\nfunction caseNameFromDetail(detail: Record | undefined): string | null {\n if (!detail) return null;\n const caseName = detail.case_name;\n return typeof caseName === \"string\" && caseName.trim() ? caseName.trim() : null;\n}\n\n/** Format the full query for the expanded thinking step. */\nfunction queryDetail(query: string): string {\n return `: \"${query}\"`;\n}\n\nfunction isFailedToolResult(result: ToolResultRecord | undefined): boolean {\n if (result?.detail?.failed === true) return true;\n if (result?.detail?.error === true) return true;\n\n const status = result?.detail?.status;\n if (typeof status !== \"string\") return false;\n\n return new Set([\"error\", \"validation_error\", \"provider_unavailable\", \"not_found\"]).has(status.trim().toLowerCase());\n}\n\ninterface CourtRecordTimelineMetadata {\n label: string;\n caseName: string | null;\n}\n\nfunction recordValue(value: unknown): Record | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record)\n : null;\n}\n\nfunction nonblankString(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction scalarDocketNumber(value: unknown): string | null {\n if (typeof value === \"number\" && Number.isFinite(value)) return String(value);\n return nonblankString(value);\n}\n\nfunction courtRecordTimelineMetadata(\n call: ToolCallRecord,\n result: ToolResultRecord | undefined,\n): CourtRecordTimelineMetadata | null {\n const input = recordValue(call.input) ?? {};\n const courtDocumentId = input.court_document_id;\n if (typeof courtDocumentId !== \"string\" && typeof courtDocumentId !== \"number\") return null;\n\n const sources = result?.detail?.docket_connect_sources;\n if (!Array.isArray(sources)) return null;\n\n const source = sources.find((candidate) => {\n const source = recordValue(candidate);\n const sourceCourtDocumentId = source?.court_document_id;\n return typeof sourceCourtDocumentId === typeof courtDocumentId && sourceCourtDocumentId === courtDocumentId;\n });\n const sourceMetadata = recordValue(source);\n const docketNumber = scalarDocketNumber(sourceMetadata?.docket_number);\n const displayTitle = nonblankString(sourceMetadata?.display_title);\n if (!displayTitle && !docketNumber) return null;\n\n return {\n label: displayTitle || `Dkt. ${docketNumber}`,\n caseName: nonblankString(sourceMetadata?.case_name),\n };\n}\n\nfunction courtRecordProgress(result: ToolResultRecord | undefined): {\n label: string;\n inProgress: boolean;\n failed?: boolean;\n} | null {\n if (!result?.detail) return null;\n const detail = result.detail;\n const recovery = recordValue(detail.recovery);\n const state = detail.processing_state;\n const waitingReason = recovery?.waiting_reason ?? detail.waiting_reason;\n if (state === \"failed\" || detail.status === \"failed\") {\n return { label: \"Court record recovery failed\", inProgress: false, failed: true };\n }\n if (state === \"waiting\" || detail.status === \"waiting\" || detail.status === \"assessment_required\") {\n const label =\n waitingReason === \"assessment_required\" || detail.status === \"assessment_required\"\n ? \"Waiting for page review\"\n : waitingReason === \"recovery_allowance_required\"\n ? \"Waiting for recovery allowance\"\n : [\"recovery_allowance_exhausted\", \"ocr_attempt_limit\", \"allowance_storage_limit\"].includes(\n String(waitingReason),\n )\n ? \"Waiting at recovery limit\"\n : \"Waiting for court record recovery\";\n return { label, inProgress: true };\n }\n if (state === \"processing\" || state === \"queued\" || detail.status === \"processing\") {\n const pending = Array.isArray(recovery?.pending_ocr_pages)\n ? new Set(recovery.pending_ocr_pages.filter((page) => Number.isSafeInteger(page) && page > 0)).size\n : 0;\n const total = recovery?.total_pages;\n const ranges = Array.isArray(recovery?.completed_native_ranges) ? recovery.completed_native_ranges : [];\n const completedRanges = ranges\n .flatMap((range): Array<[number, number]> => {\n const entry = recordValue(range);\n const first = entry?.first_page;\n const last = entry?.last_page;\n return typeof first === \"number\" &&\n typeof last === \"number\" &&\n Number.isSafeInteger(first) &&\n Number.isSafeInteger(last) &&\n first > 0 &&\n last >= first\n ? [[first, last]]\n : [];\n })\n .sort(([first], [second]) => first - second);\n let completed = 0;\n let through = 0;\n for (const [first, last] of completedRanges) {\n completed += Math.max(0, last - Math.max(through, first - 1));\n through = Math.max(through, last);\n }\n const suffix =\n pending > 0\n ? ` (${pending} ${pending === 1 ? \"page\" : \"pages\"} awaiting recovery)`\n : typeof total === \"number\" && Number.isSafeInteger(total) && completed > 0 && completed <= total\n ? ` (${completed} of ${total} pages processed)`\n : \"\";\n return {\n label: `${state === \"queued\" ? \"Queued court record\" : \"Processing court record\"}${suffix}`,\n inProgress: true,\n };\n }\n if (detail.text_coverage === \"partial\") {\n const quality = Array.isArray(detail.page_quality) ? detail.page_quality : [];\n const unresolved = Array.isArray(detail.unresolved_pages)\n ? detail.unresolved_pages\n : quality.flatMap((page) => {\n const entry = recordValue(page);\n return entry && [\"review_needed\", \"unrecoverable\"].includes(String(entry.status)) ? [entry.page_number] : [];\n });\n const count = new Set(unresolved.filter((page) => Number.isSafeInteger(page) && Number(page) > 0)).size;\n return {\n label: `Opened partial court record${count ? ` (${count} unresolved ${count === 1 ? \"page\" : \"pages\"})` : \"\"}`,\n inProgress: false,\n };\n }\n if (detail.text_coverage === \"unavailable\") return { label: \"Court record text unavailable\", inProgress: false };\n return null;\n}\n\nfunction approvalResultStatus(result: ToolResultRecord | undefined): string | null {\n const detailStatus = result?.detail?.status;\n if (typeof detailStatus === \"string\" && detailStatus.trim()) return detailStatus.trim().toLowerCase();\n\n const approvalStatus = result?.detail?.approval_status;\n if (typeof approvalStatus === \"string\" && approvalStatus.trim()) return approvalStatus.trim().toLowerCase();\n\n const summaryMatch = result?.summary?.match(/:\\s*([a-z_ -]+)\\s*$/i);\n return summaryMatch ? summaryMatch[1].trim().toLowerCase().replace(/\\s+/g, \"_\") : null;\n}\n\nfunction approvalLabel(result: ToolResultRecord | undefined, inProgress: boolean): string {\n if (inProgress) return \"Waiting for approval...\";\n\n const status = approvalResultStatus(result);\n if (!status) return \"Approval received\";\n\n const pendingStatuses = new Set([\"pending\", \"pending_approval\", \"approval_required\", \"waiting\", \"requested\"]);\n const approvedStatuses = new Set([\"approved\", \"approval_received\", \"received\", \"approval_granted\"]);\n const negativeStatuses = new Set([\n \"declined\",\n \"declined_by_timeout\",\n \"denied\",\n \"cancelled\",\n \"canceled\",\n \"rejected\",\n \"expired\",\n \"failed\",\n \"failure\",\n \"error\",\n ]);\n\n if (pendingStatuses.has(status)) return \"Waiting for approval...\";\n if (approvedStatuses.has(status)) return \"Approval received\";\n if (status === \"blocked_limit\") return \"Limit reached\";\n if (negativeStatuses.has(status)) return \"Approval not received\";\n\n return \"Approval received\";\n}\n\n/** Build a single tool step (non-delegate) */\nfunction buildToolStep(\n call: ToolCallRecord,\n result: ToolResultRecord | undefined,\n indented?: boolean,\n courtRecordMetadata?: CourtRecordTimelineMetadata | null,\n showCourtRecordCaseName = false,\n): TimelineStep {\n const progress = COURT_RECORD_TOOLS.has(call.tool) ? courtRecordProgress(result) : null;\n const inProgress = progress?.inProgress ?? !result;\n const failed = progress?.failed || isFailedToolResult(result);\n const cfg = TOOL_CONFIG[call.tool];\n // MCP-originated runs intentionally expose content-free activity events.\n // Their live web projection can therefore omit private tool inputs.\n const input = recordValue(call.input) ?? {};\n\n // Href \u2014 clickable link for searchable/readable/downloadable tools\n let href = \"#\";\n if (call.tool === \"boolean_search\") {\n const courtIds = input.court_ids;\n const isCourtScoped = Array.isArray(courtIds) && courtIds.length > 0;\n const hasPublicQuery = typeof input.query === \"string\" && input.query.trim().length > 0;\n href = isCourtScoped || !hasPublicQuery ? \"#\" : searchHref(input);\n } else if (call.tool === \"get_transcript\") {\n const transcriptId = input.transcript_id;\n if (typeof transcriptId === \"number\" && Number.isSafeInteger(transcriptId) && transcriptId > 0) {\n href = transcriptHref(transcriptId);\n }\n }\n\n // Label with contextual detail\n let label: string;\n if (call.tool === \"report_status\") {\n if (result?.summary) {\n label = result.summary;\n } else {\n label = \"Updating status...\";\n }\n return {\n type: \"status\",\n label,\n href: \"#\",\n inProgress,\n icon: TOOL_CONFIG.report_status.icon,\n indented,\n };\n }\n\n if (cfg) {\n let detail = \"\";\n if (call.tool === \"boolean_search\") {\n detail = typeof input.query === \"string\" && input.query.trim() ? queryDetail(input.query) : \"\";\n const page = input.page as number | undefined;\n if (page && page > 1) {\n detail += ` (page ${page})`;\n }\n } else if (call.tool === \"get_transcript\") {\n if (result) {\n const caseName = caseNameFromDetail(result.detail) || parseCaseName(result.summary);\n detail = caseName ? `: ${caseName}` : \" transcript\";\n } else if (input.case_name) {\n detail = `: ${input.case_name}`;\n } else {\n detail = \" transcript\";\n }\n } else if (call.tool === \"read_court_record\" && !courtRecordMetadata) {\n detail = \" court record\";\n }\n if (failed) {\n label = progress?.failed\n ? progress.label\n : (cfg.failureLabel ?? `Could not ${stripTrailingDots(cfg.activeLabel).toLowerCase()}${detail}`);\n } else if (progress) {\n label = progress.label;\n if (courtRecordMetadata) label += `: ${courtRecordMetadata.label}`;\n if (showCourtRecordCaseName && courtRecordMetadata?.caseName) label += ` (${courtRecordMetadata.caseName})`;\n if (inProgress) label += \"...\";\n } else if (COURT_RECORD_TOOLS.has(call.tool) && courtRecordMetadata) {\n label = `${inProgress ? cfg.activeLabel : cfg.doneLabel}: ${courtRecordMetadata.label}`;\n if (showCourtRecordCaseName && courtRecordMetadata.caseName) {\n label += ` (${courtRecordMetadata.caseName})`;\n }\n if (inProgress) label += \"...\";\n } else if (call.tool === \"request_court_artifact_approval\") {\n label = approvalLabel(result, inProgress);\n } else {\n label = inProgress ? `${cfg.activeLabel}${detail}...` : `${cfg.doneLabel}${detail}`;\n }\n } else {\n label = call.tool;\n }\n\n return {\n type: cfg?.type ?? \"search\",\n label,\n resultSummary: !cfg && result?.summary ? result.summary : undefined,\n href,\n inProgress,\n icon: cfg?.icon ?? Brain,\n indented,\n tone: failed ? \"error\" : undefined,\n };\n}\n\n/** Build timeline steps with delegateId-based parent-child nesting */\nfunction buildTimeline(toolCalls: ToolCallRecord[], toolResults: ToolResultRecord[]): BuildTimelineResult {\n // Tagged progress replaces earlier results for the exact call; legacy results keep FIFO matching.\n const resultForCall = new Map();\n const usedResults = new Set();\n for (let callIdx = 0; callIdx < toolCalls.length; callIdx++) {\n const call = toolCalls[callIdx];\n for (let resIdx = 0; resIdx < toolResults.length; resIdx++) {\n if (usedResults.has(resIdx)) continue;\n const res = toolResults[resIdx];\n const match =\n call.tool === res.tool &&\n call.delegateId === res.delegateId &&\n (call.toolCallId || res.toolCallId ? call.toolCallId === res.toolCallId : true);\n if (match) {\n resultForCall.set(callIdx, res);\n usedResults.add(resIdx);\n if (!call.toolCallId) break;\n }\n }\n }\n\n const courtRecordMetadataByCall = new Map();\n for (let callIdx = 0; callIdx < toolCalls.length; callIdx++) {\n const call = toolCalls[callIdx];\n if (!COURT_RECORD_TOOLS.has(call.tool)) continue;\n\n const metadata =\n courtRecordTimelineMetadata(call, resultForCall.get(callIdx)) ??\n toolResults\n .map((result) => courtRecordTimelineMetadata(call, result))\n .find((candidate): candidate is CourtRecordTimelineMetadata => candidate !== null);\n if (metadata) courtRecordMetadataByCall.set(callIdx, metadata);\n }\n const showCourtRecordCaseName =\n new Set(\n Array.from(courtRecordMetadataByCall.values())\n .map((metadata) => metadata.caseName)\n .filter((caseName): caseName is string => caseName !== null),\n ).size > 1;\n\n // Build parent-child map: delegateId \u2192 delegate's call index\n const delegateIdToCallIdx = new Map();\n for (let i = 0; i < toolCalls.length; i++) {\n const call = toolCalls[i];\n if (call.tool.startsWith(\"delegate_\") && call.delegateId) {\n delegateIdToCallIdx.set(call.delegateId, i);\n }\n }\n\n // Map child call indices to their parent delegate call index\n const childOf = new Map();\n for (let i = 0; i < toolCalls.length; i++) {\n const call = toolCalls[i];\n if (!call.tool.startsWith(\"delegate_\") && call.delegateId) {\n const parentIdx = delegateIdToCallIdx.get(call.delegateId);\n if (parentIdx !== undefined) {\n childOf.set(i, parentIdx);\n }\n }\n }\n\n // Build flat step list: delegates as headers, children indented\n const rawSteps: TimelineStep[] = [];\n const stepIdxToCallIdx = new Map();\n for (let i = 0; i < toolCalls.length; i++) {\n const call = toolCalls[i];\n const result = resultForCall.get(i);\n const isDelegate = call.tool.startsWith(\"delegate_\");\n const isChild = childOf.has(i);\n\n if (isDelegate) {\n const cfg = TOOL_CONFIG[call.tool];\n const childCount = call.delegateId ? Array.from(childOf.values()).filter((p) => p === i).length : 0;\n const singular = childCount <= 1 && cfg?.activeLabelSingular;\n const activeLabel = singular ? cfg.activeLabelSingular! : (cfg?.activeLabel ?? call.tool);\n const doneLabel = singular ? cfg.doneLabelSingular! : (cfg?.doneLabel ?? call.tool);\n\n stepIdxToCallIdx.set(rawSteps.length, i);\n rawSteps.push({\n type: cfg?.type ?? \"search\",\n label: result ? doneLabel : `${activeLabel}...`,\n href: \"#\",\n inProgress: !result,\n icon: cfg?.icon ?? Brain,\n isDelegate: true,\n callIndex: i,\n });\n } else {\n stepIdxToCallIdx.set(rawSteps.length, i);\n rawSteps.push({\n ...buildToolStep(call, result, isChild, courtRecordMetadataByCall.get(i), showCourtRecordCaseName),\n callIndex: i,\n });\n }\n }\n\n // Reorder: each delegate parent is immediately followed by its children\n const childrenByParent = new Map();\n for (const [ci, pi] of Array.from(childOf.entries())) {\n if (!childrenByParent.has(pi)) childrenByParent.set(pi, []);\n childrenByParent.get(pi)!.push(ci);\n }\n // Map from callIdx \u2192 stepIdx for child lookup\n const callIdxToStepIdx = new Map();\n for (const [si, ci] of Array.from(stepIdxToCallIdx.entries())) {\n callIdxToStepIdx.set(ci, si);\n }\n\n const steps: TimelineStep[] = [];\n const placed = new Set();\n for (let si = 0; si < rawSteps.length; si++) {\n if (placed.has(si)) continue;\n steps.push(rawSteps[si]);\n placed.add(si);\n // If this step is a delegate parent, immediately append its children\n const callIdx = stepIdxToCallIdx.get(si);\n if (callIdx !== undefined) {\n const childCallIdxs = childrenByParent.get(callIdx);\n if (childCallIdxs) {\n for (const cci of childCallIdxs) {\n const childStepIdx = callIdxToStepIdx.get(cci);\n if (childStepIdx !== undefined && !placed.has(childStepIdx)) {\n steps.push(rawSteps[childStepIdx]);\n placed.add(childStepIdx);\n }\n }\n }\n }\n }\n\n return { steps, resultForCall };\n}\n\nfunction projectTimelineSteps(\n rawSteps: TimelineStep[],\n isStreaming: boolean | undefined,\n isTerminalError: boolean | undefined,\n): TimelineStep[] {\n const executionSteps = rawSteps.filter((step) => step.type !== \"status\");\n\n if (isTerminalError) {\n return [\n ...executionSteps.map((step) => ({ ...step, inProgress: false })),\n {\n type: \"status\",\n label: TERMINAL_ERROR_STATUS_LABEL,\n href: \"#\",\n inProgress: false,\n icon: CircleAlert,\n indented: false,\n tone: \"error\",\n },\n ];\n }\n\n if (!isStreaming) return executionSteps.map((step) => ({ ...step, inProgress: false }));\n\n const latestStatus = rawSteps.reduce((latest, step) => {\n if (step.type !== \"status\") return latest;\n return !latest || (step.callIndex ?? -1) > (latest.callIndex ?? -1) ? step : latest;\n }, undefined);\n return latestStatus ? [...executionSteps, { ...latestStatus, indented: false }] : executionSteps;\n}\n\n/** Extract the last meaningful line from accumulated thinking text. */\nfunction lastThinkingLine(text: string): string {\n const lines = text.trim().split(\"\\n\").filter(Boolean);\n if (lines.length === 0) return \"Thinking...\";\n return lines[lines.length - 1].trim();\n}\n\nconst AgentPrototypeThinking: React.FC = ({\n thinking,\n thinkingSinceLastTool,\n toolCalls,\n toolResults,\n isAwaitingUserInput,\n isStreaming,\n isTerminalError,\n hasContent,\n isSegmentComplete,\n completedWorkLabel,\n}) => {\n const [expanded, setExpanded] = useState(false);\n const prevStreaming = useRef(isStreaming);\n const hasAutoExpanded = useRef(false);\n const visibleToolCalls = toolCalls.filter((call) => !isHiddenTimelineTool(call.tool));\n const visibleToolResults = toolResults.filter((result) => !isHiddenTimelineTool(result.tool));\n\n // Auto-expand when first tool call arrives during streaming\n useEffect(() => {\n if (isStreaming && !hasAutoExpanded.current && visibleToolCalls.length > 0) {\n hasAutoExpanded.current = true;\n setExpanded(true);\n }\n }, [isStreaming, visibleToolCalls.length]);\n\n // Auto-collapse when streaming finishes\n useEffect(() => {\n if (prevStreaming.current && !isStreaming) {\n setExpanded(false);\n hasAutoExpanded.current = false;\n }\n prevStreaming.current = isStreaming;\n }, [isStreaming]);\n\n const hasToolCalls = visibleToolCalls.length > 0;\n const { steps: rawSteps, resultForCall } = hasToolCalls\n ? buildTimeline(visibleToolCalls, visibleToolResults)\n : { steps: [] as TimelineStep[], resultForCall: new Map() };\n const steps = projectTimelineSteps(rawSteps, isStreaming, isTerminalError);\n const activeCourtRecordStep = [...steps]\n .reverse()\n .find(\n (step) =>\n step.inProgress &&\n step.callIndex !== undefined &&\n COURT_RECORD_TOOLS.has(visibleToolCalls[step.callIndex].tool),\n );\n\n // Append a status step when no tool/delegate is actively running\n const lastExecutionCallIdx = visibleToolCalls.reduce(\n (latestIdx, call, callIdx) => (call.tool === \"report_status\" ? latestIdx : callIdx),\n -1,\n );\n const lastExecutionToolInProgress =\n lastExecutionCallIdx >= 0 &&\n (!resultForCall.has(lastExecutionCallIdx) ||\n rawSteps.some((step) => step.callIndex === lastExecutionCallIdx && step.inProgress));\n const anyDelegateInProgress = steps.some((s) => s.isDelegate && s.inProgress);\n const lastStructuredStep = steps[steps.length - 1];\n if (!isTerminalError && !lastExecutionToolInProgress && !anyDelegateInProgress && !activeCourtRecordStep) {\n if (isStreaming && !hasContent && isAwaitingUserInput) {\n steps.push({\n type: \"waiting\",\n label: WAITING_FOR_INPUT_LABEL,\n href: \"#\",\n inProgress: true,\n icon: HelpCircle,\n });\n } else if (hasContent) {\n // Agent is generating (or has generated) its final text response\n steps.push({\n type: \"responding\",\n label: isStreaming ? \"Generating response...\" : \"Generated response.\",\n href: \"#\",\n inProgress: !!isStreaming,\n icon: PenLine,\n });\n } else if (isStreaming && lastStructuredStep?.type !== \"status\") {\n // Agent is reasoning between tool calls\n const label = thinkingSinceLastTool ? lastThinkingLine(thinkingSinceLastTool) : \"Thinking...\";\n steps.push({\n type: \"thinking\",\n label,\n href: \"#\",\n inProgress: true,\n icon: Brain,\n });\n }\n }\n\n // Fall back to thinking strings when no structured tool data (e.g. loaded history)\n const preserveThinkingFallback = !!isTerminalError && !hasToolCalls && thinking.length > 0;\n const thinkingItems = thinking.map((label) => ({ label }));\n const items = preserveThinkingFallback\n ? [...thinkingItems, ...steps]\n : hasToolCalls || steps.length > 0\n ? steps\n : thinkingItems;\n const hasWaitingStep = steps.some((step) => step.type === \"waiting\");\n\n if (items.length === 0) return null;\n\n // When answer is done and there are no tool steps and no thinking strings, hide the section\n if (!isTerminalError && !isStreaming && !hasToolCalls && thinking.length === 0) return null;\n\n const activeLiveStatusStep =\n isStreaming && !hasContent && !anyDelegateInProgress && lastStructuredStep?.type === \"status\"\n ? lastStructuredStep\n : null;\n const activeWaitingStep = isStreaming\n ? ([...steps].reverse().find((step) => step.type === \"waiting\" && step.inProgress) ?? null)\n : null;\n\n // Collapsed label: while streaming show active delegate or current step, when done show count\n const lastStep = items[items.length - 1];\n const inProgressDelegate = [...steps].reverse().find((s) => s.isDelegate && s.inProgress);\n const activeStreamingStep =\n inProgressDelegate ?? activeWaitingStep ?? activeCourtRecordStep ?? activeLiveStatusStep ?? lastStep;\n const activeStreamingStepType = \"type\" in activeStreamingStep ? activeStreamingStep.type : undefined;\n const collapsedLabel = isTerminalError\n ? TERMINAL_ERROR_STATUS_LABEL\n : isStreaming\n ? activeStreamingStep.label\n : isSegmentComplete\n ? completedWorkLabel ||\n `${steps.filter((step) => !step.inProgress && step.type !== \"status\").length} completed steps`\n : `${items.length} step${items.length === 1 ? \"\" : \"s\"}`;\n const shouldAnimateHeaderEllipsis = isStreaming && activeStreamingStepType !== \"waiting\";\n // Strip trailing dots so AnimatedEllipsis can animate them instead\n const headerText = shouldAnimateHeaderEllipsis ? stripTrailingDots(collapsedLabel) : collapsedLabel;\n\n // Group steps: each non-indented step starts a \"tool\"; indented steps are \"tasks\" under the previous tool\n type StepGroup = { header: TimelineStep; tasks: TimelineStep[] };\n const stepGroups: StepGroup[] = [];\n for (const step of steps) {\n if (step.indented && stepGroups.length > 0) {\n stepGroups[stepGroups.length - 1].tasks.push(step);\n } else {\n stepGroups.push({ header: step, tasks: [] });\n }\n }\n\n // Max height for whole section: ~3 tool blocks (1 header row + ~3 task rows per tool)\n const STEP_ROW_REM = 2.5;\n const TASK_ROW_REM = 2.25;\n const OUTER_MAX_HEIGHT_REM = 3 * (STEP_ROW_REM + 3 * TASK_ROW_REM); // 27.75rem\n\n const renderStepRow = (step: TimelineStep, indent = false) => {\n const animateStatus = !activeWaitingStep && activeLiveStatusStep === step;\n const stepLabelText = animateStatus ? stripTrailingDots(step.label) : step.label;\n const labelContent = (\n <>\n {stepLabelText}\n {animateStatus && }\n \n );\n\n return (\n \n \n \n \n {step.href !== \"#\" ? (\n e.stopPropagation()}\n color={step.tone === \"error\" ? \"error.main\" : \"text.secondary\"}\n sx={{\n flex: 1,\n minWidth: 0,\n whiteSpace: \"normal\",\n overflowWrap: \"anywhere\",\n textDecoration: \"none\",\n \"&:hover\": { textDecoration: \"underline\" },\n }}\n >\n {labelContent}\n \n ) : (\n \n {labelContent}\n \n )}\n {step.resultSummary && (\n \n \u2014 {step.resultSummary}\n \n )}\n \n {step.inProgress && isStreaming && !animateStatus && (\n \n )}\n {!step.inProgress && step.href !== \"#\" && }\n \n \n );\n };\n\n return (\n ({\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n })}\n >\n setExpanded(!expanded)}\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n py: 0.5,\n cursor: \"pointer\",\n \"&:hover .MuiTypography-caption\": { color: \"text.primary\" },\n }}\n >\n \n {headerText}\n {shouldAnimateHeaderEllipsis && }\n \n \n \n \n \n {!(isStreaming && !hasToolCalls && !hasWaitingStep) && (\n \n {preserveThinkingFallback &&\n thinking.map((item, i) => (\n \n {item}\n \n ))}\n {steps.length > 0\n ? stepGroups.map((group, gi) => (\n \n {renderStepRow(group.header)}\n {group.tasks.map((task, j) => (\n {renderStepRow(task, true)}\n ))}\n \n ))\n : thinking.map((item, i) => (\n \n {item}\n \n ))}\n \n )}\n \n \n \n );\n};\n\nexport default AgentPrototypeThinking;\n", "/** The server emits this marker only for a completed execution's final response. */\nexport function hasCompletedPlanExecution(\n messages: ReadonlyArray<{\n role: string;\n runId?: string;\n isStreaming?: boolean;\n isError?: boolean;\n metadata?: Record | null;\n }>,\n cycleToken: string,\n versionToken: string,\n): boolean {\n return messages.some((message) => {\n if (message.role !== \"assistant\" || message.isStreaming || message.isError) return false;\n const marker = message.metadata?.planning_completion;\n if (!marker || typeof marker !== \"object\") return false;\n const completion = marker as Record;\n return (\n completion.planning_cycle_token === cycleToken &&\n completion.approved_plan_version_token === versionToken &&\n typeof completion.run_id === \"string\" &&\n completion.run_id.length > 0 &&\n completion.run_id === message.runId\n );\n });\n}\n", "import React from \"react\";\nimport { Alert as MuiAlert, Box, Stack, type AlertProps as MuiAlertProps } from \"@mui/material\";\nimport type { Theme } from \"@mui/material/styles\";\nimport { CircleAlert, CircleCheck, Info, TriangleAlert, type LucideIcon } from \"lucide-react\";\n\nimport { renderLucideOrNode } from \"@/components/icons\";\n\nexport interface BenchAlertProps extends Omit {\n icon?: LucideIcon | React.ReactNode | false;\n title?: React.ReactNode;\n}\n\nconst severityIcons = { error: CircleAlert, warning: TriangleAlert, info: Info, success: CircleCheck };\n\nconst renderBenchAlertIcon = (icon: BenchAlertProps[\"icon\"], severity: NonNullable) => {\n if (icon === false) return false;\n return renderLucideOrNode(icon ?? severityIcons[severity], \"md\");\n};\n\nconst alertTitleSx = (theme: Theme) => ({\n m: 0,\n ...theme.typography.body1,\n});\n\nconst alertBodySx = (theme: Theme) => ({\n m: 0,\n ...theme.typography.body2,\n});\n\nconst alertRootSx = {\n \"& .MuiAlert-icon\": {\n mr: 0,\n pr: 1.5,\n py: 0,\n alignSelf: \"center\",\n alignItems: \"center\",\n },\n \"& .MuiAlert-message\": {\n minWidth: 0,\n flex: \"1 1 0\",\n overflow: \"hidden\",\n py: \"8px\",\n },\n \"& .MuiAlert-action\": {\n alignItems: \"flex-start\",\n alignSelf: \"flex-start\",\n flexShrink: 0,\n m: 0,\n pl: \"16px\",\n pt: \"4px\",\n },\n};\n\nexport const BenchAlert = React.forwardRef(\n ({ icon, title, children, sx, action, severity = \"success\", variant = \"standard\", ...props }, ref) => {\n const sxOverrides = Array.isArray(sx) ? sx : [sx];\n\n return (\n \n {title ? (\n \n \n {title}\n \n {children ? (\n \n {children}\n \n ) : null}\n \n ) : (\n \n {children}\n \n )}\n \n );\n },\n);\n\nBenchAlert.displayName = \"BenchAlert\";\n", "import React, { KeyboardEvent, ReactNode } from \"react\";\nimport { Autocomplete } from \"@mui/material\";\nimport { BIQInputField } from \"@/components/atoms/BIQInputField\";\n\nexport const getMatterCodeOptions = (): string[] => {\n try {\n const stored = JSON.parse(window.localStorage.getItem(\"matterCodes\") || \"[]\") as unknown;\n return Array.isArray(stored) ? stored.filter((value): value is string => typeof value === \"string\") : [];\n } catch {\n return [];\n }\n};\n\ninterface MatterCodeAutocompleteProps {\n value: string;\n onChange: (value: string) => void;\n onKeyDown?: (event: KeyboardEvent) => void;\n placeholder?: string;\n autoFocus?: boolean;\n error?: boolean;\n helper?: ReactNode;\n disabled?: boolean;\n}\n\nconst MatterCodeAutocomplete = ({\n value,\n onChange,\n onKeyDown,\n placeholder = \"Matter number\",\n autoFocus = false,\n error = false,\n helper,\n disabled = false,\n}: MatterCodeAutocompleteProps) => (\n onChange(newInputValue)}\n onKeyDown={onKeyDown}\n sx={(theme) => ({\n \"& .MuiOutlinedInput-root\": {\n minHeight: \"56px\",\n },\n \"& .MuiAutocomplete-inputRoot .MuiAutocomplete-input\": {\n width: \"auto\",\n minWidth: theme.tokens.spacing[6],\n fontSize: \"16px\",\n lineHeight: \"24px\",\n letterSpacing: \"0.15px\",\n },\n })}\n slotProps={{\n paper: {\n sx: (theme) => ({\n \"&:empty\": {\n display: \"none\",\n },\n marginTop: \"2px\",\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n border: `1px solid ${theme.border.light}`,\n boxShadow: theme.tokens.shadows.md,\n }),\n },\n }}\n renderInput={(params) => (\n \n )}\n />\n);\n\nexport default MatterCodeAutocomplete;\n", "/**\n * @internal ensures no keys provided by the user starts with an _underscore `_`_\n */\nexport const assertSchemaKeys = (schema: Record): string[] => {\n const keys = Object.keys(schema).sort((a, b) => a.localeCompare(b));\n\n const hasKeyInShapeOfInternalKey = keys.some((key) => key.startsWith('_'));\n\n if (hasKeyInShapeOfInternalKey) {\n throw new Error('Keys that start with \"_\" are reserved for Query Key Factory');\n }\n\n return keys;\n};\n", "/**\n * Create an object without inheriting anything from `Object.prototype`\n * @internal\n *\n * @see {@link https://github.com/trpc/trpc/blob/next/packages/server/src/core/internals/omitPrototype.ts tRPC repo for original code }\n */\nexport function omitPrototype>(obj: T): T {\n return Object.assign(Object.create(null), obj);\n}\n", "import type {\n AnyQueryFactoryOutputCallback,\n AnyQueryKey,\n QueryFactorySchema,\n QueryKeyFactoryResult,\n ValidateFactory,\n} from './create-query-keys.types';\nimport { assertSchemaKeys, omitPrototype } from './internals';\nimport { type DefinitionKey } from './types';\n\nexport function createQueryKeys(queryDef: Key): DefinitionKey<[Key]>;\nexport function createQueryKeys(\n queryDef: Key,\n schema: ValidateFactory,\n): QueryKeyFactoryResult;\nexport function createQueryKeys(\n queryDef: Key,\n schema?: ValidateFactory,\n): DefinitionKey<[Key]> | QueryKeyFactoryResult {\n const defKey: DefinitionKey<[Key]> = {\n _def: [queryDef] as const,\n };\n\n if (schema == null) {\n return omitPrototype(defKey);\n }\n\n const transformSchema = <$Factory extends QueryFactorySchema>(factory: $Factory, mainKey: AnyQueryKey) => {\n type $FactoryProperty = keyof $Factory;\n\n const keys = assertSchemaKeys(factory);\n return keys.reduce((factoryMap, factoryKey) => {\n const value = factory[factoryKey];\n const key = [...mainKey, factoryKey] as const;\n\n const isReadonlyArray = (arg: unknown): arg is readonly any[] => Array.isArray(arg);\n\n let yieldValue: any;\n\n if (typeof value === 'function') {\n const resultCallback: AnyQueryFactoryOutputCallback = (...args) => {\n const result = value(...args);\n\n if (isReadonlyArray(result)) {\n return omitPrototype({\n queryKey: [...key, ...result] as const,\n });\n }\n\n const innerKey = [...key, ...result.queryKey] as const;\n\n if ('queryFn' in result) {\n // type $QueryFnContext = Omit, 'queryKey'>;\n\n const queryOptions = {\n queryKey: innerKey,\n queryFn: result.queryFn,\n };\n\n if ('contextQueries' in result) {\n const transformedSchema = transformSchema(result.contextQueries, innerKey);\n\n return omitPrototype({\n _ctx: omitPrototype(Object.fromEntries(transformedSchema)),\n ...queryOptions,\n });\n }\n\n return omitPrototype({\n ...queryOptions,\n });\n }\n\n if ('contextQueries' in result) {\n const transformedSchema = transformSchema(result.contextQueries, innerKey);\n\n return omitPrototype({\n _ctx: omitPrototype(Object.fromEntries(transformedSchema)),\n queryKey: innerKey,\n });\n }\n\n return omitPrototype({\n queryKey: innerKey,\n });\n };\n\n resultCallback._def = key;\n\n yieldValue = resultCallback;\n } else if (value == null) {\n yieldValue = omitPrototype({\n queryKey: key,\n });\n } else if (isReadonlyArray(value)) {\n yieldValue = omitPrototype({\n _def: key,\n queryKey: [...key, ...value] as const,\n });\n } else if ('queryFn' in value) {\n // type $QueryFnContext = Omit, 'queryKey'>;\n\n const innerDefKey = { ...(value.queryKey ? { _def: key } : undefined) };\n const innerKey = [...key, ...(value.queryKey ?? [])] as const;\n\n const queryOptions = {\n queryKey: innerKey,\n queryFn: value.queryFn,\n };\n\n if ('contextQueries' in value) {\n const transformedSchema = transformSchema(value.contextQueries, innerKey);\n\n yieldValue = omitPrototype({\n _ctx: omitPrototype(Object.fromEntries(transformedSchema)),\n ...innerDefKey,\n ...queryOptions,\n });\n } else {\n yieldValue = omitPrototype({ ...innerDefKey, ...queryOptions });\n }\n } else if ('contextQueries' in value) {\n const innerDefKey = { ...(value.queryKey ? { _def: key } : undefined) };\n const innerKey = [...key, ...(value.queryKey ?? [])] as const;\n\n const transformedSchema = transformSchema(value.contextQueries, innerKey);\n\n yieldValue = omitPrototype({\n _ctx: omitPrototype(Object.fromEntries(transformedSchema)),\n queryKey: innerKey,\n ...innerDefKey,\n });\n } else {\n const innerDefKey = { ...(value.queryKey ? { _def: key } : undefined) };\n const innerKey = [...key, ...(value.queryKey ?? [])] as const;\n\n yieldValue = omitPrototype({\n queryKey: innerKey,\n ...innerDefKey,\n });\n }\n\n factoryMap.set(factoryKey, yieldValue);\n return factoryMap;\n }, new Map<$FactoryProperty, $Factory[$FactoryProperty]>());\n };\n\n const transformedSchema = transformSchema(schema as QueryFactorySchema, defKey._def);\n\n return omitPrototype({\n ...Object.fromEntries(transformedSchema),\n ...defKey,\n });\n}\n", "import { createQueryKeys } from './create-query-keys';\nimport type { QueryFactorySchema, QueryKeyFactoryResult } from './create-query-keys.types';\nimport type { DefinitionKey } from './types';\nimport { omitPrototype } from './internals';\n\ntype QueryKeyStoreSchema = Record;\n\nexport type QueryKeyStore = {\n [P in keyof StoreSchema & string]: StoreSchema[P] extends QueryFactorySchema ?\n QueryKeyFactoryResult\n : DefinitionKey<[P]>;\n};\n\nexport function createQueryKeyStore(\n schema: StoreSchema,\n): QueryKeyStore {\n const keys = Object.keys(schema);\n\n const store = keys.reduce((storeMap, key) => {\n const factory = schema[key];\n\n const result = factory ? createQueryKeys(key, factory) : createQueryKeys(key);\n\n storeMap.set(key, result);\n return storeMap;\n }, new Map());\n\n return omitPrototype(Object.fromEntries(store));\n}\n", "import type {\n MutationFactorySchema,\n MutationKeyFactoryResult,\n AnyMutationFactoryOutputCallback,\n ValidateFactory,\n AnyMutationKey,\n} from './create-mutation-keys.types';\nimport { assertSchemaKeys, omitPrototype } from './internals';\nimport type { DefinitionKey } from './types';\n\n/**\n * @deprecated the type inference for this function is broken and will be fixed in the next patch version\n * or possibly removed and implemented differently in a major version\n */\nexport function createMutationKeys(mutationDef: Key): DefinitionKey<[Key]>;\n/**\n * @deprecated the type inference for this function is broken and will be fixed in the next patch version\n * or possibly removed and implemented differently in a major version\n */\nexport function createMutationKeys(\n mutationDef: Key,\n schema: ValidateFactory,\n): MutationKeyFactoryResult;\n/**\n * @deprecated the type inference for this function is broken and will be fixed in the next patch version\n * or possibly removed and implemented differently in a major version\n */\nexport function createMutationKeys(\n mutationDef: Key,\n schema?: ValidateFactory,\n): DefinitionKey<[Key]> | MutationKeyFactoryResult {\n const defKey: DefinitionKey<[Key]> = {\n _def: [mutationDef] as const,\n };\n\n if (schema == null) {\n return omitPrototype(defKey);\n }\n\n const transformSchema = <$Factory extends MutationFactorySchema>(factory: $Factory, mainKey: AnyMutationKey) => {\n type $FactoryProperty = keyof $Factory;\n\n const keys = assertSchemaKeys(factory);\n return keys.reduce((factoryMap, factoryKey) => {\n const value = factory[factoryKey];\n const key = [...mainKey, factoryKey] as const;\n\n const isReadonlyArray = (arg: unknown): arg is readonly any[] => Array.isArray(arg);\n\n let yieldValue: any;\n\n if (typeof value === 'function') {\n const resultCallback: AnyMutationFactoryOutputCallback = (...args) => {\n const result = value(...args);\n\n if (isReadonlyArray(result)) {\n return omitPrototype({\n mutationKey: [...key, ...result] as const,\n });\n }\n\n const innerKey = [...key, ...result.mutationKey] as const;\n\n if ('mutationFn' in result) {\n const queryOptions = {\n mutationKey: innerKey,\n mutationFn: result.mutationFn,\n };\n\n if ('contextMutations' in result) {\n const transformedSchema = transformSchema(result.contextMutations, innerKey);\n\n return omitPrototype({\n _ctx: omitPrototype(Object.fromEntries(transformedSchema)),\n ...queryOptions,\n });\n }\n\n return omitPrototype({\n ...queryOptions,\n });\n }\n\n if ('contextMutations' in result) {\n const transformedSchema = transformSchema(result.contextMutations, innerKey);\n\n return omitPrototype({\n _ctx: omitPrototype(Object.fromEntries(transformedSchema)),\n mutationKey: innerKey,\n });\n }\n\n return omitPrototype({\n mutationKey: innerKey,\n });\n };\n\n resultCallback._def = key;\n\n yieldValue = resultCallback;\n } else if (value == null) {\n yieldValue = omitPrototype({\n mutationKey: key,\n });\n } else if (isReadonlyArray(value)) {\n yieldValue = omitPrototype({\n _def: key,\n mutationKey: [...key, ...value] as const,\n });\n } else if ('mutationFn' in value) {\n const innerDefKey = { ...(value.mutationKey ? { _def: key } : undefined) };\n const innerKey = [...key, ...(value.mutationKey ?? [])] as const;\n\n const queryOptions = {\n mutationKey: innerKey,\n mutationFn: value.mutationFn,\n };\n\n if ('contextMutations' in value) {\n const transformedSchema = transformSchema(value.contextMutations, innerKey);\n\n yieldValue = omitPrototype({\n _ctx: omitPrototype(Object.fromEntries(transformedSchema)),\n ...innerDefKey,\n ...queryOptions,\n });\n } else {\n yieldValue = omitPrototype({ ...innerDefKey, ...queryOptions });\n }\n } else if ('contextMutations' in value) {\n const innerDefKey = { ...(value.mutationKey ? { _def: key } : undefined) };\n const innerKey = [...key, ...(value.mutationKey ?? [])] as const;\n\n const transformedSchema = transformSchema(value.contextMutations, innerKey);\n\n yieldValue = omitPrototype({\n _ctx: omitPrototype(Object.fromEntries(transformedSchema)),\n mutationKey: innerKey,\n ...innerDefKey,\n });\n } else {\n const innerDefKey = { ...(value.mutationKey ? { _def: key } : undefined) };\n const innerKey = [...key, ...(value.mutationKey ?? [])] as const;\n\n yieldValue = omitPrototype({\n mutationKey: innerKey,\n ...innerDefKey,\n });\n }\n\n factoryMap.set(factoryKey, yieldValue);\n return factoryMap;\n }, new Map<$FactoryProperty, $Factory[$FactoryProperty]>());\n };\n\n const transformedSchema = transformSchema(schema, defKey._def);\n\n return omitPrototype({\n ...Object.fromEntries(transformedSchema),\n ...defKey,\n });\n}\n", "import { type AnyMutationKeyFactoryResult } from './create-mutation-keys.types';\nimport type { AnyQueryKeyFactoryResult } from './create-query-keys.types';\nimport { omitPrototype } from './internals';\nimport type { Prettify } from './types';\n\ntype StoreFromMergedQueryKeys<\n QueryOrMutationKeyFactoryResults extends Array,\n> =\n QueryOrMutationKeyFactoryResults extends (\n [\n infer First extends AnyQueryKeyFactoryResult | AnyMutationKeyFactoryResult,\n ...infer Rest extends AnyQueryKeyFactoryResult[] | AnyMutationKeyFactoryResult[],\n ]\n ) ?\n { [P in First['_def'][0]]: First } & StoreFromMergedQueryKeys\n : {};\n\nexport function mergeQueryKeys<\n QueryKeyFactoryResults extends Array,\n>(...schemas: QueryKeyFactoryResults): Prettify> {\n const store = schemas.reduce((storeMap, current) => {\n const [storeKey] = current._def;\n\n storeMap.set(storeKey, { ...storeMap.get(storeKey), ...current });\n return storeMap;\n }, new Map());\n\n return omitPrototype(Object.fromEntries(store));\n}\n", "import { globalConfig } from \"./core.js\";\n// functions\nexport function assertEqual(val) {\n return val;\n}\nexport function assertNotEqual(val) {\n return val;\n}\nexport function toZod() {\n return (schema) => schema;\n}\nexport function assertIs(_arg) { }\nexport function assertNever(_x) {\n throw new Error(\"Unexpected value in exhaustive check\");\n}\nexport function assert(_) { }\nexport function getEnumValues(entries) {\n const numericValues = Object.values(entries).filter((v) => typeof v === \"number\");\n const values = Object.entries(entries)\n .filter(([k, _]) => numericValues.indexOf(+k) === -1)\n .map(([_, v]) => v);\n return values;\n}\nexport function joinValues(array, separator = \"|\") {\n return array.map((val) => stringifyPrimitive(val)).join(separator);\n}\nexport function jsonStringifyReplacer(_, value) {\n if (typeof value === \"bigint\")\n return value.toString();\n return value;\n}\n// the accessor lives on a shared prototype: an own accessor makes every box a dictionary-mode object (~360 B and a slow load per read against ~100 B and an inlined getter here)\nclass Cached {\n constructor(getter) {\n this._getter = getter;\n this._value = undefined;\n }\n get value() {\n const getter = this._getter;\n if (getter !== undefined) {\n this._value = getter();\n this._getter = undefined;\n }\n return this._value;\n }\n}\nexport function cached(getter) {\n return new Cached(getter);\n}\nexport function nullish(input) {\n return input === null || input === undefined;\n}\nexport function cleanRegex(source) {\n const start = source.startsWith(\"^\") ? 1 : 0;\n const end = source.endsWith(\"$\") ? source.length - 1 : source.length;\n return source.slice(start, end);\n}\nexport function floatSafeRemainder(val, step) {\n const ratio = val / step;\n const roundedRatio = Math.round(ratio);\n // `val` and `step` each round to a double before the division rounds again, so a true decimal multiple's quotient can sit up to 1.5 of these scaled epsilons from the integer. A 1x tolerance therefore rejected 2.03 as a multiple of 0.07; 4x covers the worst case with margin.\n const tolerance = 4 * Number.EPSILON * Math.max(Math.abs(ratio), 1);\n if (Math.abs(ratio - roundedRatio) < tolerance)\n return 0;\n return ratio - roundedRatio;\n}\nconst EVALUATING = /* @__PURE__*/ Symbol(\"evaluating\");\nexport function defineLazy(object, key, getter) {\n let value = undefined;\n Object.defineProperty(object, key, {\n get() {\n if (value === EVALUATING) {\n // Circular reference detected, return undefined to break the cycle\n return undefined;\n }\n if (value === undefined) {\n value = EVALUATING;\n value = getter();\n }\n return value;\n },\n set(v) {\n Object.defineProperty(object, key, {\n value: v,\n // configurable: true,\n });\n // object[key] = v;\n },\n configurable: true,\n });\n}\nexport function objectClone(obj) {\n return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));\n}\nexport function assignProp(target, prop, value) {\n Object.defineProperty(target, prop, {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n}\n/**\n * Whichever object a def's `shape` currently answers from: the one the caller passed until the first read, the frozen copy after it.\n *\n * Its keys and descriptors read without invoking anything, which is what lets a discriminated union check its discriminator, and the cycle walk read a shape, without resolving a getter that references the schema being constructed. A def that answers `shape` from an accessor of its own has none.\n */\nexport function rawShape(def) {\n const desc = Object.getOwnPropertyDescriptor(def, \"shape\");\n return desc?.get ? desc.get.raw : desc?.value;\n}\n// where a builder reads its source's keys and descriptors, resolving only a shape a def answers for itself. A shape resolves by object spread, so only its enumerable keys are ever part of it.\nfunction sourceShape(schema) {\n return rawShape(schema._zod.def) ?? schema._zod.def.shape;\n}\n// a key whose value is not settled yet, self-caching so every read after the first gets the same one\nfunction deferProp(target, key, getter) {\n Object.defineProperty(target, key, {\n get() {\n const value = getter();\n assignProp(this, key, value);\n return value;\n },\n enumerable: true,\n configurable: true,\n });\n}\n// Writes a settled key. A plain assignment is much cheaper than `defineProperty` and produces the same descriptor, but it runs whatever setter already answers to the key \u2014 an accessor this shape deferred, or an inherited one, which `__proto__` has on every object and prototype pollution can add for any name.\nfunction putProp(target, key, value) {\n if (key in target)\n assignProp(target, key, value);\n else\n target[key] = value;\n}\n/**\n * Copies `keys` of `source`'s shape onto `target`, each value passed through `wrap`.\n *\n * A key the source has resolved is copied through now, so the derived shape states it outright and nothing has to resolve it to learn what it holds. A key the source still defers stays deferred, and reads back through the source's own `shape`, so it resolves once and both shapes get that one schema.\n */\nfunction mirrorShape(target, source, keys, wrap) {\n const raw = sourceShape(source);\n for (const key of keys) {\n const desc = Object.getOwnPropertyDescriptor(raw, key);\n if (!desc.enumerable)\n continue;\n if (desc.get) {\n deferProp(target, key, () => {\n const value = source._zod.def.shape[key];\n return wrap ? wrap(value, key) : value;\n });\n }\n else\n putProp(target, key, wrap ? wrap(desc.value, key) : desc.value);\n }\n}\n// same, for a plain shape a caller passed rather than a schema's\nfunction mirrorProps(target, source) {\n for (const key of Reflect.ownKeys(source)) {\n const desc = Object.getOwnPropertyDescriptor(source, key);\n if (!desc.enumerable)\n continue;\n if (desc.get)\n deferProp(target, key, () => source[key]);\n else\n putProp(target, key, desc.value);\n }\n}\nexport function mergeDefs(...defs) {\n const mergedDescriptors = {};\n for (const def of defs) {\n const descriptors = Object.getOwnPropertyDescriptors(def);\n Object.assign(mergedDescriptors, descriptors);\n }\n return Object.defineProperties({}, mergedDescriptors);\n}\nexport function cloneDef(schema) {\n return mergeDefs(schema._zod.def);\n}\nexport function getElementAtPath(obj, path) {\n if (!path)\n return obj;\n return path.reduce((acc, key) => acc?.[key], obj);\n}\nexport function promiseAllObject(promisesObj) {\n const keys = Object.keys(promisesObj);\n const promises = keys.map((key) => promisesObj[key]);\n return Promise.all(promises).then((results) => {\n const resolvedObj = {};\n for (let i = 0; i < keys.length; i++) {\n resolvedObj[keys[i]] = results[i];\n }\n return resolvedObj;\n });\n}\nexport function randomString(length = 10) {\n const chars = \"abcdefghijklmnopqrstuvwxyz\";\n let str = \"\";\n for (let i = 0; i < length; i++) {\n str += chars[Math.floor(Math.random() * chars.length)];\n }\n return str;\n}\nexport function esc(str) {\n return JSON.stringify(str);\n}\nexport function slugify(input) {\n return input\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, \"\")\n .replace(/[\\s_-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\nexport const captureStackTrace = (\"captureStackTrace\" in Error ? Error.captureStackTrace : (..._args) => { });\nexport function isObject(data) {\n return typeof data === \"object\" && data !== null && !Array.isArray(data);\n}\nexport const allowsEval = /* @__PURE__*/ cached(() => {\n // Skip the probe under `jitless`: strict CSPs report the caught `new Function` as a `securitypolicyviolation` even though the throw is swallowed.\n if (globalConfig.jitless) {\n return false;\n }\n // @ts-ignore\n if (typeof navigator !== \"undefined\" && navigator?.userAgent?.includes(\"Cloudflare\")) {\n return false;\n }\n try {\n const F = Function;\n new F(\"\");\n return true;\n }\n catch (_) {\n return false;\n }\n});\nexport function isPlainObject(o) {\n if (isObject(o) === false)\n return false;\n // modified constructor\n const ctor = o.constructor;\n if (ctor === undefined)\n return true;\n if (typeof ctor !== \"function\")\n return true;\n // modified prototype\n const prot = ctor.prototype;\n if (isObject(prot) === false)\n return false;\n // ctor doesn't have static `isPrototypeOf`\n if (Object.prototype.hasOwnProperty.call(prot, \"isPrototypeOf\") === false) {\n return false;\n }\n return true;\n}\nexport function shallowClone(o) {\n if (isPlainObject(o))\n return { ...o };\n if (Array.isArray(o))\n return [...o];\n if (o instanceof Map)\n return new Map(o);\n if (o instanceof Set)\n return new Set(o);\n return o;\n}\nexport function numKeys(data) {\n let keyCount = 0;\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n keyCount++;\n }\n }\n return keyCount;\n}\nexport const getParsedType = (data) => {\n const t = typeof data;\n switch (t) {\n case \"undefined\":\n return \"undefined\";\n case \"string\":\n return \"string\";\n case \"number\":\n return Number.isNaN(data) ? \"nan\" : \"number\";\n case \"boolean\":\n return \"boolean\";\n case \"function\":\n return \"function\";\n case \"bigint\":\n return \"bigint\";\n case \"symbol\":\n return \"symbol\";\n case \"object\":\n if (Array.isArray(data)) {\n return \"array\";\n }\n if (data === null) {\n return \"null\";\n }\n if (data.then && typeof data.then === \"function\" && data.catch && typeof data.catch === \"function\") {\n return \"promise\";\n }\n if (typeof Map !== \"undefined\" && data instanceof Map) {\n return \"map\";\n }\n if (typeof Set !== \"undefined\" && data instanceof Set) {\n return \"set\";\n }\n if (typeof Date !== \"undefined\" && data instanceof Date) {\n return \"date\";\n }\n // @ts-ignore\n if (typeof File !== \"undefined\" && data instanceof File) {\n return \"file\";\n }\n return \"object\";\n default:\n throw new Error(`Unknown data type: ${t}`);\n }\n};\nexport const propertyKeyTypes = /* @__PURE__*/ new Set([\"string\", \"number\", \"symbol\"]);\nexport const primitiveTypes = /* @__PURE__*/ new Set([\n \"string\",\n \"number\",\n \"bigint\",\n \"boolean\",\n \"symbol\",\n \"undefined\",\n]);\nexport function escapeRegex(str) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n// zod-specific utils\nexport function clone(inst, def, params) {\n const cl = new inst._zod.constr(def ?? inst._zod.def);\n if (!def || params?.parent)\n cl._zod.parent = inst;\n return cl;\n}\nexport function normalizeParams(_params) {\n const params = _params;\n if (!params)\n return {};\n if (typeof params === \"string\")\n return { error: () => params };\n if (params?.message !== undefined) {\n if (params?.error !== undefined)\n throw new Error(\"Cannot specify both `message` and `error` params\");\n params.error = params.message;\n }\n delete params.message;\n if (typeof params.error === \"string\")\n return { ...params, error: () => params.error };\n return params;\n}\nexport function createTransparentProxy(getter) {\n let target;\n return new Proxy({}, {\n get(_, prop, receiver) {\n target ?? (target = getter());\n return Reflect.get(target, prop, receiver);\n },\n set(_, prop, value, receiver) {\n target ?? (target = getter());\n return Reflect.set(target, prop, value, receiver);\n },\n has(_, prop) {\n target ?? (target = getter());\n return Reflect.has(target, prop);\n },\n deleteProperty(_, prop) {\n target ?? (target = getter());\n return Reflect.deleteProperty(target, prop);\n },\n ownKeys(_) {\n target ?? (target = getter());\n return Reflect.ownKeys(target);\n },\n getOwnPropertyDescriptor(_, prop) {\n target ?? (target = getter());\n return Reflect.getOwnPropertyDescriptor(target, prop);\n },\n defineProperty(_, prop, descriptor) {\n target ?? (target = getter());\n return Reflect.defineProperty(target, prop, descriptor);\n },\n });\n}\nexport function stringifyPrimitive(value) {\n if (typeof value === \"bigint\")\n return value.toString() + \"n\";\n if (typeof value === \"string\")\n return `\"${value}\"`;\n return `${value}`;\n}\nexport function optionalKeys(shape) {\n return Object.keys(shape).filter((k) => {\n return shape[k]._zod.optin !== undefined && shape[k]._zod.optout === \"optional\";\n });\n}\n// Wrapped in a `@__PURE__` IIFE: esbuild never tree-shakes a top-level initializer that contains a member access on `Number`, so the bare object literal survived into every bundle.\nexport const NUMBER_FORMAT_RANGES = /*@__PURE__*/ (() => ({\n safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],\n int32: [-2147483648, 2147483647],\n uint32: [0, 4294967295],\n float32: [-3.4028234663852886e38, 3.4028234663852886e38],\n float64: [-Number.MAX_VALUE, Number.MAX_VALUE],\n}))();\nexport const BIGINT_FORMAT_RANGES = {\n int64: [/* @__PURE__*/ BigInt(\"-9223372036854775808\"), /* @__PURE__*/ BigInt(\"9223372036854775807\")],\n uint64: [/* @__PURE__*/ BigInt(0), /* @__PURE__*/ BigInt(\"18446744073709551615\")],\n};\nexport function pick(schema, mask) {\n const currDef = schema._zod.def;\n const checks = currDef.checks;\n const hasChecks = checks && checks.length > 0;\n if (hasChecks) {\n throw new Error(\".pick() cannot be used on object schemas containing refinements\");\n }\n const newShape = {};\n mirrorShape(newShape, schema, maskedKeys(schema, mask));\n return clone(schema, mergeDefs(currDef, { shape: newShape, checks: [] }));\n}\n// the mask keys that select something, checked against the source's shape without resolving it\nfunction maskedKeys(schema, mask) {\n const raw = sourceShape(schema);\n const keys = [];\n // `for...in` skips symbols, so a symbol in the mask would select nothing\n for (const key of Reflect.ownKeys(mask)) {\n if (!Object.getOwnPropertyDescriptor(raw, key)?.enumerable) {\n throw new Error(`Unrecognized key: \"${String(key)}\"`);\n }\n if (mask[key])\n keys.push(key);\n }\n return keys;\n}\nexport function omit(schema, mask) {\n const currDef = schema._zod.def;\n const checks = currDef.checks;\n const hasChecks = checks && checks.length > 0;\n if (hasChecks) {\n throw new Error(\".omit() cannot be used on object schemas containing refinements\");\n }\n const omitted = new Set(maskedKeys(schema, mask));\n const newShape = {};\n mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)).filter((key) => !omitted.has(key)));\n return clone(schema, mergeDefs(currDef, { shape: newShape, checks: [] }));\n}\nexport function extend(schema, shape) {\n if (!isPlainObject(shape)) {\n throw new Error(\"Invalid input to extend: expected a plain object\");\n }\n const checks = schema._zod.def.checks;\n const hasChecks = checks && checks.length > 0;\n if (hasChecks) {\n // Only throw if new shape overlaps with existing shape. Use getOwnPropertyDescriptor to check key existence without accessing values\n const existingShape = sourceShape(schema);\n for (const key of Reflect.ownKeys(shape)) {\n if (Object.getOwnPropertyDescriptor(existingShape, key) !== undefined) {\n throw new Error(\"Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.\");\n }\n }\n }\n return clone(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) }));\n}\n// the source's keys, then the caller's overlaid on top\nfunction extended(schema, shape) {\n const newShape = {};\n mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)));\n mirrorProps(newShape, shape);\n return newShape;\n}\nexport function safeExtend(schema, shape) {\n if (!isPlainObject(shape)) {\n throw new Error(\"Invalid input to safeExtend: expected a plain object\");\n }\n return clone(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) }));\n}\nexport function merge(a, b) {\n if (!b?._zod?.def) {\n throw new Error(\"Invalid input to merge: expected an object schema. To merge a plain shape, use `.extend()`.\");\n }\n if (a._zod.def.checks?.length) {\n throw new Error(\".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.\");\n }\n const newShape = {};\n mirrorShape(newShape, a, Reflect.ownKeys(sourceShape(a)));\n mirrorShape(newShape, b, Reflect.ownKeys(sourceShape(b)));\n const def = mergeDefs(a._zod.def, {\n shape: newShape,\n get catchall() {\n return b._zod.def.catchall;\n },\n checks: b._zod.def.checks ?? [],\n });\n return clone(a, def);\n}\nexport function partial(Class, schema, mask, name = \"partial\") {\n const currDef = schema._zod.def;\n const checks = currDef.checks;\n const hasChecks = checks && checks.length > 0;\n if (hasChecks) {\n throw new Error(`.${name}() cannot be used on object schemas containing refinements`);\n }\n const selected = mask ? new Set(maskedKeys(schema, mask)) : undefined;\n const newShape = {};\n mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)), Class &&\n ((value, key) => (selected && !selected.has(key) ? value : new Class({ type: \"optional\", innerType: value }))));\n return clone(schema, mergeDefs(schema._zod.def, { shape: newShape, checks: [] }));\n}\nexport function required(Class, schema, mask) {\n const selected = mask ? new Set(maskedKeys(schema, mask)) : undefined;\n const newShape = {};\n mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)), (value, key) => \n // overwrite with non-optional\n selected && !selected.has(key) ? value : new Class({ type: \"nonoptional\", innerType: value }));\n return clone(schema, mergeDefs(schema._zod.def, { shape: newShape }));\n}\n// invalid_type | too_big | too_small | invalid_format | not_multiple_of | unrecognized_keys | invalid_union | invalid_key | invalid_element | invalid_value | custom\nexport function aborted(x, startIndex = 0) {\n if (x.aborted === true)\n return true;\n for (let i = startIndex; i < x.issues.length; i++) {\n if (x.issues[i]?.continue !== true) {\n return true;\n }\n }\n return false;\n}\n// Checks for explicit abort (continue === false), as opposed to implicit abort (continue === undefined). Used to respect `abort: true` in .refine() even for checks that have a `when` function.\nexport function explicitlyAborted(x, startIndex = 0) {\n if (x.aborted === true)\n return true;\n for (let i = startIndex; i < x.issues.length; i++) {\n if (x.issues[i]?.continue === false) {\n return true;\n }\n }\n return false;\n}\nexport function prefixIssues(path, issues) {\n return issues.map((iss) => {\n var _a;\n (_a = iss).path ?? (_a.path = []);\n iss.path.unshift(path);\n return iss;\n });\n}\nexport function unwrapMessage(message) {\n return typeof message === \"string\" ? message : message?.message;\n}\n/* A check holds no link back to the schema it is attached to \u2014 the same check instance is shared by every clone of that schema \u2014 so the owner is stamped onto the issues a check just raised, at the only point where both are in scope. Runs on the failure path only; `start` is the issue count from before the check ran. */\n/** The leading size checks of `defChecks` that set an upper bound, each paired with it. */\nexport function sizeCaps(defChecks) {\n const caps = [];\n for (const ch of defChecks ?? []) {\n const d = ch._zod.def;\n // a later check may rewrite the value\n if (!/_(length|size)$|_equals$/.test(d.check))\n break;\n const max = d.maximum ?? d.length ?? d.size;\n if (max >= 0)\n caps.push([max, ch]);\n }\n return caps;\n}\nexport function attachSchema(issues, start, inst) {\n var _a;\n for (let i = start; i < issues.length; i++) {\n (_a = issues[i]).schema ?? (_a.schema = inst);\n }\n}\nexport function finalizeIssue(iss, ctx, config) {\n var _a;\n // A schema that raised an issue itself owns it outright, and outranks any stamp an enclosing check left in `attachSchema`. String formats and z.custom() are schema and check at once, so when they act as a check they defer to that stamp instead.\n const traits = iss.inst?._zod?.traits;\n if (traits?.has(\"$ZodType\")) {\n if (traits.has(\"$ZodCheck\"))\n (_a = iss).schema ?? (_a.schema = iss.inst);\n else\n iss.schema = iss.inst;\n }\n // Decreasing specificity, first map to return a message wins. `inst` is whatever raised the issue, so a check's own map outranks the owning schema's.\n const schemaError = iss.schema !== iss.inst ? iss.schema?._zod.def?.error : undefined;\n const message = iss.message\n ? iss.message\n : (unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ??\n unwrapMessage(schemaError?.(iss)) ??\n unwrapMessage(ctx?.error?.(iss)) ??\n unwrapMessage(config.customError?.(iss)) ??\n unwrapMessage(config.localeError?.(iss)) ??\n \"Invalid input\");\n // an explicit own-key copy beats object rest with excluded keys, which v8 routes through a generic runtime call; Object.keys rather than for-in so an issue pushed with a prototype does not leak inherited keys, and an own __proto__ key is dropped rather than assigned through the setter\n const full = {};\n for (const k of Object.keys(iss)) {\n if (k === \"inst\" || k === \"schema\" || k === \"continue\" || k === \"input\" || k === \"__proto__\")\n continue;\n full[k] = iss[k];\n }\n full.path ?? (full.path = []);\n full.message = message;\n if (ctx?.reportInput) {\n full.input = iss.input;\n }\n return full;\n}\nexport function getSizableOrigin(input) {\n if (input instanceof Set)\n return \"set\";\n if (input instanceof Map)\n return \"map\";\n // @ts-ignore\n if (input instanceof File)\n return \"file\";\n return \"unknown\";\n}\nconst highSurrogate = /[\\uD800-\\uDBFF]/;\n// Code points in `str`: a surrogate pair counts once, a lone surrogate as itself. Hand-rolled because the string iterator allocates and runs ~250x slower on this path; the regex probe exits ~50x quicker for a string with no astral characters.\nexport function codePointLength(str) {\n const units = str.length;\n if (!highSurrogate.test(str))\n return units;\n let count = units;\n for (let i = 0; i < units - 1; i++) {\n if ((str.charCodeAt(i) & 0xfc00) === 0xd800 && (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00) {\n count--;\n i++;\n }\n }\n return count;\n}\nexport function getLengthableOrigin(input) {\n if (Array.isArray(input))\n return \"array\";\n if (typeof input === \"string\")\n return \"string\";\n return \"unknown\";\n}\nexport function parsedType(data) {\n const t = typeof data;\n switch (t) {\n case \"number\": {\n return Number.isNaN(data) ? \"nan\" : \"number\";\n }\n case \"object\": {\n if (data === null) {\n return \"null\";\n }\n if (Array.isArray(data)) {\n return \"array\";\n }\n const obj = data;\n if (obj && Object.getPrototypeOf(obj) !== Object.prototype && \"constructor\" in obj && obj.constructor) {\n return obj.constructor.name;\n }\n }\n }\n return t;\n}\nexport function issue(...args) {\n const [iss, input, inst] = args;\n if (typeof iss === \"string\") {\n return {\n message: iss,\n code: \"custom\",\n input,\n inst,\n };\n }\n return { ...iss };\n}\nexport function cleanEnum(obj) {\n return Object.entries(obj)\n .filter(([k, _]) => {\n // return true if NaN, meaning it's not a number, thus a string key\n return Number.isNaN(Number.parseInt(k, 10));\n })\n .map((el) => el[1]);\n}\n// Codec utility functions\nexport function base64ToUint8Array(base64) {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n}\nexport function uint8ArrayToBase64(bytes) {\n let binaryString = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binaryString += String.fromCharCode(bytes[i]);\n }\n return btoa(binaryString);\n}\nexport function base64urlToUint8Array(base64url) {\n const base64 = base64url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = \"=\".repeat((4 - (base64.length % 4)) % 4);\n return base64ToUint8Array(base64 + padding);\n}\nexport function uint8ArrayToBase64url(bytes) {\n return uint8ArrayToBase64(bytes).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\nexport function hexToUint8Array(hex) {\n const cleanHex = hex.replace(/^0x/, \"\");\n if (cleanHex.length % 2 !== 0) {\n throw new Error(\"Invalid hex string length\");\n }\n const bytes = new Uint8Array(cleanHex.length / 2);\n for (let i = 0; i < cleanHex.length; i += 2) {\n bytes[i / 2] = Number.parseInt(cleanHex.slice(i, i + 2), 16);\n }\n return bytes;\n}\nexport function uint8ArrayToHex(bytes) {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n// instanceof\nexport class Class {\n constructor(..._args) { }\n}\n////////// PROTOTYPE INSTALLERS //////////\n//\n// Members live on the prototype and materialize per instance on first read, which keeps own-property count under the step where V8 stops using inline slots. Changing anything here means re-measuring runtime, memory and bundle size together \u2014 see \"The three axes\" in AGENTS.md.\n/**\n * Installs a trait's members on its prototype. Each value builds that member for the instance on first read; the built value shadows the accessor as an own property, so a detached `const { parse } = schema` keeps working.\n *\n * Call this from a `proto` initializer, which runs once per prototype \u2014 never per instance.\n */\nexport function members(proto, table) {\n for (const key in table) {\n const desc = Object.getOwnPropertyDescriptor(table, key);\n // a getter installs as written, so it stays live: `description` reads through to the registry on every access. not enumerable: an object literal's is, and a prototype member never was\n if (desc.get)\n Object.defineProperty(proto, key, { ...desc, enumerable: false });\n // a method materializes bound on first read, which is what keeps a detached member working: `const opt = schema.optional; opt()`\n else\n defineBound(proto, key, desc.value);\n }\n}\n/** Shadows a prototype member with an own value, so a getter that builds from the instance runs once. */\nexport function own(inst, key, value, enumerable = true) {\n Object.defineProperty(inst, key, { configurable: true, writable: true, enumerable, value });\n return value;\n}\n/** Like {@link own}, for a member that was never an own data property and has to stay out of `Object.keys`. */\nexport function hide(inst, key, value) {\n return own(inst, key, value, false);\n}\n/** Adds members a table derives from the instance: each builds on first read and shadows as own data, and assignment shadows the same way, as when these were own properties. */\nexport /*@__NO_SIDE_EFFECTS__*/ function derived(computes, table) {\n for (const key in computes) {\n const compute = computes[key];\n // an object literal's accessor is configurable and enumerable, and `members` copies the descriptor as written\n Object.defineProperty(table, key, {\n configurable: true,\n enumerable: true,\n get() {\n return own(this, key, compute(this));\n },\n set(value) {\n own(this, key, value);\n },\n });\n }\n return table;\n}\nfunction defineBound(proto, key, fn) {\n Object.defineProperty(proto, key, {\n configurable: true,\n get() {\n // vitest's spyOn calls a prototype getter bare to find the function it wraps, so a nullish receiver answers the raw method\n return this == null ? fn : own(this, key, fn.bind(this));\n },\n set(value) {\n own(this, key, value);\n },\n });\n}\n/** Returns the prototype to install on, or `undefined` if this group is already installed on it. */\nfunction claim(inst, sentinel) {\n const proto = Object.getPrototypeOf(inst);\n // Runs on every construction, so `in` rather than the costlier `hasOwnProperty.call`. Sentinels are keys the group itself defines.\n return sentinel in proto ? undefined : proto;\n}\n// The internals whose init chain is installing. A second call for the same one is a derived constructor overriding its base, so it must not construct another schema in between or the override is dropped.\nlet installing;\n// Set while a getter is running, so a value that resolved through a recursion break is not memoized. One shared descriptor shadows the key for the duration, which costs no per-key allocation.\nlet broke = false;\nconst breaker = {\n configurable: true,\n get() {\n broke = true;\n return undefined;\n },\n};\n/**\n * Installs a lazily-derived internal on the `_zod` prototype of `inst`'s\n * constructor, computed from the internals object itself and cached there on\n * first read. One accessor per constructor rather than one per instance.\n */\nexport function defineLazyInternal(inst, key, compute) {\n const proto = Object.getPrototypeOf(inst._zod);\n if (key in proto && installing !== inst._zod) {\n // A repeat construction: everything is installed already. Cleared here so the reference is not held past the first construction of every type.\n installing = undefined;\n return;\n }\n installing = inst._zod;\n Object.defineProperty(proto, key, {\n configurable: true,\n get() {\n // Shadowed before computing so a re-entrant read from a recursive schema resolves to undefined instead of running the getter again.\n Object.defineProperty(this, key, breaker);\n const outer = broke;\n broke = false;\n try {\n const value = compute(this);\n // A result that resolved through a recursion break is recomputed once the graph is complete; everything else memoizes, undefined included.\n if (broke)\n delete this[key];\n else\n Object.defineProperty(this, key, { configurable: true, writable: true, value });\n broke = broke || outer;\n return value;\n }\n catch (err) {\n // A compute that threw memoizes nothing, so a later read runs it again and fails the same way. The shadow goes with it, since leaving it installed would answer undefined for every later read.\n delete this[key];\n broke = broke || outer;\n throw err;\n }\n },\n set(value) {\n Object.defineProperty(this, key, { configurable: true, writable: true, value });\n },\n });\n}\n/**\n * Installs `key` on `inst`'s prototype, computed by `make` on first read and cached there as an own\n * data property. One accessor per constructor rather than one per instance, because an own accessor\n * puts every instance after the first into v8 dictionary mode. The key doubles as the sentinel.\n */\nexport function installLazyProp(inst, key, make, enumerable) {\n const proto = claim(inst, key);\n if (!proto)\n return;\n Object.defineProperty(proto, key, {\n configurable: true,\n get() {\n // Shadowed before computing, so a re-entrant read from a self-referential shape resolves to undefined instead of running the getter again. A data property rather than an accessor: an own accessor is the dictionary-mode transition this exists to avoid.\n const desc = { configurable: true, writable: true, enumerable, value: undefined };\n Object.defineProperty(this, key, desc);\n // a compute that throws leaves the shadow behind, so later reads answer undefined instead of re-throwing; `defineLazy` did the same, and `defineLazyInternal`'s delete-on-catch would cost bytes in every bundle for a case only a throwing user getter reaches\n desc.value = make(this);\n Object.defineProperty(this, key, desc);\n return desc.value;\n },\n set(value) {\n Object.defineProperty(this, key, { configurable: true, writable: true, enumerable, value });\n },\n });\n}\n/** Marks the thunk `_catch` synthesises for a constant catch value. `Function.length` cannot tell that thunk from a user callback \u2014 rest and defaulted parameters both report arity 0 \u2014 and a user callback reads `ctx.error`, whose issues only finalize correctly against the caller's per-parse error map. Provenance can say what arity cannot. A plain string key rather than `Symbol.for`, whose call at module scope no bundler can prove pure \u2014 the same shape that anchored `urlCanParse` into every build. */\nexport const CONSTANT_CATCH = \"~constantCatch\";\n/** Wraps a constant catch value in a thunk tagged with {@link CONSTANT_CATCH}. */\nexport function constantCatch(value) {\n const fn = () => value;\n fn[CONSTANT_CATCH] = true;\n return fn;\n}\n", "var _a;\nimport { members as installMembers } from \"./util.js\";\n/** A special constant with type `never` */\nexport const NEVER = /*@__PURE__*/ Object.freeze({\n status: \"aborted\",\n});\n/* Shared descriptor for installing `_zod`; defineProperty reads it\n * synchronously, so reusing one object avoids a per-instance allocation. */\nconst _zodDesc = { value: undefined, enumerable: false };\n// null where suppressing the capture would be unrecoverable: `parse()` puts the frames back with `captureStackTrace`, so without it the throw would lose its stack. also latched to null once `stackTraceLimit` proves unassignable, which a realm can do at any point by hardening Error\nlet _E = \"captureStackTrace\" in Error ? Error : null;\n// v8 captures a stack trace inside the Error constructor, which dominates a failed parse; costs only the frames, and parse() restores those. the constructor must RUN: Object.create is cheaper and passes instanceof, but Error.isError and util.types.isNativeError check an internal slot\nfunction newError(Definition) {\n const E = _E;\n if (E) {\n const saved = E.stackTraceLimit;\n if (typeof saved === \"number\") {\n try {\n E.stackTraceLimit = 0;\n }\n catch {\n _E = null;\n return new Definition();\n }\n try {\n return new Definition();\n }\n finally {\n E.stackTraceLimit = saved;\n }\n }\n }\n return new Definition();\n}\nexport /*@__NO_SIDE_EFFECTS__*/ function $constructor(name, initializer, \n/** This trait's members, installed once on every prototype that composes it. They cannot be declared in the initializer above: that runs per instance, and the prototype is shared. */\nproto, params) {\n // Prototype for this constructor's `_zod` internals. Lazily-derived fields (`values`, `pattern`, `optin`, \u2026) install here once rather than as an accessor on every instance.\n const zodProto = {};\n // Assigning the fields in the constructor body is what gives instances in-object slots; building the object literally and reparenting it costs a second allocation and a generic property copy.\n function Internals(def) {\n this.def = def;\n this.constr = _;\n this.traits = new Set();\n }\n Internals.prototype = zodProto;\n const protoMembers = proto;\n // One trait's members land on every prototype whose chain composes it, so the answer is per prototype rather than per trait.\n const initialized = protoMembers && new WeakSet();\n function init(inst, def) {\n if (!inst._zod) {\n _zodDesc.value = new Internals(def);\n try {\n Object.defineProperty(inst, \"_zod\", _zodDesc);\n }\n finally {\n // Cleared even on throw, so the shared descriptor never leaks one instance's internals into the next.\n _zodDesc.value = undefined;\n }\n }\n else if (inst._zod.traits.has(name)) {\n return;\n }\n inst._zod.traits.add(name);\n initializer(inst, def);\n if (initialized) {\n // `super(def)` from a user subclass gives `this` a prototype the subclass owns, and installing there would overwrite whatever the subclass declared. `constr` built the instance, so its prototype is the one below the subclass's that should carry the members. A receiver whose chain never reaches that prototype installs on its own, which for a plain object handed straight to `init` means `Object.prototype` \u2014 unchanged from before.\n const own = Object.getPrototypeOf(inst);\n const ctorProto = inst._zod.constr.prototype;\n let up = own;\n while (up && up !== ctorProto)\n up = Object.getPrototypeOf(up);\n const target = up ?? own;\n if (!initialized.has(target)) {\n initialized.add(target);\n installMembers(target, protoMembers);\n }\n }\n // support prototype modifications; for-in avoids the array allocation of Object.keys on the (usually empty) prototype\n const proto = _.prototype;\n for (const k in proto) {\n if (!Object.prototype.hasOwnProperty.call(proto, k))\n continue;\n if (!(k in inst)) {\n inst[k] = proto[k].bind(inst);\n }\n }\n }\n // doesn't work if Parent has a constructor with arguments\n const Parent = params?.Parent ?? Object;\n class Definition extends Parent {\n }\n Object.defineProperty(Definition, \"name\", { value: name });\n function _(def) {\n const inst = params?.Parent ? newError(Definition) : this;\n init(inst, def);\n const deferred = inst._zod.deferred;\n if (deferred) {\n for (const fn of deferred) {\n fn();\n }\n // Released: initializers run once, and the list would otherwise be retained for the schema's lifetime.\n inst._zod.deferred = undefined;\n }\n // Global post-processor hook. Internal: installed by `import \"zod/compile\"` to enable AOT compilation for every constructed schema. Runs last, once the instance is fully built, because it hands the instance to compile(). The post-processor is expected to be reentrancy-guarded by its own implementation.\n const pp = globalThis.__zod_globalConfig?.postProcessor;\n if (pp)\n pp(inst);\n return inst;\n }\n Object.defineProperty(_, \"init\", { value: init });\n Object.defineProperty(_, Symbol.hasInstance, {\n value: (inst) => {\n if (params?.Parent && inst instanceof params.Parent)\n return true;\n return inst?._zod?.traits?.has(name);\n },\n });\n Object.defineProperty(_, \"name\", { value: name });\n return _;\n}\n////////////////////////////// UTILITIES ///////////////////////////////////////\nexport const $brand = /*@__PURE__*/ Symbol(\"zod_brand\");\nexport class $ZodAsyncError extends Error {\n constructor() {\n super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);\n }\n}\nexport class $ZodEncodeError extends Error {\n constructor(name) {\n super(`Encountered unidirectional transform during encode: ${name}`);\n this.name = \"ZodEncodeError\";\n }\n}\n(_a = globalThis).__zod_globalConfig ?? (_a.__zod_globalConfig = {});\nexport const globalConfig = globalThis.__zod_globalConfig;\nexport function config(newConfig) {\n if (newConfig)\n Object.assign(globalConfig, newConfig);\n return globalConfig;\n}\n", "import { $constructor } from \"./core.js\";\nimport * as util from \"./util.js\";\n/* Computing the message eagerly is expensive (pretty-printed JSON of all\n * issues), so defer it until first read. The accessor functions and\n * descriptors are shared across instances to keep error construction\n * cheap; the computed message is cached on the internals object. The\n * setter preserves plain assignment semantics for consumers that\n * overwrite `message`. */\nfunction _getMessage() {\n const internals = this._zod;\n internals.message ?? (internals.message = JSON.stringify(internals.def, util.jsonStringifyReplacer, 2));\n return internals.message;\n}\nfunction _setMessage(value) {\n this._zod.message = value;\n}\nconst _messageDesc = {\n get: _getMessage,\n set: _setMessage,\n enumerable: true,\n configurable: true,\n};\nconst _issuesDesc = { value: undefined, enumerable: false };\n/* Prototypes that already carry the lazy `toString`. Seeded with the\n * intrinsics so that `init` on a foreign object \u2014 it accepts any object \u2014\n * can never install an accessor onto a prototype we do not own. */\nconst _installedToString = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);\nconst initializer = (inst, def) => {\n inst.name = \"$ZodError\";\n // `_zod` is already non-enumerable: $constructor's init defined it with this same descriptor\n _issuesDesc.value = def;\n Object.defineProperty(inst, \"issues\", _issuesDesc);\n // Clear the shared slot; a retained `value` pins the last error's issues.\n _issuesDesc.value = undefined;\n Object.defineProperty(inst, \"message\", _messageDesc);\n /* `toString` lives as a non-enumerable lazy getter on the shared\n * prototype; on first access it caches a per-instance closure so\n * detached usage still works. */\n const proto = Object.getPrototypeOf(inst);\n if (!_installedToString.has(proto)) {\n _installedToString.add(proto);\n Object.defineProperty(proto, \"toString\", {\n configurable: true,\n enumerable: false,\n get() {\n const value = () => this.message;\n Object.defineProperty(this, \"toString\", { value, configurable: true, writable: true });\n return value;\n },\n set(value) {\n Object.defineProperty(this, \"toString\", { value, configurable: true, writable: true });\n },\n });\n }\n};\nexport const $ZodError = $constructor(\"$ZodError\", initializer);\nexport const $ZodRealError = $constructor(\"$ZodError\", initializer, undefined, {\n Parent: Error,\n});\n/** Get-or-create `obj[key]` as an own data property. A path segment naming an inherited member\n * (\"toString\", \"constructor\") would otherwise read through to the prototype, and assigning\n * \"__proto__\" would hit the setter instead of creating a key. */\nfunction node(obj, key, make) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) {\n if (key === \"__proto__\") {\n Object.defineProperty(obj, key, { value: make(), writable: true, enumerable: true, configurable: true });\n }\n else {\n obj[key] = make();\n }\n }\n return obj[key];\n}\nexport function flattenError(error, mapper = (issue) => issue.message) {\n const fieldErrors = {};\n const formErrors = [];\n for (const sub of error.issues) {\n if (sub.path.length > 0) {\n node(fieldErrors, sub.path[0], () => []).push(mapper(sub));\n }\n else {\n formErrors.push(mapper(sub));\n }\n }\n return { formErrors, fieldErrors };\n}\nexport function formatError(error, mapper = (issue) => issue.message) {\n const fieldErrors = { _errors: [] };\n const processError = (error, path = []) => {\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\" && issue.errors.length) {\n issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));\n }\n else if (issue.code === \"invalid_key\") {\n processError({ issues: issue.issues }, [...path, ...issue.path]);\n }\n else if (issue.code === \"invalid_element\") {\n processError({ issues: issue.issues }, [...path, ...issue.path]);\n }\n else {\n const fullpath = [...path, ...issue.path];\n if (fullpath.length === 0) {\n fieldErrors._errors.push(mapper(issue));\n }\n else {\n let curr = fieldErrors;\n let i = 0;\n while (i < fullpath.length) {\n const el = fullpath[i];\n const terminal = i === fullpath.length - 1;\n // `_errors` is reserved by this legacy format, so merge a matching path segment into the current node instead of treating its array as a child.\n if (el === \"_errors\") {\n if (terminal)\n curr._errors.push(mapper(issue));\n i++;\n continue;\n }\n // A path element may collide with an inherited property name such as\n // \"__proto__\" or \"constructor\". Truthiness checks read the prototype\n // (so no node is created, then ._errors.push throws), and bracket\n // assignment of \"__proto__\" hits the setter instead of creating an\n // own key. Guard the read with hasOwnProperty and create the node\n // with defineProperty so any path element becomes a real own key.\n if (!Object.prototype.hasOwnProperty.call(curr, el)) {\n Object.defineProperty(curr, el, {\n value: { _errors: [] },\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n const node = curr[el];\n if (terminal) {\n node._errors.push(mapper(issue));\n }\n curr = node;\n i++;\n }\n }\n }\n }\n };\n processError(error);\n return fieldErrors;\n}\nexport function treeifyError(error, mapper = (issue) => issue.message) {\n const result = { errors: [] };\n const processError = (error, path = []) => {\n var _a;\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\" && issue.errors.length) {\n // regular union error\n issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));\n }\n else if (issue.code === \"invalid_key\") {\n processError({ issues: issue.issues }, [...path, ...issue.path]);\n }\n else if (issue.code === \"invalid_element\") {\n processError({ issues: issue.issues }, [...path, ...issue.path]);\n }\n else {\n const fullpath = [...path, ...issue.path];\n if (fullpath.length === 0) {\n result.errors.push(mapper(issue));\n continue;\n }\n let curr = result;\n let i = 0;\n while (i < fullpath.length) {\n const el = fullpath[i];\n const terminal = i === fullpath.length - 1;\n if (typeof el === \"string\") {\n curr.properties ?? (curr.properties = {});\n // el may collide with an inherited property name (\"__proto__\",\n // \"constructor\", ...); ??= reads the prototype so the node is never\n // created and curr.errors.push throws. Guard with hasOwnProperty and\n // create the node with defineProperty so \"__proto__\" becomes a real\n // own key rather than invoking the prototype setter.\n if (!Object.prototype.hasOwnProperty.call(curr.properties, el)) {\n Object.defineProperty(curr.properties, el, {\n value: { errors: [] },\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n curr = curr.properties[el];\n }\n else {\n curr.items ?? (curr.items = []);\n (_a = curr.items)[el] ?? (_a[el] = { errors: [] });\n curr = curr.items[el];\n }\n if (terminal) {\n curr.errors.push(mapper(issue));\n }\n i++;\n }\n }\n }\n };\n processError(error);\n return result;\n}\n/** Format a ZodError as a human-readable string in the following form.\n *\n * From\n *\n * ```ts\n * ZodError {\n * issues: [\n * {\n * expected: 'string',\n * code: 'invalid_type',\n * path: [ 'username' ],\n * message: 'Invalid input: expected string'\n * },\n * {\n * expected: 'number',\n * code: 'invalid_type',\n * path: [ 'favoriteNumbers', 1 ],\n * message: 'Invalid input: expected number'\n * }\n * ];\n * }\n * ```\n *\n * to\n *\n * ```\n * username\n * \u2716 Expected number, received string at \"username\n * favoriteNumbers[0]\n * \u2716 Invalid input: expected number\n * ```\n */\nexport function toDotPath(_path) {\n const segs = [];\n const path = _path.map((seg) => (typeof seg === \"object\" ? seg.key : seg));\n for (const seg of path) {\n if (typeof seg === \"number\")\n segs.push(`[${seg}]`);\n else if (typeof seg === \"symbol\")\n segs.push(`[${JSON.stringify(String(seg))}]`);\n else if (/[^\\w$]/.test(seg))\n segs.push(`[${JSON.stringify(seg)}]`);\n else {\n if (segs.length)\n segs.push(\".\");\n segs.push(seg);\n }\n }\n return segs.join(\"\");\n}\nexport function prettifyError(error) {\n const lines = [];\n // sort by path length\n const issues = [...error.issues].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length);\n // Process each issue\n for (const issue of issues) {\n lines.push(`\u2716 ${issue.message}`);\n if (issue.path?.length)\n lines.push(` \u2192 at ${toDotPath(issue.path)}`);\n }\n // Convert Map to formatted string\n return lines.join(\"\\n\");\n}\n", "import * as core from \"./core.js\";\nimport * as errors from \"./errors.js\";\nimport * as util from \"./util.js\";\n// Always both keys, so the `_params` read site in `_parse` sees one object shape rather than two.\nfunction finalizeParams(callee, params) {\n return { callee: params?.callee ?? callee, Err: params?.Err };\n}\nexport const _parse = (_Err) => {\n const fn = (schema, value, _ctx, _params) => {\n const ctx = _ctx ? { ..._ctx, async: false } : { async: false };\n const result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise) {\n throw new core.$ZodAsyncError();\n }\n if (result.issues.length) {\n const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())));\n util.captureStackTrace(e, _params?.callee ?? fn);\n throw e;\n }\n return result.value;\n };\n return fn;\n};\nexport const parse = /* @__PURE__*/ _parse(errors.$ZodRealError);\nexport const _parseAsync = (_Err) => {\n const fn = async (schema, value, _ctx, params) => {\n const ctx = _ctx ? { ..._ctx, async: true } : { async: true };\n let result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise)\n result = await result;\n if (result.issues.length) {\n const e = new (params?.Err ?? _Err)(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())));\n util.captureStackTrace(e, params?.callee ?? fn);\n throw e;\n }\n return result.value;\n };\n return fn;\n};\nexport const parseAsync = /* @__PURE__*/ _parseAsync(errors.$ZodRealError);\nexport const _safeParse = (_Err) => (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, async: false } : { async: false };\n const result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise) {\n throw new core.$ZodAsyncError();\n }\n return result.issues.length ? failure(_Err, result.issues, ctx) : { success: true, data: result.value };\n};\nexport const safeParse = /* @__PURE__*/ _safeParse(errors.$ZodRealError);\n// the error is built on the first read of `error`: finalizing the issues and constructing the instance is most of a failing parse, and a caller that only branches on `success` never pays it. a getter in the literal keeps this small; the alternative, one shared accessor descriptor plus a hidden state slot, reads ~15% faster but costs ~75 B gzipped in every bundle\nfunction failure(Err, issues, ctx) {\n let error;\n return {\n success: false,\n get error() {\n if (!error) {\n error = new Err(issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())));\n // finalizeIssue drops `input`, so the built error holds nothing; keeping the raw issues past this point pins the parsed value for the life of the result\n issues = undefined;\n ctx = undefined;\n }\n return error;\n },\n set error(e) {\n error = e;\n // a replacement makes the getter's branch unreachable, so the captures have to go here too\n issues = undefined;\n ctx = undefined;\n },\n };\n}\nexport const _safeParseAsync = (_Err) => async (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, async: true } : { async: true };\n let result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise)\n result = await result;\n return result.issues.length ? failure(_Err, result.issues, ctx) : { success: true, data: result.value };\n};\nexport const safeParseAsync = /* @__PURE__*/ _safeParseAsync(errors.$ZodRealError);\n// registry mirrors of the compiler's sentinels, so this module never imports the compiler\nconst COMPILE_INVALID = /* @__PURE__ */ Symbol.for(\"zod.compile.invalid\");\nconst COMPILE_FALLBACK = /* @__PURE__ */ Symbol.for(\"zod.compile.fallback\");\n// Deliberately tiny, because v8 will not inline a body carrying the fallback's object literals and throw. Everything that is not the compiled happy path lives in validateFallback, and that split is worth ~35% on a compiled schema.\nexport const validate = ((schema, value, _ctx) => {\n const validator = schema._zod.bag.validator;\n if (validator !== undefined) {\n if (validator(value) !== COMPILE_INVALID)\n return true;\n // a definite sentinel means the runtime would reject, so skip the re-parse; a ctx can still change the answer\n if (validator.definite === true && _ctx === undefined)\n return false;\n }\n return validateFallback(schema, value, _ctx);\n});\nfunction validateFallback(schema, value, _ctx) {\n const ctx = _ctx\n ? { ..._ctx, async: false, abortEarly: true }\n : { async: false, abortEarly: true };\n const fallbackRun = schema._zod.bag.fallbackRun;\n let result;\n if (fallbackRun) {\n // skip nested fast paths on the fallback, so user callbacks keep the at-most-twice bound\n ctx[COMPILE_FALLBACK] = true;\n result = fallbackRun({ value, issues: [] }, ctx);\n }\n else {\n result = schema._zod.run({ value, issues: [] }, ctx);\n }\n if (result instanceof Promise) {\n throw new core.$ZodAsyncError();\n }\n return result.issues.length === 0;\n}\n// no fast path: the compiler keeps async parses on the runtime, because a promise-returning callback that is not declared async compiles to a throw\nexport const validateAsync = async (schema, value, _ctx) => {\n const ctx = _ctx\n ? { ..._ctx, async: true, abortEarly: true }\n : { async: true, abortEarly: true };\n let result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise)\n result = await result;\n return result.issues.length === 0;\n};\nexport const _encode = (_Err) => {\n const parse = _parse(_Err);\n const fn = (schema, value, _ctx, _params) => {\n const ctx = _ctx ? { ..._ctx, direction: \"backward\" } : { direction: \"backward\" };\n return parse(schema, value, ctx, finalizeParams(fn, _params));\n };\n return fn;\n};\nexport const encode = /* @__PURE__*/ _encode(errors.$ZodRealError);\nexport const _decode = (_Err) => {\n const parse = _parse(_Err);\n const fn = (schema, value, _ctx, _params) => {\n return parse(schema, value, _ctx, finalizeParams(fn, _params));\n };\n return fn;\n};\nexport const decode = /* @__PURE__*/ _decode(errors.$ZodRealError);\nexport const _encodeAsync = (_Err) => {\n const parseAsync = _parseAsync(_Err);\n const fn = async (schema, value, _ctx, _params) => {\n const ctx = _ctx ? { ..._ctx, direction: \"backward\" } : { direction: \"backward\" };\n return (await parseAsync(schema, value, ctx, finalizeParams(fn, _params)));\n };\n return fn;\n};\nexport const encodeAsync = /* @__PURE__*/ _encodeAsync(errors.$ZodRealError);\nexport const _decodeAsync = (_Err) => {\n const parseAsync = _parseAsync(_Err);\n const fn = async (schema, value, _ctx, _params) => {\n return await parseAsync(schema, value, _ctx, finalizeParams(fn, _params));\n };\n return fn;\n};\nexport const decodeAsync = /* @__PURE__*/ _decodeAsync(errors.$ZodRealError);\nexport const _safeEncode = (_Err) => (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, direction: \"backward\" } : { direction: \"backward\" };\n return _safeParse(_Err)(schema, value, ctx);\n};\nexport const safeEncode = /* @__PURE__*/ _safeEncode(errors.$ZodRealError);\nexport const _safeDecode = (_Err) => (schema, value, _ctx) => {\n return _safeParse(_Err)(schema, value, _ctx);\n};\nexport const safeDecode = /* @__PURE__*/ _safeDecode(errors.$ZodRealError);\nexport const _safeEncodeAsync = (_Err) => async (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, direction: \"backward\" } : { direction: \"backward\" };\n return _safeParseAsync(_Err)(schema, value, ctx);\n};\nexport const safeEncodeAsync = /* @__PURE__*/ _safeEncodeAsync(errors.$ZodRealError);\nexport const _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {\n return _safeParseAsync(_Err)(schema, value, _ctx);\n};\nexport const safeDecodeAsync = /* @__PURE__*/ _safeDecodeAsync(errors.$ZodRealError);\n", "import * as util from \"./util.js\";\n/**\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link cuid2} instead.\n * See https://github.com/paralleldrive/cuid.\n */\nexport const cuid = /^[cC][0-9a-z]{6,}$/;\nexport const cuid2 = /^[0-9a-z]+$/;\nexport const ulid = /^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/;\nexport const xid = /^[0-9a-vA-V]{20}$/;\nexport const ksuid = /^[A-Za-z0-9]{27}$/;\nexport const nanoid = /^[a-zA-Z0-9_-]{21}$/;\nexport function nanoidOfLength(length) {\n return new RegExp(`^[a-zA-Z0-9_-]{${length}}$`);\n}\n/** ISO 8601-1 duration regex. Does not support the 8601-2 extensions like negative durations or fractional/negative components. */\nexport const duration = /^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$/;\n/** Implements ISO 8601-2 extensions like explicit +- prefixes, mixing weeks with other units, and fractional/negative components. */\nexport const extendedDuration = /^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/;\n/** A regex for any UUID-like identifier: 8-4-4-4-12 hex pattern */\nexport const guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;\n/** Returns a regex for validating an RFC 9562/4122 UUID.\n *\n * @param version Optionally specify a version 1-8. If no version is specified, all versions are supported. */\nexport const uuid = (version) => {\n if (!version)\n return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;\n return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);\n};\nexport const uuid4 = /*@__PURE__*/ uuid(4);\nexport const uuid6 = /*@__PURE__*/ uuid(6);\nexport const uuid7 = /*@__PURE__*/ uuid(7);\n/** Practical email validation */\nexport const email = /^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$/;\n/** Equivalent to the HTML5 input[type=email] validation implemented by browsers. Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email */\nexport const html5Email = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n/** The classic emailregex.com regex for RFC 5322-compliant emails */\nexport const rfc5322Email = /^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n/** A loose regex that allows Unicode characters, enforces length limits, and that's about it. */\nexport const unicodeEmail = /^[^\\s@\"]{1,64}@[^\\s@]{1,255}$/u;\nexport const idnEmail = unicodeEmail;\nexport const browserEmail = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n// from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression\n// Single character class, not an alternation: the two properties overlap (U+1F9B0-U+1F9B3), so `(A|B)+` backtracks exponentially on a failed match. The leading lookahead then demands one anchor \u2014 a pictograph, a regional indicator, or the enclosing keycap \u2014 because `\\p{Emoji_Component}` on its own covers ASCII digits, `#`, `*`, ZWJ, variation selectors and skin tone modifiers, none of which is an emoji without a base.\nconst _emoji = `^(?=[\\\\s\\\\S]*[\\\\p{Extended_Pictographic}\\\\p{Regional_Indicator}\\\\u20E3])[\\\\p{Extended_Pictographic}\\\\p{Emoji_Component}]+$`;\nexport function emoji() {\n return new RegExp(_emoji, \"u\");\n}\nexport const ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;\nexport const ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;\nexport const mac = (delimiter) => {\n const escapedDelim = util.escapeRegex(delimiter ?? \":\");\n return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);\n};\nexport const cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/([0-9]|[1-2][0-9]|3[0-2])$/;\nexport const cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;\n// https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript\nexport const base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;\nexport const base64url = /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/;\n// based on https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address\n// export const hostname: RegExp = /^([a-zA-Z0-9-]+\\.)*[a-zA-Z0-9-]+$/;\nexport const hostname = /^(?=.{1,253}\\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\\.?$/;\nexport const domain = /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}$/;\nexport const httpProtocol = /^https?$/;\n// https://blog.stevenlevithan.com/archives/validate-phone-number#r4-3 (regex sans spaces) E.164: leading digit must be 1-9; total digits (excluding '+') between 7-15\nexport const e164 = /^\\+[1-9]\\d{6,14}$/;\n// Credit card shape: 12\u201319 digits, optionally separated by single spaces or single hyphens. ISO/IEC 7812 caps the PAN at 19 digits; 12 is the shortest issued length (Maestro).\nexport const creditCard = /^\\d(?:[ -]?\\d){11,18}$/;\n// ISO 4217 alpha codes from the SIX list, regenerated by scripts/update-iso-4217.ts\nexport const currencyCode = /^(?:AED|AFN|ALL|AMD|AOA|ARS|AUD|AWG|AZN|BAM|BBD|BDT|BHD|BIF|BMD|BND|BOB|BOV|BRL|BSD|BTN|BWP|BYN|BZD|CAD|CDF|CHE|CHF|CHW|CLF|CLP|CNY|COP|COU|CRC|CUP|CVE|CZK|DJF|DKK|DOP|DZD|EGP|ERN|ETB|EUR|FJD|FKP|GBP|GEL|GHS|GIP|GMD|GNF|GTQ|GYD|HKD|HNL|HTG|HUF|IDR|ILS|INR|IQD|IRR|ISK|JMD|JOD|JPY|KES|KGS|KHR|KMF|KPW|KRW|KWD|KYD|KZT|LAK|LBP|LKR|LRD|LSL|LYD|MAD|MDL|MGA|MKD|MMK|MNT|MOP|MRU|MUR|MVR|MWK|MXN|MXV|MYR|MZN|NAD|NGN|NIO|NOK|NPR|NZD|OMR|PAB|PEN|PGK|PHP|PKR|PLN|PYG|QAR|RON|RSD|RUB|RWF|SAR|SBD|SCR|SDG|SEK|SGD|SHP|SLE|SOS|SRD|SSP|STN|SVC|SYP|SZL|THB|TJS|TMT|TND|TOP|TRY|TTD|TWD|TZS|UAH|UGX|USD|USN|UYI|UYU|UYW|UZS|VED|VES|VND|VUV|WST|XAD|XAF|XAG|XAU|XBA|XBB|XBC|XBD|XCD|XCG|XDR|XOF|XPD|XPF|XPT|XSU|XTS|XUA|XXX|YER|ZAR|ZMW|ZWG)$/;\n// iban electronic format: 2-letter country, check digits 02-98 (the only values `98 - remainder` can produce), 11-30 bban characters\nexport const iban = /^[A-Z]{2}(?!00|01|99)\\d{2}[A-Z0-9]{11,30}$/;\nconst dateSource = `(?:(?:\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\\\d|30)|(?:02)-(?:0[1-9]|1\\\\d|2[0-8])))`;\n/** Anchors a pattern source. The interpolation lives here rather than at the call site because\n * esbuild will not drop a `@__PURE__` call whose own argument interpolates a variable, but it\n * will drop `anchor(dateSource)`. Keeping it inline pinned `date` into every bundle. */\nfunction anchor(source) {\n return new RegExp(`^${source}$`);\n}\nexport const date = /*@__PURE__*/ anchor(dateSource);\nfunction timeSource(args) {\n const hhmm = `(?:[01]\\\\d|2[0-3]):[0-5]\\\\d`;\n const regex = typeof args.precision === \"number\"\n ? args.precision === -1\n ? `${hhmm}`\n : args.precision === 0\n ? `${hhmm}:[0-5]\\\\d`\n : `${hhmm}:[0-5]\\\\d\\\\.\\\\d{${args.precision}}`\n : args.seconds\n ? `${hhmm}:[0-5]\\\\d(?:\\\\.\\\\d+)?`\n : `${hhmm}(?::[0-5]\\\\d(?:\\\\.\\\\d+)?)?`;\n return regex;\n}\nexport function time(args) {\n return new RegExp(`^${timeSource(args)}$`);\n}\n// Adapted from https://stackoverflow.com/a/3143231\nexport function datetime(args) {\n const opts = [\"Z\"];\n // if (args.offset) opts.push(`([+-]\\\\d{2}:\\\\d{2})`);\n if (args.offset)\n opts.push(`([+-](?:[01]\\\\d|2[0-3]):[0-5]\\\\d)`);\n // RFC 3339 mandates seconds wherever the time carries a `Z` or an offset, so only the unqualified form `local` adds may omit them\n const qualified = `${timeSource({ precision: args.precision, seconds: true })}(?:${opts.join(\"|\")})`;\n const timeRegex = args.local ? `${qualified}|${timeSource({ precision: args.precision })}` : qualified;\n return new RegExp(`^${dateSource}T(?:${timeRegex})$`);\n}\n// the unbounded form of `string()` as a literal, so every plain string shares one instance instead of building its own\nexport const anyString = /^[\\s\\S]{0,}$/;\nexport const string = (params) => {\n const regex = params ? `[\\\\s\\\\S]{${params?.minimum ?? 0},${params?.maximum ?? \"\"}}` : `[\\\\s\\\\S]*`;\n return new RegExp(`^${regex}$`);\n};\nexport const bigint = /^-?\\d+n?$/;\nexport const integer = /^-?\\d+$/;\nexport const number = /^-?\\d+(?:\\.\\d+)?$/;\nexport const boolean = /^(?:true|false)$/i;\nconst _null = /^null$/i;\nexport { _null as null };\nconst _undefined = /^undefined$/i;\nexport { _undefined as undefined };\n// regex for string with no uppercase letters\nexport const lowercase = /^[^A-Z]*$/;\n// regex for string with no lowercase letters\nexport const uppercase = /^[^a-z]*$/;\n// regex for hexadecimal strings (any length)\nexport const hex = /^[0-9a-fA-F]*$/;\n// Hash regexes for different algorithms and encodings\n// Helper function to create base64 regex with exact length and padding\nfunction fixedBase64(bodyLength, padding) {\n return new RegExp(`^[A-Za-z0-9+/]{${bodyLength}}${padding}$`);\n}\n// Helper function to create base64url regex with exact length (no padding)\nfunction fixedBase64url(length) {\n return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);\n}\n// MD5 (16 bytes): base64 = 24 chars total (22 + \"==\")\nexport const md5_hex = /^[0-9a-fA-F]{32}$/;\nexport const md5_base64 = /*@__PURE__*/ fixedBase64(22, \"==\");\nexport const md5_base64url = /*@__PURE__*/ fixedBase64url(22);\n// SHA1 (20 bytes): base64 = 28 chars total (27 + \"=\")\nexport const sha1_hex = /^[0-9a-fA-F]{40}$/;\nexport const sha1_base64 = /*@__PURE__*/ fixedBase64(27, \"=\");\nexport const sha1_base64url = /*@__PURE__*/ fixedBase64url(27);\n// SHA256 (32 bytes): base64 = 44 chars total (43 + \"=\")\nexport const sha256_hex = /^[0-9a-fA-F]{64}$/;\nexport const sha256_base64 = /*@__PURE__*/ fixedBase64(43, \"=\");\nexport const sha256_base64url = /*@__PURE__*/ fixedBase64url(43);\n// SHA384 (48 bytes): base64 = 64 chars total (no padding)\nexport const sha384_hex = /^[0-9a-fA-F]{96}$/;\nexport const sha384_base64 = /*@__PURE__*/ fixedBase64(64, \"\");\nexport const sha384_base64url = /*@__PURE__*/ fixedBase64url(64);\n// SHA512 (64 bytes): base64 = 88 chars total (86 + \"==\")\nexport const sha512_hex = /^[0-9a-fA-F]{128}$/;\nexport const sha512_base64 = /*@__PURE__*/ fixedBase64(86, \"==\");\nexport const sha512_base64url = /*@__PURE__*/ fixedBase64url(86);\n", "// import { $ZodType } from \"./schemas.js\";\nimport * as core from \"./core.js\";\nimport * as regexes from \"./regexes.js\";\nimport * as util from \"./util.js\";\nexport const $ZodCheck = /*@__PURE__*/ core.$constructor(\"$ZodCheck\", (inst, def) => {\n var _a;\n inst._zod ?? (inst._zod = {});\n inst._zod.def = def;\n (_a = inst._zod).onattach ?? (_a.onattach = []);\n});\n/** Default `when` for size-based checks: run only on non-nullish values with a `size`. */\nconst _whenHasSize = (payload) => {\n const val = payload.value;\n return !util.nullish(val) && val.size !== undefined;\n};\n/** Default `when` for length-based checks: run only on non-nullish values with a `length`. */\nconst _whenHasLength = (payload) => {\n const val = payload.value;\n return !util.nullish(val) && val.length !== undefined;\n};\nconst numericOriginMap = {\n number: \"number\",\n bigint: \"bigint\",\n object: \"date\",\n};\nexport const $ZodCheckLessThan = /*@__PURE__*/ core.$constructor(\"$ZodCheckLessThan\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const origin = numericOriginMap[typeof def.value];\n inst._zod.check = (payload) => {\n if (def.inclusive ? payload.value <= def.value : payload.value < def.value) {\n return;\n }\n payload.issues.push({\n origin: numericOriginMap[typeof payload.value] ?? origin,\n code: \"too_big\",\n maximum: typeof def.value === \"object\" ? def.value.getTime() : def.value,\n input: payload.value,\n inclusive: def.inclusive,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckGreaterThan = /*@__PURE__*/ core.$constructor(\"$ZodCheckGreaterThan\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const origin = numericOriginMap[typeof def.value];\n inst._zod.check = (payload) => {\n if (def.inclusive ? payload.value >= def.value : payload.value > def.value) {\n return;\n }\n payload.issues.push({\n origin: numericOriginMap[typeof payload.value] ?? origin,\n code: \"too_small\",\n minimum: typeof def.value === \"object\" ? def.value.getTime() : def.value,\n input: payload.value,\n inclusive: def.inclusive,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckMultipleOf = \n/*@__PURE__*/ core.$constructor(\"$ZodCheckMultipleOf\", (inst, def) => {\n $ZodCheck.init(inst, def);\n inst._zod.check = (payload) => {\n if (typeof payload.value !== typeof def.value)\n throw new Error(\"Cannot mix number and bigint in multiple_of check.\");\n const isMultiple = typeof payload.value === \"bigint\"\n ? // `value % 0n` throws, and nothing is a multiple of zero \u2014 the number branch already fails this way via NaN\n def.value !== BigInt(0) && payload.value % def.value === BigInt(0)\n : util.floatSafeRemainder(payload.value, def.value) === 0;\n if (isMultiple)\n return;\n payload.issues.push({\n origin: typeof payload.value,\n code: \"not_multiple_of\",\n divisor: def.value,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckNumberFormat = /*@__PURE__*/ core.$constructor(\"$ZodCheckNumberFormat\", (inst, def) => {\n $ZodCheck.init(inst, def); // no format checks\n def.format = def.format || \"float64\";\n const isInt = def.format?.includes(\"int\");\n const origin = isInt ? \"int\" : \"number\";\n const [minimum, maximum] = util.NUMBER_FORMAT_RANGES[def.format];\n inst._zod.check = (payload) => {\n const input = payload.value;\n if (isInt) {\n if (!Number.isInteger(input)) {\n // invalid_format issue\n // payload.issues.push({\n // expected: def.format,\n // format: def.format,\n // code: \"invalid_format\",\n // input,\n // inst,\n // });\n // invalid_type issue\n payload.issues.push({\n expected: origin,\n format: def.format,\n code: \"invalid_type\",\n continue: false,\n input,\n inst,\n });\n return;\n // not_multiple_of issue\n // payload.issues.push({\n // code: \"not_multiple_of\",\n // origin: \"number\",\n // input,\n // inst,\n // divisor: 1,\n // });\n }\n if (!Number.isSafeInteger(input)) {\n if (input > 0) {\n // too_big\n payload.issues.push({\n input,\n code: \"too_big\",\n maximum: Number.MAX_SAFE_INTEGER,\n note: \"Integers must be within the safe integer range.\",\n inst,\n origin,\n inclusive: true,\n continue: !def.abort,\n });\n }\n else {\n // too_small\n payload.issues.push({\n input,\n code: \"too_small\",\n minimum: Number.MIN_SAFE_INTEGER,\n note: \"Integers must be within the safe integer range.\",\n inst,\n origin,\n inclusive: true,\n continue: !def.abort,\n });\n }\n return;\n }\n }\n if (input < minimum) {\n payload.issues.push({\n origin: \"number\",\n input,\n code: \"too_small\",\n minimum,\n inclusive: true,\n inst,\n continue: !def.abort,\n });\n }\n if (input > maximum) {\n payload.issues.push({\n origin: \"number\",\n input,\n code: \"too_big\",\n maximum,\n inclusive: true,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\nexport const $ZodCheckBigIntFormat = /*@__PURE__*/ core.$constructor(\"$ZodCheckBigIntFormat\", (inst, def) => {\n $ZodCheck.init(inst, def); // no format checks\n const [minimum, maximum] = util.BIGINT_FORMAT_RANGES[def.format];\n inst._zod.check = (payload) => {\n const input = payload.value;\n if (input < minimum) {\n payload.issues.push({\n origin: \"bigint\",\n input,\n code: \"too_small\",\n minimum: minimum,\n inclusive: true,\n inst,\n continue: !def.abort,\n });\n }\n if (input > maximum) {\n payload.issues.push({\n origin: \"bigint\",\n input,\n code: \"too_big\",\n maximum,\n inclusive: true,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\nexport const $ZodCheckMaxSize = /*@__PURE__*/ core.$constructor(\"$ZodCheckMaxSize\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = _whenHasSize);\n inst._zod.check = (payload) => {\n const input = payload.value;\n const size = input.size;\n if (size <= def.maximum)\n return;\n payload.issues.push({\n origin: util.getSizableOrigin(input),\n code: \"too_big\",\n maximum: def.maximum,\n inclusive: true,\n input,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckMinSize = /*@__PURE__*/ core.$constructor(\"$ZodCheckMinSize\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = _whenHasSize);\n inst._zod.check = (payload) => {\n const input = payload.value;\n const size = input.size;\n if (size >= def.minimum)\n return;\n payload.issues.push({\n origin: util.getSizableOrigin(input),\n code: \"too_small\",\n minimum: def.minimum,\n inclusive: true,\n input,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckSizeEquals = /*@__PURE__*/ core.$constructor(\"$ZodCheckSizeEquals\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = _whenHasSize);\n inst._zod.check = (payload) => {\n const input = payload.value;\n const size = input.size;\n if (size === def.size)\n return;\n const tooBig = size > def.size;\n payload.issues.push({\n origin: util.getSizableOrigin(input),\n ...(tooBig ? { code: \"too_big\", maximum: def.size } : { code: \"too_small\", minimum: def.size }),\n inclusive: true,\n exact: true,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckMaxLength = /*@__PURE__*/ core.$constructor(\"$ZodCheckMaxLength\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = _whenHasLength);\n inst._zod.check = (payload) => {\n const input = payload.value;\n const units = input.length;\n // Strings are measured in Unicode code points, not UTF-16 units. A code point is at most two units, so a string that already fits in units fits in code points; only an overflow has to be counted.\n const length = typeof input === \"string\" && units > def.maximum ? util.codePointLength(input) : units;\n if (length <= def.maximum)\n return;\n const origin = util.getLengthableOrigin(input);\n payload.issues.push({\n origin,\n code: \"too_big\",\n maximum: def.maximum,\n inclusive: true,\n input,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckMinLength = /*@__PURE__*/ core.$constructor(\"$ZodCheckMinLength\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = _whenHasLength);\n inst._zod.check = (payload) => {\n const input = payload.value;\n const units = input.length;\n // A code point is one or two UTF-16 units, so fewer units than the floor can never reach it and twice the floor always clears it. Only in between is the exact count in doubt.\n const length = typeof input === \"string\" && units >= def.minimum && units < def.minimum * 2\n ? util.codePointLength(input)\n : units;\n if (length >= def.minimum)\n return;\n const origin = util.getLengthableOrigin(input);\n payload.issues.push({\n origin,\n code: \"too_small\",\n minimum: def.minimum,\n inclusive: true,\n input,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckLengthEquals = /*@__PURE__*/ core.$constructor(\"$ZodCheckLengthEquals\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = _whenHasLength);\n inst._zod.check = (payload) => {\n const input = payload.value;\n const units = input.length;\n // A code point is one or two UTF-16 units, so outside `[length, length * 2]` units the target is missed either way \u2014 and missed in the same direction in both measures.\n const length = typeof input === \"string\" && units >= def.length && units <= def.length * 2\n ? util.codePointLength(input)\n : units;\n if (length === def.length)\n return;\n const origin = util.getLengthableOrigin(input);\n const tooBig = length > def.length;\n payload.issues.push({\n origin,\n ...(tooBig ? { code: \"too_big\", maximum: def.length } : { code: \"too_small\", minimum: def.length }),\n inclusive: true,\n exact: true,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckStringFormat = /*@__PURE__*/ core.$constructor(\"$ZodCheckStringFormat\", (inst, def) => {\n var _a, _b;\n $ZodCheck.init(inst, def);\n if (def.pattern)\n (_a = inst._zod).check ?? (_a.check = (payload) => {\n def.pattern.lastIndex = 0;\n if (def.pattern.test(payload.value))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: def.format,\n input: payload.value,\n ...(def.pattern ? { pattern: def.pattern.toString() } : {}),\n inst,\n continue: !def.abort,\n });\n });\n else\n (_b = inst._zod).check ?? (_b.check = () => { });\n});\nexport const $ZodCheckRegex = /*@__PURE__*/ core.$constructor(\"$ZodCheckRegex\", (inst, def) => {\n $ZodCheckStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n def.pattern.lastIndex = 0;\n if (def.pattern.test(payload.value))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: \"regex\",\n input: payload.value,\n pattern: def.pattern.toString(),\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckLowerCase = /*@__PURE__*/ core.$constructor(\"$ZodCheckLowerCase\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.lowercase);\n $ZodCheckStringFormat.init(inst, def);\n});\nexport const $ZodCheckUpperCase = /*@__PURE__*/ core.$constructor(\"$ZodCheckUpperCase\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.uppercase);\n $ZodCheckStringFormat.init(inst, def);\n});\nexport const $ZodCheckIncludes = /*@__PURE__*/ core.$constructor(\"$ZodCheckIncludes\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const escapedRegex = util.escapeRegex(def.includes);\n // `String.prototype.includes(sub, position)` matches `sub` at `position`\n // OR LATER, so the pattern must allow at least `position` leading chars\n // (`{N,}`), not exactly `position` chars (`{N}`).\n const pattern = new RegExp(typeof def.position === \"number\" ? `^.{${def.position},}${escapedRegex}` : escapedRegex);\n def.pattern = pattern;\n inst._zod.check = (payload) => {\n if (payload.value.includes(def.includes, def.position))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: \"includes\",\n includes: def.includes,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckStartsWith = /*@__PURE__*/ core.$constructor(\"$ZodCheckStartsWith\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const pattern = new RegExp(`^${util.escapeRegex(def.prefix)}.*`);\n def.pattern ?? (def.pattern = pattern);\n inst._zod.check = (payload) => {\n if (payload.value.startsWith(def.prefix))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: \"starts_with\",\n prefix: def.prefix,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckEndsWith = /*@__PURE__*/ core.$constructor(\"$ZodCheckEndsWith\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);\n def.pattern ?? (def.pattern = pattern);\n inst._zod.check = (payload) => {\n if (payload.value.endsWith(def.suffix))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: \"ends_with\",\n suffix: def.suffix,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\n///////////////////////////////////\n///// $ZodCheckProperty /////\n///////////////////////////////////\nfunction handleCheckPropertyResult(result, payload, property) {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(property, result.issues));\n }\n}\nexport const $ZodCheckProperty = /*@__PURE__*/ core.$constructor(\"$ZodCheckProperty\", (inst, def) => {\n $ZodCheck.init(inst, def);\n inst._zod.check = (payload) => {\n const result = def.schema._zod.run({\n value: payload.value[def.property],\n issues: [],\n }, {});\n if (result instanceof Promise) {\n return result.then((result) => handleCheckPropertyResult(result, payload, def.property));\n }\n handleCheckPropertyResult(result, payload, def.property);\n return;\n };\n});\nexport const $ZodCheckProperties = /*@__PURE__*/ core.$constructor(\"$ZodCheckProperties\", (inst, def) => {\n $ZodCheck.init(inst, def);\n util.hide(inst, Symbol.iterator, function* () {\n yield inst;\n });\n // key and schema snapshotted together: reading one live and the other cached lets a later mutation of the caller's shape object pair a stale key with a missing schema\n let entries;\n inst._zod.check = (payload) => {\n // the base schema already typed the value, so only a nullish one is rejected here: the properties read on a primitive too, matching z.property() on a string's length\n if (payload.value == null) {\n payload.issues.push({ expected: \"object\", code: \"invalid_type\", input: payload.value, inst });\n return undefined;\n }\n entries ?? (entries = Reflect.ownKeys(def.shape).map((key) => [key, def.shape[key]]));\n const input = payload.value;\n let proms;\n for (const [key, schema] of entries) {\n const result = schema._zod.run({ value: input[key], issues: [] }, {});\n if (result instanceof Promise) {\n proms ?? (proms = []);\n proms.push(result.then((result) => handleCheckPropertyResult(result, payload, key)));\n }\n else {\n handleCheckPropertyResult(result, payload, key);\n }\n }\n if (proms)\n return Promise.all(proms).then(() => undefined);\n return undefined;\n };\n});\nexport const $ZodCheckMimeType = /*@__PURE__*/ core.$constructor(\"$ZodCheckMimeType\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const mimeSet = new Set(def.mime);\n inst._zod.check = (payload) => {\n if (mimeSet.has(payload.value.type))\n return;\n payload.issues.push({\n code: \"invalid_value\",\n values: def.mime,\n input: payload.value.type,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckOverwrite = /*@__PURE__*/ core.$constructor(\"$ZodCheckOverwrite\", (inst, def) => {\n $ZodCheck.init(inst, def);\n inst._zod.check = (payload) => {\n payload.value = def.tx(payload.value);\n };\n});\n", "export class Doc {\n constructor(args = [], closed = {}) {\n this.content = [];\n this.indent = 0;\n this.args = args;\n this.closed = closed;\n }\n // the compiler catches a child's throw and keeps writing into this doc, so the indent has to unwind with it\n indented(fn) {\n this.indent += 1;\n try {\n fn(this);\n }\n finally {\n this.indent -= 1;\n }\n }\n write(arg) {\n if (typeof arg === \"function\") {\n arg(this, { execution: \"sync\" });\n arg(this, { execution: \"async\" });\n return;\n }\n const content = arg;\n const lines = content.split(\"\\n\").filter((x) => x);\n const minIndent = Math.min(...lines.map((x) => x.length - x.trimStart().length));\n const dedented = lines.map((x) => x.slice(minIndent)).map((x) => \" \".repeat(this.indent * 2) + x);\n for (const line of dedented) {\n this.content.push(line);\n }\n }\n compile() {\n const F = Function;\n const content = this?.content ?? [``];\n const factory = new F(...Object.keys(this.closed), `return function (${this.args.join(\", \")}) {\\n${content.join(\"\\n\")}\\n};`);\n return factory(...Object.values(this.closed));\n }\n}\n", "export const version = {\n major: 4,\n minor: 6,\n patch: 7,\n};\n", "import * as checks from \"./checks.js\";\nimport * as core from \"./core.js\";\nimport { Doc } from \"./doc.js\";\nimport { parse, parseAsync } from \"./parse.js\";\nimport * as regexes from \"./regexes.js\";\nimport * as util from \"./util.js\";\nimport { version } from \"./versions.js\";\nexport const $ZodType = /*@__PURE__*/ core.$constructor(\"$ZodType\", (inst, def) => {\n var _a;\n inst ?? (inst = {});\n inst._zod.def = def; // set _def property\n inst._zod.bag = inst._zod.bag || {}; // initialize _bag object\n inst._zod.version = version;\n const defChecks = inst._zod.def.checks;\n // if inst is itself a checks.$ZodCheck, run it as a check\n const checks = inst._zod.traits.has(\"$ZodCheck\")\n ? [inst, ...(defChecks ?? [])]\n : defChecks?.length\n ? [...defChecks]\n : [];\n for (const ch of checks) {\n for (const fn of ch._zod.onattach) {\n fn(inst);\n }\n }\n if (checks.length === 0) {\n // deferred initializer inst._zod.parse is not yet defined\n (_a = inst._zod).deferred ?? (_a.deferred = []);\n inst._zod.deferred?.push(() => {\n inst._zod.run = inst._zod.parse;\n });\n }\n else {\n const runChecks = (payload, checks, ctx) => {\n if (payload.memo)\n return payload;\n let isAborted = util.aborted(payload);\n let asyncResult;\n for (const ch of checks) {\n if (ch._zod.def.when) {\n if (util.explicitlyAborted(payload))\n continue;\n const shouldRun = ch._zod.def.when(payload);\n if (!shouldRun)\n continue;\n }\n else if (isAborted) {\n continue;\n }\n const currLen = payload.issues.length;\n const _ = ch._zod.check(payload);\n if (_ instanceof Promise && ctx?.async === false) {\n throw new core.$ZodAsyncError();\n }\n if (asyncResult || _ instanceof Promise) {\n asyncResult = (asyncResult ?? Promise.resolve()).then(async () => {\n await _;\n const nextLen = payload.issues.length;\n if (nextLen === currLen)\n return;\n util.attachSchema(payload.issues, currLen, inst);\n if (!isAborted)\n isAborted = util.aborted(payload, currLen);\n });\n }\n else {\n const nextLen = payload.issues.length;\n if (nextLen === currLen)\n continue;\n util.attachSchema(payload.issues, currLen, inst);\n if (!isAborted)\n isAborted = util.aborted(payload, currLen);\n }\n }\n if (asyncResult) {\n return asyncResult.then(() => {\n return payload;\n });\n }\n return payload;\n };\n const handleCanaryResult = (canary, payload, ctx) => {\n // abort if the canary is aborted\n if (util.aborted(canary)) {\n canary.aborted = true;\n return canary;\n }\n // run checks first, then\n const checkResult = runChecks(payload, checks, ctx);\n if (checkResult instanceof Promise) {\n if (ctx.async === false)\n throw new core.$ZodAsyncError();\n return checkResult.then((checkResult) => inst._zod.parse(checkResult, ctx));\n }\n return inst._zod.parse(checkResult, ctx);\n };\n inst._zod.run = (payload, ctx) => {\n if (ctx.skipChecks) {\n return inst._zod.parse(payload, ctx);\n }\n if (ctx.direction === \"backward\") {\n // run canary initial pass (no checks)\n const canary = inst._zod.parse({ value: payload.value, issues: [] }, { ...ctx, skipChecks: true });\n if (canary instanceof Promise) {\n return canary.then((canary) => {\n return handleCanaryResult(canary, payload, ctx);\n });\n }\n return handleCanaryResult(canary, payload, ctx);\n }\n // forward\n const result = inst._zod.parse(payload, ctx);\n if (result instanceof Promise) {\n if (ctx.async === false)\n throw new core.$ZodAsyncError();\n return result.then((result) => runChecks(result, checks, ctx));\n }\n return runChecks(result, checks, ctx);\n };\n }\n}, {\n // Wrappers extend this by installing a richer factory over it; reading it eagerly would defeat the laziness.\n get \"~standard\"() {\n return util.hide(this, \"~standard\", standardProps(this));\n },\n set \"~standard\"(value) {\n util.own(this, \"~standard\", value);\n },\n});\n/** The Standard Schema surface for `inst`. Shared so wrappers can extend it without forcing it. */\n// a Standard Schema result only reports issues, so a failure finalizes them straight off the raw payload: no ZodError, and no lazy result to read through\nconst toStandardResult = (r, ctx) => r.issues.length ? { issues: r.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())) } : { value: r.value };\nasync function validateAsync(inst, value) {\n const ctx = { async: true };\n return toStandardResult((await inst._zod.run({ value, issues: [] }, ctx)), ctx);\n}\nexport function standardProps(inst) {\n return {\n validate: (value) => {\n const ctx = { async: false };\n try {\n const r = inst._zod.run({ value, issues: [] }, ctx);\n if (!(r instanceof Promise))\n return toStandardResult(r, ctx);\n }\n catch (_) { }\n // async function so a synchronously throwing check rejects instead of escaping validate\n return validateAsync(inst, value);\n },\n vendor: \"zod\",\n version: 1,\n };\n}\nexport { clone } from \"./util.js\";\nexport const $ZodString = /*@__PURE__*/ core.$constructor(\"$ZodString\", (inst, def) => {\n $ZodType.init(inst, def);\n // a format's own pattern, else unbounded; a template literal derives the check-aware form itself\n inst._zod.pattern = def.pattern ?? regexes.anyString;\n inst._zod.parse = (payload, _) => {\n if (def.coerce)\n try {\n payload.value = String(payload.value);\n }\n catch (_) { }\n if (typeof payload.value === \"string\")\n return payload;\n payload.issues.push({\n expected: \"string\",\n code: \"invalid_type\",\n input: payload.value,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodStringFormat = /*@__PURE__*/ core.$constructor(\"$ZodStringFormat\", (inst, def) => {\n // check initialization must come first\n checks.$ZodCheckStringFormat.init(inst, def);\n $ZodString.init(inst, def);\n});\nexport const $ZodGUID = /*@__PURE__*/ core.$constructor(\"$ZodGUID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.guid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodUUID = /*@__PURE__*/ core.$constructor(\"$ZodUUID\", (inst, def) => {\n if (def.version) {\n const versionMap = {\n v1: 1,\n v2: 2,\n v3: 3,\n v4: 4,\n v5: 5,\n v6: 6,\n v7: 7,\n v8: 8,\n };\n const v = versionMap[def.version];\n if (v === undefined)\n throw new Error(`Invalid UUID version: \"${def.version}\"`);\n def.pattern ?? (def.pattern = regexes.uuid(v));\n }\n else\n def.pattern ?? (def.pattern = regexes.uuid());\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodEmail = /*@__PURE__*/ core.$constructor(\"$ZodEmail\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.email);\n $ZodStringFormat.init(inst, def);\n});\n/** The `://` guard rejected the input before the URL constructor saw it. */\nexport const URL_BAD_FORMAT = 1;\n/** The URL parser rejected the input. */\nexport const URL_UNPARSEABLE = 2;\nexport function canParseURL(input) {\n try {\n if (typeof URL !== \"undefined\" && typeof URL.canParse === \"function\")\n return URL.canParse(input);\n new URL(input);\n return true;\n }\n catch {\n return false;\n }\n}\nexport function validateURL(trimmed, def) {\n if (!(\"normalize\" in def) && !(\"hostname\" in def) && !(\"protocol\" in def)) {\n return canParseURL(trimmed) || URL_UNPARSEABLE;\n }\n return parseURLObject(trimmed, def);\n}\n/** Parses a URL while preserving the non-normalizing HTTP guard. */\nexport function parseURLObject(trimmed, def) {\n // When normalize is off, require :// for http/https URLs. This prevents strings like \"http:example.com\" or \"https:/path\" from being silently accepted\n if (!def.normalize && def.protocol?.source === regexes.httpProtocol.source && !/^https?:\\/\\//i.test(trimmed)) {\n return URL_BAD_FORMAT;\n }\n try {\n if (typeof URL !== \"undefined\") {\n const URLStatic = URL;\n if (typeof URLStatic.parse === \"function\")\n return URLStatic.parse(trimmed) ?? URL_UNPARSEABLE;\n }\n // @ts-ignore\n return new URL(trimmed);\n }\n catch {\n return URL_UNPARSEABLE;\n }\n}\nconst asciiTabOrNewline = /[\\t\\n\\r]/g;\n/** The URL parser deletes every ASCII tab, LF and CR from its input before it parses, so `new URL(\"https://exa\\nmple.com\")` reports on `example.com`. Applying the same deletion to the returned value closes the half of that divergence which can move the host; the parser's other rewrite, stripping C0 controls at the edges, cannot. */\nexport function stripTabAndNewline(value) {\n return value.replace(asciiTabOrNewline, \"\");\n}\nexport function urlHostnameOk(url, hostname) {\n hostname.lastIndex = 0;\n return hostname.test(url.hostname);\n}\nexport function urlProtocolOk(url, protocol) {\n protocol.lastIndex = 0;\n return protocol.test(url.protocol.endsWith(\":\") ? url.protocol.slice(0, -1) : url.protocol);\n}\nexport const $ZodURL = /*@__PURE__*/ core.$constructor(\"$ZodURL\", (inst, def) => {\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n try {\n // Trim whitespace from input\n const trimmed = payload.value.trim();\n const url = validateURL(trimmed, def);\n if (url === URL_BAD_FORMAT) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n note: \"Invalid URL format\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n return;\n }\n if (url === URL_UNPARSEABLE) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n return;\n }\n if (url === true) {\n payload.value = stripTabAndNewline(trimmed);\n return;\n }\n if (def.hostname && !urlHostnameOk(url, def.hostname)) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n note: \"Invalid hostname\",\n pattern: def.hostname.source,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n if (def.protocol && !urlProtocolOk(url, def.protocol)) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n note: \"Invalid protocol\",\n pattern: def.protocol.source,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n // Set the output value based on normalize flag\n payload.value = def.normalize ? url.href : stripTabAndNewline(trimmed);\n return;\n }\n catch (_) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\nexport const $ZodEmoji = /*@__PURE__*/ core.$constructor(\"$ZodEmoji\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.emoji());\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodNanoID = /*@__PURE__*/ core.$constructor(\"$ZodNanoID\", (inst, def) => {\n if (def.length !== undefined && (!Number.isInteger(def.length) || def.length < 1))\n throw new Error(`Invalid nanoid length: ${def.length}`);\n def.pattern ?? (def.pattern = def.length === undefined ? regexes.nanoid : regexes.nanoidOfLength(def.length));\n $ZodStringFormat.init(inst, def);\n});\n/**\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link $ZodCUID2} instead.\n * See https://github.com/paralleldrive/cuid.\n */\nexport const $ZodCUID = /*@__PURE__*/ core.$constructor(\"$ZodCUID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.cuid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodCUID2 = /*@__PURE__*/ core.$constructor(\"$ZodCUID2\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.cuid2);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodULID = /*@__PURE__*/ core.$constructor(\"$ZodULID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.ulid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodXID = /*@__PURE__*/ core.$constructor(\"$ZodXID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.xid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodKSUID = /*@__PURE__*/ core.$constructor(\"$ZodKSUID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.ksuid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodISODateTime = /*@__PURE__*/ core.$constructor(\"$ZodISODateTime\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.datetime(def));\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodISODate = /*@__PURE__*/ core.$constructor(\"$ZodISODate\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.date);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodISOTime = /*@__PURE__*/ core.$constructor(\"$ZodISOTime\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.time(def));\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodISODuration = /*@__PURE__*/ core.$constructor(\"$ZodISODuration\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.duration);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodIPv4 = /*@__PURE__*/ core.$constructor(\"$ZodIPv4\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.ipv4);\n $ZodStringFormat.init(inst, def);\n});\n/** An IPv6 address is written with hex digits, colons and dots, and nothing else. The guard is what makes the check below an IPv6 check: `new URL(\"http://[...]\")` parses an authority, not an address, so `@` and `\\` re-delimit it and `\"::@1\\\\\"` validates against the host `0.0.0.1`. The URL parser also deletes ASCII tab, LF and CR rather than failing, which is how `\"::1\\n\"` validated as `::1`. */\nconst ipv6Alphabet = /^[0-9a-fA-F:.]+$/;\nexport function isValidIPv6(value) {\n if (!ipv6Alphabet.test(value))\n return false;\n return canParseURL(`http://[${value}]`);\n}\nexport const $ZodIPv6 = /*@__PURE__*/ core.$constructor(\"$ZodIPv6\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.ipv6);\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (!isValidIPv6(payload.value)) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"ipv6\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\nexport const $ZodMAC = /*@__PURE__*/ core.$constructor(\"$ZodMAC\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.mac(def.delimiter));\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodCIDRv4 = /*@__PURE__*/ core.$constructor(\"$ZodCIDRv4\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.cidrv4);\n $ZodStringFormat.init(inst, def);\n});\nexport function isValidCIDRv6(value) {\n const parts = value.split(\"/\");\n if (parts.length !== 2)\n return false;\n const [address, prefix] = parts;\n if (!prefix)\n return false;\n const prefixNum = Number(prefix);\n if (`${prefixNum}` !== prefix)\n return false;\n if (prefixNum < 0 || prefixNum > 128)\n return false;\n return isValidIPv6(address);\n}\nexport const $ZodCIDRv6 = /*@__PURE__*/ core.$constructor(\"$ZodCIDRv6\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.cidrv6); // not used for validation\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (!isValidCIDRv6(payload.value)) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"cidrv6\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\n////////////////////////////// ZodBase64 //////////////////////////////\nexport function isValidBase64(data) {\n if (data === \"\")\n return true;\n // atob ignores whitespace, so reject it up front.\n if (/\\s/.test(data))\n return false;\n if (data.length % 4 !== 0)\n return false;\n try {\n // @ts-ignore\n atob(data);\n return true;\n }\n catch {\n return false;\n }\n}\n// lax on purpose: the quantified regexes.base64 overflows the regex stack on multi-MB input and its leading ^$| alternation leaks through template-literal composition; isValidBase64 enforces length and padding\nexport const base64Charset = /^[0-9a-zA-Z+/]*={0,2}$/;\nexport const $ZodBase64 = /*@__PURE__*/ core.$constructor(\"$ZodBase64\", (inst, def) => {\n def.pattern ?? (def.pattern = base64Charset);\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (isValidBase64(payload.value))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: \"base64\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\n////////////////////////////// ZodBase64URL //////////////////////////////\n// lax on purpose: the quantified regexes.base64url overflows the regex stack on multi-MB input; isValidBase64 enforces length on the padded string\nexport const base64urlCharset = /^[A-Za-z0-9_-]*$/;\nexport function isValidBase64URL(data) {\n if (!base64urlCharset.test(data))\n return false;\n const base64 = data.replace(/[-_]/g, (c) => (c === \"-\" ? \"+\" : \"/\"));\n const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, \"=\");\n return isValidBase64(padded);\n}\nexport const $ZodBase64URL = /*@__PURE__*/ core.$constructor(\"$ZodBase64URL\", (inst, def) => {\n def.pattern ?? (def.pattern = base64urlCharset);\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (isValidBase64URL(payload.value))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: \"base64url\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodE164 = /*@__PURE__*/ core.$constructor(\"$ZodE164\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.e164);\n $ZodStringFormat.init(inst, def);\n});\n////////////////////////////// ZodCreditCard //////////////////////////////\nconst CC_SANITIZE = /[- ]/g;\n/** Luhn checksum on a digit-only string. Adapted from valibot (MIT). */\nfunction isLuhnAlgo(digits) {\n let length = digits.length;\n let bit = 1;\n let sum = 0;\n while (length) {\n const value = digits.charCodeAt(--length) - 48;\n bit ^= 1;\n sum += bit ? [0, 2, 4, 6, 8, 1, 3, 5, 7, 9][value] : value;\n }\n return sum % 10 === 0;\n}\nexport function isValidCreditCard(input) {\n if (!regexes.creditCard.test(input))\n return false;\n return isLuhnAlgo(input.replace(CC_SANITIZE, \"\"));\n}\nexport const $ZodCreditCard = /*@__PURE__*/ core.$constructor(\"$ZodCreditCard\", (inst, def) => {\n // Shape only \u2014 the Luhn check below is not expressible as a pattern, so consumers of `pattern` (JSON Schema, template literals) get the length and separator rules alone.\n def.pattern ?? (def.pattern = regexes.creditCard);\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (isValidCreditCard(payload.value))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: \"credit_card\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\n////////////////////////////// ZodIBAN //////////////////////////////\n// iso 7064 mod 97-10 checksum without BigInt\nfunction isIso7064Mod97(iban) {\n let remainder = 0;\n const len = iban.length;\n for (let i = 4; i < len; i++) {\n const code = iban.charCodeAt(i);\n remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;\n }\n for (let i = 0; i < 4; i++) {\n const code = iban.charCodeAt(i);\n remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;\n }\n return remainder === 1;\n}\nexport function isValidIBAN(input) {\n if (!regexes.iban.test(input))\n return false;\n return isIso7064Mod97(input);\n}\nexport const $ZodIBAN = /*@__PURE__*/ core.$constructor(\"$ZodIBAN\", (inst, def) => {\n // shape only \u2014 checksum is not expressible as a pattern\n def.pattern ?? (def.pattern = regexes.iban);\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (isValidIBAN(payload.value))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: \"iban\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\n////////////////////////////// ZodJWT //////////////////////////////\nexport function isValidJWT(token, algorithm = null) {\n try {\n const tokensParts = token.split(\".\");\n if (tokensParts.length !== 3)\n return false;\n const [header] = tokensParts;\n if (!header)\n return false;\n // @ts-ignore\n const parsedHeader = JSON.parse(atob(header));\n if (\"typ\" in parsedHeader && parsedHeader?.typ !== \"JWT\")\n return false;\n if (!parsedHeader.alg)\n return false;\n if (algorithm && (!(\"alg\" in parsedHeader) || parsedHeader.alg !== algorithm))\n return false;\n return true;\n }\n catch {\n return false;\n }\n}\nexport const $ZodJWT = /*@__PURE__*/ core.$constructor(\"$ZodJWT\", (inst, def) => {\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (isValidJWT(payload.value, def.alg))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: \"jwt\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCustomStringFormat = /*@__PURE__*/ core.$constructor(\"$ZodCustomStringFormat\", (inst, def) => {\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (def.fn(payload.value))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: def.format,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodNumber = /*@__PURE__*/ core.$constructor(\"$ZodNumber\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.number;\n inst._zod.parse = (payload, _ctx) => {\n if (def.coerce)\n try {\n payload.value = Number(payload.value);\n }\n catch (_) { }\n const input = payload.value;\n if (typeof input === \"number\" && !Number.isNaN(input) && Number.isFinite(input)) {\n return payload;\n }\n const received = typeof input === \"number\"\n ? Number.isNaN(input)\n ? \"NaN\"\n : !Number.isFinite(input)\n ? String(input)\n : undefined\n : undefined;\n payload.issues.push({\n expected: \"number\",\n code: \"invalid_type\",\n input,\n inst,\n ...(received ? { received } : {}),\n });\n return payload;\n };\n});\nexport const $ZodNumberFormat = /*@__PURE__*/ core.$constructor(\"$ZodNumberFormat\", (inst, def) => {\n checks.$ZodCheckNumberFormat.init(inst, def);\n $ZodNumber.init(inst, def); // no format checks\n});\nexport const $ZodBoolean = /*@__PURE__*/ core.$constructor(\"$ZodBoolean\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.boolean;\n inst._zod.parse = (payload, _ctx) => {\n if (def.coerce)\n try {\n payload.value = Boolean(payload.value);\n }\n catch (_) { }\n const input = payload.value;\n if (typeof input === \"boolean\")\n return payload;\n payload.issues.push({\n expected: \"boolean\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodBigInt = /*@__PURE__*/ core.$constructor(\"$ZodBigInt\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.bigint;\n inst._zod.parse = (payload, _ctx) => {\n if (def.coerce)\n try {\n payload.value = BigInt(payload.value);\n }\n catch (_) { }\n if (typeof payload.value === \"bigint\")\n return payload;\n payload.issues.push({\n expected: \"bigint\",\n code: \"invalid_type\",\n input: payload.value,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodBigIntFormat = /*@__PURE__*/ core.$constructor(\"$ZodBigIntFormat\", (inst, def) => {\n checks.$ZodCheckBigIntFormat.init(inst, def);\n $ZodBigInt.init(inst, def); // no format checks\n});\nexport const $ZodSymbol = /*@__PURE__*/ core.$constructor(\"$ZodSymbol\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (typeof input === \"symbol\")\n return payload;\n payload.issues.push({\n expected: \"symbol\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodUndefined = /*@__PURE__*/ core.$constructor(\"$ZodUndefined\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.undefined;\n inst._zod.values = new Set([undefined]);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (typeof input === \"undefined\")\n return payload;\n payload.issues.push({\n expected: \"undefined\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodNull = /*@__PURE__*/ core.$constructor(\"$ZodNull\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.null;\n inst._zod.values = new Set([null]);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (input === null)\n return payload;\n payload.issues.push({\n expected: \"null\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodAny = /*@__PURE__*/ core.$constructor(\"$ZodAny\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload) => payload;\n});\nexport const $ZodUnknown = /*@__PURE__*/ core.$constructor(\"$ZodUnknown\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload) => payload;\n});\nexport const $ZodNever = /*@__PURE__*/ core.$constructor(\"$ZodNever\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n payload.issues.push({\n expected: \"never\",\n code: \"invalid_type\",\n input: payload.value,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodVoid = /*@__PURE__*/ core.$constructor(\"$ZodVoid\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (typeof input === \"undefined\")\n return payload;\n payload.issues.push({\n expected: \"void\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodDate = /*@__PURE__*/ core.$constructor(\"$ZodDate\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n if (def.coerce) {\n try {\n payload.value = new Date(payload.value);\n }\n catch (_err) { }\n }\n const input = payload.value;\n const isDate = input instanceof Date;\n const isValidDate = isDate && !Number.isNaN(input.getTime());\n if (isValidDate)\n return payload;\n payload.issues.push({\n expected: \"date\",\n code: \"invalid_type\",\n input,\n ...(isDate ? { received: \"Invalid Date\" } : {}),\n inst,\n });\n return payload;\n };\n});\n// an oversized container fails its leading size checks before any element is parsed\nfunction capSize(inst, size) {\n const caps = util.sizeCaps(inst._zod.def.checks);\n if (!caps.length)\n return;\n const cap = Math.min(...caps.map((c) => c[0]));\n const parse = inst._zod.parse;\n inst._zod.parse = (payload, ctx) => {\n const n = size(payload.value);\n if (n > cap && !ctx?.skipChecks && ctx?.direction !== \"backward\") {\n for (const [max, ch] of util.sizeCaps(inst._zod.def.checks)) {\n if (n > max && ch._zod.def.when(payload)) {\n const start = payload.issues.length;\n ch._zod.check(payload);\n // the value is still the raw input, so no later check may read it\n payload.issues[start].continue = false;\n util.attachSchema(payload.issues, start, inst);\n return payload;\n }\n }\n }\n return parse(payload, ctx);\n };\n}\nconst arraySize = (input) => (Array.isArray(input) ? input.length : -1);\nconst mapSize = (input) => (input instanceof Map ? input.size : -1);\nconst setSize = (input) => (input instanceof Set ? input.size : -1);\nfunction handleArrayResult(result, final, index) {\n if (result.issues.length) {\n final.issues.push(...util.prefixIssues(index, result.issues));\n }\n final.value[index] = result.value;\n}\nexport const $ZodArray = /*@__PURE__*/ core.$constructor(\"$ZodArray\", (inst, def) => {\n $ZodType.init(inst, def);\n const memo = core.globalConfig.memoizer;\n memo?.attach(inst);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!Array.isArray(input)) {\n payload.issues.push({\n expected: \"array\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n payload.value = memo ? memo.alloc(inst, payload, Array(input.length), ctx) : Array(input.length);\n const proms = [];\n const abortEarly = ctx?.abortEarly;\n for (let i = 0; i < input.length; i++) {\n const item = input[i];\n const result = def.element._zod.run({\n value: item,\n issues: [],\n }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((result) => handleArrayResult(result, payload, i)));\n }\n else {\n handleArrayResult(result, payload, i);\n // the element's payload is authoritative here, since handleArrayResult forwards every issue; an object's is not, because it drops a failed absent optional\n if (abortEarly && result.issues.length !== 0 && util.aborted(result))\n break;\n }\n }\n if (proms.length) {\n return Promise.all(proms).then(() => payload);\n }\n return payload; //handleArrayResultsAsync(parseResults, final);\n };\n capSize(inst, arraySize);\n});\nfunction handlePropertyResult(result, final, key, input, optin, optout) {\n const isPresent = key in input;\n const isOptionalOut = optout === \"optional\";\n // The middle rung means \"absence permitted, nothing supplied in its place\", so an absent key contributes nothing \u2014 whatever the schema made of `undefined` is invented, not substituted. Only `optional` reaches this with a value: `defaulted` substitutes, and a schema that isn't optional-out has to keep the key.\n if (!isPresent && isOptionalOut && optin === \"optional\") {\n return;\n }\n if (result.issues.length) {\n // For optional-in/out schemas, ignore errors on absent keys.\n if (optin !== undefined && isOptionalOut && !isPresent) {\n return;\n }\n final.issues.push(...util.prefixIssues(key, result.issues));\n }\n if (!isPresent && optin === undefined) {\n if (!result.issues.length) {\n final.issues.push({\n code: \"invalid_type\",\n expected: \"nonoptional\",\n input: undefined,\n path: [key],\n });\n }\n return;\n }\n if (result.value === undefined) {\n if (isPresent || (optin === \"defaulted\" && !isOptionalOut)) {\n final.value[key] = undefined;\n }\n }\n else {\n final.value[key] = result.value;\n }\n}\n// one shared instance; a fresh [] per schema cost 56 bytes retained\nconst NO_SYMBOL_KEYS = [];\nfunction normalizeDef(def) {\n const keys = Object.keys(def.shape);\n const ownSymbols = Object.getOwnPropertySymbols(def.shape);\n const symbolKeys = ownSymbols.length ? ownSymbols : NO_SYMBOL_KEYS;\n // aliases `keys` when there are no symbols, so a string-only shape keeps one array\n const allKeys = symbolKeys.length ? [...keys, ...symbolKeys] : keys;\n for (const k of allKeys) {\n if (!def.shape?.[k]?._zod?.traits?.has(\"$ZodType\")) {\n throw new Error(`Invalid element at key \"${String(k)}\": expected a Zod schema`);\n }\n }\n const okeys = util.optionalKeys(def.shape);\n return {\n ...def,\n allKeys,\n symbolKeys,\n // string-only: handleCatchall matches it against `for...in`, which never yields a symbol\n keySet: new Set(keys),\n numKeys: keys.length,\n optionalKeys: new Set(okeys),\n };\n}\nfunction handleCatchall(proms, input, payload, ctx, def, inst, abortEarly) {\n const unrecognized = [];\n const keySet = def.keySet;\n const _catchall = def.catchall._zod;\n const t = _catchall.def.type;\n const optin = _catchall.optin;\n const optout = _catchall.optout;\n // starts at 0, not the current length: the shape phase already ran and may have aborted\n let seen = 0;\n for (const key in input) {\n if (abortEarly && payload.issues.length !== seen) {\n if (util.aborted(payload, seen))\n break;\n seen = payload.issues.length;\n }\n // Must precede the __proto__ branch: a declared key is not unrecognized, even though the shape loop deliberately strips __proto__ from the parsed output.\n if (keySet.has(key))\n continue;\n // Don't copy an undeclared __proto__ into the result; assignment to a plain {} would replace the result prototype. But in strict mode it is still an unknown key, so report it before skipping.\n if (key === \"__proto__\") {\n if (t === \"never\")\n unrecognized.push(key);\n continue;\n }\n if (t === \"never\") {\n unrecognized.push(key);\n continue;\n }\n const r = _catchall.run({ value: input[key], issues: [] }, ctx);\n if (r instanceof Promise) {\n proms.push(r.then((r) => handlePropertyResult(r, payload, key, input, optin, optout)));\n }\n else {\n handlePropertyResult(r, payload, key, input, optin, optout);\n }\n }\n if (unrecognized.length) {\n payload.issues.push({\n code: \"unrecognized_keys\",\n keys: unrecognized,\n input,\n inst,\n // Describes the shape of the input, not the validity of the parsed value, so it never aborts. The parse still fails; the schema's own checks just get to run first, and an enclosing intersection can reconcile the key against a sibling operand.\n continue: true,\n });\n }\n if (!proms.length)\n return payload;\n return Promise.all(proms).then(() => {\n return payload;\n });\n}\nexport const $ZodObject = /*@__PURE__*/ core.$constructor(\"$ZodObject\", (inst, def) => {\n // requires cast because technically $ZodObject doesn't extend\n $ZodType.init(inst, def);\n const desc = Object.getOwnPropertyDescriptor(def, \"shape\");\n // a cloned def carries its source's accessor, which knows the shape it answers from; adopting that keeps the clone's keys readable without running it\n const sh = desc?.get ? desc.get.raw : (def.shape ?? {});\n if (sh) {\n // Freezes the shape on first read, so its getters resolve once and every later read sees the same schemas.\n const get = () => {\n const newSh = { ...sh };\n Object.defineProperty(def, \"shape\", { value: newSh });\n get.raw = newSh;\n return newSh;\n };\n get.raw = sh;\n Object.defineProperty(def, \"shape\", { get });\n }\n const _normalized = util.cached(() => normalizeDef(def));\n util.defineLazyInternal(inst, \"propValues\", (zod) => {\n const shape = zod.def.shape;\n const propValues = {};\n for (const key in shape) {\n const field = shape[key]._zod;\n if (field.values) {\n if (!Object.prototype.hasOwnProperty.call(propValues, key)) {\n util.assignProp(propValues, key, new Set());\n }\n for (const v of field.values)\n propValues[key].add(v);\n // An omittable slot reads back as undefined at a discriminator lookup, so it has to claim undefined: two options that can both omit the key are not discriminable on it.\n if (field.optin !== undefined)\n propValues[key].add(undefined);\n }\n }\n return propValues;\n });\n const isObject = util.isObject;\n const catchall = def.catchall;\n let value;\n const memo = core.globalConfig.memoizer;\n memo?.attach(inst);\n inst._zod.parse = (payload, ctx) => {\n value ?? (value = _normalized.value);\n const input = payload.value;\n if (!isObject(input)) {\n payload.issues.push({\n expected: \"object\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n payload.value = memo ? memo.alloc(inst, payload, {}, ctx) : {};\n const proms = [];\n const shape = value.shape;\n const abortEarly = ctx?.abortEarly;\n let seen = payload.issues.length;\n for (const key of value.allKeys) {\n if (abortEarly && payload.issues.length !== seen) {\n if (util.aborted(payload, seen))\n break;\n seen = payload.issues.length;\n }\n if (key === \"__proto__\")\n continue;\n const el = shape[key];\n const optin = el._zod.optin;\n const optout = el._zod.optout;\n const r = el._zod.run({ value: input[key], issues: [] }, ctx);\n if (r instanceof Promise) {\n proms.push(r.then((r) => handlePropertyResult(r, payload, key, input, optin, optout)));\n }\n else {\n handlePropertyResult(r, payload, key, input, optin, optout);\n }\n }\n if (!catchall) {\n return proms.length ? Promise.all(proms).then(() => payload) : payload;\n }\n return handleCatchall(proms, input, payload, ctx, _normalized.value, inst, abortEarly === true);\n };\n});\nexport const $ZodObjectJIT = /*@__PURE__*/ core.$constructor(\"$ZodObjectJIT\", (inst, def) => {\n // requires cast because technically $ZodObject doesn't extend\n $ZodObject.init(inst, def);\n const superParse = inst._zod.parse;\n const _normalized = util.cached(() => normalizeDef(def));\n const memo = core.globalConfig.memoizer;\n const generateFastpass = (shape) => {\n const normalized = _normalized.value;\n const syms = normalized.symbolKeys;\n // a symbol has no source literal, so it is read as `syms[i]` off the closed-over scope\n const doc = new Doc([\"payload\", \"ctx\"], { shape, inst, memo, syms });\n const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;\n // prefixes in place, like util.prefixIssues. newResult must land before the early return: a catchall runs after this and would otherwise write onto the caller's input\n const prefixStr = (id, k) => `\n let ${id}_ab = false;\n for (let i = 0; i < ${id}.issues.length; i++) {\n const iss = ${id}.issues[i];\n iss.path = iss.path ? [${k}, ...iss.path] : [${k}];\n payload.issues.push(iss);\n if (iss.continue !== true) ${id}_ab = true;\n }\n if (${id}_ab && ctx && ctx.abortEarly) {\n payload.value = newResult;\n return payload;\n }`;\n doc.write(`const input = payload.value;`);\n const ids = Object.create(null);\n let counter = 0;\n for (const key of normalized.allKeys) {\n ids[key] = `key_${counter++}`;\n }\n // A: preserve key order {\n doc.write(memo ? `const newResult = memo.alloc(inst, payload, {}, ctx);` : `const newResult = {};`);\n for (const key of normalized.allKeys) {\n if (key === \"__proto__\")\n continue;\n const id = ids[key];\n const k = typeof key === \"symbol\" ? `syms[${syms.indexOf(key)}]` : util.esc(key);\n const isPresent = `${k} in input`;\n const schema = shape[key];\n const optin = schema?._zod?.optin;\n const isOptionalIn = optin !== undefined;\n const isOptionalOut = schema?._zod?.optout === \"optional\";\n doc.write(`const ${id} = ${parseStr(k)};`);\n if (isOptionalIn && isOptionalOut) {\n // For optional-in/out schemas, ignore errors on absent keys \u2014 and, like the interpreted path, drop the value produced alongside them. The middle rung goes further: it permits absence without supplying anything in its place, so an absent key contributes nothing at all.\n const assign = optin === \"optional\" ? `${id}_present` : `${id}.value !== undefined || ${id}_present`;\n doc.write(`\n const ${id}_present = ${isPresent};\n if (!${id}.issues.length || ${id}_present) {\n if (${id}.issues.length) {${prefixStr(id, k)}\n }\n\n if (${assign}) {\n newResult[${k}] = ${id}.value;\n }\n }\n\n `);\n }\n else if (!isOptionalIn) {\n doc.write(`\n const ${id}_present = ${isPresent};\n if (${id}.issues.length) {${prefixStr(id, k)}\n }\n if (!${id}_present && !${id}.issues.length) {\n payload.issues.push({\n code: \"invalid_type\",\n expected: \"nonoptional\",\n input: undefined,\n path: [${k}]\n });\n if (ctx && ctx.abortEarly) {\n payload.value = newResult;\n return payload;\n }\n }\n\n if (${id}_present) {\n newResult[${k}] = ${id}.value;\n }\n\n `);\n }\n else {\n doc.write(`\n if (${id}.issues.length) {${prefixStr(id, k)}\n }\n `);\n if (optin === \"defaulted\") {\n doc.write(`newResult[${k}] = ${id}.value;`);\n }\n else {\n doc.write(`\n if (${id}.value !== undefined || ${isPresent}) {\n newResult[${k}] = ${id}.value;\n }\n `);\n }\n }\n }\n doc.write(`payload.value = newResult;`);\n doc.write(`return payload;`);\n // closing `shape` in is what pays: turbofan specializes the parser against that one shape object, so every `shape[k]._zod.run` folds to a known callee. as a parameter it stays a generic load and measures 13% slower even with the forwarding frame gone\n return doc.compile();\n };\n let fastpass;\n const isObject = util.isObject;\n const jit = !core.globalConfig.jitless;\n const allowsEval = util.allowsEval;\n const fastEnabled = jit && allowsEval.value; // && !def.catchall;\n const catchall = def.catchall;\n let value;\n inst._zod.parse = (payload, ctx) => {\n value ?? (value = _normalized.value);\n const input = payload.value;\n if (!isObject(input)) {\n payload.issues.push({\n expected: \"object\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) {\n // always synchronous\n if (!fastpass)\n fastpass = generateFastpass(def.shape);\n payload = fastpass(payload, ctx);\n if (!catchall)\n return payload;\n return handleCatchall([], input, payload, ctx, value, inst, ctx?.abortEarly === true);\n }\n return superParse(payload, ctx);\n };\n});\nfunction handleUnionResults(results, final, inst, ctx) {\n for (const result of results) {\n if (result.issues.length === 0) {\n final.value = result.value;\n return final;\n }\n }\n const nonaborted = results.filter((r) => !util.aborted(r));\n if (nonaborted.length === 1) {\n final.value = nonaborted[0].value;\n return nonaborted[0];\n }\n final.issues.push({\n code: \"invalid_union\",\n input: final.value,\n inst,\n errors: results.map((result) => result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config()))),\n });\n return final;\n}\nexport const $ZodUnion = /*@__PURE__*/ core.$constructor(\"$ZodUnion\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazyInternal(inst, \"optin\", (zod) => zod.def.options.some((o) => o._zod.optin === \"defaulted\")\n ? \"defaulted\"\n : zod.def.options.some((o) => o._zod.optin !== undefined)\n ? \"optional\"\n : undefined);\n util.defineLazyInternal(inst, \"optout\", (zod) => zod.def.options.some((o) => o._zod.optout === \"optional\") ? \"optional\" : undefined);\n util.defineLazyInternal(inst, \"values\", (zod) => {\n if (zod.def.options.every((o) => o._zod.values)) {\n return new Set(zod.def.options.flatMap((option) => Array.from(option._zod.values)));\n }\n return undefined;\n });\n util.defineLazyInternal(inst, \"pattern\", (zod) => {\n if (zod.def.options.every((o) => o._zod.pattern)) {\n const patterns = zod.def.options.map((o) => o._zod.pattern);\n return new RegExp(`^(${patterns.map((p) => util.cleanRegex(p.source)).join(\"|\")})$`);\n }\n return undefined;\n });\n const first = def.options.length === 1 ? def.options[0]._zod.run : null;\n inst._zod.parse = (payload, ctx) => {\n if (first) {\n return first(payload, ctx);\n }\n let async = false;\n const results = [];\n for (const option of def.options) {\n const result = option._zod.run({\n value: payload.value,\n issues: [],\n }, ctx);\n if (result instanceof Promise) {\n results.push(result);\n async = true;\n }\n else {\n if (result.issues.length === 0)\n return result;\n results.push(result);\n }\n }\n if (!async)\n return handleUnionResults(results, payload, inst, ctx);\n return Promise.all(results).then((results) => {\n return handleUnionResults(results, payload, inst, ctx);\n });\n };\n});\nfunction handleExclusiveUnionResults(results, final, inst, ctx) {\n const matches = [];\n for (let i = 0; i < results.length; i++) {\n if (results[i].issues.length === 0)\n matches.push(i);\n }\n if (matches.length === 1) {\n final.value = results[matches[0]].value;\n return final;\n }\n if (matches.length === 0) {\n // No matches - same as regular union\n final.issues.push({\n code: \"invalid_union\",\n input: final.value,\n inst,\n errors: results.map((result) => result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config()))),\n });\n }\n else {\n // Multiple matches - exclusive union failure\n final.issues.push({\n code: \"invalid_union\",\n input: final.value,\n inst,\n errors: [],\n inclusive: false,\n matches,\n });\n }\n return final;\n}\nexport const $ZodXor = /*@__PURE__*/ core.$constructor(\"$ZodXor\", (inst, def) => {\n $ZodUnion.init(inst, def);\n def.inclusive = false;\n const first = def.options.length === 1 ? def.options[0]._zod.run : null;\n inst._zod.parse = (payload, ctx) => {\n if (first) {\n return first(payload, ctx);\n }\n let async = false;\n const results = [];\n for (const option of def.options) {\n const result = option._zod.run({\n value: payload.value,\n issues: [],\n }, ctx);\n if (result instanceof Promise) {\n results.push(result);\n async = true;\n }\n else {\n results.push(result);\n }\n }\n if (!async)\n return handleExclusiveUnionResults(results, payload, inst, ctx);\n return Promise.all(results).then((results) => {\n return handleExclusiveUnionResults(results, payload, inst, ctx);\n });\n };\n});\n/** Returns the option whose discriminator claims `value`, or throws if ambiguous. */\nexport function getDiscriminatedOption(union, value) {\n const internals = union._zod;\n let map = internals.bag.optionsMap;\n if (!map) {\n map = discriminatorMap(internals.def);\n internals.bag.optionsMap = map;\n }\n const option = map.get(value);\n if (option === null)\n throw new Error(`Ambiguous discriminator value \"${String(value)}\"`);\n return option;\n}\nfunction discriminatorMap(def) {\n const map = new Map();\n for (const option of def.options) {\n const values = option._zod.propValues?.[def.discriminator];\n if (!values || values.size === 0)\n throw new Error(`Invalid discriminated union option at index \"${def.options.indexOf(option)}\"`);\n for (const value of values) {\n if (map.has(value)) {\n if (value !== undefined)\n throw new Error(`Duplicate discriminator value \"${String(value)}\"`);\n // keep the collision marked so a later member cannot reclaim it\n map.set(value, null);\n }\n else {\n map.set(value, option);\n }\n }\n }\n return map;\n}\nexport const $ZodDiscriminatedUnion = \n/*@__PURE__*/\ncore.$constructor(\"$ZodDiscriminatedUnion\", (inst, def) => {\n def.inclusive = false;\n $ZodUnion.init(inst, def);\n const _super = inst._zod.parse;\n util.defineLazyInternal(inst, \"propValues\", (zod) => {\n const propValues = {};\n let undefinedCount = 0;\n for (const option of zod.def.options) {\n const pv = option._zod.propValues;\n if (!pv || Object.keys(pv).length === 0)\n throw new Error(`Invalid discriminated union option at index \"${zod.def.options.indexOf(option)}\"`);\n if (pv[zod.def.discriminator]?.has(undefined))\n undefinedCount++;\n for (const [k, v] of Object.entries(pv)) {\n if (!Object.prototype.hasOwnProperty.call(propValues, k)) {\n util.assignProp(propValues, k, new Set());\n }\n for (const val of v) {\n propValues[k].add(val);\n }\n }\n }\n if (!zod.def.unionFallback && undefinedCount > 1)\n propValues[zod.def.discriminator]?.delete(undefined);\n return propValues;\n });\n // Checked now rather than in the lookup map below, so an option that lacks the discriminator fails at the `discriminatedUnion` call instead of on the first object parsed. Options whose shape cannot be enumerated without resolving it \u2014 pipes and lazies \u2014 are left to the map.\n def.options.forEach((option, i) => {\n const propShape = util.rawShape(option._zod.def);\n if (propShape && !Object.prototype.hasOwnProperty.call(propShape, def.discriminator)) {\n throw new Error(`Invalid discriminated union option at index \"${i}\"`);\n }\n });\n const disc = util.cached(() => discriminatorMap(def));\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!util.isObject(input)) {\n payload.issues.push({\n code: \"invalid_type\",\n expected: \"object\",\n input,\n inst,\n });\n return payload;\n }\n const value = input?.[def.discriminator];\n const opt = disc.value.get(value);\n // forward metadata cannot choose an encoder for an absent tag\n if (opt && (value !== undefined || ctx.direction !== \"backward\")) {\n return opt._zod.run(payload, ctx);\n }\n // Fall back to union matching when the fast discriminator path fails:\n // - explicitly enabled via unionFallback, or\n // - during backward direction (encode), since codec-based discriminators have different values in forward vs backward directions\n if (def.unionFallback || ctx.direction === \"backward\") {\n return _super(payload, ctx);\n }\n // no matching discriminator\n payload.issues.push({\n code: \"invalid_union\",\n errors: [],\n note: \"No matching discriminator\",\n discriminator: def.discriminator,\n options: Array.from(disc.value.keys()).filter((value) => disc.value.get(value) !== null),\n input,\n path: [def.discriminator],\n inst,\n });\n return payload;\n };\n});\nexport const $ZodIntersection = /*@__PURE__*/ core.$constructor(\"$ZodIntersection\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n const left = def.left._zod.run({ value: input, issues: [] }, ctx);\n const right = def.right._zod.run({ value: input, issues: [] }, ctx);\n const async = left instanceof Promise || right instanceof Promise;\n if (async) {\n return Promise.all([left, right]).then(([left, right]) => {\n return handleIntersectionResults(payload, left, right);\n });\n }\n return handleIntersectionResults(payload, left, right);\n };\n});\nexport function mergeValues(a, b) {\n // const aType = parse.t(a);\n // const bType = parse.t(b);\n if (a === b) {\n return { valid: true, data: a };\n }\n if (a instanceof Date && b instanceof Date && +a === +b) {\n return { valid: true, data: a };\n }\n if (util.isPlainObject(a) && util.isPlainObject(b)) {\n const bKeys = Object.keys(b);\n const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);\n const newObj = { ...a, ...b };\n if (Object.prototype.hasOwnProperty.call(newObj, \"__proto__\"))\n delete newObj.__proto__;\n for (const key of sharedKeys) {\n if (key === \"__proto__\")\n continue;\n const sharedValue = mergeValues(a[key], b[key]);\n if (!sharedValue.valid) {\n return {\n valid: false,\n mergeErrorPath: [key, ...sharedValue.mergeErrorPath],\n };\n }\n newObj[key] = sharedValue.data;\n }\n return { valid: true, data: newObj };\n }\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return { valid: false, mergeErrorPath: [] };\n }\n const newArray = [];\n for (let index = 0; index < a.length; index++) {\n const itemA = a[index];\n const itemB = b[index];\n const sharedValue = mergeValues(itemA, itemB);\n if (!sharedValue.valid) {\n return {\n valid: false,\n mergeErrorPath: [index, ...sharedValue.mergeErrorPath],\n };\n }\n newArray.push(sharedValue.data);\n }\n return { valid: true, data: newArray };\n }\n return { valid: false, mergeErrorPath: [] };\n}\nfunction handleIntersectionResults(result, left, right) {\n // Track which side(s) reject each key. A key rejection is reported only when BOTH sides reject it, so a key owned by one branch survives the other's key schema. strictObject reports these as unrecognized_keys; a record with an open key schema reports one invalid_key per key.\n const unrecKeys = new Map();\n let unrecIssue;\n const keyIssues = new Map();\n const collect = (iss, side) => {\n let keys;\n if (iss.code === \"unrecognized_keys\" && !iss.path?.length) {\n unrecIssue ?? (unrecIssue = iss);\n keys = iss.keys;\n }\n else if (iss.code === \"invalid_key\" && iss.origin === \"record\" && iss.path?.length === 1) {\n const k = String(iss.path[0]);\n if (!keyIssues.has(k))\n keyIssues.set(k, iss);\n keys = [k];\n }\n else {\n return false;\n }\n for (const k of keys) {\n if (!unrecKeys.has(k))\n unrecKeys.set(k, {});\n unrecKeys.get(k)[side] = true;\n }\n return true;\n };\n for (const iss of left.issues) {\n if (!collect(iss, \"l\"))\n result.issues.push(iss);\n }\n for (const iss of right.issues) {\n if (!collect(iss, \"r\"))\n result.issues.push(iss);\n }\n // Report only keys rejected by BOTH sides\n const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);\n if (bothKeys.length) {\n const aggregated = unrecIssue ? bothKeys.filter((k) => unrecIssue.keys.includes(k)) : [];\n if (aggregated.length)\n result.issues.push({ ...unrecIssue, keys: aggregated });\n for (const k of bothKeys) {\n if (!aggregated.includes(k) && keyIssues.has(k))\n result.issues.push(keyIssues.get(k));\n }\n }\n const merged = mergeValues(left.value, right.value);\n if (!merged.valid) {\n if (util.aborted(result))\n return result;\n throw new Error(`Unmergable intersection. Error path: ` + `${JSON.stringify(merged.mergeErrorPath)}`);\n }\n result.value = merged.data;\n return result;\n}\nexport const $ZodTuple = /*@__PURE__*/ core.$constructor(\"$ZodTuple\", (inst, def) => {\n $ZodType.init(inst, def);\n const items = def.items;\n const memo = core.globalConfig.memoizer;\n memo?.attach(inst);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!Array.isArray(input)) {\n payload.issues.push({\n input,\n inst,\n expected: \"tuple\",\n code: \"invalid_type\",\n });\n return payload;\n }\n payload.value = memo ? memo.alloc(inst, payload, [], ctx) : [];\n const proms = [];\n const optinStart = getTupleOptStart(items, \"optin\");\n const optoutStart = getTupleOptStart(items, \"optout\");\n if (!def.rest) {\n if (input.length < optinStart) {\n payload.issues.push({\n code: \"too_small\",\n minimum: optinStart,\n inclusive: true,\n input,\n inst,\n origin: \"array\",\n });\n return payload;\n }\n if (input.length > items.length) {\n payload.issues.push({\n code: \"too_big\",\n maximum: items.length,\n inclusive: true,\n input,\n inst,\n origin: \"array\",\n });\n }\n }\n // Run every item in parallel, collecting results into an indexed array. The post-processing in `handleTupleResults` walks them in order so it can decide whether an absent optional-output error can truncate the tail or must be reported to preserve required output.\n const itemResults = new Array(items.length);\n // only tracked when there is a rest loop to skip\n const abortEarly = def.rest ? ctx?.abortEarly : undefined;\n let itemAborted = false;\n for (let i = 0; i < items.length; i++) {\n const r = items[i]._zod.run({ value: input[i], issues: [] }, ctx);\n if (r instanceof Promise) {\n proms.push(r.then((rr) => {\n itemResults[i] = rr;\n }));\n }\n else {\n itemResults[i] = r;\n if (abortEarly && !itemAborted && r.issues.length)\n itemAborted = util.aborted(r);\n }\n }\n // sound because rest is non-empty exactly when every fixed index is present, the one case handleTupleResults cannot discard an item's issues\n if (def.rest && !itemAborted) {\n let i = items.length - 1;\n const rest = input.slice(items.length);\n let seen = payload.issues.length;\n for (const el of rest) {\n if (abortEarly && payload.issues.length !== seen) {\n if (util.aborted(payload, seen))\n break;\n seen = payload.issues.length;\n }\n i++;\n const result = def.rest._zod.run({ value: el, issues: [] }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((r) => handleTupleResult(r, payload, i)));\n }\n else {\n handleTupleResult(result, payload, i);\n }\n }\n }\n if (proms.length) {\n return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input, optoutStart));\n }\n return handleTupleResults(itemResults, payload, items, input, optoutStart);\n };\n});\nfunction getTupleOptStart(items, key) {\n for (let i = items.length - 1; i >= 0; i--) {\n // optin is a three-rung ladder so any rung above `undefined` permits an absent slot; optout stays two-valued.\n const omittable = key === \"optin\" ? items[i]._zod.optin !== undefined : items[i]._zod.optout === \"optional\";\n if (!omittable)\n return i + 1;\n }\n return 0;\n}\nfunction handleTupleResult(result, final, index) {\n if (result.issues.length) {\n final.issues.push(...util.prefixIssues(index, result.issues));\n }\n final.value[index] = result.value;\n}\nfunction handleTupleResults(itemResults, final, items, input, optoutStart) {\n // Walk results in order. Mirror $ZodObject's swallow-on-absent-optional rule, but only after `optoutStart`: the first index where the output tuple tail can be absent.\n for (let i = 0; i < items.length; i++) {\n const r = itemResults[i];\n const isPresent = i < input.length;\n // The array analog of `handlePropertyResult`'s absent-key early return: the middle rung permits absence without supplying anything in its place, so the tail truncates here instead of materializing whatever the item made of `undefined`.\n if (!isPresent && i >= optoutStart && items[i]._zod.optin === \"optional\") {\n final.value.length = i;\n break;\n }\n if (r.issues.length) {\n if (!isPresent && i >= optoutStart) {\n final.value.length = i;\n break;\n }\n final.issues.push(...util.prefixIssues(i, r.issues));\n }\n final.value[i] = r.value;\n }\n // Drop trailing slots that produced `undefined` for absent input\n // (the array analog of an absent optional key on an object). The\n // `i >= input.length` floor is critical: an explicit `undefined`\n // *inside* the input must be preserved even when the schema is\n // optional-out (e.g. `z.string().or(z.undefined())` accepting an\n // explicit undefined value).\n for (let i = final.value.length - 1; i >= input.length; i--) {\n if (items[i]._zod.optout === \"optional\" && final.value[i] === undefined) {\n final.value.length = i;\n }\n else {\n break;\n }\n }\n return final;\n}\nexport const $ZodRecord = /*@__PURE__*/ core.$constructor(\"$ZodRecord\", (inst, def) => {\n $ZodType.init(inst, def);\n const memo = core.globalConfig.memoizer;\n memo?.attach(inst);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!util.isPlainObject(input)) {\n payload.issues.push({\n expected: \"record\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n // no guard in either loop below: a record's invalid_key aborts but an enclosing intersection can reconcile it, so a stopped loop hides keys the sibling does not own and the intersection then rejects nothing\n const proms = [];\n const values = def.keyType._zod.values;\n if (values && !def.partial) {\n payload.value = memo ? memo.alloc(inst, payload, {}, ctx) : {};\n const recordKeys = new Set();\n for (const key of values) {\n if (typeof key === \"string\" || typeof key === \"number\" || typeof key === \"symbol\") {\n recordKeys.add(typeof key === \"number\" ? key.toString() : key);\n // A declared __proto__ is stripped but is not an unrecognized key.\n if (key === \"__proto__\")\n continue;\n const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);\n if (keyResult instanceof Promise) {\n throw new Error(\"Async schemas not supported in object keys currently\");\n }\n if (keyResult.issues.length) {\n payload.issues.push({\n code: \"invalid_key\",\n origin: \"record\",\n issues: keyResult.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n input: key,\n path: [key],\n inst,\n });\n continue;\n }\n const outKey = keyResult.value;\n if (outKey === \"__proto__\")\n continue;\n const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((result) => {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(key, result.issues));\n }\n payload.value[outKey] = result.value;\n }));\n }\n else {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(key, result.issues));\n }\n payload.value[outKey] = result.value;\n }\n }\n }\n let unrecognized;\n for (const key in input) {\n if (!recordKeys.has(key)) {\n if (def.mode === \"loose\") {\n // skip __proto__ so it can't replace the result prototype via the assignment setter on the plain {} we build into\n if (key === \"__proto__\")\n continue;\n payload.value[key] = input[key];\n }\n else {\n unrecognized = unrecognized ?? [];\n unrecognized.push(key);\n }\n }\n }\n if (unrecognized && unrecognized.length > 0) {\n payload.issues.push({\n code: \"unrecognized_keys\",\n input,\n inst,\n keys: unrecognized,\n continue: true,\n });\n }\n }\n else {\n payload.value = memo ? memo.alloc(inst, payload, {}, ctx) : {};\n // An enumerable key schema declares which keys the record owns, so a key outside the set is unrecognized. A non-enumerable one (regex, refine) is a constraint every key must satisfy, so a failing key is invalid. Only the former is reconcilable against the other side of an intersection.\n let unrecognized;\n // Reflect.ownKeys for Symbol-key support; filter non-enumerable to match z.object()\n for (const key of Reflect.ownKeys(input)) {\n if (key === \"__proto__\")\n continue;\n if (!Object.prototype.propertyIsEnumerable.call(input, key))\n continue;\n let keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);\n if (keyResult instanceof Promise) {\n throw new Error(\"Async schemas not supported in object keys currently\");\n }\n // Numeric string fallback: if key is a numeric string and failed, retry with Number(key). This handles z.number(), z.literal([1, 2, 3]), and unions containing numeric literals\n const checkNumericKey = typeof key === \"string\" && regexes.number.test(key) && keyResult.issues.length;\n if (checkNumericKey) {\n const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx);\n if (retryResult instanceof Promise) {\n throw new Error(\"Async schemas not supported in object keys currently\");\n }\n if (retryResult.issues.length === 0) {\n keyResult = retryResult;\n }\n }\n if (keyResult.issues.length) {\n if (def.mode === \"loose\") {\n // Pass through unchanged\n payload.value[key] = input[key];\n }\n else if (values) {\n unrecognized = unrecognized ?? [];\n unrecognized.push(key);\n }\n else {\n // Default \"strict\" behavior: error on invalid key\n payload.issues.push({\n code: \"invalid_key\",\n origin: \"record\",\n issues: keyResult.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n input: key,\n path: [key],\n inst,\n });\n }\n continue;\n }\n // the guard above tests the raw input key, but the key schema can normalize an ordinary key into __proto__; re-check the key we actually write under\n const outKey = keyResult.value;\n if (outKey === \"__proto__\")\n continue;\n const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((result) => {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(key, result.issues));\n }\n payload.value[outKey] = result.value;\n }));\n }\n else {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(key, result.issues));\n }\n payload.value[outKey] = result.value;\n }\n }\n if (unrecognized && unrecognized.length > 0) {\n payload.issues.push({\n code: \"unrecognized_keys\",\n input,\n inst,\n keys: unrecognized,\n continue: true,\n });\n }\n }\n if (proms.length) {\n return Promise.all(proms).then(() => payload);\n }\n return payload;\n };\n});\nexport const $ZodMap = /*@__PURE__*/ core.$constructor(\"$ZodMap\", (inst, def) => {\n $ZodType.init(inst, def);\n const memo = core.globalConfig.memoizer;\n memo?.attach(inst);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!(input instanceof Map)) {\n payload.issues.push({\n expected: \"map\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n const proms = [];\n payload.value = memo ? memo.alloc(inst, payload, new Map(), ctx) : new Map();\n const abortEarly = ctx?.abortEarly;\n let seen = payload.issues.length;\n for (const [key, value] of input) {\n if (abortEarly && payload.issues.length !== seen) {\n if (util.aborted(payload, seen))\n break;\n seen = payload.issues.length;\n }\n const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);\n const valueResult = def.valueType._zod.run({ value: value, issues: [] }, ctx);\n if (keyResult instanceof Promise || valueResult instanceof Promise) {\n proms.push(Promise.all([keyResult, valueResult]).then(([keyResult, valueResult]) => {\n handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx);\n }));\n }\n else {\n handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx);\n }\n }\n if (proms.length)\n return Promise.all(proms).then(() => payload);\n return payload;\n };\n capSize(inst, mapSize);\n});\nfunction handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) {\n if (keyResult.issues.length) {\n if (util.propertyKeyTypes.has(typeof key)) {\n final.issues.push(...util.prefixIssues(key, keyResult.issues));\n }\n else {\n final.issues.push({\n code: \"invalid_key\",\n origin: \"map\",\n input,\n inst,\n issues: keyResult.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n });\n }\n }\n if (valueResult.issues.length) {\n if (util.propertyKeyTypes.has(typeof key)) {\n final.issues.push(...util.prefixIssues(key, valueResult.issues));\n }\n else {\n final.issues.push({\n origin: \"map\",\n code: \"invalid_element\",\n input,\n inst,\n key: key,\n issues: valueResult.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n });\n }\n }\n final.value.set(keyResult.value, valueResult.value);\n}\nexport const $ZodSet = /*@__PURE__*/ core.$constructor(\"$ZodSet\", (inst, def) => {\n $ZodType.init(inst, def);\n const memo = core.globalConfig.memoizer;\n memo?.attach(inst);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!(input instanceof Set)) {\n payload.issues.push({\n input,\n inst,\n expected: \"set\",\n code: \"invalid_type\",\n });\n return payload;\n }\n const proms = [];\n payload.value = memo ? memo.alloc(inst, payload, new Set(), ctx) : new Set();\n const abortEarly = ctx?.abortEarly;\n let seen = payload.issues.length;\n for (const item of input) {\n if (abortEarly && payload.issues.length !== seen) {\n if (util.aborted(payload, seen))\n break;\n seen = payload.issues.length;\n }\n const result = def.valueType._zod.run({ value: item, issues: [] }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((result) => handleSetResult(result, payload)));\n }\n else\n handleSetResult(result, payload);\n }\n if (proms.length)\n return Promise.all(proms).then(() => payload);\n return payload;\n };\n capSize(inst, setSize);\n});\nfunction handleSetResult(result, final) {\n if (result.issues.length) {\n final.issues.push(...result.issues);\n }\n final.value.add(result.value);\n}\nexport const $ZodEnum = /*@__PURE__*/ core.$constructor(\"$ZodEnum\", (inst, def) => {\n $ZodType.init(inst, def);\n const values = util.getEnumValues(def.entries);\n const valuesSet = new Set(values);\n inst._zod.values = valuesSet;\n util.defineLazyInternal(inst, \"pattern\", (zod) => {\n const patternValues = util.getEnumValues(zod.def.entries).filter((k) => util.propertyKeyTypes.has(typeof k));\n // unmatchable fallback, RE2-safe: an empty alternation would compile to /^()$/, which matches \"\"\n return new RegExp(patternValues.length ? `^(${patternValues.map((o) => util.escapeRegex(o.toString())).join(\"|\")})$` : \"^[^\\\\s\\\\S]$\");\n });\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (valuesSet.has(input)) {\n return payload;\n }\n payload.issues.push({\n code: \"invalid_value\",\n values,\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodLiteral = /*@__PURE__*/ core.$constructor(\"$ZodLiteral\", (inst, def) => {\n $ZodType.init(inst, def);\n const values = new Set(def.values);\n inst._zod.values = values;\n util.defineLazyInternal(inst, \"pattern\", (zod) => {\n const vals = zod.def.values;\n // unmatchable fallback, RE2-safe: an empty alternation would compile to /^()$/, which matches \"\"\n return new RegExp(vals.length\n ? `^(${vals\n .map((o) => typeof o === \"string\" ? util.escapeRegex(o) : o ? util.escapeRegex(o.toString()) : String(o))\n .join(\"|\")})$`\n : \"^[^\\\\s\\\\S]$\");\n });\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (values.has(input)) {\n return payload;\n }\n payload.issues.push({\n code: \"invalid_value\",\n values: def.values,\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodFile = /*@__PURE__*/ core.$constructor(\"$ZodFile\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n // @ts-ignore\n if (input instanceof File)\n return payload;\n payload.issues.push({\n expected: \"file\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodTransform = /*@__PURE__*/ core.$constructor(\"$ZodTransform\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.optin = \"optional\";\n core.globalConfig.memoizer?.guard(inst);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n throw new core.$ZodEncodeError(inst.constructor.name);\n }\n const _out = def.transform(payload.value, payload);\n if (ctx.async) {\n const output = _out instanceof Promise ? _out : Promise.resolve(_out);\n return output.then((output) => {\n payload.value = output;\n return payload;\n });\n }\n if (_out instanceof Promise) {\n throw new core.$ZodAsyncError();\n }\n payload.value = _out;\n return payload;\n };\n});\nfunction handleOptionalResult(payload, result) {\n // A substituting schema that still failed has no usable answer; yield undefined. Its issues are simply dropped: it ran on a payload of its own, so there is no shared array to truncate and nothing of the caller's to lose with it.\n payload.value = result.issues.length ? undefined : result.value;\n return payload;\n}\nexport const $ZodOptional = /*@__PURE__*/ core.$constructor(\"$ZodOptional\", (inst, def) => {\n $ZodType.init(inst, def);\n // .optional() propagates absence rather than substituting for it, so a defaulted inner keeps its rung.\n util.defineLazyInternal(inst, \"optin\", (zod) => zod.def.innerType._zod.optin === \"defaulted\" ? \"defaulted\" : \"optional\");\n inst._zod.optout = \"optional\";\n util.defineLazyInternal(inst, \"values\", (zod) => {\n const values = zod.def.innerType._zod.values;\n return values ? new Set([...values, undefined]) : undefined;\n });\n util.defineLazyInternal(inst, \"pattern\", (zod) => {\n const pattern = zod.def.innerType._zod.pattern;\n return pattern ? new RegExp(`^(${util.cleanRegex(pattern.source)})?$`) : undefined;\n });\n inst._zod.parse = (payload, ctx) => {\n if (payload.value === undefined) {\n // Only the top rung substitutes a value for absence; everything else leaves it intact, which is what .optional() means.\n if (def.innerType._zod.optin !== \"defaulted\")\n return payload;\n // Its own payload, for the same reason $ZodCatch gets one: a pipe forwards an unrecognized key through the caller's issues array, and this must not read that as the substituting schema failing and drop it.\n const result = def.innerType._zod.run({ value: payload.value, issues: [] }, ctx);\n if (result instanceof Promise)\n return result.then((result) => handleOptionalResult(payload, result));\n return handleOptionalResult(payload, result);\n }\n return def.innerType._zod.run(payload, ctx);\n };\n});\nexport const $ZodExactOptional = /*@__PURE__*/ core.$constructor(\"$ZodExactOptional\", (inst, def) => {\n // Call parent init - inherits optin/optout = \"optional\"\n $ZodOptional.init(inst, def);\n // Override values/pattern to NOT add undefined\n util.defineLazyInternal(inst, \"values\", (zod) => zod.def.innerType._zod.values);\n util.defineLazyInternal(inst, \"pattern\", (zod) => zod.def.innerType._zod.pattern);\n // Override parse to just delegate (no undefined handling)\n inst._zod.parse = (payload, ctx) => {\n return def.innerType._zod.run(payload, ctx);\n };\n});\nexport const $ZodNullable = /*@__PURE__*/ core.$constructor(\"$ZodNullable\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazyInternal(inst, \"optin\", (zod) => zod.def.innerType._zod.optin);\n util.defineLazyInternal(inst, \"optout\", (zod) => zod.def.innerType._zod.optout);\n util.defineLazyInternal(inst, \"pattern\", (zod) => {\n const pattern = zod.def.innerType._zod.pattern;\n return pattern ? new RegExp(`^(${util.cleanRegex(pattern.source)}|null)$`) : undefined;\n });\n util.defineLazyInternal(inst, \"values\", (zod) => {\n return zod.def.innerType._zod.values ? new Set([...zod.def.innerType._zod.values, null]) : undefined;\n });\n inst._zod.parse = (payload, ctx) => {\n // Forward direction (decode): allow null to pass through\n if (payload.value === null)\n return payload;\n return def.innerType._zod.run(payload, ctx);\n };\n});\nexport const $ZodDefault = /*@__PURE__*/ core.$constructor(\"$ZodDefault\", (inst, def) => {\n $ZodType.init(inst, def);\n // inst._zod.qin = \"true\";\n inst._zod.optin = \"defaulted\";\n util.defineLazyInternal(inst, \"values\", (zod) => zod.def.innerType._zod.values);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n return def.innerType._zod.run(payload, ctx);\n }\n // Forward direction (decode): apply defaults for undefined input\n if (payload.value === undefined) {\n payload.value = def.defaultValue;\n /**\n * $ZodDefault returns the default value immediately in forward direction.\n * It doesn't pass the default value into the validator (\"prefault\"). There's no reason to pass the default value through validation. The validity of the default is enforced by TypeScript statically. Otherwise, it's the responsibility of the user to ensure the default is valid. In the case of pipes with divergent in/out types, you can specify the default on the `in` schema of your ZodPipe to set a \"prefault\" for the pipe. */\n return payload;\n }\n // Forward direction: continue with default handling\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then((result) => handleDefaultResult(result, def));\n }\n return handleDefaultResult(result, def);\n };\n});\nfunction handleDefaultResult(payload, def) {\n if (payload.value === undefined) {\n payload.value = def.defaultValue;\n }\n return payload;\n}\nexport const $ZodPrefault = /*@__PURE__*/ core.$constructor(\"$ZodPrefault\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.optin = \"defaulted\";\n util.defineLazyInternal(inst, \"values\", (zod) => zod.def.innerType._zod.values);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n return def.innerType._zod.run(payload, ctx);\n }\n // Forward direction (decode): apply prefault for undefined input\n if (payload.value === undefined) {\n payload.value = def.defaultValue;\n }\n return def.innerType._zod.run(payload, ctx);\n };\n});\nexport const $ZodNonOptional = /*@__PURE__*/ core.$constructor(\"$ZodNonOptional\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazyInternal(inst, \"values\", (zod) => {\n const v = zod.def.innerType._zod.values;\n return v ? new Set([...v].filter((x) => x !== undefined)) : undefined;\n });\n inst._zod.parse = (payload, ctx) => {\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then((result) => handleNonOptionalResult(result, inst));\n }\n return handleNonOptionalResult(result, inst);\n };\n});\nfunction handleNonOptionalResult(payload, inst) {\n if (!payload.issues.length && payload.value === undefined) {\n payload.issues.push({\n code: \"invalid_type\",\n expected: \"nonoptional\",\n input: payload.value,\n inst,\n });\n }\n return payload;\n}\nexport const $ZodSuccess = /*@__PURE__*/ core.$constructor(\"$ZodSuccess\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n throw new core.$ZodEncodeError(\"ZodSuccess\");\n }\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then((result) => {\n payload.value = result.issues.length === 0;\n return payload;\n });\n }\n payload.value = result.issues.length === 0;\n return payload;\n };\n});\nfunction handleCatchResult(payload, result, def, ctx) {\n if (!result.issues.length) {\n payload.value = result.value;\n // The value carries up, so the flag describing it has to carry with it: a back-edge into a node still being parsed must not be frozen by an enclosing readonly, and its checks belong to the node itself. Guarded so the ordinary case adds no own property.\n if (result.memo)\n payload.memo = true;\n return payload;\n }\n // Spread the inner's own payload, not ours: `value` has to stay the input the catch was handed, and the inner ran on a payload of its own so its issues are already private to this call.\n payload.value = def.catchValue({\n ...result,\n value: payload.value,\n error: {\n issues: result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n },\n input: payload.value,\n });\n return payload;\n}\nexport const $ZodCatch = /*@__PURE__*/ core.$constructor(\"$ZodCatch\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazyInternal(inst, \"optin\", (zod) => zod.def.innerType._zod.optin === \"defaulted\" ? \"defaulted\" : \"optional\");\n util.defineLazyInternal(inst, \"optout\", (zod) => zod.def.innerType._zod.optout);\n util.defineLazyInternal(inst, \"values\", (zod) => zod.def.innerType._zod.values);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n return def.innerType._zod.run(payload, ctx);\n }\n // Forward direction (decode): apply catch logic\n const result = def.innerType._zod.run({ value: payload.value, issues: [] }, ctx);\n if (result instanceof Promise) {\n return result.then((result) => handleCatchResult(payload, result, def, ctx));\n }\n return handleCatchResult(payload, result, def, ctx);\n };\n});\nexport const $ZodNaN = /*@__PURE__*/ core.$constructor(\"$ZodNaN\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n if (typeof payload.value !== \"number\" || !Number.isNaN(payload.value)) {\n payload.issues.push({\n input: payload.value,\n inst,\n expected: \"nan\",\n code: \"invalid_type\",\n });\n return payload;\n }\n return payload;\n };\n});\nexport const $ZodPipe = /*@__PURE__*/ core.$constructor(\"$ZodPipe\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazyInternal(inst, \"values\", (zod) => zod.def.in._zod.values);\n util.defineLazyInternal(inst, \"optin\", (zod) => zod.def.in._zod.optin);\n util.defineLazyInternal(inst, \"optout\", (zod) => zod.def.out._zod.optout);\n util.defineLazyInternal(inst, \"propValues\", (zod) => zod.def.in._zod.propValues);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n const right = def.out._zod.run(payload, ctx);\n if (right instanceof Promise) {\n return right.then((right) => handlePipeResult(right, def.in, ctx));\n }\n return handlePipeResult(right, def.in, ctx);\n }\n const left = def.in._zod.run(payload, ctx);\n if (left instanceof Promise) {\n return left.then((left) => handlePipeResult(left, def.out, ctx));\n }\n return handlePipeResult(left, def.out, ctx);\n };\n});\nfunction handlePipeResult(left, next, ctx) {\n // Any issue stops the pipe, so a failing refinement never feeds its transform. An unrecognized key is the exception: it describes the input's extra properties, not the value being piped, and an enclosing intersection may yet reconcile it.\n if (left.issues.some((iss) => iss.code !== \"unrecognized_keys\")) {\n // prevent further checks\n left.aborted = true;\n return left;\n }\n return next._zod.run({ value: left.value, issues: left.issues }, ctx);\n}\nexport const $ZodCodec = /*@__PURE__*/ core.$constructor(\"$ZodCodec\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazyInternal(inst, \"values\", (zod) => zod.def.in._zod.values);\n util.defineLazyInternal(inst, \"optin\", (zod) => zod.def.in._zod.optin);\n util.defineLazyInternal(inst, \"optout\", (zod) => zod.def.out._zod.optout);\n util.defineLazyInternal(inst, \"propValues\", (zod) => zod.def.in._zod.propValues);\n inst._zod.parse = (payload, ctx) => {\n const direction = ctx.direction || \"forward\";\n if (direction === \"forward\") {\n const left = def.in._zod.run(payload, ctx);\n if (left instanceof Promise) {\n return left.then((left) => handleCodecAResult(left, def, ctx));\n }\n return handleCodecAResult(left, def, ctx);\n }\n else {\n const right = def.out._zod.run(payload, ctx);\n if (right instanceof Promise) {\n return right.then((right) => handleCodecAResult(right, def, ctx));\n }\n return handleCodecAResult(right, def, ctx);\n }\n };\n});\nfunction handleCodecAResult(result, def, ctx) {\n if (result.issues.length) {\n // prevent further checks\n result.aborted = true;\n return result;\n }\n const direction = ctx.direction || \"forward\";\n if (direction === \"forward\") {\n const transformed = def.transform(result.value, result);\n if (transformed instanceof Promise) {\n return transformed.then((value) => handleCodecTxResult(result, value, def.out, ctx));\n }\n return handleCodecTxResult(result, transformed, def.out, ctx);\n }\n else {\n const transformed = def.reverseTransform(result.value, result);\n if (transformed instanceof Promise) {\n return transformed.then((value) => handleCodecTxResult(result, value, def.in, ctx));\n }\n return handleCodecTxResult(result, transformed, def.in, ctx);\n }\n}\nfunction handleCodecTxResult(left, value, nextSchema, ctx) {\n // Check if transform added any issues\n if (left.issues.length) {\n left.aborted = true;\n return left;\n }\n return nextSchema._zod.run({ value, issues: left.issues }, ctx);\n}\nexport const $ZodPreprocess = /*@__PURE__*/ core.$constructor(\"$ZodPreprocess\", (inst, def) => {\n $ZodPipe.init(inst, def);\n});\nexport const $ZodReadonly = /*@__PURE__*/ core.$constructor(\"$ZodReadonly\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazyInternal(inst, \"propValues\", (zod) => zod.def.innerType._zod.propValues);\n util.defineLazyInternal(inst, \"values\", (zod) => zod.def.innerType._zod.values);\n util.defineLazyInternal(inst, \"optin\", (zod) => zod.def.innerType?._zod?.optin);\n util.defineLazyInternal(inst, \"optout\", (zod) => zod.def.innerType?._zod?.optout);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n return def.innerType._zod.run(payload, ctx);\n }\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then(handleReadonlyResult);\n }\n return handleReadonlyResult(result);\n };\n});\nfunction handleReadonlyResult(payload) {\n // A repeat visit hands back a node that is still being built; freezing it here would make the rest of its keys fail to assign.\n if (!payload.memo)\n payload.value = Object.freeze(payload.value);\n return payload;\n}\n// a leaf's pattern source with its own checks folded in: the last pattern-carrying check wins, else length bounds narrow the catch-all, else an integer format narrows the number form. the fold lives here instead of on `_zod.pattern` so a bundle without template literals never pays for it\nfunction leafPattern(schema) {\n const def = schema._zod.def;\n let pattern = def.pattern;\n let isInt = !!def.format?.includes(\"int\");\n let minimum;\n let maximum;\n for (const ch of def.checks ?? []) {\n const d = ch._zod.def;\n if (d.pattern)\n pattern = d.pattern;\n isInt || (isInt = !!d.format?.includes(\"int\"));\n const lo = d.minimum ?? d.length;\n const hi = d.maximum ?? d.length;\n if (lo !== undefined && (minimum === undefined || lo > minimum))\n minimum = lo;\n if (hi !== undefined && (maximum === undefined || hi < maximum))\n maximum = hi;\n }\n if (pattern)\n return pattern.source;\n // an empty range matches nothing at runtime, and `{8,5}` is not a legal quantifier\n if (minimum !== undefined && maximum !== undefined && minimum > maximum)\n return \"(?!)\";\n if (minimum !== undefined || maximum !== undefined)\n return regexes.string({ minimum, maximum }).source;\n const own = schema._zod.pattern;\n return (isInt && own === regexes.number ? regexes.integer : own)?.source;\n}\n// a part's pattern source. a wrapper's pattern embeds its inner pattern's source verbatim, so the folded form is substituted in place without knowing the wrapper's own composition; a union's options are joined the way the union builds its own pattern\nfunction partPattern(schema) {\n const def = schema._zod.def;\n const own = schema._zod.pattern?.source;\n // lazy resolves its inner on the internals, not the def\n const inner = def.innerType ?? schema._zod.innerType;\n if (inner) {\n const before = inner._zod.pattern?.source;\n const after = partPattern(inner);\n if (own && before && after && after !== before) {\n return own.replace(util.cleanRegex(before), () => util.cleanRegex(after));\n }\n return own;\n }\n if (def.options) {\n const sources = def.options.map(partPattern);\n if (sources.every(Boolean))\n return `^(${sources.map((s) => util.cleanRegex(s)).join(\"|\")})$`;\n }\n return leafPattern(schema);\n}\nexport const $ZodTemplateLiteral = /*@__PURE__*/ core.$constructor(\"$ZodTemplateLiteral\", (inst, def) => {\n $ZodType.init(inst, def);\n const regexParts = [];\n for (const part of def.parts) {\n if (typeof part === \"object\" && part !== null) {\n // is Zod schema\n const source = partPattern(part);\n if (!source) {\n throw new Error(`Invalid template literal part, no pattern found: ${[...part._zod.traits].shift()}`);\n }\n regexParts.push(util.cleanRegex(source));\n }\n else if (part === null || util.primitiveTypes.has(typeof part)) {\n regexParts.push(util.escapeRegex(`${part}`));\n }\n else {\n throw new Error(`Invalid template literal part: ${part}`);\n }\n }\n inst._zod.pattern = new RegExp(`^${regexParts.join(\"\")}$`);\n inst._zod.parse = (payload, _ctx) => {\n if (typeof payload.value !== \"string\") {\n payload.issues.push({\n input: payload.value,\n inst,\n expected: \"string\",\n code: \"invalid_type\",\n });\n return payload;\n }\n inst._zod.pattern.lastIndex = 0;\n if (!inst._zod.pattern.test(payload.value)) {\n payload.issues.push({\n input: payload.value,\n inst,\n code: \"invalid_format\",\n format: def.format ?? \"template_literal\",\n pattern: inst._zod.pattern.source,\n });\n return payload;\n }\n return payload;\n };\n});\nexport const $ZodFunction = /*@__PURE__*/ core.$constructor(\"$ZodFunction\", (inst, def) => {\n $ZodType.init(inst, def);\n // Defined, not assigned: the classic prototype exposes `_def` as a getter with no setter.\n Object.defineProperty(inst, \"_def\", { value: def });\n inst._zod.def = def;\n inst.implement = (func) => {\n if (typeof func !== \"function\") {\n throw new Error(\"implement() must be called with a function\");\n }\n // Defined inline so the closure stays anonymous: binding it to a `const` first names it, which costs 256 bytes per implemented function.\n return Object.defineProperty(function (...args) {\n const parsedArgs = inst._def.input ? parse(inst._def.input, args) : args;\n const result = Reflect.apply(func, this, parsedArgs);\n if (inst._def.output) {\n return parse(inst._def.output, result);\n }\n return result;\n }, \"_zod\", { value: inst._zod, enumerable: false });\n };\n inst.implementAsync = (func) => {\n if (typeof func !== \"function\") {\n throw new Error(\"implementAsync() must be called with a function\");\n }\n return Object.defineProperty(async function (...args) {\n const parsedArgs = inst._def.input ? await parseAsync(inst._def.input, args) : args;\n const result = await Reflect.apply(func, this, parsedArgs);\n if (inst._def.output) {\n return await parseAsync(inst._def.output, result);\n }\n return result;\n }, \"_zod\", { value: inst._zod, enumerable: false });\n };\n inst._zod.parse = (payload, _ctx) => {\n if (typeof payload.value !== \"function\") {\n payload.issues.push({\n code: \"invalid_type\",\n expected: \"function\",\n input: payload.value,\n inst,\n });\n return payload;\n }\n // Check if output is a promise type to determine if we should use async implementation\n const hasPromiseOutput = inst._def.output && inst._def.output._zod.def.type === \"promise\";\n if (hasPromiseOutput) {\n payload.value = inst.implementAsync(payload.value);\n }\n else {\n payload.value = inst.implement(payload.value);\n }\n return payload;\n };\n inst.input = (...args) => {\n const F = inst.constructor;\n if (Array.isArray(args[0])) {\n return new F({\n type: \"function\",\n input: new $ZodTuple({\n type: \"tuple\",\n items: args[0],\n rest: args[1],\n }),\n output: inst._def.output,\n });\n }\n return new F({\n type: \"function\",\n input: args[0],\n output: inst._def.output,\n });\n };\n inst.output = (output) => {\n const F = inst.constructor;\n return new F({\n type: \"function\",\n input: inst._def.input,\n output,\n });\n };\n return inst;\n});\nexport const $ZodPromise = /*@__PURE__*/ core.$constructor(\"$ZodPromise\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n return Promise.resolve(payload.value).then((inner) => def.innerType._zod.run({ value: inner, issues: [] }, ctx));\n };\n});\nexport const $ZodLazy = /*@__PURE__*/ core.$constructor(\"$ZodLazy\", (inst, def) => {\n $ZodType.init(inst, def);\n // Cache the resolved inner type on the shared `def` so all clones of this lazy (e.g. via `.describe()`/`.meta()`) share the same inner instance, preserving identity for cycle detection on recursive schemas.\n util.defineLazy(inst._zod, \"innerType\", () => {\n const d = def;\n if (!d._cachedInner)\n d._cachedInner = def.getter();\n return d._cachedInner;\n });\n util.defineLazyInternal(inst, \"pattern\", (zod) => zod.innerType?._zod?.pattern);\n util.defineLazyInternal(inst, \"propValues\", (zod) => zod.innerType?._zod?.propValues);\n util.defineLazyInternal(inst, \"optin\", (zod) => zod.innerType?._zod?.optin ?? undefined);\n util.defineLazyInternal(inst, \"optout\", (zod) => zod.innerType?._zod?.optout ?? undefined);\n inst._zod.parse = (payload, ctx) => {\n const inner = inst._zod.innerType;\n return inner._zod.run(payload, ctx);\n };\n});\nexport const $ZodCustom = /*@__PURE__*/ core.$constructor(\"$ZodCustom\", (inst, def) => {\n checks.$ZodCheck.init(inst, def);\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _) => {\n return payload;\n };\n inst._zod.check = (payload) => {\n const input = payload.value;\n const r = def.fn(input);\n if (r instanceof Promise) {\n return r.then((r) => handleRefineResult(r, payload, input, inst));\n }\n handleRefineResult(r, payload, input, inst);\n return;\n };\n});\nfunction handleRefineResult(result, payload, input, inst) {\n if (!result) {\n const _iss = {\n code: \"custom\",\n input,\n inst, // incorporates params.error into issue reporting\n path: [...(inst._zod.def.path ?? [])], // incorporates params.error into issue reporting\n continue: !inst._zod.def.abort,\n // params: inst._zod.def.params,\n };\n if (inst._zod.def.params)\n _iss.params = inst._zod.def.params;\n payload.issues.push(util.issue(_iss));\n }\n}\n", "import * as util from \"./util.js\";\nexport class $ZodCyclicError extends Error {\n constructor() {\n super(`Cannot parse a reference cycle that closes through a transform`);\n this.name = \"ZodCyclicError\";\n }\n}\n/** Keyed off the context object every schema in one parse call already shares. */\nconst STATE = \"~memo\";\nconst NO_ISSUES = [];\n// a value a cycle can close through\nfunction isRef(value) {\n return value !== null && typeof value === \"object\";\n}\n// Receivers prefix paths in place, so the cache and every hand-out need their own copies.\nfunction cloneIssues(issues) {\n return issues.map((iss) => (iss.path ? { ...iss, path: iss.path.slice() } : { ...iss }));\n}\nconst recursive = /*@__PURE__*/ new WeakMap();\n/** What the walk established, in order of certainty: ordered so the strongest answer among children wins. */\nconst NONE = 0;\nconst ASSUMED = 1;\nconst PROVEN = 2;\n/** Whether this schema's subtree contains a cycle, so one parse can re-enter it. */\nfunction isRecursive(inst, stack, resolve) {\n const cached = recursive.get(inst);\n if (cached !== undefined)\n return cached ? PROVEN : NONE;\n // Relative to the walk in progress, so not cached.\n if (stack.has(inst))\n return PROVEN;\n stack.add(inst);\n let result = NONE;\n const check = (child) => {\n if (result !== PROVEN && child?._zod) {\n const answer = isRecursive(child, stack, resolve);\n if (answer > result)\n result = answer;\n }\n };\n // `Reflect.ownKeys` rather than `Object.keys`, so a cycle through a declared symbol key is still seen\n const shape = (sh, spread) => {\n let answer = NONE;\n for (const key of Reflect.ownKeys(sh)) {\n const desc = Object.getOwnPropertyDescriptor(sh, key);\n // an object resolves its shape by spread, so a key it does not enumerate is never parsed; `z.properties` reads every own key and so keeps them all\n if (spread && !desc.enumerable)\n continue;\n // resolving runs user code, and a factory mints a fresh subtree per read, so an edge the walk can't follow counts as a cycle\n const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve) : NONE;\n if (child > answer)\n answer = child;\n }\n return answer;\n };\n const merge = (answer) => {\n if (answer > result)\n result = answer;\n };\n const def = inst._zod.def;\n const kind = def.type;\n switch (kind) {\n case \"object\": {\n const raw = util.rawShape(def);\n // a def with no raw shape answers `shape` from an accessor of its own, and running that can mint a whole fresh subtree\n merge(raw ? shape(raw, true) : ASSUMED);\n check(def.catchall);\n break;\n }\n case \"array\":\n check(def.element);\n break;\n case \"tuple\":\n for (const el of def.items)\n check(el);\n check(def.rest);\n break;\n case \"record\":\n case \"map\":\n check(def.keyType);\n check(def.valueType);\n break;\n case \"set\":\n check(def.valueType);\n break;\n case \"union\":\n for (const el of def.options)\n check(el);\n break;\n case \"intersection\":\n check(def.left);\n check(def.right);\n break;\n case \"optional\":\n case \"nullable\":\n case \"default\":\n case \"prefault\":\n case \"catch\":\n case \"readonly\":\n case \"nonoptional\":\n case \"promise\":\n case \"success\":\n check(def.innerType);\n break;\n case \"pipe\":\n check(def.in);\n check(def.out);\n break;\n case \"function\":\n check(def.input);\n check(def.output);\n break;\n // `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly\n case \"lazy\": {\n const inner = def._cachedInner ?? (resolve ? inst._zod.innerType : undefined);\n // walked with resolution off: one hop sees past the deferral, and a lazy that yields only another unresolved lazy is generative, so it stops there\n merge(inner ? isRecursive(inner, stack, false) : ASSUMED);\n break;\n }\n // a leaf by choice: `parts` are regex fragments, not data positions\n case \"template_literal\":\n // leaves\n case \"string\":\n case \"number\":\n case \"int\":\n case \"boolean\":\n case \"bigint\":\n case \"symbol\":\n case \"undefined\":\n case \"null\":\n case \"void\":\n case \"never\":\n case \"any\":\n case \"unknown\":\n case \"date\":\n case \"nan\":\n case \"enum\":\n case \"literal\":\n case \"file\":\n case \"transform\":\n case \"custom\":\n break;\n default: {\n // a new built-in kind becomes a compile error here\n kind;\n // a user-defined kind can still hold children, and only its author knows where, so fall back to scanning the def \u2014 skipping accessors, since reading one can run user code\n for (const key in def) {\n const desc = Object.getOwnPropertyDescriptor(def, key);\n if (!desc || desc.get)\n continue;\n const value = desc.value;\n if (!value || typeof value !== \"object\")\n continue;\n if (value._zod)\n check(value);\n else if (Array.isArray(value))\n for (const el of value)\n check(el);\n }\n }\n }\n stack.delete(inst);\n return settle(inst, result);\n}\n/** An assumed answer must not outlive the resolution that settles it, so only a certain one is cached. */\nfunction settle(inst, answer) {\n if (answer !== ASSUMED)\n recursive.set(inst, answer === PROVEN);\n return answer;\n}\n/**\n * Whether one parse can re-enter this schema, i.e. its subtree contains a cycle.\n * Exported for `z.compile`, which refuses to compile such a schema: cycle\n * breaking is driven from here off state keyed on the parse context, and a\n * generated fast path has no context to key on.\n */\nexport function isRecursiveSchema(inst) {\n // z.compile never parses, so nothing would ever resolve a lazy for it; it runs once and already treats a throw here as recursive\n return isRecursive(inst, new Set(), true) !== NONE;\n}\nfunction bucketFor(state, inst) {\n let bucket = state.buckets.get(inst);\n if (!bucket) {\n bucket = new WeakMap();\n state.buckets.set(inst, bucket);\n }\n return bucket;\n}\n// Set immediately before delegating to core and cleared immediately after, so `alloc` registers only for a visit this module is driving.\nlet handoff;\n// Allocated but unfinished entries. `alloc` and the matching pop both happen in the synchronous part of a parse, so they nest even when children are async, and one stack serves every schema.\nconst open = [];\nconst memo = {\n alloc(_inst, payload, empty) {\n const bucket = handoff;\n if (!bucket)\n return empty;\n handoff = undefined;\n const entry = { value: empty, issues: null };\n bucket.set(payload.value, entry);\n open.push(entry);\n return empty;\n },\n guard(inst) {\n var _a;\n (_a = inst._zod).deferred ?? (_a.deferred = []);\n inst._zod.deferred.push(() => {\n const base = inst._zod.parse;\n const wrapped = (payload, ctx) => {\n // The value is a placeholder a back-edge is still waiting on, so the cycle closes through this transform. Its output can't exist in time to bind.\n if (ctx.direction !== \"backward\" && isBackEdge(ctx, payload.value))\n throw new $ZodCyclicError();\n return base(payload, ctx);\n };\n inst._zod.parse = wrapped;\n if (inst._zod.run === base)\n inst._zod.run = wrapped;\n });\n },\n attach(inst) {\n var _a;\n let isRecursiveInst;\n let rechecked = false;\n // a recursive schema is re-entered many times per parse and its bucket never changes\n let lastCtx;\n let lastBucket;\n // Wraps `parse` in a deferred so it sees the container's final parse. Core's own deferred copies `parse` into `run` when there are no checks, and it ran first, so `run` is patched to match; with checks, `run` reads `parse` dynamically.\n (_a = inst._zod).deferred ?? (_a.deferred = []);\n inst._zod.deferred.push(() => {\n const base = inst._zod.parse;\n const wrapped = (payload, ctx) => {\n if (isRecursiveInst === undefined) {\n const walked = isRecursive(inst, new Set(), false);\n if (walked === NONE) {\n // Nothing here can ever fire, so take it back out.\n inst._zod.parse = base;\n if (inst._zod.run === wrapped)\n inst._zod.run = base;\n return base(payload, ctx);\n }\n // this parse resolves the deferred edges on its own path, so ask once more before latching\n if (walked === PROVEN || rechecked)\n isRecursiveInst = true;\n else\n rechecked = true;\n }\n const input = payload.value;\n if (!isRef(input))\n return base(payload, ctx);\n let state = ctx[STATE];\n if (!state) {\n state = { buckets: new WeakMap(), backEdges: undefined };\n ctx[STATE] = state;\n }\n let bucket;\n if (lastCtx === ctx) {\n bucket = lastBucket;\n }\n else {\n bucket = bucketFor(state, inst);\n lastCtx = ctx;\n lastBucket = bucket;\n }\n const hit = bucket.get(input);\n if (hit) {\n payload.value = hit.value;\n if (hit.issues) {\n if (hit.issues.length)\n payload.issues.push(...cloneIssues(hit.issues));\n }\n else {\n // Still being parsed: its own checks cover it, so skip them here.\n payload.memo = true;\n state.backEdges ?? (state.backEdges = new WeakSet());\n state.backEdges.add(hit.value);\n }\n return payload;\n }\n handoff = bucket;\n const depth = open.length;\n const result = base(payload, ctx);\n handoff = undefined;\n // A container that rejected its input outright allocated nothing.\n const entry = open.length > depth ? open.pop() : undefined;\n // Both paths written out so the sync one allocates no closure. It runs once per node, and capturing here cost more than everything else combined.\n if (result instanceof Promise) {\n return result.then((r) => {\n if (entry)\n entry.issues = r.issues.length ? cloneIssues(r.issues) : NO_ISSUES;\n return r;\n });\n }\n if (entry)\n entry.issues = result.issues.length ? cloneIssues(result.issues) : NO_ISSUES;\n return result;\n };\n inst._zod.parse = wrapped;\n if (inst._zod.run === base)\n inst._zod.run = wrapped;\n });\n },\n};\n/** The memoizer that gives containers cycle support. `zod` installs it by default; `zod/mini` opts in with `config({ memoizer: memoizer() })`. */\nexport function memoizer() {\n return memo;\n}\n/** Whether this value is a node a back-edge resolved to before it finished. */\nexport function isBackEdge(ctx, value) {\n const backEdges = ctx[STATE]?.backEdges;\n return backEdges !== undefined && isRef(value) && backEdges.has(value);\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u062D\u0631\u0641\", verb: \"\u0623\u0646 \u064A\u062D\u0648\u064A\" },\n file: { unit: \"\u0628\u0627\u064A\u062A\", verb: \"\u0623\u0646 \u064A\u062D\u0648\u064A\" },\n array: { unit: \"\u0639\u0646\u0635\u0631\", verb: \"\u0623\u0646 \u064A\u062D\u0648\u064A\" },\n set: { unit: \"\u0639\u0646\u0635\u0631\", verb: \"\u0623\u0646 \u064A\u062D\u0648\u064A\" },\n map: { unit: \"\u0639\u0646\u0635\u0631\", verb: \"\u0623\u0646 \u064A\u062D\u0648\u064A\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0645\u062F\u062E\u0644\",\n email: \"\u0628\u0631\u064A\u062F \u0625\u0644\u0643\u062A\u0631\u0648\u0646\u064A\",\n url: \"\u0631\u0627\u0628\u0637\",\n emoji: \"\u0625\u064A\u0645\u0648\u062C\u064A\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u062A\u0627\u0631\u064A\u062E \u0648\u0648\u0642\u062A \u0628\u0645\u0639\u064A\u0627\u0631 ISO\",\n date: \"\u062A\u0627\u0631\u064A\u062E \u0628\u0645\u0639\u064A\u0627\u0631 ISO\",\n time: \"\u0648\u0642\u062A \u0628\u0645\u0639\u064A\u0627\u0631 ISO\",\n duration: \"\u0645\u062F\u0629 \u0628\u0645\u0639\u064A\u0627\u0631 ISO\",\n ipv4: \"\u0639\u0646\u0648\u0627\u0646 IPv4\",\n ipv6: \"\u0639\u0646\u0648\u0627\u0646 IPv6\",\n mac: \"\u0639\u0646\u0648\u0627\u0646 MAC\",\n cidrv4: \"\u0645\u062F\u0649 \u0639\u0646\u0627\u0648\u064A\u0646 \u0628\u0635\u064A\u063A\u0629 IPv4\",\n cidrv6: \"\u0645\u062F\u0649 \u0639\u0646\u0627\u0648\u064A\u0646 \u0628\u0635\u064A\u063A\u0629 IPv6\",\n base64: \"\u0646\u064E\u0635 \u0628\u062A\u0631\u0645\u064A\u0632 base64-encoded\",\n base64url: \"\u0646\u064E\u0635 \u0628\u062A\u0631\u0645\u064A\u0632 base64url-encoded\",\n json_string: \"\u0646\u064E\u0635 \u0639\u0644\u0649 \u0647\u064A\u0626\u0629 JSON\",\n e164: \"\u0631\u0642\u0645 \u0647\u0627\u062A\u0641 \u0628\u0645\u0639\u064A\u0627\u0631 E.164\",\n credit_card: \"\u0631\u0642\u0645 \u0628\u0637\u0627\u0642\u0629 \u0627\u0644\u0627\u0626\u062A\u0645\u0627\u0646\",\n currency_code: \"\u0631\u0645\u0632 \u0627\u0644\u0639\u0645\u0644\u0629\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0645\u062F\u062E\u0644\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u0645\u062F\u062E\u0644\u0627\u062A \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644\u0629: \u064A\u0641\u062A\u0631\u0636 \u0625\u062F\u062E\u0627\u0644 instanceof ${issue.expected}\u060C \u0648\u0644\u0643\u0646 \u062A\u0645 \u0625\u062F\u062E\u0627\u0644 ${received}`;\n }\n return `\u0645\u062F\u062E\u0644\u0627\u062A \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644\u0629: \u064A\u0641\u062A\u0631\u0636 \u0625\u062F\u062E\u0627\u0644 ${expected}\u060C \u0648\u0644\u0643\u0646 \u062A\u0645 \u0625\u062F\u062E\u0627\u0644 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0645\u062F\u062E\u0644\u0627\u062A \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644\u0629: \u064A\u0641\u062A\u0631\u0636 \u0625\u062F\u062E\u0627\u0644 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0627\u062E\u062A\u064A\u0627\u0631 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644: \u064A\u062A\u0648\u0642\u0639 \u0627\u0646\u062A\u0642\u0627\u0621 \u0623\u062D\u062F \u0647\u0630\u0647 \u0627\u0644\u062E\u064A\u0627\u0631\u0627\u062A: ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return ` \u0623\u0643\u0628\u0631 \u0645\u0646 \u0627\u0644\u0644\u0627\u0632\u0645: \u064A\u0641\u062A\u0631\u0636 \u0623\u0646 \u062A\u0643\u0648\u0646 ${issue.origin ?? \"\u0627\u0644\u0642\u064A\u0645\u0629\"} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? \"\u0639\u0646\u0635\u0631\"}`;\n return `\u0623\u0643\u0628\u0631 \u0645\u0646 \u0627\u0644\u0644\u0627\u0632\u0645: \u064A\u0641\u062A\u0631\u0636 \u0623\u0646 \u062A\u0643\u0648\u0646 ${issue.origin ?? \"\u0627\u0644\u0642\u064A\u0645\u0629\"} ${adj} ${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0623\u0635\u063A\u0631 \u0645\u0646 \u0627\u0644\u0644\u0627\u0632\u0645: \u064A\u0641\u062A\u0631\u0636 \u0644\u0640 ${issue.origin} \u0623\u0646 \u064A\u0643\u0648\u0646 ${adj} ${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u0623\u0635\u063A\u0631 \u0645\u0646 \u0627\u0644\u0644\u0627\u0632\u0645: \u064A\u0641\u062A\u0631\u0636 \u0644\u0640 ${issue.origin} \u0623\u0646 \u064A\u0643\u0648\u0646 ${adj} ${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u0646\u064E\u0635 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644: \u064A\u062C\u0628 \u0623\u0646 \u064A\u0628\u062F\u0623 \u0628\u0640 \"${issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `\u0646\u064E\u0635 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644: \u064A\u062C\u0628 \u0623\u0646 \u064A\u0646\u062A\u0647\u064A \u0628\u0640 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u0646\u064E\u0635 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644: \u064A\u062C\u0628 \u0623\u0646 \u064A\u062A\u0636\u0645\u0651\u064E\u0646 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u0646\u064E\u0635 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644: \u064A\u062C\u0628 \u0623\u0646 \u064A\u0637\u0627\u0628\u0642 \u0627\u0644\u0646\u0645\u0637 ${_issue.pattern}`;\n return `${FormatDictionary[_issue.format] ?? issue.format} \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644`;\n }\n case \"not_multiple_of\":\n return `\u0631\u0642\u0645 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644: \u064A\u062C\u0628 \u0623\u0646 \u064A\u0643\u0648\u0646 \u0645\u0646 \u0645\u0636\u0627\u0639\u0641\u0627\u062A ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u0645\u0639\u0631\u0641${issue.keys.length > 1 ? \"\u0627\u062A\" : \"\"} \u063A\u0631\u064A\u0628${issue.keys.length > 1 ? \"\u0629\" : \"\"}: ${util.joinValues(issue.keys, \"\u060C \")}`;\n case \"invalid_key\":\n return `\u0645\u0639\u0631\u0641 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644 \u0641\u064A ${issue.origin}`;\n case \"invalid_union\":\n return \"\u0645\u062F\u062E\u0644 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644\";\n case \"invalid_element\":\n return `\u0645\u062F\u062E\u0644 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644 \u0641\u064A ${issue.origin}`;\n default:\n return \"\u0645\u062F\u062E\u0644 \u063A\u064A\u0631 \u0645\u0642\u0628\u0648\u0644\";\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"simvol\", verb: \"olmal\u0131d\u0131r\" },\n file: { unit: \"bayt\", verb: \"olmal\u0131d\u0131r\" },\n array: { unit: \"element\", verb: \"olmal\u0131d\u0131r\" },\n set: { unit: \"element\", verb: \"olmal\u0131d\u0131r\" },\n map: { unit: \"element\", verb: \"olmal\u0131d\u0131r\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"input\",\n email: \"email address\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO datetime\",\n date: \"ISO date\",\n time: \"ISO time\",\n duration: \"ISO duration\",\n ipv4: \"IPv4 address\",\n ipv6: \"IPv6 address\",\n mac: \"MAC address\",\n cidrv4: \"IPv4 range\",\n cidrv6: \"IPv6 range\",\n base64: \"base64-encoded string\",\n base64url: \"base64url-encoded string\",\n json_string: \"JSON string\",\n e164: \"E.164 number\",\n credit_card: \"kredit kart\u0131 n\u00F6mr\u0259si\",\n currency_code: \"valyuta kodu\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Yanl\u0131\u015F d\u0259y\u0259r: g\u00F6zl\u0259nil\u0259n instanceof ${issue.expected}, daxil olan ${received}`;\n }\n return `Yanl\u0131\u015F d\u0259y\u0259r: g\u00F6zl\u0259nil\u0259n ${expected}, daxil olan ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Yanl\u0131\u015F d\u0259y\u0259r: g\u00F6zl\u0259nil\u0259n ${util.stringifyPrimitive(issue.values[0])}`;\n return `Yanl\u0131\u015F se\u00E7im: a\u015Fa\u011F\u0131dak\u0131lardan biri olmal\u0131d\u0131r: ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u00C7ox b\u00F6y\u00FCk: g\u00F6zl\u0259nil\u0259n ${issue.origin ?? \"d\u0259y\u0259r\"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"element\"}`;\n return `\u00C7ox b\u00F6y\u00FCk: g\u00F6zl\u0259nil\u0259n ${issue.origin ?? \"d\u0259y\u0259r\"} ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u00C7ox ki\u00E7ik: g\u00F6zl\u0259nil\u0259n ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n return `\u00C7ox ki\u00E7ik: g\u00F6zl\u0259nil\u0259n ${issue.origin} ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Yanl\u0131\u015F m\u0259tn: \"${_issue.prefix}\" il\u0259 ba\u015Flamal\u0131d\u0131r`;\n if (_issue.format === \"ends_with\")\n return `Yanl\u0131\u015F m\u0259tn: \"${_issue.suffix}\" il\u0259 bitm\u0259lidir`;\n if (_issue.format === \"includes\")\n return `Yanl\u0131\u015F m\u0259tn: \"${_issue.includes}\" daxil olmal\u0131d\u0131r`;\n if (_issue.format === \"regex\")\n return `Yanl\u0131\u015F m\u0259tn: ${_issue.pattern} \u015Fablonuna uy\u011Fun olmal\u0131d\u0131r`;\n return `Yanl\u0131\u015F ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Yanl\u0131\u015F \u0259d\u0259d: ${issue.divisor} il\u0259 b\u00F6l\u00FCn\u0259 bil\u0259n olmal\u0131d\u0131r`;\n case \"unrecognized_keys\":\n return `Tan\u0131nmayan a\u00E7ar${issue.keys.length > 1 ? \"lar\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} daxilind\u0259 yanl\u0131\u015F a\u00E7ar`;\n case \"invalid_union\":\n return \"Yanl\u0131\u015F d\u0259y\u0259r\";\n case \"invalid_element\":\n return `${issue.origin} daxilind\u0259 yanl\u0131\u015F d\u0259y\u0259r`;\n default:\n return `Yanl\u0131\u015F d\u0259y\u0259r`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nfunction getBelarusianPlural(count, one, few, many) {\n const absCount = Math.abs(count);\n const lastDigit = absCount % 10;\n const lastTwoDigits = absCount % 100;\n if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {\n return many;\n }\n if (lastDigit === 1) {\n return one;\n }\n if (lastDigit >= 2 && lastDigit <= 4) {\n return few;\n }\n return many;\n}\nconst error = () => {\n const Sizable = {\n string: {\n unit: {\n one: \"\u0441\u0456\u043C\u0432\u0430\u043B\",\n few: \"\u0441\u0456\u043C\u0432\u0430\u043B\u044B\",\n many: \"\u0441\u0456\u043C\u0432\u0430\u043B\u0430\u045E\",\n },\n verb: \"\u043C\u0435\u0446\u044C\",\n },\n array: {\n unit: {\n one: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\",\n few: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\",\n many: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u045E\",\n },\n verb: \"\u043C\u0435\u0446\u044C\",\n },\n set: {\n unit: {\n one: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\",\n few: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\",\n many: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u045E\",\n },\n verb: \"\u043C\u0435\u0446\u044C\",\n },\n map: {\n unit: {\n one: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\",\n few: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\",\n many: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u045E\",\n },\n verb: \"\u043C\u0435\u0446\u044C\",\n },\n file: {\n unit: {\n one: \"\u0431\u0430\u0439\u0442\",\n few: \"\u0431\u0430\u0439\u0442\u044B\",\n many: \"\u0431\u0430\u0439\u0442\u0430\u045E\",\n },\n verb: \"\u043C\u0435\u0446\u044C\",\n },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0443\u0432\u043E\u0434\",\n email: \"email \u0430\u0434\u0440\u0430\u0441\",\n url: \"URL\",\n emoji: \"\u044D\u043C\u043E\u0434\u0437\u0456\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0434\u0430\u0442\u0430 \u0456 \u0447\u0430\u0441\",\n date: \"ISO \u0434\u0430\u0442\u0430\",\n time: \"ISO \u0447\u0430\u0441\",\n duration: \"ISO \u043F\u0440\u0430\u0446\u044F\u0433\u043B\u0430\u0441\u0446\u044C\",\n ipv4: \"IPv4 \u0430\u0434\u0440\u0430\u0441\",\n ipv6: \"IPv6 \u0430\u0434\u0440\u0430\u0441\",\n mac: \"MAC \u0430\u0434\u0440\u0430\u0441\",\n cidrv4: \"IPv4 \u0434\u044B\u044F\u043F\u0430\u0437\u043E\u043D\",\n cidrv6: \"IPv6 \u0434\u044B\u044F\u043F\u0430\u0437\u043E\u043D\",\n base64: \"\u0440\u0430\u0434\u043E\u043A \u0443 \u0444\u0430\u0440\u043C\u0430\u0446\u0435 base64\",\n base64url: \"\u0440\u0430\u0434\u043E\u043A \u0443 \u0444\u0430\u0440\u043C\u0430\u0446\u0435 base64url\",\n json_string: \"JSON \u0440\u0430\u0434\u043E\u043A\",\n e164: \"\u043D\u0443\u043C\u0430\u0440 E.164\",\n credit_card: \"\u043D\u0443\u043C\u0430\u0440 \u043A\u0440\u044D\u0434\u044B\u0442\u043D\u0430\u0439 \u043A\u0430\u0440\u0442\u044B\",\n currency_code: \"\u043A\u043E\u0434 \u0432\u0430\u043B\u044E\u0442\u044B\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0443\u0432\u043E\u0434\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u043B\u0456\u043A\",\n array: \"\u043C\u0430\u0441\u0456\u045E\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u045E\u0432\u043E\u0434: \u0447\u0430\u043A\u0430\u045E\u0441\u044F instanceof ${issue.expected}, \u0430\u0442\u0440\u044B\u043C\u0430\u043D\u0430 ${received}`;\n }\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u045E\u0432\u043E\u0434: \u0447\u0430\u043A\u0430\u045E\u0441\u044F ${expected}, \u0430\u0442\u0440\u044B\u043C\u0430\u043D\u0430 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u045E\u0432\u043E\u0434: \u0447\u0430\u043A\u0430\u043B\u0430\u0441\u044F ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u0432\u0430\u0440\u044B\u044F\u043D\u0442: \u0447\u0430\u043A\u0430\u045E\u0441\u044F \u0430\u0434\u0437\u0456\u043D \u0437 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n const maxValue = Number(issue.maximum);\n const unit = getBelarusianPlural(maxValue, sizing.unit.one, sizing.unit.few, sizing.unit.many);\n return `\u0417\u0430\u043D\u0430\u0434\u0442\u0430 \u0432\u044F\u043B\u0456\u043A\u0456: \u0447\u0430\u043A\u0430\u043B\u0430\u0441\u044F, \u0448\u0442\u043E ${issue.origin ?? \"\u0437\u043D\u0430\u0447\u044D\u043D\u043D\u0435\"} \u043F\u0430\u0432\u0456\u043D\u043D\u0430 ${sizing.verb} ${adj}${issue.maximum.toString()} ${unit}`;\n }\n return `\u0417\u0430\u043D\u0430\u0434\u0442\u0430 \u0432\u044F\u043B\u0456\u043A\u0456: \u0447\u0430\u043A\u0430\u043B\u0430\u0441\u044F, \u0448\u0442\u043E ${issue.origin ?? \"\u0437\u043D\u0430\u0447\u044D\u043D\u043D\u0435\"} \u043F\u0430\u0432\u0456\u043D\u043D\u0430 \u0431\u044B\u0446\u044C ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n const minValue = Number(issue.minimum);\n const unit = getBelarusianPlural(minValue, sizing.unit.one, sizing.unit.few, sizing.unit.many);\n return `\u0417\u0430\u043D\u0430\u0434\u0442\u0430 \u043C\u0430\u043B\u044B: \u0447\u0430\u043A\u0430\u043B\u0430\u0441\u044F, \u0448\u0442\u043E ${issue.origin} \u043F\u0430\u0432\u0456\u043D\u043D\u0430 ${sizing.verb} ${adj}${issue.minimum.toString()} ${unit}`;\n }\n return `\u0417\u0430\u043D\u0430\u0434\u0442\u0430 \u043C\u0430\u043B\u044B: \u0447\u0430\u043A\u0430\u043B\u0430\u0441\u044F, \u0448\u0442\u043E ${issue.origin} \u043F\u0430\u0432\u0456\u043D\u043D\u0430 \u0431\u044B\u0446\u044C ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u0440\u0430\u0434\u043E\u043A: \u043F\u0430\u0432\u0456\u043D\u0435\u043D \u043F\u0430\u0447\u044B\u043D\u0430\u0446\u0446\u0430 \u0437 \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u0440\u0430\u0434\u043E\u043A: \u043F\u0430\u0432\u0456\u043D\u0435\u043D \u0437\u0430\u043A\u0430\u043D\u0447\u0432\u0430\u0446\u0446\u0430 \u043D\u0430 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u0440\u0430\u0434\u043E\u043A: \u043F\u0430\u0432\u0456\u043D\u0435\u043D \u0437\u043C\u044F\u0448\u0447\u0430\u0446\u044C \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u0440\u0430\u0434\u043E\u043A: \u043F\u0430\u0432\u0456\u043D\u0435\u043D \u0430\u0434\u043F\u0430\u0432\u044F\u0434\u0430\u0446\u044C \u0448\u0430\u0431\u043B\u043E\u043D\u0443 ${_issue.pattern}`;\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u043B\u0456\u043A: \u043F\u0430\u0432\u0456\u043D\u0435\u043D \u0431\u044B\u0446\u044C \u043A\u0440\u0430\u0442\u043D\u044B\u043C ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u041D\u0435\u0440\u0430\u0441\u043F\u0430\u0437\u043D\u0430\u043D\u044B ${issue.keys.length > 1 ? \"\u043A\u043B\u044E\u0447\u044B\" : \"\u043A\u043B\u044E\u0447\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u043A\u043B\u044E\u0447 \u0443 ${issue.origin}`;\n case \"invalid_union\":\n return \"\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u045E\u0432\u043E\u0434\";\n case \"invalid_element\":\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u0430\u0435 \u0437\u043D\u0430\u0447\u044D\u043D\u043D\u0435 \u045E ${issue.origin}`;\n default:\n return `\u041D\u044F\u043F\u0440\u0430\u0432\u0456\u043B\u044C\u043D\u044B \u045E\u0432\u043E\u0434`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0441\u0438\u043C\u0432\u043E\u043B\u0430\", verb: \"\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\" },\n file: { unit: \"\u0431\u0430\u0439\u0442\u0430\", verb: \"\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\" },\n array: { unit: \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0430\", verb: \"\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\" },\n set: { unit: \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0430\", verb: \"\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\" },\n map: { unit: \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0430\", verb: \"\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0432\u0445\u043E\u0434\",\n email: \"\u0438\u043C\u0435\u0439\u043B \u0430\u0434\u0440\u0435\u0441\",\n url: \"URL\",\n emoji: \"\u0435\u043C\u043E\u0434\u0436\u0438\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0432\u0440\u0435\u043C\u0435\",\n date: \"ISO \u0434\u0430\u0442\u0430\",\n time: \"ISO \u0432\u0440\u0435\u043C\u0435\",\n duration: \"ISO \u043F\u0440\u043E\u0434\u044A\u043B\u0436\u0438\u0442\u0435\u043B\u043D\u043E\u0441\u0442\",\n ipv4: \"IPv4 \u0430\u0434\u0440\u0435\u0441\",\n ipv6: \"IPv6 \u0430\u0434\u0440\u0435\u0441\",\n mac: \"MAC \u0430\u0434\u0440\u0435\u0441\",\n cidrv4: \"IPv4 \u0434\u0438\u0430\u043F\u0430\u0437\u043E\u043D\",\n cidrv6: \"IPv6 \u0434\u0438\u0430\u043F\u0430\u0437\u043E\u043D\",\n base64: \"base64-\u043A\u043E\u0434\u0438\u0440\u0430\u043D \u043D\u0438\u0437\",\n base64url: \"base64url-\u043A\u043E\u0434\u0438\u0440\u0430\u043D \u043D\u0438\u0437\",\n json_string: \"JSON \u043D\u0438\u0437\",\n e164: \"E.164 \u043D\u043E\u043C\u0435\u0440\",\n credit_card: \"\u043D\u043E\u043C\u0435\u0440 \u043D\u0430 \u043A\u0440\u0435\u0434\u0438\u0442\u043D\u0430 \u043A\u0430\u0440\u0442\u0430\",\n currency_code: \"\u043A\u043E\u0434 \u043D\u0430 \u0432\u0430\u043B\u0443\u0442\u0430\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0432\u0445\u043E\u0434\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0447\u0438\u0441\u043B\u043E\",\n array: \"\u043C\u0430\u0441\u0438\u0432\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u0432\u0445\u043E\u0434: \u043E\u0447\u0430\u043A\u0432\u0430\u043D instanceof ${issue.expected}, \u043F\u043E\u043B\u0443\u0447\u0435\u043D ${received}`;\n }\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u0432\u0445\u043E\u0434: \u043E\u0447\u0430\u043A\u0432\u0430\u043D ${expected}, \u043F\u043E\u043B\u0443\u0447\u0435\u043D ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u0432\u0445\u043E\u0434: \u043E\u0447\u0430\u043A\u0432\u0430\u043D ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u0430 \u043E\u043F\u0446\u0438\u044F: \u043E\u0447\u0430\u043A\u0432\u0430\u043D\u043E \u0435\u0434\u043D\u043E \u043E\u0442 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0422\u0432\u044A\u0440\u0434\u0435 \u0433\u043E\u043B\u044F\u043C\u043E: \u043E\u0447\u0430\u043A\u0432\u0430 \u0441\u0435 ${issue.origin ?? \"\u0441\u0442\u043E\u0439\u043D\u043E\u0441\u0442\"} \u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430 ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0430\"}`;\n return `\u0422\u0432\u044A\u0440\u0434\u0435 \u0433\u043E\u043B\u044F\u043C\u043E: \u043E\u0447\u0430\u043A\u0432\u0430 \u0441\u0435 ${issue.origin ?? \"\u0441\u0442\u043E\u0439\u043D\u043E\u0441\u0442\"} \u0434\u0430 \u0431\u044A\u0434\u0435 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0422\u0432\u044A\u0440\u0434\u0435 \u043C\u0430\u043B\u043A\u043E: \u043E\u0447\u0430\u043A\u0432\u0430 \u0441\u0435 ${issue.origin} \u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430 ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u0422\u0432\u044A\u0440\u0434\u0435 \u043C\u0430\u043B\u043A\u043E: \u043E\u0447\u0430\u043A\u0432\u0430 \u0441\u0435 ${issue.origin} \u0434\u0430 \u0431\u044A\u0434\u0435 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u043D\u0438\u0437: \u0442\u0440\u044F\u0431\u0432\u0430 \u0434\u0430 \u0437\u0430\u043F\u043E\u0447\u0432\u0430 \u0441 \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u043D\u0438\u0437: \u0442\u0440\u044F\u0431\u0432\u0430 \u0434\u0430 \u0437\u0430\u0432\u044A\u0440\u0448\u0432\u0430 \u0441 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u043D\u0438\u0437: \u0442\u0440\u044F\u0431\u0432\u0430 \u0434\u0430 \u0432\u043A\u043B\u044E\u0447\u0432\u0430 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u043D\u0438\u0437: \u0442\u0440\u044F\u0431\u0432\u0430 \u0434\u0430 \u0441\u044A\u0432\u043F\u0430\u0434\u0430 \u0441 ${_issue.pattern}`;\n let invalid_adj = \"\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D\";\n if (_issue.format === \"emoji\")\n invalid_adj = \"\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u043E\";\n if (_issue.format === \"datetime\")\n invalid_adj = \"\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u043E\";\n if (_issue.format === \"date\")\n invalid_adj = \"\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u0430\";\n if (_issue.format === \"time\")\n invalid_adj = \"\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u043E\";\n if (_issue.format === \"duration\")\n invalid_adj = \"\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u0430\";\n return `${invalid_adj} ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u043E \u0447\u0438\u0441\u043B\u043E: \u0442\u0440\u044F\u0431\u0432\u0430 \u0434\u0430 \u0431\u044A\u0434\u0435 \u043A\u0440\u0430\u0442\u043D\u043E \u043D\u0430 ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u041D\u0435\u0440\u0430\u0437\u043F\u043E\u0437\u043D\u0430\u0442${issue.keys.length > 1 ? \"\u0438\" : \"\"} \u043A\u043B\u044E\u0447${issue.keys.length > 1 ? \"\u043E\u0432\u0435\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u043A\u043B\u044E\u0447 \u0432 ${issue.origin}`;\n case \"invalid_union\":\n return \"\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u0432\u0445\u043E\u0434\";\n case \"invalid_element\":\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u0430 \u0441\u0442\u043E\u0439\u043D\u043E\u0441\u0442 \u0432 ${issue.origin}`;\n default:\n return `\u041D\u0435\u0432\u0430\u043B\u0438\u0434\u0435\u043D \u0432\u0445\u043E\u0434`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0985\u0995\u09CD\u09B7\u09B0\", verb: \"\u09A5\u09BE\u0995\u09A4\u09C7 \u09B9\u09AC\u09C7\" },\n file: { unit: \"\u09AC\u09BE\u0987\u099F\", verb: \"\u09A5\u09BE\u0995\u09A4\u09C7 \u09B9\u09AC\u09C7\" },\n array: { unit: \"\u0986\u0987\u099F\u09C7\u09AE\", verb: \"\u09A5\u09BE\u0995\u09A4\u09C7 \u09B9\u09AC\u09C7\" },\n set: { unit: \"\u0986\u0987\u099F\u09C7\u09AE\", verb: \"\u09A5\u09BE\u0995\u09A4\u09C7 \u09B9\u09AC\u09C7\" },\n map: { unit: \"\u098F\u09A8\u09CD\u099F\u09CD\u09B0\u09BF\", verb: \"\u09A5\u09BE\u0995\u09A4\u09C7 \u09B9\u09AC\u09C7\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0987\u09A8\u09AA\u09C1\u099F\",\n email: \"\u0987\u09AE\u09C7\u0987\u09B2 \u09A0\u09BF\u0995\u09BE\u09A8\u09BE\",\n url: \"URL\",\n emoji: \"\u0987\u09AE\u09CB\u099C\u09BF\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u09A4\u09BE\u09B0\u09BF\u0996 \u0993 \u09B8\u09AE\u09AF\u09BC\",\n date: \"ISO \u09A4\u09BE\u09B0\u09BF\u0996\",\n time: \"ISO \u09B8\u09AE\u09AF\u09BC\",\n duration: \"ISO \u09B8\u09AE\u09AF\u09BC\u0995\u09BE\u09B2\",\n ipv4: \"IPv4 \u09A0\u09BF\u0995\u09BE\u09A8\u09BE\",\n ipv6: \"IPv6 \u09A0\u09BF\u0995\u09BE\u09A8\u09BE\",\n mac: \"MAC \u09A0\u09BF\u0995\u09BE\u09A8\u09BE\",\n cidrv4: \"IPv4 \u09B0\u09C7\u099E\u09CD\u099C\",\n cidrv6: \"IPv6 \u09B0\u09C7\u099E\u09CD\u099C\",\n base64: \"base64-\u098F\u09A8\u0995\u09CB\u09A1\u09C7\u09A1 \u09B8\u09CD\u099F\u09CD\u09B0\u09BF\u0982\",\n base64url: \"base64url-\u098F\u09A8\u0995\u09CB\u09A1\u09C7\u09A1 \u09B8\u09CD\u099F\u09CD\u09B0\u09BF\u0982\",\n json_string: \"JSON \u09B8\u09CD\u099F\u09CD\u09B0\u09BF\u0982\",\n e164: \"E.164 \u09A8\u09AE\u09CD\u09AC\u09B0\",\n credit_card: \"\u0995\u09CD\u09B0\u09C7\u09A1\u09BF\u099F \u0995\u09BE\u09B0\u09CD\u09A1 \u09A8\u09AE\u09CD\u09AC\u09B0\",\n currency_code: \"\u09AE\u09C1\u09A6\u09CD\u09B0\u09BE \u0995\u09CB\u09A1\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0987\u09A8\u09AA\u09C1\u099F\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n return `\u0985\u09AC\u09C8\u09A7 \u0987\u09A8\u09AA\u09C1\u099F: \u09AA\u09CD\u09B0\u09A4\u09CD\u09AF\u09BE\u09B6\u09BF\u09A4 ${expected}, \u09AA\u09CD\u09B0\u09BE\u09AA\u09CD\u09A4 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0985\u09AC\u09C8\u09A7 \u0987\u09A8\u09AA\u09C1\u099F: \u09AA\u09CD\u09B0\u09A4\u09CD\u09AF\u09BE\u09B6\u09BF\u09A4 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0985\u09AC\u09C8\u09A7 \u0985\u09AA\u09B6\u09A8: ${util.joinValues(issue.values, \" | \")} \u098F\u09B0 \u09AE\u09A7\u09CD\u09AF\u09C7 \u098F\u0995\u099F\u09BF \u09AA\u09CD\u09B0\u09A4\u09CD\u09AF\u09BE\u09B6\u09BF\u09A4`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0985\u09A8\u09C7\u0995 \u09AC\u09A1\u09BC: ${issue.origin ?? \"\u09AE\u09BE\u09A8\"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u098F\u09B2\u09BF\u09AE\u09C7\u09A8\u09CD\u099F\"} \u09B9\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n return `\u0985\u09A8\u09C7\u0995 \u09AC\u09A1\u09BC: ${issue.origin ?? \"\u09AE\u09BE\u09A8\"} ${adj}${issue.maximum.toString()} \u09B9\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0985\u09A8\u09C7\u0995 \u099B\u09CB\u099F: ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} \u09B9\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n }\n return `\u0985\u09A8\u09C7\u0995 \u099B\u09CB\u099F: ${issue.origin} ${adj}${issue.minimum.toString()} \u09B9\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u0985\u09AC\u09C8\u09A7 \u09B8\u09CD\u099F\u09CD\u09B0\u09BF\u0982: \"${_issue.prefix}\" \u09A6\u09BF\u09AF\u09BC\u09C7 \u09B6\u09C1\u09B0\u09C1 \u09B9\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n }\n if (_issue.format === \"ends_with\")\n return `\u0985\u09AC\u09C8\u09A7 \u09B8\u09CD\u099F\u09CD\u09B0\u09BF\u0982: \"${_issue.suffix}\" \u09A6\u09BF\u09AF\u09BC\u09C7 \u09B6\u09C7\u09B7 \u09B9\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n if (_issue.format === \"includes\")\n return `\u0985\u09AC\u09C8\u09A7 \u09B8\u09CD\u099F\u09CD\u09B0\u09BF\u0982: \"${_issue.includes}\" \u0985\u09A8\u09CD\u09A4\u09B0\u09CD\u09AD\u09C1\u0995\u09CD\u09A4 \u09A5\u09BE\u0995\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n if (_issue.format === \"regex\")\n return `\u0985\u09AC\u09C8\u09A7 \u09B8\u09CD\u099F\u09CD\u09B0\u09BF\u0982: ${_issue.pattern} \u09AA\u09CD\u09AF\u09BE\u099F\u09BE\u09B0\u09CD\u09A8 \u09AE\u09BF\u09B2\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n return `\u0985\u09AC\u09C8\u09A7 ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u0985\u09AC\u09C8\u09A7 \u09A8\u09AE\u09CD\u09AC\u09B0: ${issue.divisor} \u098F\u09B0 \u0997\u09C1\u09A3\u09BF\u09A4\u0995 \u09B9\u09A4\u09C7 \u09B9\u09AC\u09C7`;\n case \"unrecognized_keys\":\n return `\u0985\u099A\u09C7\u09A8\u09BE \u0995\u09C0${issue.keys.length > 1 ? \"\u0997\u09C1\u09B2\u09CB\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} \u098F \u0985\u09AC\u09C8\u09A7 \u0995\u09C0`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `\u0985\u09AC\u09C8\u09A7 \u09A1\u09BF\u09B8\u0995\u09CD\u09B0\u09BF\u09AE\u09BF\u09A8\u09C7\u099F\u09B0 \u09AE\u09BE\u09A8\u0964 \u09AA\u09CD\u09B0\u09A4\u09CD\u09AF\u09BE\u09B6\u09BF\u09A4 ${opts}`;\n }\n return \"\u0985\u09AC\u09C8\u09A7 \u0987\u09A8\u09AA\u09C1\u099F\";\n case \"invalid_element\":\n return `${issue.origin} \u098F \u0985\u09AC\u09C8\u09A7 \u09AE\u09BE\u09A8`;\n default:\n return \"\u0985\u09AC\u09C8\u09A7 \u0987\u09A8\u09AA\u09C1\u099F\";\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"car\u00E0cters\", verb: \"contenir\" },\n file: { unit: \"bytes\", verb: \"contenir\" },\n array: { unit: \"elements\", verb: \"contenir\" },\n set: { unit: \"elements\", verb: \"contenir\" },\n map: { unit: \"elements\", verb: \"contenir\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"entrada\",\n email: \"adre\u00E7a electr\u00F2nica\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"data i hora ISO\",\n date: \"data ISO\",\n time: \"hora ISO\",\n duration: \"durada ISO\",\n ipv4: \"adre\u00E7a IPv4\",\n ipv6: \"adre\u00E7a IPv6\",\n mac: \"adre\u00E7a MAC\",\n cidrv4: \"rang IPv4\",\n cidrv6: \"rang IPv6\",\n base64: \"cadena codificada en base64\",\n base64url: \"cadena codificada en base64url\",\n json_string: \"cadena JSON\",\n e164: \"n\u00FAmero E.164\",\n credit_card: \"n\u00FAmero de targeta de cr\u00E8dit\",\n currency_code: \"codi de moneda\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"entrada\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Tipus inv\u00E0lid: s'esperava instanceof ${issue.expected}, s'ha rebut ${received}`;\n }\n return `Tipus inv\u00E0lid: s'esperava ${expected}, s'ha rebut ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Valor inv\u00E0lid: s'esperava ${util.stringifyPrimitive(issue.values[0])}`;\n return `Opci\u00F3 inv\u00E0lida: s'esperava una de ${util.joinValues(issue.values, \" o \")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"com a m\u00E0xim\" : \"menys de\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Massa gran: s'esperava que ${issue.origin ?? \"el valor\"} contingu\u00E9s ${adj} ${issue.maximum.toString()} ${sizing.unit ?? \"elements\"}`;\n return `Massa gran: s'esperava que ${issue.origin ?? \"el valor\"} fos ${adj} ${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \"com a m\u00EDnim\" : \"m\u00E9s de\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Massa petit: s'esperava que ${issue.origin} contingu\u00E9s ${adj} ${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Massa petit: s'esperava que ${issue.origin} fos ${adj} ${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `Format inv\u00E0lid: ha de comen\u00E7ar amb \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `Format inv\u00E0lid: ha d'acabar amb \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Format inv\u00E0lid: ha d'incloure \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Format inv\u00E0lid: ha de coincidir amb el patr\u00F3 ${_issue.pattern}`;\n return `Format inv\u00E0lid per a ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `N\u00FAmero inv\u00E0lid: ha de ser m\u00FAltiple de ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Clau${issue.keys.length > 1 ? \"s\" : \"\"} no reconeguda${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Clau inv\u00E0lida a ${issue.origin}`;\n case \"invalid_union\":\n return \"Entrada inv\u00E0lida\"; // Could also be \"Tipus d'uni\u00F3 inv\u00E0lid\" but \"Entrada inv\u00E0lida\" is more general\n case \"invalid_element\":\n return `Element inv\u00E0lid a ${issue.origin}`;\n default:\n return `Entrada inv\u00E0lida`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u067E\u06CC\u062A\", verb: \"\u0628\u06CE\u062A\" },\n file: { unit: \"\u0628\u0627\u06CC\u062A\", verb: \"\u0628\u06CE\u062A\" },\n array: { unit: \"\u062F\u0627\u0646\u06D5\", verb: \"\u0628\u06CE\u062A\" },\n set: { unit: \"\u062F\u0627\u0646\u06D5\", verb: \"\u0628\u06CE\u062A\" },\n map: { unit: \"\u062F\u0627\u0646\u06D5\", verb: \"\u0628\u06CE\u062A\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"regex\",\n email: \"\u0626\u06CC\u0645\u06D5\u06CC\u06B5\",\n url: \"\u0628\u06D5\u0633\u062A\u06D5\u0631 (URL)\",\n emoji: \"\u0626\u06CC\u0645\u06C6\u062C\u06CC\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u0695\u06CE\u06A9\u06D5\u0648\u062A \u0648 \u06A9\u0627\u062A\",\n date: \"\u0695\u06CE\u06A9\u06D5\u0648\u062A\",\n time: \"\u06A9\u0627\u062A\",\n duration: \"\u0645\u0627\u0648\u06D5\",\n ipv4: \"\u0646\u0627\u0648\u0646\u06CC\u0634\u0627\u0646\u06CC IPv4\",\n ipv6: \"\u0646\u0627\u0648\u0646\u06CC\u0634\u0627\u0646\u06CC IPv6\",\n mac: \"\u0646\u0627\u0648\u0646\u06CC\u0634\u0627\u0646\u06CC MAC\",\n cidrv4: \"\u0645\u06D5\u0648\u062F\u0627\u06CC IPv4\",\n cidrv6: \"\u0645\u06D5\u0648\u062F\u0627\u06CC IPv6\",\n base64: \"\u062F\u06D5\u0642\u06CC base64\",\n base64url: \"\u062F\u06D5\u0642\u06CC base64url\",\n json_string: \"\u062F\u06D5\u0642\u06CC JSON\",\n e164: \"\u0698\u0645\u0627\u0631\u06D5\u06CC E.164\",\n credit_card: \"\u0698\u0645\u0627\u0631\u06D5\u06CC \u06A9\u0627\u0631\u062A\u06CC \u06A9\u0631\u06CE\u062F\u06CC\u062A\",\n currency_code: \"\u06A9\u06C6\u062F\u06CC \u062F\u0631\u0627\u0648\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u062A\u06CE\u06A9\u0631\u062F\u06D5\",\n };\n // type names: missing keys = do not translate (use raw value via ?? fallback)\n const TypeDictionary = {\n nan: \"NaN\",\n string: \"\u0646\u0648\u0648\u0633\u06CC\u0646\",\n number: \"\u0698\u0645\u0627\u0631\u06D5\",\n boolean: \"boolean\",\n array: \"array\",\n object: \"object\",\n date: \"\u0695\u06CE\u06A9\u06D5\u0648\u062A\",\n integer: \"\u0698\u0645\u0627\u0631\u06D5\",\n float: \"\u0698\u0645\u0627\u0631\u06D5\",\n null: \"null\",\n undefined: \"undefined\",\n function: \"function\",\n symbol: \"symbol\",\n unknown: \"unknown\",\n promise: \"promise\",\n void: \"void\",\n never: \"never\",\n map: \"map\",\n set: \"set\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n const postfix = [\"\u0627\", \"\u0648\", \"\u06C6\", \"\u0648\u0648\", \"\u06D5\", \"\u06CC\", \"\u06CE\"].some((p) => received.endsWith(p)) ? \"\u06CC\u06D5\" : \"\u06D5\";\n const isEnglish = /^[a-zA-Z]+$/.test(received);\n if (receivedType === \"null\" || receivedType === \"undefined\")\n return `\u062F\u0627\u0648\u0627\u06A9\u0631\u0627\u0648\u06D5`;\n return `\u0686\u0627\u0648\u06D5\u0695\u0648\u0627\u0646\u06A9\u0631\u0627\u0648\u06D5 ${expected} \u0628\u06CE\u062A\u060C \u0628\u06D5\u06B5\u0627\u0645 ${received}${isEnglish ? \"\" : postfix}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0628\u06D5\u0647\u0627\u06A9\u06D5 \u0646\u0627\u062F\u0631\u0648\u0648\u0633\u062A\u06D5: \u0686\u0627\u0648\u06D5\u0695\u0648\u0627\u0646\u06A9\u0631\u0627\u0648\u06D5 ${util.stringifyPrimitive(issue.values[0])} \u0628\u06CE\u062A`;\n return `\u0647\u06D5\u06B5\u0628\u0698\u0627\u0631\u062F\u06D5\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A: \u0686\u0627\u0648\u06D5\u0695\u0648\u0627\u0646\u06A9\u0631\u0627\u0648\u06D5 \u06CC\u06D5\u06A9\u06CE\u06A9 \u0628\u06CE\u062A \u0644\u06D5 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u067E\u06CE\u0648\u06CC\u0633\u062A\u06D5 \u0628\u06D5 \u0644\u0627\u06CC\u06D5\u0646\u06CC \u0632\u06C6\u0631\u06D5\u0648\u06D5 ${issue.maximum.toString()} ${sizing.unit} ${sizing.verb}`;\n return `\u067E\u06CE\u0648\u06CC\u0633\u062A\u06D5 \u0628\u06D5 \u0644\u0627\u06CC\u06D5\u0646\u06CC \u0632\u06C6\u0631\u06D5\u0648\u06D5 ${issue.maximum.toString()} \u0628\u06CE\u062A`;\n }\n case \"too_small\": {\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u067E\u06CE\u0648\u06CC\u0633\u062A\u06D5 \u0628\u06D5 \u0644\u0627\u06CC\u06D5\u0646\u06CC \u06A9\u06D5\u0645\u06D5\u0648\u06D5 ${issue.minimum.toString()} ${sizing.unit} ${sizing.verb}`;\n return `\u067E\u06CE\u0648\u06CC\u0633\u062A\u06D5 \u0628\u06D5 \u0644\u0627\u06CC\u06D5\u0646\u06CC \u06A9\u06D5\u0645\u06D5\u0648\u06D5 ${issue.minimum.toString()} \u0628\u06CE\u062A`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u062F\u06D5\u0642\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A: \u067E\u06CE\u0648\u06CC\u0633\u062A\u06D5 \u062F\u06D5\u0633\u062A\u067E\u06CE\u0628\u06A9\u0627\u062A \u0628\u06D5 \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u062F\u06D5\u0642\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A: \u067E\u06CE\u0648\u06CC\u0633\u062A\u06D5 \u06A9\u06C6\u062A\u0627\u06CC\u06CC\u0628\u06CE\u062A \u0628\u06D5 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u062F\u06D5\u0642\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A: \u067E\u06CE\u0648\u06CC\u0633\u062A\u06D5 \"${_issue.includes}\" \u0644\u06D5\u062E\u06C6\u0628\u06AF\u0631\u06CE\u062A`;\n if (_issue.format === \"regex\")\n return `\u062F\u06D5\u0642\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A: \u067E\u06CE\u0648\u06CC\u0633\u062A\u06D5 \u0644\u06D5\u06AF\u06D5\u06B5 \u067E\u0627\u062A\u06CE\u0631\u0646\u06CC ${_issue.pattern} \u0628\u06AF\u0648\u0646\u062C\u06CE\u062A`;\n return `\u0628\u06D5\u0647\u0627\u06CC ${FormatDictionary[_issue.format] ?? issue.format} \u0646\u0627\u062F\u0631\u0648\u0633\u062A\u06D5`;\n }\n case \"not_multiple_of\":\n return `\u0698\u0645\u0627\u0631\u06D5\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A: \u062F\u06D5\u0628\u06CE\u062A \u0686\u06D5\u0646\u062F \u0647\u06CE\u0646\u062F\u06D5 \u0628\u06CE\u062A \u0628\u06C6 ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u06A9\u0644\u06CC\u0644\u06CC \u0646\u06D5\u0646\u0627\u0633\u0631\u0627\u0648: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u06A9\u0644\u06CC\u0644\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A \u0644\u06D5 ${issue.origin}`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `\u0628\u06D5\u0647\u0627\u06CC \u0646\u06D5\u0646\u0627\u0633\u0631\u0627\u0648 \u0647\u06D5\u06CC\u06D5. \u0628\u06D5\u0647\u0627\u06CC \u0686\u0627\u0648\u06D5\u0695\u0648\u0627\u0646\u06A9\u0631\u0627\u0648: ${opts}`;\n }\n return \"\u06CC\u06D5\u06A9\u06AF\u0631\u062A\u0646\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A\";\n case \"invalid_element\":\n return `${issue.origin} \u0628\u06D5\u0647\u0627\u06A9\u06D5 \u0646\u0627\u062F\u0631\u0648\u0633\u062A\u06D5`;\n default:\n return `\u062A\u06CE\u06A9\u0631\u062F\u06D5\u06CC \u0646\u0627\u062F\u0631\u0648\u0633\u062A`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"znak\u016F\", verb: \"m\u00EDt\" },\n file: { unit: \"bajt\u016F\", verb: \"m\u00EDt\" },\n array: { unit: \"prvk\u016F\", verb: \"m\u00EDt\" },\n set: { unit: \"prvk\u016F\", verb: \"m\u00EDt\" },\n map: { unit: \"prvk\u016F\", verb: \"m\u00EDt\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"regul\u00E1rn\u00ED v\u00FDraz\",\n email: \"e-mailov\u00E1 adresa\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"datum a \u010Das ve form\u00E1tu ISO\",\n date: \"datum ve form\u00E1tu ISO\",\n time: \"\u010Das ve form\u00E1tu ISO\",\n duration: \"doba trv\u00E1n\u00ED ISO\",\n ipv4: \"IPv4 adresa\",\n ipv6: \"IPv6 adresa\",\n mac: \"MAC adresa\",\n cidrv4: \"rozsah IPv4\",\n cidrv6: \"rozsah IPv6\",\n base64: \"\u0159et\u011Bzec zak\u00F3dovan\u00FD ve form\u00E1tu base64\",\n base64url: \"\u0159et\u011Bzec zak\u00F3dovan\u00FD ve form\u00E1tu base64url\",\n json_string: \"\u0159et\u011Bzec ve form\u00E1tu JSON\",\n e164: \"\u010D\u00EDslo E.164\",\n credit_card: \"\u010D\u00EDslo kreditn\u00ED karty\",\n currency_code: \"k\u00F3d m\u011Bny\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"vstup\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u010D\u00EDslo\",\n string: \"\u0159et\u011Bzec\",\n function: \"funkce\",\n array: \"pole\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Neplatn\u00FD vstup: o\u010Dek\u00E1v\u00E1no instanceof ${issue.expected}, obdr\u017Eeno ${received}`;\n }\n return `Neplatn\u00FD vstup: o\u010Dek\u00E1v\u00E1no ${expected}, obdr\u017Eeno ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Neplatn\u00FD vstup: o\u010Dek\u00E1v\u00E1no ${util.stringifyPrimitive(issue.values[0])}`;\n return `Neplatn\u00E1 mo\u017Enost: o\u010Dek\u00E1v\u00E1na jedna z hodnot ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Hodnota je p\u0159\u00EDli\u0161 velk\u00E1: ${issue.origin ?? \"hodnota\"} mus\u00ED m\u00EDt ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"prvk\u016F\"}`;\n }\n return `Hodnota je p\u0159\u00EDli\u0161 velk\u00E1: ${issue.origin ?? \"hodnota\"} mus\u00ED b\u00FDt ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Hodnota je p\u0159\u00EDli\u0161 mal\u00E1: ${issue.origin ?? \"hodnota\"} mus\u00ED m\u00EDt ${adj}${issue.minimum.toString()} ${sizing.unit ?? \"prvk\u016F\"}`;\n }\n return `Hodnota je p\u0159\u00EDli\u0161 mal\u00E1: ${issue.origin ?? \"hodnota\"} mus\u00ED b\u00FDt ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Neplatn\u00FD \u0159et\u011Bzec: mus\u00ED za\u010D\u00EDnat na \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Neplatn\u00FD \u0159et\u011Bzec: mus\u00ED kon\u010Dit na \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Neplatn\u00FD \u0159et\u011Bzec: mus\u00ED obsahovat \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Neplatn\u00FD \u0159et\u011Bzec: mus\u00ED odpov\u00EDdat vzoru ${_issue.pattern}`;\n return `Neplatn\u00FD form\u00E1t ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Neplatn\u00E9 \u010D\u00EDslo: mus\u00ED b\u00FDt n\u00E1sobkem ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Nezn\u00E1m\u00E9 kl\u00ED\u010De: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Neplatn\u00FD kl\u00ED\u010D v ${issue.origin}`;\n case \"invalid_union\":\n return \"Neplatn\u00FD vstup\";\n case \"invalid_element\":\n return `Neplatn\u00E1 hodnota v ${issue.origin}`;\n default:\n return `Neplatn\u00FD vstup`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"tegn\", verb: \"havde\" },\n file: { unit: \"bytes\", verb: \"havde\" },\n array: { unit: \"elementer\", verb: \"indeholdt\" },\n set: { unit: \"elementer\", verb: \"indeholdt\" },\n map: { unit: \"elementer\", verb: \"indeholdt\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"input\",\n email: \"e-mailadresse\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO dato- og klokkesl\u00E6t\",\n date: \"ISO-dato\",\n time: \"ISO-klokkesl\u00E6t\",\n duration: \"ISO-varighed\",\n ipv4: \"IPv4-adresse\",\n ipv6: \"IPv6-adresse\",\n mac: \"MAC-adresse\",\n cidrv4: \"IPv4-spektrum\",\n cidrv6: \"IPv6-spektrum\",\n base64: \"base64-kodet streng\",\n base64url: \"base64url-kodet streng\",\n json_string: \"JSON-streng\",\n e164: \"E.164-nummer\",\n credit_card: \"kreditkortnummer\",\n currency_code: \"valutakode\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n string: \"streng\",\n number: \"tal\",\n boolean: \"boolean\",\n array: \"liste\",\n object: \"objekt\",\n set: \"s\u00E6t\",\n file: \"fil\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Ugyldigt input: forventede instanceof ${issue.expected}, fik ${received}`;\n }\n return `Ugyldigt input: forventede ${expected}, fik ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Ugyldig v\u00E6rdi: forventede ${util.stringifyPrimitive(issue.values[0])}`;\n return `Ugyldigt valg: forventede en af f\u00F8lgende ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n if (sizing)\n return `For stor: forventede ${origin ?? \"value\"} ${sizing.verb} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? \"elementer\"}`;\n return `For stor: forventede ${origin ?? \"value\"} havde ${adj} ${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n if (sizing) {\n return `For lille: forventede ${origin} ${sizing.verb} ${adj} ${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `For lille: forventede ${origin} havde ${adj} ${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Ugyldig streng: skal starte med \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Ugyldig streng: skal ende med \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Ugyldig streng: skal indeholde \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Ugyldig streng: skal matche m\u00F8nsteret ${_issue.pattern}`;\n return `Ugyldig ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Ugyldigt tal: skal v\u00E6re deleligt med ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `${issue.keys.length > 1 ? \"Ukendte n\u00F8gler\" : \"Ukendt n\u00F8gle\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Ugyldig n\u00F8gle i ${issue.origin}`;\n case \"invalid_union\":\n return \"Ugyldigt input: matcher ingen af de tilladte typer\";\n case \"invalid_element\":\n return `Ugyldig v\u00E6rdi i ${issue.origin}`;\n default:\n return `Ugyldigt input`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"Zeichen\", verb: \"zu haben\" },\n file: { unit: \"Bytes\", verb: \"zu haben\" },\n array: { unit: \"Elemente\", verb: \"zu haben\" },\n set: { unit: \"Elemente\", verb: \"zu haben\" },\n map: { unit: \"Elemente\", verb: \"zu haben\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"Eingabe\",\n email: \"E-Mail-Adresse\",\n url: \"URL\",\n emoji: \"Emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO-Datum und -Uhrzeit\",\n date: \"ISO-Datum\",\n time: \"ISO-Uhrzeit\",\n duration: \"ISO-Dauer\",\n ipv4: \"IPv4-Adresse\",\n ipv6: \"IPv6-Adresse\",\n mac: \"MAC-Adresse\",\n cidrv4: \"IPv4-Bereich\",\n cidrv6: \"IPv6-Bereich\",\n base64: \"Base64-codierter String\",\n base64url: \"Base64-URL-codierter String\",\n json_string: \"JSON-String\",\n e164: \"E.164-Nummer\",\n credit_card: \"Kreditkartennummer\",\n currency_code: \"W\u00E4hrungscode\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"Eingabe\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"Zahl\",\n array: \"Array\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Ung\u00FCltige Eingabe: erwartet instanceof ${issue.expected}, erhalten ${received}`;\n }\n return `Ung\u00FCltige Eingabe: erwartet ${expected}, erhalten ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Ung\u00FCltige Eingabe: erwartet ${util.stringifyPrimitive(issue.values[0])}`;\n return `Ung\u00FCltige Option: erwartet eine von ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Zu gro\u00DF: erwartet, dass ${issue.origin ?? \"Wert\"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"Elemente\"} hat`;\n return `Zu gro\u00DF: erwartet, dass ${issue.origin ?? \"Wert\"} ${adj}${issue.maximum.toString()} ist`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Zu klein: erwartet, dass ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} hat`;\n }\n return `Zu klein: erwartet, dass ${issue.origin} ${adj}${issue.minimum.toString()} ist`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Ung\u00FCltiger String: muss mit \"${_issue.prefix}\" beginnen`;\n if (_issue.format === \"ends_with\")\n return `Ung\u00FCltiger String: muss mit \"${_issue.suffix}\" enden`;\n if (_issue.format === \"includes\")\n return `Ung\u00FCltiger String: muss \"${_issue.includes}\" enthalten`;\n if (_issue.format === \"regex\")\n return `Ung\u00FCltiger String: muss dem Muster ${_issue.pattern} entsprechen`;\n return `Ung\u00FCltig: ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Ung\u00FCltige Zahl: muss ein Vielfaches von ${issue.divisor} sein`;\n case \"unrecognized_keys\":\n return `${issue.keys.length > 1 ? \"Unbekannte Schl\u00FCssel\" : \"Unbekannter Schl\u00FCssel\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Ung\u00FCltiger Schl\u00FCssel in ${issue.origin}`;\n case \"invalid_union\":\n return \"Ung\u00FCltige Eingabe\";\n case \"invalid_element\":\n return `Ung\u00FCltiger Wert in ${issue.origin}`;\n default:\n return `Ung\u00FCltige Eingabe`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03B5\u03C2\", verb: \"\u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9\" },\n file: { unit: \"bytes\", verb: \"\u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9\" },\n array: { unit: \"\u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03B1\", verb: \"\u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9\" },\n set: { unit: \"\u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03B1\", verb: \"\u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9\" },\n map: { unit: \"\u03BA\u03B1\u03C4\u03B1\u03C7\u03C9\u03C1\u03AE\u03C3\u03B5\u03B9\u03C2\", verb: \"\u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u03B5\u03AF\u03C3\u03BF\u03B4\u03BF\u03C2\",\n email: \"\u03B4\u03B9\u03B5\u03CD\u03B8\u03C5\u03BD\u03C3\u03B7 email\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u03B7\u03BC\u03B5\u03C1\u03BF\u03BC\u03B7\u03BD\u03AF\u03B1 \u03BA\u03B1\u03B9 \u03CE\u03C1\u03B1\",\n date: \"ISO \u03B7\u03BC\u03B5\u03C1\u03BF\u03BC\u03B7\u03BD\u03AF\u03B1\",\n time: \"ISO \u03CE\u03C1\u03B1\",\n duration: \"ISO \u03B4\u03B9\u03AC\u03C1\u03BA\u03B5\u03B9\u03B1\",\n ipv4: \"\u03B4\u03B9\u03B5\u03CD\u03B8\u03C5\u03BD\u03C3\u03B7 IPv4\",\n ipv6: \"\u03B4\u03B9\u03B5\u03CD\u03B8\u03C5\u03BD\u03C3\u03B7 IPv6\",\n mac: \"\u03B4\u03B9\u03B5\u03CD\u03B8\u03C5\u03BD\u03C3\u03B7 MAC\",\n cidrv4: \"\u03B5\u03CD\u03C1\u03BF\u03C2 IPv4\",\n cidrv6: \"\u03B5\u03CD\u03C1\u03BF\u03C2 IPv6\",\n base64: \"\u03C3\u03C5\u03BC\u03B2\u03BF\u03BB\u03BF\u03C3\u03B5\u03B9\u03C1\u03AC \u03BA\u03C9\u03B4\u03B9\u03BA\u03BF\u03C0\u03BF\u03B9\u03B7\u03BC\u03AD\u03BD\u03B7 \u03C3\u03B5 base64\",\n base64url: \"\u03C3\u03C5\u03BC\u03B2\u03BF\u03BB\u03BF\u03C3\u03B5\u03B9\u03C1\u03AC \u03BA\u03C9\u03B4\u03B9\u03BA\u03BF\u03C0\u03BF\u03B9\u03B7\u03BC\u03AD\u03BD\u03B7 \u03C3\u03B5 base64url\",\n json_string: \"\u03C3\u03C5\u03BC\u03B2\u03BF\u03BB\u03BF\u03C3\u03B5\u03B9\u03C1\u03AC JSON\",\n e164: \"\u03B1\u03C1\u03B9\u03B8\u03BC\u03CC\u03C2 E.164\",\n credit_card: \"\u03B1\u03C1\u03B9\u03B8\u03BC\u03CC\u03C2 \u03C0\u03B9\u03C3\u03C4\u03C9\u03C4\u03B9\u03BA\u03AE\u03C2 \u03BA\u03AC\u03C1\u03C4\u03B1\u03C2\",\n currency_code: \"\u03BA\u03C9\u03B4\u03B9\u03BA\u03CC\u03C2 \u03BD\u03BF\u03BC\u03AF\u03C3\u03BC\u03B1\u03C4\u03BF\u03C2\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u03B5\u03AF\u03C3\u03BF\u03B4\u03BF\u03C2\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (typeof issue.expected === \"string\" && /^[A-Z]/.test(issue.expected)) {\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03B5\u03AF\u03C3\u03BF\u03B4\u03BF\u03C2: \u03B1\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03C4\u03B1\u03BD instanceof ${issue.expected}, \u03BB\u03AE\u03C6\u03B8\u03B7\u03BA\u03B5 ${received}`;\n }\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03B5\u03AF\u03C3\u03BF\u03B4\u03BF\u03C2: \u03B1\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03C4\u03B1\u03BD ${expected}, \u03BB\u03AE\u03C6\u03B8\u03B7\u03BA\u03B5 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03B5\u03AF\u03C3\u03BF\u03B4\u03BF\u03C2: \u03B1\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03C4\u03B1\u03BD ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03B5\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE: \u03B1\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03C4\u03B1\u03BD \u03AD\u03BD\u03B1 \u03B1\u03C0\u03CC ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u03A0\u03BF\u03BB\u03CD \u03BC\u03B5\u03B3\u03AC\u03BB\u03BF: \u03B1\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03C4\u03B1\u03BD ${issue.origin ?? \"\u03C4\u03B9\u03BC\u03AE\"} \u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9 ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03B1\"}`;\n return `\u03A0\u03BF\u03BB\u03CD \u03BC\u03B5\u03B3\u03AC\u03BB\u03BF: \u03B1\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03C4\u03B1\u03BD ${issue.origin ?? \"\u03C4\u03B9\u03BC\u03AE\"} \u03BD\u03B1 \u03B5\u03AF\u03BD\u03B1\u03B9 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u03A0\u03BF\u03BB\u03CD \u03BC\u03B9\u03BA\u03C1\u03CC: \u03B1\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03C4\u03B1\u03BD ${issue.origin} \u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9 ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u03A0\u03BF\u03BB\u03CD \u03BC\u03B9\u03BA\u03C1\u03CC: \u03B1\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03C4\u03B1\u03BD ${issue.origin} \u03BD\u03B1 \u03B5\u03AF\u03BD\u03B1\u03B9 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03C3\u03C5\u03BC\u03B2\u03BF\u03BB\u03BF\u03C3\u03B5\u03B9\u03C1\u03AC: \u03C0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03BE\u03B5\u03BA\u03B9\u03BD\u03AC \u03BC\u03B5 \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03C3\u03C5\u03BC\u03B2\u03BF\u03BB\u03BF\u03C3\u03B5\u03B9\u03C1\u03AC: \u03C0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03C4\u03B5\u03BB\u03B5\u03B9\u03CE\u03BD\u03B5\u03B9 \u03BC\u03B5 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03C3\u03C5\u03BC\u03B2\u03BF\u03BB\u03BF\u03C3\u03B5\u03B9\u03C1\u03AC: \u03C0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03C0\u03B5\u03C1\u03B9\u03AD\u03C7\u03B5\u03B9 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03C3\u03C5\u03BC\u03B2\u03BF\u03BB\u03BF\u03C3\u03B5\u03B9\u03C1\u03AC: \u03C0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03C4\u03B1\u03B9\u03C1\u03B9\u03AC\u03B6\u03B5\u03B9 \u03BC\u03B5 \u03C4\u03BF \u03BC\u03BF\u03C4\u03AF\u03B2\u03BF ${_issue.pattern}`;\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03BF: ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03BF\u03C2 \u03B1\u03C1\u03B9\u03B8\u03BC\u03CC\u03C2: \u03C0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03B5\u03AF\u03BD\u03B1\u03B9 \u03C0\u03BF\u03BB\u03BB\u03B1\u03C0\u03BB\u03AC\u03C3\u03B9\u03BF \u03C4\u03BF\u03C5 ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u0386\u03B3\u03BD\u03C9\u03C3\u03C4${issue.keys.length > 1 ? \"\u03B1\" : \"\u03BF\"} \u03BA\u03BB\u03B5\u03B9\u03B4${issue.keys.length > 1 ? \"\u03B9\u03AC\" : \"\u03AF\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03BF \u03BA\u03BB\u03B5\u03B9\u03B4\u03AF \u03C3\u03C4\u03BF ${issue.origin}`;\n case \"invalid_union\":\n return \"\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03B5\u03AF\u03C3\u03BF\u03B4\u03BF\u03C2\";\n case \"invalid_element\":\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03C4\u03B9\u03BC\u03AE \u03C3\u03C4\u03BF ${issue.origin}`;\n default:\n return `\u039C\u03B7 \u03AD\u03B3\u03BA\u03C5\u03C1\u03B7 \u03B5\u03AF\u03C3\u03BF\u03B4\u03BF\u03C2`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"characters\", verb: \"to have\" },\n file: { unit: \"bytes\", verb: \"to have\" },\n array: { unit: \"items\", verb: \"to have\" },\n set: { unit: \"items\", verb: \"to have\" },\n map: { unit: \"entries\", verb: \"to have\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"input\",\n email: \"email address\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO datetime\",\n date: \"ISO date\",\n time: \"ISO time\",\n duration: \"ISO duration\",\n ipv4: \"IPv4 address\",\n ipv6: \"IPv6 address\",\n mac: \"MAC address\",\n cidrv4: \"IPv4 range\",\n cidrv6: \"IPv6 range\",\n base64: \"base64-encoded string\",\n base64url: \"base64url-encoded string\",\n json_string: \"JSON string\",\n e164: \"E.164 number\",\n currency_code: \"currency code\",\n credit_card: \"credit card number\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n // type names: missing keys = do not translate (use raw value via ?? fallback)\n const TypeDictionary = {\n // Compatibility: \"nan\" -> \"NaN\" for display\n nan: \"NaN\",\n // All other type names omitted - they fall back to raw values via ?? operator\n };\n function getTypeName(type, input) {\n if (type === \"number\" && typeof input === \"number\" && !Number.isFinite(input)) {\n return String(input);\n }\n return TypeDictionary[type] ?? type;\n }\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = getTypeName(issue.expected);\n const receivedType = util.parsedType(issue.input);\n const received = getTypeName(receivedType, issue.input);\n return `Invalid input: expected ${expected}, received ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Invalid input: expected ${util.stringifyPrimitive(issue.values[0])}`;\n return `Invalid option: expected one of ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.exact ? \"exactly \" : issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Too big: expected ${issue.origin ?? \"value\"} to have ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elements\"}`;\n return `Too big: expected ${issue.origin ?? \"value\"} to be ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.exact ? \"exactly \" : issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Too small: expected ${issue.origin} to have ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Too small: expected ${issue.origin} to be ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `Invalid string: must start with \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `Invalid string: must end with \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Invalid string: must include \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Invalid string: must match pattern ${_issue.pattern}`;\n return `Invalid ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Invalid number: must be a multiple of ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Unrecognized key${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Invalid key in ${issue.origin}`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `Invalid discriminator value. Expected ${opts}`;\n }\n if (issue.inclusive === false) {\n return \"Invalid input: more than one option matched\";\n }\n return \"Invalid input\";\n case \"invalid_element\":\n return `Invalid value in ${issue.origin}`;\n default:\n return `Invalid input`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"karaktrojn\", verb: \"havi\" },\n file: { unit: \"bajtojn\", verb: \"havi\" },\n array: { unit: \"elementojn\", verb: \"havi\" },\n set: { unit: \"elementojn\", verb: \"havi\" },\n map: { unit: \"elementojn\", verb: \"havi\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"enigo\",\n email: \"retadreso\",\n url: \"URL\",\n emoji: \"emo\u011Dio\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO-datotempo\",\n date: \"ISO-dato\",\n time: \"ISO-tempo\",\n duration: \"ISO-da\u016Dro\",\n ipv4: \"IPv4-adreso\",\n ipv6: \"IPv6-adreso\",\n mac: \"MAC-adreso\",\n cidrv4: \"IPv4-rango\",\n cidrv6: \"IPv6-rango\",\n base64: \"64-ume kodita karaktraro\",\n base64url: \"URL-64-ume kodita karaktraro\",\n json_string: \"JSON-karaktraro\",\n e164: \"E.164-nombro\",\n credit_card: \"kreditkarta numero\",\n currency_code: \"valuta kodo\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"enigo\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"nombro\",\n array: \"tabelo\",\n null: \"senvalora\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Nevalida enigo: atendi\u011Dis instanceof ${issue.expected}, ricevi\u011Dis ${received}`;\n }\n return `Nevalida enigo: atendi\u011Dis ${expected}, ricevi\u011Dis ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Nevalida enigo: atendi\u011Dis ${util.stringifyPrimitive(issue.values[0])}`;\n return `Nevalida opcio: atendi\u011Dis unu el ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Tro granda: atendi\u011Dis ke ${issue.origin ?? \"valoro\"} havu ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elementojn\"}`;\n return `Tro granda: atendi\u011Dis ke ${issue.origin ?? \"valoro\"} havu ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Tro malgranda: atendi\u011Dis ke ${issue.origin} havu ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Tro malgranda: atendi\u011Dis ke ${issue.origin} estu ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Nevalida karaktraro: devas komenci\u011Di per \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Nevalida karaktraro: devas fini\u011Di per \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Nevalida karaktraro: devas inkluzivi \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Nevalida karaktraro: devas kongrui kun la modelo ${_issue.pattern}`;\n return `Nevalida ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Nevalida nombro: devas esti oblo de ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Nekonata${issue.keys.length > 1 ? \"j\" : \"\"} \u015Dlosilo${issue.keys.length > 1 ? \"j\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Nevalida \u015Dlosilo en ${issue.origin}`;\n case \"invalid_union\":\n return \"Nevalida enigo\";\n case \"invalid_element\":\n return `Nevalida valoro en ${issue.origin}`;\n default:\n return `Nevalida enigo`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"caracteres\", verb: \"tener\" },\n file: { unit: \"bytes\", verb: \"tener\" },\n array: { unit: \"elementos\", verb: \"tener\" },\n set: { unit: \"elementos\", verb: \"tener\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"entrada\",\n email: \"direcci\u00F3n de correo electr\u00F3nico\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"fecha y hora ISO\",\n date: \"fecha ISO\",\n time: \"hora ISO\",\n duration: \"duraci\u00F3n ISO\",\n ipv4: \"direcci\u00F3n IPv4\",\n ipv6: \"direcci\u00F3n IPv6\",\n mac: \"direcci\u00F3n MAC\",\n cidrv4: \"rango IPv4\",\n cidrv6: \"rango IPv6\",\n base64: \"cadena codificada en base64\",\n base64url: \"URL codificada en base64\",\n json_string: \"cadena JSON\",\n e164: \"n\u00FAmero E.164\",\n credit_card: \"n\u00FAmero de tarjeta de cr\u00E9dito\",\n currency_code: \"c\u00F3digo de moneda\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"entrada\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n string: \"texto\",\n number: \"n\u00FAmero\",\n boolean: \"booleano\",\n array: \"arreglo\",\n object: \"objeto\",\n set: \"conjunto\",\n file: \"archivo\",\n date: \"fecha\",\n bigint: \"n\u00FAmero grande\",\n symbol: \"s\u00EDmbolo\",\n undefined: \"indefinido\",\n null: \"nulo\",\n function: \"funci\u00F3n\",\n map: \"mapa\",\n record: \"registro\",\n tuple: \"tupla\",\n enum: \"enumeraci\u00F3n\",\n union: \"uni\u00F3n\",\n literal: \"literal\",\n promise: \"promesa\",\n void: \"vac\u00EDo\",\n never: \"nunca\",\n unknown: \"desconocido\",\n any: \"cualquiera\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Entrada inv\u00E1lida: se esperaba instanceof ${issue.expected}, recibido ${received}`;\n }\n return `Entrada inv\u00E1lida: se esperaba ${expected}, recibido ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Entrada inv\u00E1lida: se esperaba ${util.stringifyPrimitive(issue.values[0])}`;\n return `Opci\u00F3n inv\u00E1lida: se esperaba una de ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n if (sizing)\n return `Demasiado grande: se esperaba que ${origin ?? \"valor\"} tuviera ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elementos\"}`;\n return `Demasiado grande: se esperaba que ${origin ?? \"valor\"} fuera ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n if (sizing) {\n return `Demasiado peque\u00F1o: se esperaba que ${origin} tuviera ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Demasiado peque\u00F1o: se esperaba que ${origin} fuera ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Cadena inv\u00E1lida: debe comenzar con \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Cadena inv\u00E1lida: debe terminar en \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Cadena inv\u00E1lida: debe incluir \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Cadena inv\u00E1lida: debe coincidir con el patr\u00F3n ${_issue.pattern}`;\n return `Inv\u00E1lido ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `N\u00FAmero inv\u00E1lido: debe ser m\u00FAltiplo de ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Llave${issue.keys.length > 1 ? \"s\" : \"\"} desconocida${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Llave inv\u00E1lida en ${TypeDictionary[issue.origin] ?? issue.origin}`;\n case \"invalid_union\":\n return \"Entrada inv\u00E1lida\";\n case \"invalid_element\":\n return `Valor inv\u00E1lido en ${TypeDictionary[issue.origin] ?? issue.origin}`;\n default:\n return `Entrada inv\u00E1lida`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u06A9\u0627\u0631\u0627\u06A9\u062A\u0631\", verb: \"\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F\" },\n file: { unit: \"\u0628\u0627\u06CC\u062A\", verb: \"\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F\" },\n array: { unit: \"\u0622\u06CC\u062A\u0645\", verb: \"\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F\" },\n set: { unit: \"\u0622\u06CC\u062A\u0645\", verb: \"\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F\" },\n map: { unit: \"\u0622\u06CC\u062A\u0645\", verb: \"\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0648\u0631\u0648\u062F\u06CC\",\n email: \"\u0622\u062F\u0631\u0633 \u0627\u06CC\u0645\u06CC\u0644\",\n url: \"URL\",\n emoji: \"\u0627\u06CC\u0645\u0648\u062C\u06CC\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u062A\u0627\u0631\u06CC\u062E \u0648 \u0632\u0645\u0627\u0646 \u0627\u06CC\u0632\u0648\",\n date: \"\u062A\u0627\u0631\u06CC\u062E \u0627\u06CC\u0632\u0648\",\n time: \"\u0632\u0645\u0627\u0646 \u0627\u06CC\u0632\u0648\",\n duration: \"\u0645\u062F\u062A \u0632\u0645\u0627\u0646 \u0627\u06CC\u0632\u0648\",\n ipv4: \"IPv4 \u0622\u062F\u0631\u0633\",\n ipv6: \"IPv6 \u0622\u062F\u0631\u0633\",\n mac: \"MAC \u0622\u062F\u0631\u0633\",\n cidrv4: \"IPv4 \u062F\u0627\u0645\u0646\u0647\",\n cidrv6: \"IPv6 \u062F\u0627\u0645\u0646\u0647\",\n base64: \"base64-encoded \u0631\u0634\u062A\u0647\",\n base64url: \"base64url-encoded \u0631\u0634\u062A\u0647\",\n json_string: \"JSON \u0631\u0634\u062A\u0647\",\n e164: \"E.164 \u0639\u062F\u062F\",\n credit_card: \"\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A \u0627\u0639\u062A\u0628\u0627\u0631\u06CC\",\n currency_code: \"\u06A9\u062F \u0627\u0631\u0632\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0648\u0631\u0648\u062F\u06CC\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0639\u062F\u062F\",\n array: \"\u0622\u0631\u0627\u06CC\u0647\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u0648\u0631\u0648\u062F\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0645\u06CC\u200C\u0628\u0627\u06CC\u0633\u062A instanceof ${issue.expected} \u0645\u06CC\u200C\u0628\u0648\u062F\u060C ${received} \u062F\u0631\u06CC\u0627\u0641\u062A \u0634\u062F`;\n }\n return `\u0648\u0631\u0648\u062F\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0645\u06CC\u200C\u0628\u0627\u06CC\u0633\u062A ${expected} \u0645\u06CC\u200C\u0628\u0648\u062F\u060C ${received} \u062F\u0631\u06CC\u0627\u0641\u062A \u0634\u062F`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1) {\n return `\u0648\u0631\u0648\u062F\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0645\u06CC\u200C\u0628\u0627\u06CC\u0633\u062A ${util.stringifyPrimitive(issue.values[0])} \u0645\u06CC\u200C\u0628\u0648\u062F`;\n }\n return `\u06AF\u0632\u06CC\u0646\u0647 \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0645\u06CC\u200C\u0628\u0627\u06CC\u0633\u062A \u06CC\u06A9\u06CC \u0627\u0632 ${util.joinValues(issue.values, \"|\")} \u0645\u06CC\u200C\u0628\u0648\u062F`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u062E\u06CC\u0644\u06CC \u0628\u0632\u0631\u06AF: ${issue.origin ?? \"\u0645\u0642\u062F\u0627\u0631\"} \u0628\u0627\u06CC\u062F ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0639\u0646\u0635\u0631\"} \u0628\u0627\u0634\u062F`;\n }\n return `\u062E\u06CC\u0644\u06CC \u0628\u0632\u0631\u06AF: ${issue.origin ?? \"\u0645\u0642\u062F\u0627\u0631\"} \u0628\u0627\u06CC\u062F ${adj}${issue.maximum.toString()} \u0628\u0627\u0634\u062F`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u062E\u06CC\u0644\u06CC \u06A9\u0648\u0686\u06A9: ${issue.origin} \u0628\u0627\u06CC\u062F ${adj}${issue.minimum.toString()} ${sizing.unit} \u0628\u0627\u0634\u062F`;\n }\n return `\u062E\u06CC\u0644\u06CC \u06A9\u0648\u0686\u06A9: ${issue.origin} \u0628\u0627\u06CC\u062F ${adj}${issue.minimum.toString()} \u0628\u0627\u0634\u062F`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u0631\u0634\u062A\u0647 \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0628\u0627\u06CC\u062F \u0628\u0627 \"${_issue.prefix}\" \u0634\u0631\u0648\u0639 \u0634\u0648\u062F`;\n }\n if (_issue.format === \"ends_with\") {\n return `\u0631\u0634\u062A\u0647 \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0628\u0627\u06CC\u062F \u0628\u0627 \"${_issue.suffix}\" \u062A\u0645\u0627\u0645 \u0634\u0648\u062F`;\n }\n if (_issue.format === \"includes\") {\n return `\u0631\u0634\u062A\u0647 \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0628\u0627\u06CC\u062F \u0634\u0627\u0645\u0644 \"${_issue.includes}\" \u0628\u0627\u0634\u062F`;\n }\n if (_issue.format === \"regex\") {\n return `\u0631\u0634\u062A\u0647 \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0628\u0627\u06CC\u062F \u0628\u0627 \u0627\u0644\u06AF\u0648\u06CC ${_issue.pattern} \u0645\u0637\u0627\u0628\u0642\u062A \u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F`;\n }\n return `${FormatDictionary[_issue.format] ?? issue.format} \u0646\u0627\u0645\u0639\u062A\u0628\u0631`;\n }\n case \"not_multiple_of\":\n return `\u0639\u062F\u062F \u0646\u0627\u0645\u0639\u062A\u0628\u0631: \u0628\u0627\u06CC\u062F \u0645\u0636\u0631\u0628 ${issue.divisor} \u0628\u0627\u0634\u062F`;\n case \"unrecognized_keys\":\n return `\u06A9\u0644\u06CC\u062F${issue.keys.length > 1 ? \"\u0647\u0627\u06CC\" : \"\"} \u0646\u0627\u0634\u0646\u0627\u0633: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u06A9\u0644\u06CC\u062F \u0646\u0627\u0634\u0646\u0627\u0633 \u062F\u0631 ${issue.origin}`;\n case \"invalid_union\":\n return `\u0648\u0631\u0648\u062F\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631`;\n case \"invalid_element\":\n return `\u0645\u0642\u062F\u0627\u0631 \u0646\u0627\u0645\u0639\u062A\u0628\u0631 \u062F\u0631 ${issue.origin}`;\n default:\n return `\u0648\u0631\u0648\u062F\u06CC \u0646\u0627\u0645\u0639\u062A\u0628\u0631`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"merkki\u00E4\", subject: \"merkkijonon\" },\n file: { unit: \"tavua\", subject: \"tiedoston\" },\n array: { unit: \"alkiota\", subject: \"listan\" },\n set: { unit: \"alkiota\", subject: \"joukon\" },\n map: { unit: \"alkiota\", subject: \"kuvauksen\" },\n number: { unit: \"\", subject: \"luvun\" },\n bigint: { unit: \"\", subject: \"suuren kokonaisluvun\" },\n int: { unit: \"\", subject: \"kokonaisluvun\" },\n date: { unit: \"\", subject: \"p\u00E4iv\u00E4m\u00E4\u00E4r\u00E4n\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"s\u00E4\u00E4nn\u00F6llinen lauseke\",\n email: \"s\u00E4hk\u00F6postiosoite\",\n url: \"URL-osoite\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO-aikaleima\",\n date: \"ISO-p\u00E4iv\u00E4m\u00E4\u00E4r\u00E4\",\n time: \"ISO-aika\",\n duration: \"ISO-kesto\",\n ipv4: \"IPv4-osoite\",\n ipv6: \"IPv6-osoite\",\n mac: \"MAC-osoite\",\n cidrv4: \"IPv4-alue\",\n cidrv6: \"IPv6-alue\",\n base64: \"base64-koodattu merkkijono\",\n base64url: \"base64url-koodattu merkkijono\",\n json_string: \"JSON-merkkijono\",\n e164: \"E.164-luku\",\n credit_card: \"luottokortin numero\",\n currency_code: \"valuuttakoodi\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"templaattimerkkijono\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Virheellinen tyyppi: odotettiin instanceof ${issue.expected}, oli ${received}`;\n }\n return `Virheellinen tyyppi: odotettiin ${expected}, oli ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Virheellinen sy\u00F6te: t\u00E4ytyy olla ${util.stringifyPrimitive(issue.values[0])}`;\n return `Virheellinen valinta: t\u00E4ytyy olla yksi seuraavista: ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Liian suuri: ${sizing.subject} t\u00E4ytyy olla ${adj}${issue.maximum.toString()} ${sizing.unit}`.trim();\n }\n return `Liian suuri: arvon t\u00E4ytyy olla ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Liian pieni: ${sizing.subject} t\u00E4ytyy olla ${adj}${issue.minimum.toString()} ${sizing.unit}`.trim();\n }\n return `Liian pieni: arvon t\u00E4ytyy olla ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Virheellinen sy\u00F6te: t\u00E4ytyy alkaa \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Virheellinen sy\u00F6te: t\u00E4ytyy loppua \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Virheellinen sy\u00F6te: t\u00E4ytyy sis\u00E4lt\u00E4\u00E4 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\") {\n return `Virheellinen sy\u00F6te: t\u00E4ytyy vastata s\u00E4\u00E4nn\u00F6llist\u00E4 lauseketta ${_issue.pattern}`;\n }\n return `Virheellinen ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Virheellinen luku: t\u00E4ytyy olla luvun ${issue.divisor} monikerta`;\n case \"unrecognized_keys\":\n return `${issue.keys.length > 1 ? \"Tuntemattomat avaimet\" : \"Tuntematon avain\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return \"Virheellinen avain tietueessa\";\n case \"invalid_union\":\n return \"Virheellinen unioni\";\n case \"invalid_element\":\n return \"Virheellinen arvo joukossa\";\n default:\n return `Virheellinen sy\u00F6te`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"caract\u00E8res\", verb: \"avoir\" },\n file: { unit: \"octets\", verb: \"avoir\" },\n array: { unit: \"\u00E9l\u00E9ments\", verb: \"avoir\" },\n set: { unit: \"\u00E9l\u00E9ments\", verb: \"avoir\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"expression r\u00E9guli\u00E8re\",\n email: \"adresse e-mail\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"date et heure ISO\",\n date: \"date ISO\",\n time: \"heure ISO\",\n duration: \"dur\u00E9e ISO\",\n ipv4: \"adresse IPv4\",\n ipv6: \"adresse IPv6\",\n mac: \"adresse MAC\",\n cidrv4: \"plage IPv4\",\n cidrv6: \"plage IPv6\",\n base64: \"cha\u00EEne de caract\u00E8res encod\u00E9e en base64\",\n base64url: \"cha\u00EEne de caract\u00E8res encod\u00E9e en base64url\",\n json_string: \"cha\u00EEne de caract\u00E8res JSON\",\n e164: \"num\u00E9ro au format E.164\",\n credit_card: \"num\u00E9ro de carte de cr\u00E9dit\",\n currency_code: \"code de devise\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"entr\u00E9e\",\n };\n const TypeDictionary = {\n string: \"cha\u00EEne de caract\u00E8res\",\n number: \"nombre\",\n int: \"entier\",\n boolean: \"bool\u00E9en\",\n bigint: \"grand entier\",\n symbol: \"symbole\",\n undefined: \"ind\u00E9fini\",\n null: \"null\",\n never: \"jamais\",\n void: \"vide\",\n date: \"date\",\n array: \"tableau\",\n object: \"objet\",\n tuple: \"tuple\",\n record: \"record\",\n map: \"map\",\n set: \"ensemble\",\n file: \"fichier\",\n nonoptional: \"non optionnel\",\n nan: \"NaN\",\n function: \"fonction\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Entr\u00E9e invalide : instance de ${issue.expected} attendu, ${received} re\u00E7u`;\n }\n return `Entr\u00E9e invalide : ${expected} attendu, ${received} re\u00E7u`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Entr\u00E9e invalide : ${util.stringifyPrimitive(issue.values[0])} attendu`;\n return `Option invalide : une valeur parmi ${util.joinValues(issue.values, \"|\")} attendue`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Trop grand : ${TypeDictionary[issue.origin] ?? \"valeur\"} doit ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u00E9l\u00E9ment(s)\"}`;\n return `Trop grand : ${TypeDictionary[issue.origin] ?? \"valeur\"} doit \u00EAtre ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Trop petit : ${TypeDictionary[issue.origin] ?? \"valeur\"} doit ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n return `Trop petit : ${TypeDictionary[issue.origin] ?? \"valeur\"} doit \u00EAtre ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Cha\u00EEne de caract\u00E8res invalide : doit commencer par \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Cha\u00EEne de caract\u00E8res invalide : doit se terminer par \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Cha\u00EEne de caract\u00E8res invalide : doit inclure \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Cha\u00EEne de caract\u00E8res invalide : doit correspondre au motif ${_issue.pattern}`;\n return `${FormatDictionary[_issue.format] ?? issue.format} invalide`;\n }\n case \"not_multiple_of\":\n return `Nombre invalide : doit \u00EAtre un multiple de ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Cl\u00E9${issue.keys.length > 1 ? \"s\" : \"\"} non reconnue${issue.keys.length > 1 ? \"s\" : \"\"} : ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Cl\u00E9 invalide dans ${issue.origin}`;\n case \"invalid_union\":\n return \"Entr\u00E9e invalide\";\n case \"invalid_element\":\n return `Valeur invalide dans ${issue.origin}`;\n default:\n return `Entr\u00E9e invalide`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"caract\u00E8res\", verb: \"avoir\" },\n file: { unit: \"octets\", verb: \"avoir\" },\n array: { unit: \"\u00E9l\u00E9ments\", verb: \"avoir\" },\n set: { unit: \"\u00E9l\u00E9ments\", verb: \"avoir\" },\n map: { unit: \"\u00E9l\u00E9ments\", verb: \"avoir\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"entr\u00E9e\",\n email: \"adresse courriel\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"date-heure ISO\",\n date: \"date ISO\",\n time: \"heure ISO\",\n duration: \"dur\u00E9e ISO\",\n ipv4: \"adresse IPv4\",\n ipv6: \"adresse IPv6\",\n mac: \"adresse MAC\",\n cidrv4: \"plage IPv4\",\n cidrv6: \"plage IPv6\",\n base64: \"cha\u00EEne encod\u00E9e en base64\",\n base64url: \"cha\u00EEne encod\u00E9e en base64url\",\n json_string: \"cha\u00EEne JSON\",\n e164: \"num\u00E9ro E.164\",\n credit_card: \"num\u00E9ro de carte de cr\u00E9dit\",\n currency_code: \"code de devise\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"entr\u00E9e\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Entr\u00E9e invalide : attendu instanceof ${issue.expected}, re\u00E7u ${received}`;\n }\n return `Entr\u00E9e invalide : attendu ${expected}, re\u00E7u ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Entr\u00E9e invalide : attendu ${util.stringifyPrimitive(issue.values[0])}`;\n return `Option invalide : attendu l'une des valeurs suivantes ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"\u2264\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Trop grand : attendu que ${issue.origin ?? \"la valeur\"} ait ${adj}${issue.maximum.toString()} ${sizing.unit}`;\n return `Trop grand : attendu que ${issue.origin ?? \"la valeur\"} soit ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \"\u2265\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Trop petit : attendu que ${issue.origin} ait ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Trop petit : attendu que ${issue.origin} soit ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `Cha\u00EEne invalide : doit commencer par \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `Cha\u00EEne invalide : doit se terminer par \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Cha\u00EEne invalide : doit inclure \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Cha\u00EEne invalide : doit correspondre au motif ${_issue.pattern}`;\n return `${FormatDictionary[_issue.format] ?? issue.format} invalide`;\n }\n case \"not_multiple_of\":\n return `Nombre invalide : doit \u00EAtre un multiple de ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Cl\u00E9${issue.keys.length > 1 ? \"s\" : \"\"} non reconnue${issue.keys.length > 1 ? \"s\" : \"\"} : ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Cl\u00E9 invalide dans ${issue.origin}`;\n case \"invalid_union\":\n return \"Entr\u00E9e invalide\";\n case \"invalid_element\":\n return `Valeur invalide dans ${issue.origin}`;\n default:\n return `Entr\u00E9e invalide`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0A85\u0A95\u0ACD\u0AB7\u0AB0\", verb: \"\u0AB9\u0ACB\u0AB5\u0ABE \u0A9C\u0ACB\u0A88\u0A8F\" },\n file: { unit: \"\u0AAC\u0ABE\u0AAF\u0A9F\", verb: \"\u0AB9\u0ACB\u0AB5\u0ABE \u0A9C\u0ACB\u0A88\u0A8F\" },\n array: { unit: \"\u0A86\u0A87\u0A9F\u0AAE\", verb: \"\u0AB9\u0ACB\u0AB5\u0ABE \u0A9C\u0ACB\u0A88\u0A8F\" },\n set: { unit: \"\u0A86\u0A87\u0A9F\u0AAE\", verb: \"\u0AB9\u0ACB\u0AB5\u0ABE \u0A9C\u0ACB\u0A88\u0A8F\" },\n map: { unit: \"\u0A8F\u0AA8\u0ACD\u0A9F\u0ACD\u0AB0\u0AC0\", verb: \"\u0AB9\u0ACB\u0AB5\u0ABE \u0A9C\u0ACB\u0A88\u0A8F\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0A87\u0AA8\u0AAA\u0AC1\u0A9F\",\n email: \"\u0A88\u0AAE\u0AC7\u0A87\u0AB2 \u0A8F\u0AA1\u0ACD\u0AB0\u0AC7\u0AB8\",\n url: \"URL\",\n emoji: \"\u0A87\u0AAE\u0ACB\u0A9C\u0AC0\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0AA4\u0ABE\u0AB0\u0AC0\u0A96 \u0A85\u0AA8\u0AC7 \u0AB8\u0AAE\u0AAF\",\n date: \"ISO \u0AA4\u0ABE\u0AB0\u0AC0\u0A96\",\n time: \"ISO \u0AB8\u0AAE\u0AAF\",\n duration: \"ISO \u0A85\u0AB5\u0AA7\u0ABF\",\n ipv4: \"IPv4 \u0A8F\u0AA1\u0ACD\u0AB0\u0AC7\u0AB8\",\n ipv6: \"IPv6 \u0A8F\u0AA1\u0ACD\u0AB0\u0AC7\u0AB8\",\n mac: \"MAC \u0A8F\u0AA1\u0ACD\u0AB0\u0AC7\u0AB8\",\n cidrv4: \"IPv4 \u0AB6\u0ACD\u0AB0\u0AC7\u0AA3\u0AC0\",\n cidrv6: \"IPv6 \u0AB6\u0ACD\u0AB0\u0AC7\u0AA3\u0AC0\",\n base64: \"base64-\u0A8F\u0AA8\u0ACD\u0A95\u0ACB\u0AA1\u0AC7\u0AA1 \u0AB8\u0ACD\u0A9F\u0ACD\u0AB0\u0ABF\u0A82\u0A97\",\n base64url: \"base64url-\u0A8F\u0AA8\u0ACD\u0A95\u0ACB\u0AA1\u0AC7\u0AA1 \u0AB8\u0ACD\u0A9F\u0ACD\u0AB0\u0ABF\u0A82\u0A97\",\n json_string: \"JSON \u0AB8\u0ACD\u0A9F\u0ACD\u0AB0\u0ABF\u0A82\u0A97\",\n e164: \"E.164 \u0AA8\u0A82\u0AAC\u0AB0\",\n credit_card: \"\u0A95\u0ACD\u0AB0\u0AC7\u0AA1\u0ABF\u0A9F \u0A95\u0ABE\u0AB0\u0ACD\u0AA1 \u0AA8\u0A82\u0AAC\u0AB0\",\n currency_code: \"\u0A9A\u0AB2\u0AA3 \u0A95\u0ACB\u0AA1\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0A87\u0AA8\u0AAA\u0AC1\u0A9F\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0A87\u0AA8\u0AAA\u0AC1\u0A9F: \u0A85\u0AAA\u0AC7\u0A95\u0ACD\u0AB7\u0ABF\u0AA4 ${expected}, \u0AAA\u0ACD\u0AB0\u0ABE\u0AAA\u0ACD\u0AA4 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0A87\u0AA8\u0AAA\u0AC1\u0A9F: \u0A85\u0AAA\u0AC7\u0A95\u0ACD\u0AB7\u0ABF\u0AA4 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0AB5\u0ABF\u0A95\u0AB2\u0ACD\u0AAA: ${util.joinValues(issue.values, \" | \")} \u0AAE\u0ABE\u0AA7\u0ACD\u0AAF\u0AAE\u0AA5\u0AC0 \u0A8F\u0A95 \u0A85\u0AAA\u0AC7\u0A95\u0ACD\u0AB7\u0ABF\u0AA4`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0A96\u0AC2\u0AAC \u0AAE\u0ACB\u0A9F\u0AC1\u0A82: ${issue.origin ?? \"\u0AAE\u0AC2\u0AB2\u0ACD\u0AAF\"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0A8F\u0AB2\u0ABF\u0AAE\u0AC7\u0AA8\u0ACD\u0A9F\"} \u0AB9\u0ACB\u0AB5\u0ABE \u0A9C\u0ACB\u0A88\u0A8F`;\n return `\u0A96\u0AC2\u0AAC \u0AAE\u0ACB\u0A9F\u0AC1\u0A82: ${issue.origin ?? \"\u0AAE\u0AC2\u0AB2\u0ACD\u0AAF\"} ${adj}${issue.maximum.toString()} \u0AB9\u0ACB\u0AB5\u0AC1\u0A82 \u0A9C\u0ACB\u0A88\u0A8F`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0A96\u0AC2\u0AAC \u0AA8\u0ABE\u0AA8\u0AC1\u0A82: ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} \u0AB9\u0ACB\u0AB5\u0ABE \u0A9C\u0ACB\u0A88\u0A8F`;\n }\n return `\u0A96\u0AC2\u0AAC \u0AA8\u0ABE\u0AA8\u0AC1\u0A82: ${issue.origin} ${adj}${issue.minimum.toString()} \u0AB9\u0ACB\u0AB5\u0AC1\u0A82 \u0A9C\u0ACB\u0A88\u0A8F`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0AB8\u0ACD\u0A9F\u0ACD\u0AB0\u0ABF\u0A82\u0A97: \"${_issue.prefix}\" \u0AA5\u0AC0 \u0AB6\u0AB0\u0AC2 \u0AA5\u0AB5\u0AC1\u0A82 \u0A9C\u0ACB\u0A88\u0A8F`;\n }\n if (_issue.format === \"ends_with\")\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0AB8\u0ACD\u0A9F\u0ACD\u0AB0\u0ABF\u0A82\u0A97: \"${_issue.suffix}\" \u0AAA\u0AB0 \u0AB8\u0AAE\u0ABE\u0AAA\u0ACD\u0AA4 \u0AA5\u0AB5\u0AC1\u0A82 \u0A9C\u0ACB\u0A88\u0A8F`;\n if (_issue.format === \"includes\")\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0AB8\u0ACD\u0A9F\u0ACD\u0AB0\u0ABF\u0A82\u0A97: \"${_issue.includes}\" \u0AB6\u0ABE\u0AAE\u0AC7\u0AB2 \u0AB9\u0ACB\u0AB5\u0AC1\u0A82 \u0A9C\u0ACB\u0A88\u0A8F`;\n if (_issue.format === \"regex\")\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0AB8\u0ACD\u0A9F\u0ACD\u0AB0\u0ABF\u0A82\u0A97: \u0AAA\u0AC7\u0A9F\u0AB0\u0ACD\u0AA8 ${_issue.pattern} \u0AB8\u0ABE\u0AA5\u0AC7 \u0AAE\u0AC7\u0AB3 \u0A96\u0ABE\u0AB5\u0AC1\u0A82 \u0A9C\u0ACB\u0A88\u0A8F`;\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0AA8\u0A82\u0AAC\u0AB0: ${issue.divisor} \u0AA8\u0ACB \u0A97\u0AC1\u0AA3\u0ABE\u0A82\u0A95 \u0AB9\u0ACB\u0AB5\u0ACB \u0A9C\u0ACB\u0A88\u0A8F`;\n case \"unrecognized_keys\":\n return `\u0A93\u0AB3\u0A96\u0AC0 \u0AB6\u0A95\u0ABE\u0AA4\u0ABE \u0AA8\u0AB9\u0AC0\u0A82 \u0AA4\u0AC7 \u0A95\u0AC0${issue.keys.length > 1 ? \"\u0A93\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} \u0AAE\u0ABE\u0A82 \u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0A95\u0AC0`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0AA1\u0ABF\u0AB8\u0ACD\u0A95\u0ACD\u0AB0\u0ABF\u0AAE\u0ABF\u0AA8\u0AC7\u0A9F\u0AB0 \u0AAE\u0AC2\u0AB2\u0ACD\u0AAF. \u0A85\u0AAA\u0AC7\u0A95\u0ACD\u0AB7\u0ABF\u0AA4 ${opts}`;\n }\n return \"\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0A87\u0AA8\u0AAA\u0AC1\u0A9F\";\n case \"invalid_element\":\n return `${issue.origin} \u0AAE\u0ABE\u0A82 \u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0AAE\u0AC2\u0AB2\u0ACD\u0AAF`;\n default:\n return \"\u0A85\u0AAE\u0ABE\u0AA8\u0ACD\u0AAF \u0A87\u0AA8\u0AAA\u0AC1\u0A9F\";\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n // Hebrew labels + grammatical gender\n const TypeNames = {\n string: { label: \"\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA\", gender: \"f\" },\n number: { label: \"\u05DE\u05E1\u05E4\u05E8\", gender: \"m\" },\n boolean: { label: \"\u05E2\u05E8\u05DA \u05D1\u05D5\u05DC\u05D9\u05D0\u05E0\u05D9\", gender: \"m\" },\n bigint: { label: \"BigInt\", gender: \"m\" },\n date: { label: \"\u05EA\u05D0\u05E8\u05D9\u05DA\", gender: \"m\" },\n array: { label: \"\u05DE\u05E2\u05E8\u05DA\", gender: \"m\" },\n object: { label: \"\u05D0\u05D5\u05D1\u05D9\u05D9\u05E7\u05D8\", gender: \"m\" },\n null: { label: \"\u05E2\u05E8\u05DA \u05E8\u05D9\u05E7 (null)\", gender: \"m\" },\n undefined: { label: \"\u05E2\u05E8\u05DA \u05DC\u05D0 \u05DE\u05D5\u05D2\u05D3\u05E8 (undefined)\", gender: \"m\" },\n symbol: { label: \"\u05E1\u05D9\u05DE\u05D1\u05D5\u05DC (Symbol)\", gender: \"m\" },\n function: { label: \"\u05E4\u05D5\u05E0\u05E7\u05E6\u05D9\u05D4\", gender: \"f\" },\n map: { label: \"\u05DE\u05E4\u05D4 (Map)\", gender: \"f\" },\n set: { label: \"\u05E7\u05D1\u05D5\u05E6\u05D4 (Set)\", gender: \"f\" },\n file: { label: \"\u05E7\u05D5\u05D1\u05E5\", gender: \"m\" },\n promise: { label: \"Promise\", gender: \"m\" },\n NaN: { label: \"NaN\", gender: \"m\" },\n unknown: { label: \"\u05E2\u05E8\u05DA \u05DC\u05D0 \u05D9\u05D3\u05D5\u05E2\", gender: \"m\" },\n value: { label: \"\u05E2\u05E8\u05DA\", gender: \"m\" },\n };\n // Sizing units for size-related messages + localized origin labels\n const Sizable = {\n string: { unit: \"\u05EA\u05D5\u05D5\u05D9\u05DD\", shortLabel: \"\u05E7\u05E6\u05E8\", longLabel: \"\u05D0\u05E8\u05D5\u05DA\" },\n file: { unit: \"\u05D1\u05D9\u05D9\u05D8\u05D9\u05DD\", shortLabel: \"\u05E7\u05D8\u05DF\", longLabel: \"\u05D2\u05D3\u05D5\u05DC\" },\n array: { unit: \"\u05E4\u05E8\u05D9\u05D8\u05D9\u05DD\", shortLabel: \"\u05E7\u05D8\u05DF\", longLabel: \"\u05D2\u05D3\u05D5\u05DC\" },\n set: { unit: \"\u05E4\u05E8\u05D9\u05D8\u05D9\u05DD\", shortLabel: \"\u05E7\u05D8\u05DF\", longLabel: \"\u05D2\u05D3\u05D5\u05DC\" },\n number: { unit: \"\", shortLabel: \"\u05E7\u05D8\u05DF\", longLabel: \"\u05D2\u05D3\u05D5\u05DC\" }, // no unit\n };\n // Helpers \u2014 labels, articles, and verbs\n const typeEntry = (t) => (t ? TypeNames[t] : undefined);\n const typeLabel = (t) => {\n const e = typeEntry(t);\n if (e)\n return e.label;\n // fallback: show raw string if unknown\n return t ?? TypeNames.unknown.label;\n };\n const withDefinite = (t) => `\u05D4${typeLabel(t)}`;\n const verbFor = (t) => {\n const e = typeEntry(t);\n const gender = e?.gender ?? \"m\";\n return gender === \"f\" ? \"\u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05D9\u05D5\u05EA\" : \"\u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA\";\n };\n const getSizing = (origin) => {\n if (!origin)\n return null;\n return Sizable[origin] ?? null;\n };\n const FormatDictionary = {\n regex: { label: \"\u05E7\u05DC\u05D8\", gender: \"m\" },\n email: { label: \"\u05DB\u05EA\u05D5\u05D1\u05EA \u05D0\u05D9\u05DE\u05D9\u05D9\u05DC\", gender: \"f\" },\n url: { label: \"\u05DB\u05EA\u05D5\u05D1\u05EA \u05E8\u05E9\u05EA\", gender: \"f\" },\n emoji: { label: \"\u05D0\u05D9\u05DE\u05D5\u05D2'\u05D9\", gender: \"m\" },\n uuid: { label: \"UUID\", gender: \"m\" },\n uuidv4: { label: \"UUIDv4\", gender: \"m\" },\n uuidv6: { label: \"UUIDv6\", gender: \"m\" },\n nanoid: { label: \"nanoid\", gender: \"m\" },\n guid: { label: \"GUID\", gender: \"m\" },\n cuid: { label: \"cuid\", gender: \"m\" },\n cuid2: { label: \"cuid2\", gender: \"m\" },\n ulid: { label: \"ULID\", gender: \"m\" },\n xid: { label: \"XID\", gender: \"m\" },\n ksuid: { label: \"KSUID\", gender: \"m\" },\n datetime: { label: \"\u05EA\u05D0\u05E8\u05D9\u05DA \u05D5\u05D6\u05DE\u05DF ISO\", gender: \"m\" },\n date: { label: \"\u05EA\u05D0\u05E8\u05D9\u05DA ISO\", gender: \"m\" },\n time: { label: \"\u05D6\u05DE\u05DF ISO\", gender: \"m\" },\n duration: { label: \"\u05DE\u05E9\u05DA \u05D6\u05DE\u05DF ISO\", gender: \"m\" },\n ipv4: { label: \"\u05DB\u05EA\u05D5\u05D1\u05EA IPv4\", gender: \"f\" },\n ipv6: { label: \"\u05DB\u05EA\u05D5\u05D1\u05EA IPv6\", gender: \"f\" },\n mac: { label: \"\u05DB\u05EA\u05D5\u05D1\u05EA MAC\", gender: \"f\" },\n cidrv4: { label: \"\u05D8\u05D5\u05D5\u05D7 IPv4\", gender: \"m\" },\n cidrv6: { label: \"\u05D8\u05D5\u05D5\u05D7 IPv6\", gender: \"m\" },\n base64: { label: \"\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA \u05D1\u05D1\u05E1\u05D9\u05E1 64\", gender: \"f\" },\n base64url: { label: \"\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA \u05D1\u05D1\u05E1\u05D9\u05E1 64 \u05DC\u05DB\u05EA\u05D5\u05D1\u05D5\u05EA \u05E8\u05E9\u05EA\", gender: \"f\" },\n json_string: { label: \"\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA JSON\", gender: \"f\" },\n e164: { label: \"\u05DE\u05E1\u05E4\u05E8 E.164\", gender: \"m\" },\n credit_card: { label: \"\u05DE\u05E1\u05E4\u05E8 \u05DB\u05E8\u05D8\u05D9\u05E1 \u05D0\u05E9\u05E8\u05D0\u05D9\", gender: \"m\" },\n currency_code: { label: \"\u05E7\u05D5\u05D3 \u05DE\u05D8\u05D1\u05E2\", gender: \"m\" },\n iban: { label: \"IBAN\", gender: \"m\" },\n jwt: { label: \"JWT\", gender: \"m\" },\n template_literal: { label: \"\u05E7\u05DC\u05D8\", gender: \"m\" },\n ends_with: { label: \"\u05E7\u05DC\u05D8\", gender: \"m\" },\n includes: { label: \"\u05E7\u05DC\u05D8\", gender: \"m\" },\n lowercase: { label: \"\u05E7\u05DC\u05D8\", gender: \"m\" },\n starts_with: { label: \"\u05E7\u05DC\u05D8\", gender: \"m\" },\n uppercase: { label: \"\u05E7\u05DC\u05D8\", gender: \"m\" },\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n // Expected type: show without definite article for clearer Hebrew\n const expectedKey = issue.expected;\n const expected = TypeDictionary[expectedKey ?? \"\"] ?? typeLabel(expectedKey);\n // Received: show localized label if known, otherwise constructor/raw\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? TypeNames[receivedType]?.label ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u05E7\u05DC\u05D8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA instanceof ${issue.expected}, \u05D4\u05EA\u05E7\u05D1\u05DC ${received}`;\n }\n return `\u05E7\u05DC\u05D8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${expected}, \u05D4\u05EA\u05E7\u05D1\u05DC ${received}`;\n }\n case \"invalid_value\": {\n if (issue.values.length === 1) {\n return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D4\u05E2\u05E8\u05DA \u05D7\u05D9\u05D9\u05D1 \u05DC\u05D4\u05D9\u05D5\u05EA ${util.stringifyPrimitive(issue.values[0])}`;\n }\n // Join values with proper Hebrew formatting\n const stringified = issue.values.map((v) => util.stringifyPrimitive(v));\n if (issue.values.length === 2) {\n return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D4\u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA \u05D4\u05DE\u05EA\u05D0\u05D9\u05DE\u05D5\u05EA \u05D4\u05DF ${stringified[0]} \u05D0\u05D5 ${stringified[1]}`;\n }\n // For 3+ values: \"a\", \"b\" \u05D0\u05D5 \"c\"\n const lastValue = stringified[stringified.length - 1];\n const restValues = stringified.slice(0, -1).join(\", \");\n return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D4\u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA \u05D4\u05DE\u05EA\u05D0\u05D9\u05DE\u05D5\u05EA \u05D4\u05DF ${restValues} \u05D0\u05D5 ${lastValue}`;\n }\n case \"too_big\": {\n const sizing = getSizing(issue.origin);\n const subject = withDefinite(issue.origin ?? \"value\");\n if (issue.origin === \"string\") {\n // Special handling for strings - more natural Hebrew\n return `${sizing?.longLabel ?? \"\u05D0\u05E8\u05D5\u05DA\"} \u05DE\u05D3\u05D9: ${subject} \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05DB\u05D9\u05DC ${issue.maximum.toString()} ${sizing?.unit ?? \"\"} ${issue.inclusive ? \"\u05D0\u05D5 \u05E4\u05D7\u05D5\u05EA\" : \"\u05DC\u05DB\u05DC \u05D4\u05D9\u05D5\u05EA\u05E8\"}`.trim();\n }\n if (issue.origin === \"number\") {\n // Natural Hebrew for numbers\n const comparison = issue.inclusive ? `\u05E7\u05D8\u05DF \u05D0\u05D5 \u05E9\u05D5\u05D5\u05D4 \u05DC-${issue.maximum}` : `\u05E7\u05D8\u05DF \u05DE-${issue.maximum}`;\n return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${subject} \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${comparison}`;\n }\n if (issue.origin === \"array\" || issue.origin === \"set\") {\n // Natural Hebrew for arrays and sets\n const verb = issue.origin === \"set\" ? \"\u05E6\u05E8\u05D9\u05DB\u05D4\" : \"\u05E6\u05E8\u05D9\u05DA\";\n const comparison = issue.inclusive\n ? `${issue.maximum} ${sizing?.unit ?? \"\"} \u05D0\u05D5 \u05E4\u05D7\u05D5\u05EA`\n : `\u05E4\u05D7\u05D5\u05EA \u05DE-${issue.maximum} ${sizing?.unit ?? \"\"}`;\n return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${subject} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${comparison}`.trim();\n }\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const be = verbFor(issue.origin ?? \"value\");\n if (sizing?.unit) {\n return `${sizing.longLabel} \u05DE\u05D3\u05D9: ${subject} ${be} ${adj}${issue.maximum.toString()} ${sizing.unit}`;\n }\n return `${sizing?.longLabel ?? \"\u05D2\u05D3\u05D5\u05DC\"} \u05DE\u05D3\u05D9: ${subject} ${be} ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const sizing = getSizing(issue.origin);\n const subject = withDefinite(issue.origin ?? \"value\");\n if (issue.origin === \"string\") {\n // Special handling for strings - more natural Hebrew\n return `${sizing?.shortLabel ?? \"\u05E7\u05E6\u05E8\"} \u05DE\u05D3\u05D9: ${subject} \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05DB\u05D9\u05DC ${issue.minimum.toString()} ${sizing?.unit ?? \"\"} ${issue.inclusive ? \"\u05D0\u05D5 \u05D9\u05D5\u05EA\u05E8\" : \"\u05DC\u05E4\u05D7\u05D5\u05EA\"}`.trim();\n }\n if (issue.origin === \"number\") {\n // Natural Hebrew for numbers\n const comparison = issue.inclusive ? `\u05D2\u05D3\u05D5\u05DC \u05D0\u05D5 \u05E9\u05D5\u05D5\u05D4 \u05DC-${issue.minimum}` : `\u05D2\u05D3\u05D5\u05DC \u05DE-${issue.minimum}`;\n return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject} \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${comparison}`;\n }\n if (issue.origin === \"array\" || issue.origin === \"set\") {\n // Natural Hebrew for arrays and sets\n const verb = issue.origin === \"set\" ? \"\u05E6\u05E8\u05D9\u05DB\u05D4\" : \"\u05E6\u05E8\u05D9\u05DA\";\n // Special case for singular (minimum === 1)\n if (issue.minimum === 1 && issue.inclusive) {\n const singularPhrase = issue.origin === \"set\" ? \"\u05DC\u05E4\u05D7\u05D5\u05EA \u05E4\u05E8\u05D9\u05D8 \u05D0\u05D7\u05D3\" : \"\u05DC\u05E4\u05D7\u05D5\u05EA \u05E4\u05E8\u05D9\u05D8 \u05D0\u05D7\u05D3\";\n return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${singularPhrase}`;\n }\n const comparison = issue.inclusive\n ? `${issue.minimum} ${sizing?.unit ?? \"\"} \u05D0\u05D5 \u05D9\u05D5\u05EA\u05E8`\n : `\u05D9\u05D5\u05EA\u05E8 \u05DE-${issue.minimum} ${sizing?.unit ?? \"\"}`;\n return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${comparison}`.trim();\n }\n const adj = issue.inclusive ? \">=\" : \">\";\n const be = verbFor(issue.origin ?? \"value\");\n if (sizing?.unit) {\n return `${sizing.shortLabel} \u05DE\u05D3\u05D9: ${subject} ${be} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `${sizing?.shortLabel ?? \"\u05E7\u05D8\u05DF\"} \u05DE\u05D3\u05D9: ${subject} ${be} ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n // These apply to strings \u2014 use feminine grammar + \u05D4\u05F3 \u05D4\u05D9\u05D3\u05D9\u05E2\u05D4\n if (_issue.format === \"starts_with\")\n return `\u05D4\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA \u05D7\u05D9\u05D9\u05D1\u05EA \u05DC\u05D4\u05EA\u05D7\u05D9\u05DC \u05D1 \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `\u05D4\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA \u05D7\u05D9\u05D9\u05D1\u05EA \u05DC\u05D4\u05E1\u05EA\u05D9\u05D9\u05DD \u05D1 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u05D4\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA \u05D7\u05D9\u05D9\u05D1\u05EA \u05DC\u05DB\u05DC\u05D5\u05DC \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u05D4\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA \u05D7\u05D9\u05D9\u05D1\u05EA \u05DC\u05D4\u05EA\u05D0\u05D9\u05DD \u05DC\u05EA\u05D1\u05E0\u05D9\u05EA ${_issue.pattern}`;\n // Handle gender agreement for formats\n const nounEntry = FormatDictionary[_issue.format];\n const noun = nounEntry?.label ?? _issue.format;\n const gender = nounEntry?.gender ?? \"m\";\n const adjective = gender === \"f\" ? \"\u05EA\u05E7\u05D9\u05E0\u05D4\" : \"\u05EA\u05E7\u05D9\u05DF\";\n return `${noun} \u05DC\u05D0 ${adjective}`;\n }\n case \"not_multiple_of\":\n return `\u05DE\u05E1\u05E4\u05E8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D7\u05D9\u05D9\u05D1 \u05DC\u05D4\u05D9\u05D5\u05EA \u05DE\u05DB\u05E4\u05DC\u05D4 \u05E9\u05DC ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u05DE\u05E4\u05EA\u05D7${issue.keys.length > 1 ? \"\u05D5\u05EA\" : \"\"} \u05DC\u05D0 \u05DE\u05D6\u05D5\u05D4${issue.keys.length > 1 ? \"\u05D9\u05DD\" : \"\u05D4\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\": {\n return `\u05E9\u05D3\u05D4 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF \u05D1\u05D0\u05D5\u05D1\u05D9\u05D9\u05E7\u05D8`;\n }\n case \"invalid_union\":\n return \"\u05E7\u05DC\u05D8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF\";\n case \"invalid_element\": {\n const place = withDefinite(issue.origin ?? \"array\");\n return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF \u05D1${place}`;\n }\n default:\n return `\u05E7\u05DC\u05D8 \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0905\u0915\u094D\u0937\u0930\", verb: \"\u0930\u0916\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F\" },\n file: { unit: \"\u092C\u093E\u0907\u091F\u094D\u0938\", verb: \"\u0930\u0916\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F\" },\n array: { unit: \"\u0924\u0924\u094D\u0935\", verb: \"\u0930\u0916\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F\" },\n set: { unit: \"\u0924\u0924\u094D\u0935\", verb: \"\u0930\u0916\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F\" },\n map: { unit: \"\u092A\u094D\u0930\u0935\u093F\u0937\u094D\u091F\u093F\u092F\u093E\u0901\", verb: \"\u0930\u0916\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0907\u0928\u092A\u0941\u091F\",\n email: \"\u0908\u092E\u0947\u0932 \u092A\u0924\u093E\",\n url: \"URL\",\n emoji: \"\u0907\u092E\u094B\u091C\u0940\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0924\u093F\u0925\u093F \u0914\u0930 \u0938\u092E\u092F\",\n date: \"ISO \u0924\u093F\u0925\u093F\",\n time: \"ISO \u0938\u092E\u092F\",\n duration: \"ISO \u0905\u0935\u0927\u093F\",\n ipv4: \"IPv4 \u092A\u0924\u093E\",\n ipv6: \"IPv6 \u092A\u0924\u093E\",\n mac: \"MAC \u092A\u0924\u093E\",\n cidrv4: \"IPv4 \u0936\u094D\u0930\u0947\u0923\u0940\",\n cidrv6: \"IPv6 \u0936\u094D\u0930\u0947\u0923\u0940\",\n base64: \"Base64-\u090F\u0928\u094D\u0915\u094B\u0921\u0947\u0921 \u0938\u094D\u091F\u094D\u0930\u093F\u0902\u0917\",\n base64url: \"Base64URL-\u090F\u0928\u094D\u0915\u094B\u0921\u0947\u0921 \u0938\u094D\u091F\u094D\u0930\u093F\u0902\u0917\",\n json_string: \"JSON \u0938\u094D\u091F\u094D\u0930\u093F\u0902\u0917\",\n e164: \"E.164 \u0938\u0902\u0916\u094D\u092F\u093E\",\n credit_card: \"\u0915\u094D\u0930\u0947\u0921\u093F\u091F \u0915\u093E\u0930\u094D\u0921 \u0938\u0902\u0916\u094D\u092F\u093E\",\n currency_code: \"\u092E\u0941\u0926\u094D\u0930\u093E \u0915\u094B\u0921\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0907\u0928\u092A\u0941\u091F\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0907\u0928\u092A\u0941\u091F: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 ${expected}, \u092A\u094D\u0930\u093E\u092A\u094D\u0924 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0907\u0928\u092A\u0941\u091F: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0935\u093F\u0915\u0932\u094D\u092A: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 \u092E\u093E\u0928\u094B\u0902 \u092E\u0947\u0902 \u0938\u0947 \u090F\u0915 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u092C\u0939\u0941\u0924 \u092C\u0921\u093C\u093E: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 \u0925\u093E \u0915\u093F ${issue.origin ?? \"\u092E\u093E\u0928\"} \u092E\u0947\u0902 ${adj}${issue.maximum} ${sizing.unit} \u0939\u094B\u0902`;\n return `\u092C\u0939\u0941\u0924 \u092C\u0921\u093C\u093E: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 \u0925\u093E \u0915\u093F ${issue.origin ?? \"\u092E\u093E\u0928\"} ${adj}${issue.maximum} \u0939\u094B`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u092C\u0939\u0941\u0924 \u091B\u094B\u091F\u093E: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 \u0925\u093E \u0915\u093F ${issue.origin} \u092E\u0947\u0902 ${adj}${issue.minimum} ${sizing.unit} \u0939\u094B\u0902`;\n return `\u092C\u0939\u0941\u0924 \u091B\u094B\u091F\u093E: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 \u0925\u093E \u0915\u093F ${issue.origin} ${adj}${issue.minimum} \u0939\u094B`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u094D\u091F\u094D\u0930\u093F\u0902\u0917: \"${_issue.prefix}\" \u0938\u0947 \u0936\u0941\u0930\u0942 \u0939\u094B\u0928\u093E \u091A\u093E\u0939\u093F\u090F`;\n if (_issue.format === \"ends_with\")\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u094D\u091F\u094D\u0930\u093F\u0902\u0917: \"${_issue.suffix}\" \u092A\u0930 \u0938\u092E\u093E\u092A\u094D\u0924 \u0939\u094B\u0928\u093E \u091A\u093E\u0939\u093F\u090F`;\n if (_issue.format === \"includes\")\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u094D\u091F\u094D\u0930\u093F\u0902\u0917: \u0907\u0938\u092E\u0947\u0902 \"${_issue.includes}\" \u0936\u093E\u092E\u093F\u0932 \u0939\u094B\u0928\u093E \u091A\u093E\u0939\u093F\u090F`;\n if (_issue.format === \"regex\")\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u094D\u091F\u094D\u0930\u093F\u0902\u0917: \u092A\u0948\u091F\u0930\u094D\u0928 ${_issue.pattern} \u0938\u0947 \u092E\u0947\u0932 \u0916\u093E\u0928\u093E \u091A\u093E\u0939\u093F\u090F`;\n return `\u0905\u092E\u093E\u0928\u094D\u092F ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u0902\u0916\u094D\u092F\u093E: \u092F\u0939 ${issue.divisor} \u0915\u093E \u0917\u0941\u0923\u091C \u0939\u094B\u0928\u093E \u091A\u093E\u0939\u093F\u090F`;\n case \"unrecognized_keys\":\n return `\u0905\u092A\u0930\u093F\u091A\u093F\u0924 \u0915\u0941\u0902\u091C\u0940${issue.keys.length > 1 ? \"\u092F\u093E\u0901\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0915\u0941\u0902\u091C\u0940: ${issue.origin} \u092E\u0947\u0902`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0921\u093F\u0938\u094D\u0915\u094D\u0930\u093F\u092E\u093F\u0928\u0947\u091F\u0930 \u092E\u093E\u0928: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 ${opts}`;\n }\n return \"\u0905\u092E\u093E\u0928\u094D\u092F \u0907\u0928\u092A\u0941\u091F\";\n case \"invalid_element\":\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u092E\u093E\u0928: ${issue.origin} \u092E\u0947\u0902`;\n default:\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0907\u0928\u092A\u0941\u091F`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"znakova\", verb: \"imati\" },\n file: { unit: \"bajtova\", verb: \"imati\" },\n array: { unit: \"stavki\", verb: \"imati\" },\n set: { unit: \"stavki\", verb: \"imati\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"unos\",\n email: \"email adresa\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO datum i vrijeme\",\n date: \"ISO datum\",\n time: \"ISO vrijeme\",\n duration: \"ISO trajanje\",\n ipv4: \"IPv4 adresa\",\n ipv6: \"IPv6 adresa\",\n mac: \"MAC adresa\",\n cidrv4: \"IPv4 raspon\",\n cidrv6: \"IPv6 raspon\",\n base64: \"base64 kodirani tekst\",\n base64url: \"base64url kodirani tekst\",\n json_string: \"JSON tekst\",\n e164: \"E.164 broj\",\n credit_card: \"broj kreditne kartice\",\n currency_code: \"kod valute\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"unos\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n string: \"tekst\",\n number: \"broj\",\n boolean: \"boolean\",\n array: \"niz\",\n object: \"objekt\",\n set: \"skup\",\n file: \"datoteka\",\n date: \"datum\",\n bigint: \"bigint\",\n symbol: \"simbol\",\n undefined: \"undefined\",\n null: \"null\",\n function: \"funkcija\",\n map: \"mapa\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Neispravan unos: o\u010Dekuje se instanceof ${issue.expected}, a primljeno je ${received}`;\n }\n return `Neispravan unos: o\u010Dekuje se ${expected}, a primljeno je ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Neispravna vrijednost: o\u010Dekivano ${util.stringifyPrimitive(issue.values[0])}`;\n return `Neispravna opcija: o\u010Dekivano jedno od ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n if (sizing)\n return `Preveliko: o\u010Dekivano da ${origin ?? \"vrijednost\"} ima ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elemenata\"}`;\n return `Preveliko: o\u010Dekivano da ${origin ?? \"vrijednost\"} bude ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n if (sizing) {\n return `Premalo: o\u010Dekivano da ${origin} ima ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Premalo: o\u010Dekivano da ${origin} bude ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Neispravan tekst: mora zapo\u010Dinjati s \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Neispravan tekst: mora zavr\u0161avati s \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Neispravan tekst: mora sadr\u017Eavati \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Neispravan tekst: mora odgovarati uzorku ${_issue.pattern}`;\n return `Neispravna ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Neispravan broj: mora biti vi\u0161ekratnik od ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Neprepoznat${issue.keys.length > 1 ? \"i klju\u010Devi\" : \" klju\u010D\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Neispravan klju\u010D u ${TypeDictionary[issue.origin] ?? issue.origin}`;\n case \"invalid_union\":\n return \"Neispravan unos\";\n case \"invalid_element\":\n return `Neispravna vrijednost u ${TypeDictionary[issue.origin] ?? issue.origin}`;\n default:\n return `Neispravan unos`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"karakter\", verb: \"legyen\" },\n file: { unit: \"byte\", verb: \"legyen\" },\n array: { unit: \"elem\", verb: \"legyen\" },\n set: { unit: \"elem\", verb: \"legyen\" },\n map: { unit: \"elem\", verb: \"legyen\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"bemenet\",\n email: \"email c\u00EDm\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO id\u0151b\u00E9lyeg\",\n date: \"ISO d\u00E1tum\",\n time: \"ISO id\u0151\",\n duration: \"ISO id\u0151intervallum\",\n ipv4: \"IPv4 c\u00EDm\",\n ipv6: \"IPv6 c\u00EDm\",\n mac: \"MAC c\u00EDm\",\n cidrv4: \"IPv4 tartom\u00E1ny\",\n cidrv6: \"IPv6 tartom\u00E1ny\",\n base64: \"base64-k\u00F3dolt string\",\n base64url: \"base64url-k\u00F3dolt string\",\n json_string: \"JSON string\",\n e164: \"E.164 sz\u00E1m\",\n credit_card: \"hitelk\u00E1rtyasz\u00E1m\",\n currency_code: \"p\u00E9nznemk\u00F3d\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"bemenet\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"sz\u00E1m\",\n array: \"t\u00F6mb\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u00C9rv\u00E9nytelen bemenet: a v\u00E1rt \u00E9rt\u00E9k instanceof ${issue.expected}, a kapott \u00E9rt\u00E9k ${received}`;\n }\n return `\u00C9rv\u00E9nytelen bemenet: a v\u00E1rt \u00E9rt\u00E9k ${expected}, a kapott \u00E9rt\u00E9k ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u00C9rv\u00E9nytelen bemenet: a v\u00E1rt \u00E9rt\u00E9k ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u00C9rv\u00E9nytelen opci\u00F3: valamelyik \u00E9rt\u00E9k v\u00E1rt ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `T\u00FAl nagy: ${issue.origin ?? \"\u00E9rt\u00E9k\"} m\u00E9rete t\u00FAl nagy ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elem\"}`;\n return `T\u00FAl nagy: a bemeneti \u00E9rt\u00E9k ${issue.origin ?? \"\u00E9rt\u00E9k\"} t\u00FAl nagy: ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `T\u00FAl kicsi: a bemeneti \u00E9rt\u00E9k ${issue.origin} m\u00E9rete t\u00FAl kicsi ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `T\u00FAl kicsi: a bemeneti \u00E9rt\u00E9k ${issue.origin} t\u00FAl kicsi ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u00C9rv\u00E9nytelen string: \"${_issue.prefix}\" \u00E9rt\u00E9kkel kell kezd\u0151dnie`;\n if (_issue.format === \"ends_with\")\n return `\u00C9rv\u00E9nytelen string: \"${_issue.suffix}\" \u00E9rt\u00E9kkel kell v\u00E9gz\u0151dnie`;\n if (_issue.format === \"includes\")\n return `\u00C9rv\u00E9nytelen string: \"${_issue.includes}\" \u00E9rt\u00E9ket kell tartalmaznia`;\n if (_issue.format === \"regex\")\n return `\u00C9rv\u00E9nytelen string: ${_issue.pattern} mint\u00E1nak kell megfelelnie`;\n return `\u00C9rv\u00E9nytelen ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u00C9rv\u00E9nytelen sz\u00E1m: ${issue.divisor} t\u00F6bbsz\u00F6r\u00F6s\u00E9nek kell lennie`;\n case \"unrecognized_keys\":\n return `Ismeretlen kulcs${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u00C9rv\u00E9nytelen kulcs ${issue.origin}`;\n case \"invalid_union\":\n return \"\u00C9rv\u00E9nytelen bemenet\";\n case \"invalid_element\":\n return `\u00C9rv\u00E9nytelen \u00E9rt\u00E9k: ${issue.origin}`;\n default:\n return `\u00C9rv\u00E9nytelen bemenet`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nfunction getArmenianPlural(count, one, many) {\n return Math.abs(count) === 1 ? one : many;\n}\nfunction withDefiniteArticle(word) {\n if (!word)\n return \"\";\n const vowels = [\"\u0561\", \"\u0565\", \"\u0568\", \"\u056B\", \"\u0578\", \"\u0578\u0582\", \"\u0585\"];\n const lastChar = word[word.length - 1];\n return word + (vowels.includes(lastChar) ? \"\u0576\" : \"\u0568\");\n}\nconst error = () => {\n const Sizable = {\n string: {\n unit: {\n one: \"\u0576\u0577\u0561\u0576\",\n many: \"\u0576\u0577\u0561\u0576\u0576\u0565\u0580\",\n },\n verb: \"\u0578\u0582\u0576\u0565\u0576\u0561\u056C\",\n },\n file: {\n unit: {\n one: \"\u0562\u0561\u0575\u0569\",\n many: \"\u0562\u0561\u0575\u0569\u0565\u0580\",\n },\n verb: \"\u0578\u0582\u0576\u0565\u0576\u0561\u056C\",\n },\n array: {\n unit: {\n one: \"\u057F\u0561\u0580\u0580\",\n many: \"\u057F\u0561\u0580\u0580\u0565\u0580\",\n },\n verb: \"\u0578\u0582\u0576\u0565\u0576\u0561\u056C\",\n },\n set: {\n unit: {\n one: \"\u057F\u0561\u0580\u0580\",\n many: \"\u057F\u0561\u0580\u0580\u0565\u0580\",\n },\n verb: \"\u0578\u0582\u0576\u0565\u0576\u0561\u056C\",\n },\n map: {\n unit: {\n one: \"\u057F\u0561\u0580\u0580\",\n many: \"\u057F\u0561\u0580\u0580\u0565\u0580\",\n },\n verb: \"\u0578\u0582\u0576\u0565\u0576\u0561\u056C\",\n },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0574\u0578\u0582\u057F\u0584\",\n email: \"\u0567\u056C. \u0570\u0561\u057D\u0581\u0565\",\n url: \"URL\",\n emoji: \"\u0567\u0574\u0578\u057B\u056B\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0561\u0574\u057D\u0561\u0569\u056B\u057E \u0587 \u056A\u0561\u0574\",\n date: \"ISO \u0561\u0574\u057D\u0561\u0569\u056B\u057E\",\n time: \"ISO \u056A\u0561\u0574\",\n duration: \"ISO \u057F\u0587\u0578\u0572\u0578\u0582\u0569\u0575\u0578\u0582\u0576\",\n ipv4: \"IPv4 \u0570\u0561\u057D\u0581\u0565\",\n ipv6: \"IPv6 \u0570\u0561\u057D\u0581\u0565\",\n mac: \"MAC \u0570\u0561\u057D\u0581\u0565\",\n cidrv4: \"IPv4 \u0574\u056B\u057B\u0561\u056F\u0561\u0575\u0584\",\n cidrv6: \"IPv6 \u0574\u056B\u057B\u0561\u056F\u0561\u0575\u0584\",\n base64: \"base64 \u0571\u0587\u0561\u0579\u0561\u0583\u0578\u057E \u057F\u0578\u0572\",\n base64url: \"base64url \u0571\u0587\u0561\u0579\u0561\u0583\u0578\u057E \u057F\u0578\u0572\",\n json_string: \"JSON \u057F\u0578\u0572\",\n e164: \"E.164 \u0570\u0561\u0574\u0561\u0580\",\n credit_card: \"\u056F\u0580\u0565\u0564\u056B\u057F \u0584\u0561\u0580\u057F\u056B \u0570\u0561\u0574\u0561\u0580\",\n currency_code: \"\u0561\u0580\u056A\u0578\u0582\u0575\u0569\u056B \u056F\u0578\u0564\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0574\u0578\u0582\u057F\u0584\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0569\u056B\u057E\",\n array: \"\u0566\u0561\u0576\u0563\u057E\u0561\u056E\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u054D\u056D\u0561\u056C \u0574\u0578\u0582\u057F\u0584\u0561\u0563\u0580\u0578\u0582\u0574\u2024 \u057D\u057A\u0561\u057D\u057E\u0578\u0582\u0574 \u0567\u0580 instanceof ${issue.expected}, \u057D\u057F\u0561\u0581\u057E\u0565\u056C \u0567 ${received}`;\n }\n return `\u054D\u056D\u0561\u056C \u0574\u0578\u0582\u057F\u0584\u0561\u0563\u0580\u0578\u0582\u0574\u2024 \u057D\u057A\u0561\u057D\u057E\u0578\u0582\u0574 \u0567\u0580 ${expected}, \u057D\u057F\u0561\u0581\u057E\u0565\u056C \u0567 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u054D\u056D\u0561\u056C \u0574\u0578\u0582\u057F\u0584\u0561\u0563\u0580\u0578\u0582\u0574\u2024 \u057D\u057A\u0561\u057D\u057E\u0578\u0582\u0574 \u0567\u0580 ${util.stringifyPrimitive(issue.values[1])}`;\n return `\u054D\u056D\u0561\u056C \u057F\u0561\u0580\u0562\u0565\u0580\u0561\u056F\u2024 \u057D\u057A\u0561\u057D\u057E\u0578\u0582\u0574 \u0567\u0580 \u0570\u0565\u057F\u0587\u0575\u0561\u056C\u0576\u0565\u0580\u056B\u0581 \u0574\u0565\u056F\u0568\u055D ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n const maxValue = Number(issue.maximum);\n const unit = getArmenianPlural(maxValue, sizing.unit.one, sizing.unit.many);\n return `\u0549\u0561\u0583\u0561\u0566\u0561\u0576\u0581 \u0574\u0565\u056E \u0561\u0580\u056A\u0565\u0584\u2024 \u057D\u057A\u0561\u057D\u057E\u0578\u0582\u0574 \u0567, \u0578\u0580 ${withDefiniteArticle(issue.origin ?? \"\u0561\u0580\u056A\u0565\u0584\")} \u056F\u0578\u0582\u0576\u0565\u0576\u0561 ${adj}${issue.maximum.toString()} ${unit}`;\n }\n return `\u0549\u0561\u0583\u0561\u0566\u0561\u0576\u0581 \u0574\u0565\u056E \u0561\u0580\u056A\u0565\u0584\u2024 \u057D\u057A\u0561\u057D\u057E\u0578\u0582\u0574 \u0567, \u0578\u0580 ${withDefiniteArticle(issue.origin ?? \"\u0561\u0580\u056A\u0565\u0584\")} \u056C\u056B\u0576\u056B ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n const minValue = Number(issue.minimum);\n const unit = getArmenianPlural(minValue, sizing.unit.one, sizing.unit.many);\n return `\u0549\u0561\u0583\u0561\u0566\u0561\u0576\u0581 \u0583\u0578\u0584\u0580 \u0561\u0580\u056A\u0565\u0584\u2024 \u057D\u057A\u0561\u057D\u057E\u0578\u0582\u0574 \u0567, \u0578\u0580 ${withDefiniteArticle(issue.origin)} \u056F\u0578\u0582\u0576\u0565\u0576\u0561 ${adj}${issue.minimum.toString()} ${unit}`;\n }\n return `\u0549\u0561\u0583\u0561\u0566\u0561\u0576\u0581 \u0583\u0578\u0584\u0580 \u0561\u0580\u056A\u0565\u0584\u2024 \u057D\u057A\u0561\u057D\u057E\u0578\u0582\u0574 \u0567, \u0578\u0580 ${withDefiniteArticle(issue.origin)} \u056C\u056B\u0576\u056B ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u054D\u056D\u0561\u056C \u057F\u0578\u0572\u2024 \u057A\u0565\u057F\u0584 \u0567 \u057D\u056F\u057D\u057E\u056B \"${_issue.prefix}\"-\u0578\u057E`;\n if (_issue.format === \"ends_with\")\n return `\u054D\u056D\u0561\u056C \u057F\u0578\u0572\u2024 \u057A\u0565\u057F\u0584 \u0567 \u0561\u057E\u0561\u0580\u057F\u057E\u056B \"${_issue.suffix}\"-\u0578\u057E`;\n if (_issue.format === \"includes\")\n return `\u054D\u056D\u0561\u056C \u057F\u0578\u0572\u2024 \u057A\u0565\u057F\u0584 \u0567 \u057A\u0561\u0580\u0578\u0582\u0576\u0561\u056F\u056B \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u054D\u056D\u0561\u056C \u057F\u0578\u0572\u2024 \u057A\u0565\u057F\u0584 \u0567 \u0570\u0561\u0574\u0561\u057A\u0561\u057F\u0561\u057D\u056D\u0561\u0576\u056B ${_issue.pattern} \u0571\u0587\u0561\u0579\u0561\u0583\u056B\u0576`;\n return `\u054D\u056D\u0561\u056C ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u054D\u056D\u0561\u056C \u0569\u056B\u057E\u2024 \u057A\u0565\u057F\u0584 \u0567 \u0562\u0561\u0566\u0574\u0561\u057A\u0561\u057F\u056B\u056F \u056C\u056B\u0576\u056B ${issue.divisor}-\u056B`;\n case \"unrecognized_keys\":\n return `\u0549\u0573\u0561\u0576\u0561\u0579\u057E\u0561\u056E \u0562\u0561\u0576\u0561\u056C\u056B${issue.keys.length > 1 ? \"\u0576\u0565\u0580\" : \"\"}. ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u054D\u056D\u0561\u056C \u0562\u0561\u0576\u0561\u056C\u056B ${withDefiniteArticle(issue.origin)}-\u0578\u0582\u0574`;\n case \"invalid_union\":\n return \"\u054D\u056D\u0561\u056C \u0574\u0578\u0582\u057F\u0584\u0561\u0563\u0580\u0578\u0582\u0574\";\n case \"invalid_element\":\n return `\u054D\u056D\u0561\u056C \u0561\u0580\u056A\u0565\u0584 ${withDefiniteArticle(issue.origin)}-\u0578\u0582\u0574`;\n default:\n return `\u054D\u056D\u0561\u056C \u0574\u0578\u0582\u057F\u0584\u0561\u0563\u0580\u0578\u0582\u0574`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"karakter\", verb: \"memiliki\" },\n file: { unit: \"byte\", verb: \"memiliki\" },\n array: { unit: \"item\", verb: \"memiliki\" },\n set: { unit: \"item\", verb: \"memiliki\" },\n map: { unit: \"item\", verb: \"memiliki\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"input\",\n email: \"alamat email\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"tanggal dan waktu format ISO\",\n date: \"tanggal format ISO\",\n time: \"jam format ISO\",\n duration: \"durasi format ISO\",\n ipv4: \"alamat IPv4\",\n ipv6: \"alamat IPv6\",\n mac: \"alamat MAC\",\n cidrv4: \"rentang alamat IPv4\",\n cidrv6: \"rentang alamat IPv6\",\n base64: \"string dengan enkode base64\",\n base64url: \"string dengan enkode base64url\",\n json_string: \"string JSON\",\n e164: \"angka E.164\",\n credit_card: \"nomor kartu kredit\",\n currency_code: \"kode mata uang\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Input tidak valid: diharapkan instanceof ${issue.expected}, diterima ${received}`;\n }\n return `Input tidak valid: diharapkan ${expected}, diterima ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Input tidak valid: diharapkan ${util.stringifyPrimitive(issue.values[0])}`;\n return `Pilihan tidak valid: diharapkan salah satu dari ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Terlalu besar: diharapkan ${issue.origin ?? \"value\"} memiliki ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elemen\"}`;\n return `Terlalu besar: diharapkan ${issue.origin ?? \"value\"} menjadi ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Terlalu kecil: diharapkan ${issue.origin} memiliki ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Terlalu kecil: diharapkan ${issue.origin} menjadi ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `String tidak valid: harus dimulai dengan \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `String tidak valid: harus berakhir dengan \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `String tidak valid: harus menyertakan \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `String tidak valid: harus sesuai pola ${_issue.pattern}`;\n return `${FormatDictionary[_issue.format] ?? issue.format} tidak valid`;\n }\n case \"not_multiple_of\":\n return `Angka tidak valid: harus kelipatan dari ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Kunci tidak dikenali ${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Kunci tidak valid di ${issue.origin}`;\n case \"invalid_union\":\n return \"Input tidak valid\";\n case \"invalid_element\":\n return `Nilai tidak valid di ${issue.origin}`;\n default:\n return `Input tidak valid`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"stafi\", verb: \"a\u00F0 hafa\" },\n file: { unit: \"b\u00E6ti\", verb: \"a\u00F0 hafa\" },\n array: { unit: \"hluti\", verb: \"a\u00F0 hafa\" },\n set: { unit: \"hluti\", verb: \"a\u00F0 hafa\" },\n map: { unit: \"hluti\", verb: \"a\u00F0 hafa\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"gildi\",\n email: \"netfang\",\n url: \"vefsl\u00F3\u00F0\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO dagsetning og t\u00EDmi\",\n date: \"ISO dagsetning\",\n time: \"ISO t\u00EDmi\",\n duration: \"ISO t\u00EDmalengd\",\n ipv4: \"IPv4 address\",\n ipv6: \"IPv6 address\",\n mac: \"MAC address\",\n cidrv4: \"IPv4 range\",\n cidrv6: \"IPv6 range\",\n base64: \"base64-encoded strengur\",\n base64url: \"base64url-encoded strengur\",\n json_string: \"JSON strengur\",\n e164: \"E.164 t\u00F6lugildi\",\n credit_card: \"kreditkortan\u00FAmer\",\n currency_code: \"gjaldmi\u00F0ilsk\u00F3\u00F0i\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"gildi\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"n\u00FAmer\",\n array: \"fylki\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Rangt gildi: \u00DE\u00FA sl\u00F3st inn ${received} \u00FEar sem \u00E1 a\u00F0 vera instanceof ${issue.expected}`;\n }\n return `Rangt gildi: \u00DE\u00FA sl\u00F3st inn ${received} \u00FEar sem \u00E1 a\u00F0 vera ${expected}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Rangt gildi: gert r\u00E1\u00F0 fyrir ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u00D3gilt val: m\u00E1 vera eitt af eftirfarandi ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Of st\u00F3rt: gert er r\u00E1\u00F0 fyrir a\u00F0 ${issue.origin ?? \"gildi\"} hafi ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"hluti\"}`;\n return `Of st\u00F3rt: gert er r\u00E1\u00F0 fyrir a\u00F0 ${issue.origin ?? \"gildi\"} s\u00E9 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Of l\u00EDti\u00F0: gert er r\u00E1\u00F0 fyrir a\u00F0 ${issue.origin} hafi ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Of l\u00EDti\u00F0: gert er r\u00E1\u00F0 fyrir a\u00F0 ${issue.origin} s\u00E9 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u00D3gildur strengur: ver\u00F0ur a\u00F0 byrja \u00E1 \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u00D3gildur strengur: ver\u00F0ur a\u00F0 enda \u00E1 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u00D3gildur strengur: ver\u00F0ur a\u00F0 innihalda \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u00D3gildur strengur: ver\u00F0ur a\u00F0 fylgja mynstri ${_issue.pattern}`;\n return `Rangt ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `R\u00F6ng tala: ver\u00F0ur a\u00F0 vera margfeldi af ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u00D3\u00FEekkt ${issue.keys.length > 1 ? \"ir lyklar\" : \"ur lykill\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Rangur lykill \u00ED ${issue.origin}`;\n case \"invalid_union\":\n return \"Rangt gildi\";\n case \"invalid_element\":\n return `Rangt gildi \u00ED ${issue.origin}`;\n default:\n return `Rangt gildi`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"caratteri\", verb: \"avere\" },\n file: { unit: \"byte\", verb: \"avere\" },\n array: { unit: \"elementi\", verb: \"avere\" },\n set: { unit: \"elementi\", verb: \"avere\" },\n map: { unit: \"elementi\", verb: \"avere\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"input\",\n email: \"indirizzo email\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"data e ora ISO\",\n date: \"data ISO\",\n time: \"ora ISO\",\n duration: \"durata ISO\",\n ipv4: \"indirizzo IPv4\",\n ipv6: \"indirizzo IPv6\",\n mac: \"indirizzo MAC\",\n cidrv4: \"intervallo IPv4\",\n cidrv6: \"intervallo IPv6\",\n base64: \"stringa codificata in base64\",\n base64url: \"URL codificata in base64\",\n json_string: \"stringa JSON\",\n e164: \"numero E.164\",\n credit_card: \"numero di carta di credito\",\n currency_code: \"codice valuta\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"numero\",\n array: \"vettore\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Input non valido: atteso instanceof ${issue.expected}, ricevuto ${received}`;\n }\n return `Input non valido: atteso ${expected}, ricevuto ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Input non valido: atteso ${util.stringifyPrimitive(issue.values[0])}`;\n return `Opzione non valida: atteso uno tra ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Troppo grande: ${issue.origin ?? \"valore\"} deve avere ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elementi\"}`;\n return `Troppo grande: ${issue.origin ?? \"valore\"} deve essere ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Troppo piccolo: ${issue.origin} deve avere ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Troppo piccolo: ${issue.origin} deve essere ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Stringa non valida: deve iniziare con \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Stringa non valida: deve terminare con \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Stringa non valida: deve includere \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Stringa non valida: deve corrispondere al pattern ${_issue.pattern}`;\n return `Input non valido: ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Numero non valido: deve essere un multiplo di ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Chiav${issue.keys.length > 1 ? \"i\" : \"e\"} non riconosciut${issue.keys.length > 1 ? \"e\" : \"a\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Chiave non valida in ${issue.origin}`;\n case \"invalid_union\":\n return \"Input non valido\";\n case \"invalid_element\":\n return `Valore non valido in ${issue.origin}`;\n default:\n return `Input non valido`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u6587\u5B57\", verb: \"\u3067\u3042\u308B\" },\n file: { unit: \"\u30D0\u30A4\u30C8\", verb: \"\u3067\u3042\u308B\" },\n array: { unit: \"\u8981\u7D20\", verb: \"\u3067\u3042\u308B\" },\n set: { unit: \"\u8981\u7D20\", verb: \"\u3067\u3042\u308B\" },\n map: { unit: \"\u8981\u7D20\", verb: \"\u3067\u3042\u308B\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u5165\u529B\u5024\",\n email: \"\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\",\n url: \"URL\",\n emoji: \"\u7D75\u6587\u5B57\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO\u65E5\u6642\",\n date: \"ISO\u65E5\u4ED8\",\n time: \"ISO\u6642\u523B\",\n duration: \"ISO\u671F\u9593\",\n ipv4: \"IPv4\u30A2\u30C9\u30EC\u30B9\",\n ipv6: \"IPv6\u30A2\u30C9\u30EC\u30B9\",\n mac: \"MAC\u30A2\u30C9\u30EC\u30B9\",\n cidrv4: \"IPv4\u7BC4\u56F2\",\n cidrv6: \"IPv6\u7BC4\u56F2\",\n base64: \"base64\u30A8\u30F3\u30B3\u30FC\u30C9\u6587\u5B57\u5217\",\n base64url: \"base64url\u30A8\u30F3\u30B3\u30FC\u30C9\u6587\u5B57\u5217\",\n json_string: \"JSON\u6587\u5B57\u5217\",\n e164: \"E.164\u756A\u53F7\",\n credit_card: \"\u30AF\u30EC\u30B8\u30C3\u30C8\u30AB\u30FC\u30C9\u756A\u53F7\",\n currency_code: \"\u901A\u8CA8\u30B3\u30FC\u30C9\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u5165\u529B\u5024\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u6570\u5024\",\n array: \"\u914D\u5217\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u7121\u52B9\u306A\u5165\u529B: instanceof ${issue.expected}\u304C\u671F\u5F85\u3055\u308C\u307E\u3057\u305F\u304C\u3001${received}\u304C\u5165\u529B\u3055\u308C\u307E\u3057\u305F`;\n }\n return `\u7121\u52B9\u306A\u5165\u529B: ${expected}\u304C\u671F\u5F85\u3055\u308C\u307E\u3057\u305F\u304C\u3001${received}\u304C\u5165\u529B\u3055\u308C\u307E\u3057\u305F`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u7121\u52B9\u306A\u5165\u529B: ${util.stringifyPrimitive(issue.values[0])}\u304C\u671F\u5F85\u3055\u308C\u307E\u3057\u305F`;\n return `\u7121\u52B9\u306A\u9078\u629E: ${util.joinValues(issue.values, \"\u3001\")}\u306E\u3044\u305A\u308C\u304B\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"\u4EE5\u4E0B\u3067\u3042\u308B\" : \"\u3088\u308A\u5C0F\u3055\u3044\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u5927\u304D\u3059\u304E\u308B\u5024: ${issue.origin ?? \"\u5024\"}\u306F${issue.maximum.toString()}${sizing.unit ?? \"\u8981\u7D20\"}${adj}\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n return `\u5927\u304D\u3059\u304E\u308B\u5024: ${issue.origin ?? \"\u5024\"}\u306F${issue.maximum.toString()}${adj}\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \"\u4EE5\u4E0A\u3067\u3042\u308B\" : \"\u3088\u308A\u5927\u304D\u3044\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u5C0F\u3055\u3059\u304E\u308B\u5024: ${issue.origin}\u306F${issue.minimum.toString()}${sizing.unit}${adj}\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n return `\u5C0F\u3055\u3059\u304E\u308B\u5024: ${issue.origin}\u306F${issue.minimum.toString()}${adj}\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u7121\u52B9\u306A\u6587\u5B57\u5217: \"${_issue.prefix}\"\u3067\u59CB\u307E\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n if (_issue.format === \"ends_with\")\n return `\u7121\u52B9\u306A\u6587\u5B57\u5217: \"${_issue.suffix}\"\u3067\u7D42\u308F\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n if (_issue.format === \"includes\")\n return `\u7121\u52B9\u306A\u6587\u5B57\u5217: \"${_issue.includes}\"\u3092\u542B\u3080\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n if (_issue.format === \"regex\")\n return `\u7121\u52B9\u306A\u6587\u5B57\u5217: \u30D1\u30BF\u30FC\u30F3${_issue.pattern}\u306B\u4E00\u81F4\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n return `\u7121\u52B9\u306A${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u7121\u52B9\u306A\u6570\u5024: ${issue.divisor}\u306E\u500D\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;\n case \"unrecognized_keys\":\n return `\u8A8D\u8B58\u3055\u308C\u3066\u3044\u306A\u3044\u30AD\u30FC${issue.keys.length > 1 ? \"\u7FA4\" : \"\"}: ${util.joinValues(issue.keys, \"\u3001\")}`;\n case \"invalid_key\":\n return `${issue.origin}\u5185\u306E\u7121\u52B9\u306A\u30AD\u30FC`;\n case \"invalid_union\":\n return \"\u7121\u52B9\u306A\u5165\u529B\";\n case \"invalid_element\":\n return `${issue.origin}\u5185\u306E\u7121\u52B9\u306A\u5024`;\n default:\n return `\u7121\u52B9\u306A\u5165\u529B`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u10E1\u10D8\u10DB\u10D1\u10DD\u10DA\u10DD\", verb: \"\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1\" },\n file: { unit: \"\u10D1\u10D0\u10D8\u10E2\u10D8\", verb: \"\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1\" },\n array: { unit: \"\u10D4\u10DA\u10D4\u10DB\u10D4\u10DC\u10E2\u10D8\", verb: \"\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1\" },\n set: { unit: \"\u10D4\u10DA\u10D4\u10DB\u10D4\u10DC\u10E2\u10D8\", verb: \"\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1\" },\n map: { unit: \"\u10D4\u10DA\u10D4\u10DB\u10D4\u10DC\u10E2\u10D8\", verb: \"\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u10E8\u10D4\u10E7\u10D5\u10D0\u10DC\u10D0\",\n email: \"\u10D4\u10DA-\u10E4\u10DD\u10E1\u10E2\u10D8\u10E1 \u10DB\u10D8\u10E1\u10D0\u10DB\u10D0\u10E0\u10D7\u10D8\",\n url: \"URL\",\n emoji: \"\u10D4\u10DB\u10DD\u10EF\u10D8\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u10D7\u10D0\u10E0\u10D8\u10E6\u10D8-\u10D3\u10E0\u10DD\",\n date: \"\u10D7\u10D0\u10E0\u10D8\u10E6\u10D8\",\n time: \"\u10D3\u10E0\u10DD\",\n duration: \"\u10EE\u10D0\u10DC\u10D2\u10E0\u10EB\u10DA\u10D8\u10D5\u10DD\u10D1\u10D0\",\n ipv4: \"IPv4 \u10DB\u10D8\u10E1\u10D0\u10DB\u10D0\u10E0\u10D7\u10D8\",\n ipv6: \"IPv6 \u10DB\u10D8\u10E1\u10D0\u10DB\u10D0\u10E0\u10D7\u10D8\",\n mac: \"MAC \u10DB\u10D8\u10E1\u10D0\u10DB\u10D0\u10E0\u10D7\u10D8\",\n cidrv4: \"IPv4 \u10D3\u10D8\u10D0\u10DE\u10D0\u10D6\u10DD\u10DC\u10D8\",\n cidrv6: \"IPv6 \u10D3\u10D8\u10D0\u10DE\u10D0\u10D6\u10DD\u10DC\u10D8\",\n base64: \"base64-\u10D9\u10DD\u10D3\u10D8\u10E0\u10D4\u10D1\u10E3\u10DA\u10D8 \u10D5\u10D4\u10DA\u10D8\",\n base64url: \"base64url-\u10D9\u10DD\u10D3\u10D8\u10E0\u10D4\u10D1\u10E3\u10DA\u10D8 \u10D5\u10D4\u10DA\u10D8\",\n json_string: \"JSON \u10D5\u10D4\u10DA\u10D8\",\n e164: \"E.164 \u10DC\u10DD\u10DB\u10D4\u10E0\u10D8\",\n credit_card: \"\u10E1\u10D0\u10D9\u10E0\u10D4\u10D3\u10D8\u10E2\u10DD \u10D1\u10D0\u10E0\u10D0\u10D7\u10D8\u10E1 \u10DC\u10DD\u10DB\u10D4\u10E0\u10D8\",\n currency_code: \"\u10D5\u10D0\u10DA\u10E3\u10E2\u10D8\u10E1 \u10D9\u10DD\u10D3\u10D8\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u10E8\u10D4\u10E7\u10D5\u10D0\u10DC\u10D0\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u10E0\u10D8\u10EA\u10EE\u10D5\u10D8\",\n string: \"\u10D5\u10D4\u10DA\u10D8\",\n boolean: \"\u10D1\u10E3\u10DA\u10D4\u10D0\u10DC\u10D8\",\n function: \"\u10E4\u10E3\u10DC\u10E5\u10EA\u10D8\u10D0\",\n array: \"\u10DB\u10D0\u10E1\u10D8\u10D5\u10D8\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10E8\u10D4\u10E7\u10D5\u10D0\u10DC\u10D0: \u10DB\u10DD\u10E1\u10D0\u10DA\u10DD\u10D3\u10DC\u10D4\u10DA\u10D8 instanceof ${issue.expected}, \u10DB\u10D8\u10E6\u10D4\u10D1\u10E3\u10DA\u10D8 ${received}`;\n }\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10E8\u10D4\u10E7\u10D5\u10D0\u10DC\u10D0: \u10DB\u10DD\u10E1\u10D0\u10DA\u10DD\u10D3\u10DC\u10D4\u10DA\u10D8 ${expected}, \u10DB\u10D8\u10E6\u10D4\u10D1\u10E3\u10DA\u10D8 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10E8\u10D4\u10E7\u10D5\u10D0\u10DC\u10D0: \u10DB\u10DD\u10E1\u10D0\u10DA\u10DD\u10D3\u10DC\u10D4\u10DA\u10D8 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10D5\u10D0\u10E0\u10D8\u10D0\u10DC\u10E2\u10D8: \u10DB\u10DD\u10E1\u10D0\u10DA\u10DD\u10D3\u10DC\u10D4\u10DA\u10D8\u10D0 \u10D4\u10E0\u10D7-\u10D4\u10E0\u10D7\u10D8 ${util.joinValues(issue.values, \"|\")}-\u10D3\u10D0\u10DC`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u10D6\u10D4\u10D3\u10DB\u10D4\u10E2\u10D0\u10D3 \u10D3\u10D8\u10D3\u10D8: \u10DB\u10DD\u10E1\u10D0\u10DA\u10DD\u10D3\u10DC\u10D4\u10DA\u10D8 ${issue.origin ?? \"\u10DB\u10DC\u10D8\u10E8\u10D5\u10DC\u10D4\u10DA\u10DD\u10D1\u10D0\"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit}`;\n return `\u10D6\u10D4\u10D3\u10DB\u10D4\u10E2\u10D0\u10D3 \u10D3\u10D8\u10D3\u10D8: \u10DB\u10DD\u10E1\u10D0\u10DA\u10DD\u10D3\u10DC\u10D4\u10DA\u10D8 ${issue.origin ?? \"\u10DB\u10DC\u10D8\u10E8\u10D5\u10DC\u10D4\u10DA\u10DD\u10D1\u10D0\"} \u10D8\u10E7\u10DD\u10E1 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u10D6\u10D4\u10D3\u10DB\u10D4\u10E2\u10D0\u10D3 \u10DE\u10D0\u10E2\u10D0\u10E0\u10D0: \u10DB\u10DD\u10E1\u10D0\u10DA\u10DD\u10D3\u10DC\u10D4\u10DA\u10D8 ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u10D6\u10D4\u10D3\u10DB\u10D4\u10E2\u10D0\u10D3 \u10DE\u10D0\u10E2\u10D0\u10E0\u10D0: \u10DB\u10DD\u10E1\u10D0\u10DA\u10DD\u10D3\u10DC\u10D4\u10DA\u10D8 ${issue.origin} \u10D8\u10E7\u10DD\u10E1 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10D5\u10D4\u10DA\u10D8: \u10E3\u10DC\u10D3\u10D0 \u10D8\u10EC\u10E7\u10D4\u10D1\u10DD\u10D3\u10D4\u10E1 \"${_issue.prefix}\"-\u10D8\u10D7`;\n }\n if (_issue.format === \"ends_with\")\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10D5\u10D4\u10DA\u10D8: \u10E3\u10DC\u10D3\u10D0 \u10DB\u10D7\u10D0\u10D5\u10E0\u10D3\u10D4\u10D1\u10DD\u10D3\u10D4\u10E1 \"${_issue.suffix}\"-\u10D8\u10D7`;\n if (_issue.format === \"includes\")\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10D5\u10D4\u10DA\u10D8: \u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1 \"${_issue.includes}\"-\u10E1`;\n if (_issue.format === \"regex\")\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10D5\u10D4\u10DA\u10D8: \u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D4\u10E1\u10D0\u10D1\u10D0\u10DB\u10D4\u10D1\u10DD\u10D3\u10D4\u10E1 \u10E8\u10D0\u10D1\u10DA\u10DD\u10DC\u10E1 ${_issue.pattern}`;\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10E0\u10D8\u10EA\u10EE\u10D5\u10D8: \u10E3\u10DC\u10D3\u10D0 \u10D8\u10E7\u10DD\u10E1 ${issue.divisor}-\u10D8\u10E1 \u10EF\u10D4\u10E0\u10D0\u10D3\u10D8`;\n case \"unrecognized_keys\":\n return `\u10E3\u10EA\u10DC\u10DD\u10D1\u10D8 \u10D2\u10D0\u10E1\u10D0\u10E6\u10D4\u10D1${issue.keys.length > 1 ? \"\u10D4\u10D1\u10D8\" : \"\u10D8\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10D2\u10D0\u10E1\u10D0\u10E6\u10D4\u10D1\u10D8 ${issue.origin}-\u10E8\u10D8`;\n case \"invalid_union\":\n return \"\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10E8\u10D4\u10E7\u10D5\u10D0\u10DC\u10D0\";\n case \"invalid_element\":\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10DB\u10DC\u10D8\u10E8\u10D5\u10DC\u10D4\u10DA\u10DD\u10D1\u10D0 ${issue.origin}-\u10E8\u10D8`;\n default:\n return `\u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D8 \u10E8\u10D4\u10E7\u10D5\u10D0\u10DC\u10D0`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u178F\u17BD\u17A2\u1780\u17D2\u179F\u179A\", verb: \"\u1782\u17BD\u179A\u1798\u17B6\u1793\" },\n file: { unit: \"\u1794\u17C3\", verb: \"\u1782\u17BD\u179A\u1798\u17B6\u1793\" },\n array: { unit: \"\u1792\u17B6\u178F\u17BB\", verb: \"\u1782\u17BD\u179A\u1798\u17B6\u1793\" },\n set: { unit: \"\u1792\u17B6\u178F\u17BB\", verb: \"\u1782\u17BD\u179A\u1798\u17B6\u1793\" },\n map: { unit: \"\u1792\u17B6\u178F\u17BB\", verb: \"\u1782\u17BD\u179A\u1798\u17B6\u1793\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u1791\u17B7\u1793\u17D2\u1793\u1793\u17D0\u1799\u1794\u1789\u17D2\u1785\u17BC\u179B\",\n email: \"\u17A2\u17B6\u179F\u1799\u178A\u17D2\u178B\u17B6\u1793\u17A2\u17CA\u17B8\u1798\u17C2\u179B\",\n url: \"URL\",\n emoji: \"\u179F\u1789\u17D2\u1789\u17B6\u17A2\u17B6\u179A\u1798\u17D2\u1798\u178E\u17CD\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u1780\u17B6\u179B\u1794\u179A\u17B7\u1785\u17D2\u1786\u17C1\u1791 \u1793\u17B7\u1784\u1798\u17C9\u17C4\u1784 ISO\",\n date: \"\u1780\u17B6\u179B\u1794\u179A\u17B7\u1785\u17D2\u1786\u17C1\u1791 ISO\",\n time: \"\u1798\u17C9\u17C4\u1784 ISO\",\n duration: \"\u179A\u1799\u17C8\u1796\u17C1\u179B ISO\",\n ipv4: \"\u17A2\u17B6\u179F\u1799\u178A\u17D2\u178B\u17B6\u1793 IPv4\",\n ipv6: \"\u17A2\u17B6\u179F\u1799\u178A\u17D2\u178B\u17B6\u1793 IPv6\",\n mac: \"\u17A2\u17B6\u179F\u1799\u178A\u17D2\u178B\u17B6\u1793 MAC\",\n cidrv4: \"\u178A\u17C2\u1793\u17A2\u17B6\u179F\u1799\u178A\u17D2\u178B\u17B6\u1793 IPv4\",\n cidrv6: \"\u178A\u17C2\u1793\u17A2\u17B6\u179F\u1799\u178A\u17D2\u178B\u17B6\u1793 IPv6\",\n base64: \"\u1781\u17D2\u179F\u17C2\u17A2\u1780\u17D2\u179F\u179A\u17A2\u17CA\u17B7\u1780\u17BC\u178A base64\",\n base64url: \"\u1781\u17D2\u179F\u17C2\u17A2\u1780\u17D2\u179F\u179A\u17A2\u17CA\u17B7\u1780\u17BC\u178A base64url\",\n json_string: \"\u1781\u17D2\u179F\u17C2\u17A2\u1780\u17D2\u179F\u179A JSON\",\n e164: \"\u179B\u17C1\u1781 E.164\",\n credit_card: \"\u179B\u17C1\u1781\u1794\u17D0\u178E\u17D2\u178E\u17A5\u178E\u1791\u17B6\u1793\",\n currency_code: \"\u1780\u17BC\u178A\u179A\u17BC\u1794\u17B7\u1799\u1794\u17D0\u178E\u17D2\u178E\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u1791\u17B7\u1793\u17D2\u1793\u1793\u17D0\u1799\u1794\u1789\u17D2\u1785\u17BC\u179B\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u179B\u17C1\u1781\",\n array: \"\u17A2\u17B6\u179A\u17C1 (Array)\",\n null: \"\u1782\u17D2\u1798\u17B6\u1793\u178F\u1798\u17D2\u179B\u17C3 (null)\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u1791\u17B7\u1793\u17D2\u1793\u1793\u17D0\u1799\u1794\u1789\u17D2\u1785\u17BC\u179B\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1780\u17B6\u179A instanceof ${issue.expected} \u1794\u17C9\u17BB\u1793\u17D2\u178F\u17C2\u1791\u1791\u17BD\u179B\u1794\u17B6\u1793 ${received}`;\n }\n return `\u1791\u17B7\u1793\u17D2\u1793\u1793\u17D0\u1799\u1794\u1789\u17D2\u1785\u17BC\u179B\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1780\u17B6\u179A ${expected} \u1794\u17C9\u17BB\u1793\u17D2\u178F\u17C2\u1791\u1791\u17BD\u179B\u1794\u17B6\u1793 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u1791\u17B7\u1793\u17D2\u1793\u1793\u17D0\u1799\u1794\u1789\u17D2\u1785\u17BC\u179B\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1780\u17B6\u179A ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u1787\u1798\u17D2\u179A\u17BE\u179F\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1787\u17B6\u1798\u17BD\u1799\u1780\u17D2\u1793\u17BB\u1784\u1785\u17C6\u178E\u17C4\u1798 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u1792\u17C6\u1796\u17C1\u1780\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1780\u17B6\u179A ${issue.origin ?? \"\u178F\u1798\u17D2\u179B\u17C3\"} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? \"\u1792\u17B6\u178F\u17BB\"}`;\n return `\u1792\u17C6\u1796\u17C1\u1780\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1780\u17B6\u179A ${issue.origin ?? \"\u178F\u1798\u17D2\u179B\u17C3\"} ${adj} ${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u178F\u17BC\u1785\u1796\u17C1\u1780\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1780\u17B6\u179A ${issue.origin} ${adj} ${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u178F\u17BC\u1785\u1796\u17C1\u1780\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1780\u17B6\u179A ${issue.origin} ${adj} ${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u1781\u17D2\u179F\u17C2\u17A2\u1780\u17D2\u179F\u179A\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1785\u17B6\u1794\u17CB\u1795\u17D2\u178F\u17BE\u1798\u178A\u17C4\u1799 \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u1781\u17D2\u179F\u17C2\u17A2\u1780\u17D2\u179F\u179A\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1794\u1789\u17D2\u1785\u1794\u17CB\u178A\u17C4\u1799 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u1781\u17D2\u179F\u17C2\u17A2\u1780\u17D2\u179F\u179A\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u1798\u17B6\u1793 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u1781\u17D2\u179F\u17C2\u17A2\u1780\u17D2\u179F\u179A\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u178F\u17C2\u1795\u17D2\u1782\u17BC\u1795\u17D2\u1782\u1784\u1793\u17B9\u1784\u1791\u1798\u17D2\u179A\u1784\u17CB\u178A\u17C2\u179B\u1794\u17B6\u1793\u1780\u17C6\u178E\u178F\u17CB ${_issue.pattern}`;\n return `\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u179B\u17C1\u1781\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u17D6 \u178F\u17D2\u179A\u17BC\u179C\u178F\u17C2\u1787\u17B6\u1796\u17A0\u17BB\u1782\u17BB\u178E\u1793\u17C3 ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u179A\u1780\u1783\u17BE\u1789\u179F\u17C4\u1798\u17B7\u1793\u179F\u17D2\u1782\u17B6\u179B\u17CB\u17D6 ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u179F\u17C4\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u1793\u17C5\u1780\u17D2\u1793\u17BB\u1784 ${issue.origin}`;\n case \"invalid_union\":\n return `\u1791\u17B7\u1793\u17D2\u1793\u1793\u17D0\u1799\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C`;\n case \"invalid_element\":\n return `\u1791\u17B7\u1793\u17D2\u1793\u1793\u17D0\u1799\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C\u1793\u17C5\u1780\u17D2\u1793\u17BB\u1784 ${issue.origin}`;\n default:\n return `\u1791\u17B7\u1793\u17D2\u1793\u1793\u17D0\u1799\u1798\u17B7\u1793\u178F\u17D2\u179A\u17B9\u1798\u178F\u17D2\u179A\u17BC\u179C`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import km from \"./km.js\";\n/** @deprecated Use `km` instead. */\nexport default function () {\n return km();\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0C85\u0C95\u0CCD\u0CB7\u0CB0\u0C97\u0CB3\u0CC1\", verb: \"\u0CB9\u0CCA\u0C82\u0CA6\u0CB2\u0CC1\" },\n file: { unit: \"\u0CAC\u0CC8\u0C9F\u0CCD\u200C\u0C97\u0CB3\u0CC1\", verb: \"\u0CB9\u0CCA\u0C82\u0CA6\u0CB2\u0CC1\" },\n array: { unit: \"\u0CB5\u0CB8\u0CCD\u0CA4\u0CC1\u0C97\u0CB3\u0CC1\", verb: \"\u0CB9\u0CCA\u0C82\u0CA6\u0CB2\u0CC1\" },\n set: { unit: \"\u0CB5\u0CB8\u0CCD\u0CA4\u0CC1\u0C97\u0CB3\u0CC1\", verb: \"\u0CB9\u0CCA\u0C82\u0CA6\u0CB2\u0CC1\" },\n map: { unit: \"entries\", verb: \"\u0CB9\u0CCA\u0C82\u0CA6\u0CB2\u0CC1\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0C87\u0CA8\u0CCD\u0CAA\u0CC1\u0C9F\u0CCD\",\n email: \"email \u0CB5\u0CBF\u0CB3\u0CBE\u0CB8\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0CA6\u0CBF\u0CA8\u0CBE\u0C82\u0C95\u0CA6 \u0CB8\u0CAE\u0CAF\",\n date: \"ISO \u0CA6\u0CBF\u0CA8\u0CBE\u0C82\u0C95\",\n time: \"ISO \u0CB8\u0CAE\u0CAF\",\n duration: \"ISO \u0C85\u0CB5\u0CA7\u0CBF\",\n ipv4: \"IPv4 \u0CB5\u0CBF\u0CB3\u0CBE\u0CB8\",\n ipv6: \"IPv6 \u0CB5\u0CBF\u0CB3\u0CBE\u0CB8\",\n mac: \"MAC \u0CB5\u0CBF\u0CB3\u0CBE\u0CB8\",\n cidrv4: \"IPv4 \u0CB5\u0CCD\u0CAF\u0CBE\u0CAA\u0CCD\u0CA4\u0CBF\u0CAF\",\n cidrv6: \"IPv6 \u0CB5\u0CCD\u0CAF\u0CBE\u0CAA\u0CCD\u0CA4\u0CBF\u0CAF\",\n base64: \"base64-encoded\u0CB8\u0CCD\u0C9F\u0CCD\u0CB0\u0CBF\u0C82\u0C97\u0CCD\",\n base64url: \"base64url-encoded\u0CB8\u0CCD\u0C9F\u0CCD\u0CB0\u0CBF\u0C82\u0C97\u0CCD\",\n json_string: \"JSON\u0CB8\u0CCD\u0C9F\u0CCD\u0CB0\u0CBF\u0C82\u0C97\u0CCD\",\n e164: \"E.164 \u0CB8\u0C82\u0C96\u0CCD\u0CAF\u0CC6\",\n credit_card: \"\u0C95\u0CCD\u0CB0\u0CC6\u0CA1\u0CBF\u0C9F\u0CCD \u0C95\u0CBE\u0CB0\u0CCD\u0CA1\u0CCD \u0CB8\u0C82\u0C96\u0CCD\u0CAF\u0CC6\",\n currency_code: \"\u0C95\u0CB0\u0CC6\u0CA8\u0CCD\u0CB8\u0CBF \u0C95\u0CCB\u0CA1\u0CCD\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0C87\u0CA8\u0CCD\u0CAA\u0CC1\u0C9F\u0CCD\",\n };\n // type names: missing keys = do not translate (use raw value via ?? fallback)\n const TypeDictionary = {\n // Compatibility: \"nan\" -> \"NaN\" for display\n nan: \"NaN\",\n // All other type names omitted - they fall back to raw values via ?? operator\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0C87\u0CA8\u0CCD\u200C\u0CAA\u0CC1\u0C9F\u0CCD: \u0CA8\u0CBF\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 ${expected}, \u0CB8\u0CCD\u0CB5\u0CC0\u0C95\u0CB0\u0CBF\u0CB8\u0CBF\u0CA6\u0CA8\u0CC1 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0C87\u0CA8\u0CCD\u200C\u0CAA\u0CC1\u0C9F\u0CCD: \u0CA8\u0CBF\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0C86\u0CAF\u0CCD\u0C95\u0CC6: \u0C87\u0CB5\u0CC1\u0C97\u0CB3\u0CB2\u0CCD\u0CB2\u0CBF \u0C92\u0C82\u0CA6\u0CA8\u0CCD\u0CA8\u0CC1 \u0CA8\u0CBF\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0CA4\u0CC1\u0C82\u0CAC\u0CBE \u0CA6\u0CCA\u0CA1\u0CCD\u0CA1\u0CA6\u0CC1: \u0CA8\u0CBF\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 ${issue.origin ?? \"value\"} \u0CB9\u0CCA\u0C82\u0CA6\u0CB2\u0CC1 ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0C85\u0C82\u0CB6\u0C97\u0CB3\u0CC1\"}`;\n return `\u0CA4\u0CC1\u0C82\u0CAC\u0CBE \u0CA6\u0CCA\u0CA1\u0CCD\u0CA1\u0CA6\u0CC1: \u0CA8\u0CBF\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 ${issue.origin ?? \"value\"} \u0C8E\u0C82\u0CA6\u0CC1 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0CA4\u0CC1\u0C82\u0CAC\u0CBE \u0C9A\u0CBF\u0C95\u0CCD\u0C95\u0CA6\u0CC1: \u0CA8\u0CBF\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 ${issue.origin} \u0CB9\u0CCA\u0C82\u0CA6\u0CB2\u0CC1 ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u0CA4\u0CC1\u0C82\u0CAC\u0CBE \u0C9A\u0CBF\u0C95\u0CCD\u0C95\u0CA6\u0CC1: \u0CA8\u0CBF\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 ${issue.origin} \u0C8E\u0C82\u0CA6\u0CC1 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF\u0CB5\u0CBE\u0CA6 \u0CB8\u0CCD\u0C9F\u0CCD\u0CB0\u0CBF\u0C82\u0C97\u0CCD: \u0C87\u0CA6\u0CB0\u0CCA\u0C82\u0CA6\u0CBF\u0C97\u0CC6 \u0CAA\u0CCD\u0CB0\u0CBE\u0CB0\u0C82\u0CAD\u0CBF\u0CB8\u0CAC\u0CC7\u0C95\u0CC1 \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF\u0CB5\u0CBE\u0CA6 \u0CB8\u0CCD\u0C9F\u0CCD\u0CB0\u0CBF\u0C82\u0C97\u0CCD: \u0C87\u0CA6\u0CB0\u0CCA\u0C82\u0CA6\u0CBF\u0C97\u0CC6 \u0C95\u0CCA\u0CA8\u0CC6\u0C97\u0CCA\u0CB3\u0CCD\u0CB3\u0CAC\u0CC7\u0C95\u0CC1 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0CB8\u0CCD\u0C9F\u0CCD\u0CB0\u0CBF\u0C82\u0C97\u0CCD: \u0C92\u0CB3\u0C97\u0CCA\u0C82\u0CA1\u0CBF\u0CB0\u0CAC\u0CC7\u0C95\u0CC1 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF\u0CB5\u0CBE\u0CA6 \u0CB8\u0CCD\u0C9F\u0CCD\u0CB0\u0CBF\u0C82\u0C97\u0CCD: \u0CAE\u0CBE\u0CA6\u0CB0\u0CBF\u0C97\u0CC6 \u0CB9\u0CCA\u0C82\u0CA6\u0CBF\u0C95\u0CC6\u0CAF\u0CBE\u0C97\u0CAC\u0CC7\u0C95\u0CC1 ${_issue.pattern}`;\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0CB8\u0C82\u0C96\u0CCD\u0CAF\u0CC6: \u0CAC\u0CB9\u0CC1\u0CB8\u0C82\u0C96\u0CCD\u0CAF\u0CC6\u0CAF\u0CBE\u0C97\u0CBF\u0CB0\u0CAC\u0CC7\u0C95\u0CC1 ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u0C97\u0CC1\u0CB0\u0CC1\u0CA4\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CA6 \u0C95\u0CC0 ${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF\u0CB5\u0CBE\u0CA6 \u0C95\u0CC0 \u0C87\u0CA8\u0CCD ${issue.origin}`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0CA4\u0CBE\u0CB0\u0CA4\u0CAE\u0CCD\u0CAF \u0CAE\u0CCC\u0CB2\u0CCD\u0CAF. \u0CA8\u0CBF\u0CB0\u0CC0\u0C95\u0CCD\u0CB7\u0CBF\u0CB8\u0CB2\u0CBE\u0C97\u0CBF\u0CA6\u0CC6 ${opts}`;\n }\n return \"\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0C87\u0CA8\u0CCD\u200C\u0CAA\u0CC1\u0C9F\u0CCD\";\n case \"invalid_element\":\n return `\u0CB0\u0CB2\u0CCD\u0CB2\u0CBF \u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0CAE\u0CCC\u0CB2\u0CCD\u0CAF ${issue.origin}`;\n default:\n return `\u0C85\u0CAE\u0CBE\u0CA8\u0CCD\u0CAF \u0C87\u0CA8\u0CCD\u200C\u0CAA\u0CC1\u0C9F\u0CCD`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\uBB38\uC790\", verb: \"to have\" },\n file: { unit: \"\uBC14\uC774\uD2B8\", verb: \"to have\" },\n array: { unit: \"\uAC1C\", verb: \"to have\" },\n set: { unit: \"\uAC1C\", verb: \"to have\" },\n map: { unit: \"\uAC1C\", verb: \"to have\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\uC785\uB825\",\n email: \"\uC774\uBA54\uC77C \uC8FC\uC18C\",\n url: \"URL\",\n emoji: \"\uC774\uBAA8\uC9C0\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \uB0A0\uC9DC\uC2DC\uAC04\",\n date: \"ISO \uB0A0\uC9DC\",\n time: \"ISO \uC2DC\uAC04\",\n duration: \"ISO \uAE30\uAC04\",\n ipv4: \"IPv4 \uC8FC\uC18C\",\n ipv6: \"IPv6 \uC8FC\uC18C\",\n mac: \"MAC \uC8FC\uC18C\",\n cidrv4: \"IPv4 \uBC94\uC704\",\n cidrv6: \"IPv6 \uBC94\uC704\",\n base64: \"base64 \uC778\uCF54\uB529 \uBB38\uC790\uC5F4\",\n base64url: \"base64url \uC778\uCF54\uB529 \uBB38\uC790\uC5F4\",\n json_string: \"JSON \uBB38\uC790\uC5F4\",\n e164: \"E.164 \uBC88\uD638\",\n credit_card: \"\uC2E0\uC6A9\uCE74\uB4DC \uBC88\uD638\",\n currency_code: \"\uD1B5\uD654 \uCF54\uB4DC\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\uC785\uB825\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\uC798\uBABB\uB41C \uC785\uB825: \uC608\uC0C1 \uD0C0\uC785\uC740 instanceof ${issue.expected}, \uBC1B\uC740 \uD0C0\uC785\uC740 ${received}\uC785\uB2C8\uB2E4`;\n }\n return `\uC798\uBABB\uB41C \uC785\uB825: \uC608\uC0C1 \uD0C0\uC785\uC740 ${expected}, \uBC1B\uC740 \uD0C0\uC785\uC740 ${received}\uC785\uB2C8\uB2E4`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\uC798\uBABB\uB41C \uC785\uB825: \uAC12\uC740 ${util.stringifyPrimitive(issue.values[0])} \uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4`;\n return `\uC798\uBABB\uB41C \uC635\uC158: ${util.joinValues(issue.values, \"\uB610\uB294 \")} \uC911 \uD558\uB098\uC5EC\uC57C \uD569\uB2C8\uB2E4`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"\uC774\uD558\" : \"\uBBF8\uB9CC\";\n const suffix = adj === \"\uBBF8\uB9CC\" ? \"\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4\" : \"\uC5EC\uC57C \uD569\uB2C8\uB2E4\";\n const sizing = getSizing(issue.origin);\n const unit = sizing?.unit ?? \"\uC694\uC18C\";\n if (sizing)\n return `${issue.origin ?? \"\uAC12\"}\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4: ${issue.maximum.toString()}${unit} ${adj}${suffix}`;\n return `${issue.origin ?? \"\uAC12\"}\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4: ${issue.maximum.toString()} ${adj}${suffix}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \"\uC774\uC0C1\" : \"\uCD08\uACFC\";\n const suffix = adj === \"\uC774\uC0C1\" ? \"\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4\" : \"\uC5EC\uC57C \uD569\uB2C8\uB2E4\";\n const sizing = getSizing(issue.origin);\n const unit = sizing?.unit ?? \"\uC694\uC18C\";\n if (sizing) {\n return `${issue.origin ?? \"\uAC12\"}\uC774 \uB108\uBB34 \uC791\uC2B5\uB2C8\uB2E4: ${issue.minimum.toString()}${unit} ${adj}${suffix}`;\n }\n return `${issue.origin ?? \"\uAC12\"}\uC774 \uB108\uBB34 \uC791\uC2B5\uB2C8\uB2E4: ${issue.minimum.toString()} ${adj}${suffix}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\uC798\uBABB\uB41C \uBB38\uC790\uC5F4: \"${_issue.prefix}\"(\uC73C)\uB85C \uC2DC\uC791\uD574\uC57C \uD569\uB2C8\uB2E4`;\n }\n if (_issue.format === \"ends_with\")\n return `\uC798\uBABB\uB41C \uBB38\uC790\uC5F4: \"${_issue.suffix}\"(\uC73C)\uB85C \uB05D\uB098\uC57C \uD569\uB2C8\uB2E4`;\n if (_issue.format === \"includes\")\n return `\uC798\uBABB\uB41C \uBB38\uC790\uC5F4: \"${_issue.includes}\"\uC744(\uB97C) \uD3EC\uD568\uD574\uC57C \uD569\uB2C8\uB2E4`;\n if (_issue.format === \"regex\")\n return `\uC798\uBABB\uB41C \uBB38\uC790\uC5F4: \uC815\uADDC\uC2DD ${_issue.pattern} \uD328\uD134\uACFC \uC77C\uCE58\uD574\uC57C \uD569\uB2C8\uB2E4`;\n return `\uC798\uBABB\uB41C ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\uC798\uBABB\uB41C \uC22B\uC790: ${issue.divisor}\uC758 \uBC30\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4`;\n case \"unrecognized_keys\":\n return `\uC778\uC2DD\uD560 \uC218 \uC5C6\uB294 \uD0A4: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\uC798\uBABB\uB41C \uD0A4: ${issue.origin}`;\n case \"invalid_union\":\n return `\uC798\uBABB\uB41C \uC785\uB825`;\n case \"invalid_element\":\n return `\uC798\uBABB\uB41C \uAC12: ${issue.origin}`;\n default:\n return `\uC798\uBABB\uB41C \uC785\uB825`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst capitalizeFirstCharacter = (text) => {\n return text.charAt(0).toUpperCase() + text.slice(1);\n};\nfunction getUnitTypeFromNumber(number) {\n const abs = Math.abs(number);\n const last = abs % 10;\n const last2 = abs % 100;\n if ((last2 >= 11 && last2 <= 19) || last === 0)\n return \"many\";\n if (last === 1)\n return \"one\";\n return \"few\";\n}\nconst error = () => {\n const Sizable = {\n string: {\n unit: {\n one: \"simbolis\",\n few: \"simboliai\",\n many: \"simboli\u0173\",\n },\n verb: {\n smaller: {\n inclusive: \"turi b\u016Bti ne ilgesn\u0117 kaip\",\n notInclusive: \"turi b\u016Bti trumpesn\u0117 kaip\",\n },\n bigger: {\n inclusive: \"turi b\u016Bti ne trumpesn\u0117 kaip\",\n notInclusive: \"turi b\u016Bti ilgesn\u0117 kaip\",\n },\n },\n },\n file: {\n unit: {\n one: \"baitas\",\n few: \"baitai\",\n many: \"bait\u0173\",\n },\n verb: {\n smaller: {\n inclusive: \"turi b\u016Bti ne didesnis kaip\",\n notInclusive: \"turi b\u016Bti ma\u017Eesnis kaip\",\n },\n bigger: {\n inclusive: \"turi b\u016Bti ne ma\u017Eesnis kaip\",\n notInclusive: \"turi b\u016Bti didesnis kaip\",\n },\n },\n },\n array: {\n unit: {\n one: \"element\u0105\",\n few: \"elementus\",\n many: \"element\u0173\",\n },\n verb: {\n smaller: {\n inclusive: \"turi tur\u0117ti ne daugiau kaip\",\n notInclusive: \"turi tur\u0117ti ma\u017Eiau kaip\",\n },\n bigger: {\n inclusive: \"turi tur\u0117ti ne ma\u017Eiau kaip\",\n notInclusive: \"turi tur\u0117ti daugiau kaip\",\n },\n },\n },\n set: {\n unit: {\n one: \"element\u0105\",\n few: \"elementus\",\n many: \"element\u0173\",\n },\n verb: {\n smaller: {\n inclusive: \"turi tur\u0117ti ne daugiau kaip\",\n notInclusive: \"turi tur\u0117ti ma\u017Eiau kaip\",\n },\n bigger: {\n inclusive: \"turi tur\u0117ti ne ma\u017Eiau kaip\",\n notInclusive: \"turi tur\u0117ti daugiau kaip\",\n },\n },\n },\n };\n function getSizing(origin, unitType, inclusive, targetShouldBe) {\n const result = Sizable[origin] ?? null;\n if (result === null)\n return result;\n return {\n unit: result.unit[unitType],\n verb: result.verb[targetShouldBe][inclusive ? \"inclusive\" : \"notInclusive\"],\n };\n }\n const FormatDictionary = {\n regex: \"\u012Fvestis\",\n email: \"el. pa\u0161to adresas\",\n url: \"URL\",\n emoji: \"jaustukas\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO data ir laikas\",\n date: \"ISO data\",\n time: \"ISO laikas\",\n duration: \"ISO trukm\u0117\",\n ipv4: \"IPv4 adresas\",\n ipv6: \"IPv6 adresas\",\n mac: \"MAC adresas\",\n cidrv4: \"IPv4 tinklo prefiksas (CIDR)\",\n cidrv6: \"IPv6 tinklo prefiksas (CIDR)\",\n base64: \"base64 u\u017Ekoduota eilut\u0117\",\n base64url: \"base64url u\u017Ekoduota eilut\u0117\",\n json_string: \"JSON eilut\u0117\",\n e164: \"E.164 numeris\",\n credit_card: \"kredito kortel\u0117s numeris\",\n currency_code: \"valiutos kodas\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u012Fvestis\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"skai\u010Dius\",\n bigint: \"sveikasis skai\u010Dius\",\n string: \"eilut\u0117\",\n boolean: \"login\u0117 reik\u0161m\u0117\",\n undefined: \"neapibr\u0117\u017Eta reik\u0161m\u0117\",\n function: \"funkcija\",\n symbol: \"simbolis\",\n array: \"masyvas\",\n object: \"objektas\",\n null: \"nulin\u0117 reik\u0161m\u0117\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Gautas tipas ${received}, o tik\u0117tasi - instanceof ${issue.expected}`;\n }\n return `Gautas tipas ${received}, o tik\u0117tasi - ${expected}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Privalo b\u016Bti ${util.stringifyPrimitive(issue.values[0])}`;\n return `Privalo b\u016Bti vienas i\u0161 ${util.joinValues(issue.values, \"|\")} pasirinkim\u0173`;\n case \"too_big\": {\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n const sizing = getSizing(issue.origin, getUnitTypeFromNumber(Number(issue.maximum)), issue.inclusive ?? false, \"smaller\");\n if (sizing?.verb)\n return `${capitalizeFirstCharacter(origin ?? issue.origin ?? \"reik\u0161m\u0117\")} ${sizing.verb} ${issue.maximum.toString()} ${sizing.unit ?? \"element\u0173\"}`;\n const adj = issue.inclusive ? \"ne didesnis kaip\" : \"ma\u017Eesnis kaip\";\n return `${capitalizeFirstCharacter(origin ?? issue.origin ?? \"reik\u0161m\u0117\")} turi b\u016Bti ${adj} ${issue.maximum.toString()} ${sizing?.unit}`;\n }\n case \"too_small\": {\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n const sizing = getSizing(issue.origin, getUnitTypeFromNumber(Number(issue.minimum)), issue.inclusive ?? false, \"bigger\");\n if (sizing?.verb)\n return `${capitalizeFirstCharacter(origin ?? issue.origin ?? \"reik\u0161m\u0117\")} ${sizing.verb} ${issue.minimum.toString()} ${sizing.unit ?? \"element\u0173\"}`;\n const adj = issue.inclusive ? \"ne ma\u017Eesnis kaip\" : \"didesnis kaip\";\n return `${capitalizeFirstCharacter(origin ?? issue.origin ?? \"reik\u0161m\u0117\")} turi b\u016Bti ${adj} ${issue.minimum.toString()} ${sizing?.unit}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `Eilut\u0117 privalo prasid\u0117ti \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `Eilut\u0117 privalo pasibaigti \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Eilut\u0117 privalo \u012Ftraukti \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Eilut\u0117 privalo atitikti ${_issue.pattern}`;\n return `Neteisingas ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Skai\u010Dius privalo b\u016Bti ${issue.divisor} kartotinis.`;\n case \"unrecognized_keys\":\n return `Neatpa\u017Eint${issue.keys.length > 1 ? \"i\" : \"as\"} rakt${issue.keys.length > 1 ? \"ai\" : \"as\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return \"Rastas klaidingas raktas\";\n case \"invalid_union\":\n return \"Klaidinga \u012Fvestis\";\n case \"invalid_element\": {\n const origin = TypeDictionary[issue.origin] ?? issue.origin;\n return `${capitalizeFirstCharacter(origin ?? issue.origin ?? \"reik\u0161m\u0117\")} turi klaiding\u0105 \u012Fvest\u012F`;\n }\n default:\n return \"Klaidinga \u012Fvestis\";\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0437\u043D\u0430\u0446\u0438\", verb: \"\u0434\u0430 \u0438\u043C\u0430\u0430\u0442\" },\n file: { unit: \"\u0431\u0430\u0458\u0442\u0438\", verb: \"\u0434\u0430 \u0438\u043C\u0430\u0430\u0442\" },\n array: { unit: \"\u0441\u0442\u0430\u0432\u043A\u0438\", verb: \"\u0434\u0430 \u0438\u043C\u0430\u0430\u0442\" },\n set: { unit: \"\u0441\u0442\u0430\u0432\u043A\u0438\", verb: \"\u0434\u0430 \u0438\u043C\u0430\u0430\u0442\" },\n map: { unit: \"\u0441\u0442\u0430\u0432\u043A\u0438\", verb: \"\u0434\u0430 \u0438\u043C\u0430\u0430\u0442\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0432\u043D\u0435\u0441\",\n email: \"\u0430\u0434\u0440\u0435\u0441\u0430 \u043D\u0430 \u0435-\u043F\u043E\u0448\u0442\u0430\",\n url: \"URL\",\n emoji: \"\u0435\u043C\u043E\u045F\u0438\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0434\u0430\u0442\u0443\u043C \u0438 \u0432\u0440\u0435\u043C\u0435\",\n date: \"ISO \u0434\u0430\u0442\u0443\u043C\",\n time: \"ISO \u0432\u0440\u0435\u043C\u0435\",\n duration: \"ISO \u0432\u0440\u0435\u043C\u0435\u0442\u0440\u0430\u0435\u045A\u0435\",\n ipv4: \"IPv4 \u0430\u0434\u0440\u0435\u0441\u0430\",\n ipv6: \"IPv6 \u0430\u0434\u0440\u0435\u0441\u0430\",\n mac: \"MAC \u0430\u0434\u0440\u0435\u0441\u0430\",\n cidrv4: \"IPv4 \u043E\u043F\u0441\u0435\u0433\",\n cidrv6: \"IPv6 \u043E\u043F\u0441\u0435\u0433\",\n base64: \"base64-\u0435\u043D\u043A\u043E\u0434\u0438\u0440\u0430\u043D\u0430 \u043D\u0438\u0437\u0430\",\n base64url: \"base64url-\u0435\u043D\u043A\u043E\u0434\u0438\u0440\u0430\u043D\u0430 \u043D\u0438\u0437\u0430\",\n json_string: \"JSON \u043D\u0438\u0437\u0430\",\n e164: \"E.164 \u0431\u0440\u043E\u0458\",\n credit_card: \"\u0431\u0440\u043E\u0458 \u043D\u0430 \u043A\u0440\u0435\u0434\u0438\u0442\u043D\u0430 \u043A\u0430\u0440\u0442\u0438\u0447\u043A\u0430\",\n currency_code: \"\u043A\u043E\u0434 \u043D\u0430 \u0432\u0430\u043B\u0443\u0442\u0430\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0432\u043D\u0435\u0441\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0431\u0440\u043E\u0458\",\n array: \"\u043D\u0438\u0437\u0430\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u0413\u0440\u0435\u0448\u0435\u043D \u0432\u043D\u0435\u0441: \u0441\u0435 \u043E\u0447\u0435\u043A\u0443\u0432\u0430 instanceof ${issue.expected}, \u043F\u0440\u0438\u043C\u0435\u043D\u043E ${received}`;\n }\n return `\u0413\u0440\u0435\u0448\u0435\u043D \u0432\u043D\u0435\u0441: \u0441\u0435 \u043E\u0447\u0435\u043A\u0443\u0432\u0430 ${expected}, \u043F\u0440\u0438\u043C\u0435\u043D\u043E ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Invalid input: expected ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0413\u0440\u0435\u0448\u0430\u043D\u0430 \u043E\u043F\u0446\u0438\u0458\u0430: \u0441\u0435 \u043E\u0447\u0435\u043A\u0443\u0432\u0430 \u0435\u0434\u043D\u0430 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u041F\u0440\u0435\u043C\u043D\u043E\u0433\u0443 \u0433\u043E\u043B\u0435\u043C: \u0441\u0435 \u043E\u0447\u0435\u043A\u0443\u0432\u0430 ${issue.origin ?? \"\u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442\u0430\"} \u0434\u0430 \u0438\u043C\u0430 ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0438\"}`;\n return `\u041F\u0440\u0435\u043C\u043D\u043E\u0433\u0443 \u0433\u043E\u043B\u0435\u043C: \u0441\u0435 \u043E\u0447\u0435\u043A\u0443\u0432\u0430 ${issue.origin ?? \"\u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442\u0430\"} \u0434\u0430 \u0431\u0438\u0434\u0435 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u041F\u0440\u0435\u043C\u043D\u043E\u0433\u0443 \u043C\u0430\u043B: \u0441\u0435 \u043E\u0447\u0435\u043A\u0443\u0432\u0430 ${issue.origin} \u0434\u0430 \u0438\u043C\u0430 ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u041F\u0440\u0435\u043C\u043D\u043E\u0433\u0443 \u043C\u0430\u043B: \u0441\u0435 \u043E\u0447\u0435\u043A\u0443\u0432\u0430 ${issue.origin} \u0434\u0430 \u0431\u0438\u0434\u0435 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u041D\u0435\u0432\u0430\u0436\u0435\u0447\u043A\u0430 \u043D\u0438\u0437\u0430: \u043C\u043E\u0440\u0430 \u0434\u0430 \u0437\u0430\u043F\u043E\u0447\u043D\u0443\u0432\u0430 \u0441\u043E \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u041D\u0435\u0432\u0430\u0436\u0435\u0447\u043A\u0430 \u043D\u0438\u0437\u0430: \u043C\u043E\u0440\u0430 \u0434\u0430 \u0437\u0430\u0432\u0440\u0448\u0443\u0432\u0430 \u0441\u043E \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u041D\u0435\u0432\u0430\u0436\u0435\u0447\u043A\u0430 \u043D\u0438\u0437\u0430: \u043C\u043E\u0440\u0430 \u0434\u0430 \u0432\u043A\u043B\u0443\u0447\u0443\u0432\u0430 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u041D\u0435\u0432\u0430\u0436\u0435\u0447\u043A\u0430 \u043D\u0438\u0437\u0430: \u043C\u043E\u0440\u0430 \u0434\u0430 \u043E\u0434\u0433\u043E\u0430\u0440\u0430 \u043D\u0430 \u043F\u0430\u0442\u0435\u0440\u043D\u043E\u0442 ${_issue.pattern}`;\n return `Invalid ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u0413\u0440\u0435\u0448\u0435\u043D \u0431\u0440\u043E\u0458: \u043C\u043E\u0440\u0430 \u0434\u0430 \u0431\u0438\u0434\u0435 \u0434\u0435\u043B\u0438\u0432 \u0441\u043E ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `${issue.keys.length > 1 ? \"\u041D\u0435\u043F\u0440\u0435\u043F\u043E\u0437\u043D\u0430\u0435\u043D\u0438 \u043A\u043B\u0443\u0447\u0435\u0432\u0438\" : \"\u041D\u0435\u043F\u0440\u0435\u043F\u043E\u0437\u043D\u0430\u0435\u043D \u043A\u043B\u0443\u0447\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u0413\u0440\u0435\u0448\u0435\u043D \u043A\u043B\u0443\u0447 \u0432\u043E ${issue.origin}`;\n case \"invalid_union\":\n return \"\u0413\u0440\u0435\u0448\u0435\u043D \u0432\u043D\u0435\u0441\";\n case \"invalid_element\":\n return `\u0413\u0440\u0435\u0448\u043D\u0430 \u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442 \u0432\u043E ${issue.origin}`;\n default:\n return `\u0413\u0440\u0435\u0448\u0435\u043D \u0432\u043D\u0435\u0441`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"aksara\", verb: \"mempunyai\" },\n file: { unit: \"bait\", verb: \"mempunyai\" },\n array: { unit: \"elemen\", verb: \"mempunyai\" },\n set: { unit: \"elemen\", verb: \"mempunyai\" },\n map: { unit: \"elemen\", verb: \"mempunyai\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"input\",\n email: \"alamat e-mel\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"tarikh masa ISO\",\n date: \"tarikh ISO\",\n time: \"masa ISO\",\n duration: \"tempoh ISO\",\n ipv4: \"alamat IPv4\",\n ipv6: \"alamat IPv6\",\n mac: \"alamat MAC\",\n cidrv4: \"julat IPv4\",\n cidrv6: \"julat IPv6\",\n base64: \"string dikodkan base64\",\n base64url: \"string dikodkan base64url\",\n json_string: \"string JSON\",\n e164: \"nombor E.164\",\n credit_card: \"nombor kad kredit\",\n currency_code: \"kod mata wang\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"nombor\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Input tidak sah: dijangka instanceof ${issue.expected}, diterima ${received}`;\n }\n return `Input tidak sah: dijangka ${expected}, diterima ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Input tidak sah: dijangka ${util.stringifyPrimitive(issue.values[0])}`;\n return `Pilihan tidak sah: dijangka salah satu daripada ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Terlalu besar: dijangka ${issue.origin ?? \"nilai\"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elemen\"}`;\n return `Terlalu besar: dijangka ${issue.origin ?? \"nilai\"} adalah ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Terlalu kecil: dijangka ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Terlalu kecil: dijangka ${issue.origin} adalah ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `String tidak sah: mesti bermula dengan \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `String tidak sah: mesti berakhir dengan \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `String tidak sah: mesti mengandungi \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `String tidak sah: mesti sepadan dengan corak ${_issue.pattern}`;\n return `${FormatDictionary[_issue.format] ?? issue.format} tidak sah`;\n }\n case \"not_multiple_of\":\n return `Nombor tidak sah: perlu gandaan ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Kunci tidak dikenali: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Kunci tidak sah dalam ${issue.origin}`;\n case \"invalid_union\":\n return \"Input tidak sah\";\n case \"invalid_element\":\n return `Nilai tidak sah dalam ${issue.origin}`;\n default:\n return `Input tidak sah`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0905\u0915\u094D\u0937\u0930\", verb: \"\u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B\" },\n file: { unit: \"\u092C\u093E\u0907\u091F\", verb: \"\u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B\" },\n array: { unit: \"\u0924\u0924\u094D\u0935\", verb: \"\u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B\" },\n set: { unit: \"\u0924\u0924\u094D\u0935\", verb: \"\u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B\" },\n map: { unit: \"\u092A\u094D\u0930\u0935\u093F\u0937\u094D\u091F\u093F\", verb: \"\u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0907\u0928\u092A\u0941\u091F\",\n email: \"\u0907\u092E\u0947\u0932 \u0920\u0947\u0917\u093E\u0928\u093E\",\n url: \"URL\",\n emoji: \"\u0907\u092E\u094B\u091C\u0940\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u092E\u093F\u0924\u093F \u0930 \u0938\u092E\u092F\",\n date: \"ISO \u092E\u093F\u0924\u093F\",\n time: \"ISO \u0938\u092E\u092F\",\n duration: \"ISO \u0905\u0935\u0927\u093F\",\n ipv4: \"IPv4 \u0920\u0947\u0917\u093E\u0928\u093E\",\n ipv6: \"IPv6 \u0920\u0947\u0917\u093E\u0928\u093E\",\n mac: \"MAC \u0920\u0947\u0917\u093E\u0928\u093E\",\n cidrv4: \"IPv4 \u0926\u093E\u092F\u0930\u093E\",\n cidrv6: \"IPv6 \u0926\u093E\u092F\u0930\u093E\",\n base64: \"base64-\u0907\u0928\u094D\u0915\u094B\u0921 \u0917\u0930\u093F\u090F\u0915\u094B \u0938\u094D\u091F\u094D\u0930\u093F\u0919\",\n base64url: \"base64url-\u0907\u0928\u094D\u0915\u094B\u0921 \u0917\u0930\u093F\u090F\u0915\u094B \u0938\u094D\u091F\u094D\u0930\u093F\u0919\",\n json_string: \"JSON \u0938\u094D\u091F\u094D\u0930\u093F\u0919\",\n e164: \"E.164 \u0928\u092E\u094D\u092C\u0930\",\n credit_card: \"\u0915\u094D\u0930\u0947\u0921\u093F\u091F \u0915\u093E\u0930\u094D\u0921 \u0928\u092E\u094D\u092C\u0930\",\n currency_code: \"\u092E\u0941\u0926\u094D\u0930\u093E \u0915\u094B\u0921\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0907\u0928\u092A\u0941\u091F\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0907\u0928\u092A\u0941\u091F: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 ${expected}, \u092A\u094D\u0930\u093E\u092A\u094D\u0924 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0907\u0928\u092A\u0941\u091F: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0935\u093F\u0915\u0932\u094D\u092A: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 \u092E\u093E\u0928\u0939\u0930\u0942 \u092E\u0927\u094D\u092F\u0947 \u090F\u0915 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0927\u0947\u0930\u0948 \u0920\u0942\u0932\u094B: ${issue.origin ?? \"\u092E\u093E\u0928\"} \u092E\u093E ${adj}${issue.maximum.toString()} ${sizing.unit} ${sizing.verb}`;\n return `\u0927\u0947\u0930\u0948 \u0920\u0942\u0932\u094B: ${issue.origin ?? \"\u092E\u093E\u0928\"} ${adj}${issue.maximum.toString()} \u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0927\u0947\u0930\u0948 \u0938\u093E\u0928\u094B: ${issue.origin} \u092E\u093E ${adj}${issue.minimum.toString()} ${sizing.unit} ${sizing.verb}`;\n return `\u0927\u0947\u0930\u0948 \u0938\u093E\u0928\u094B: ${issue.origin} ${adj}${issue.minimum.toString()} \u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u094D\u091F\u094D\u0930\u093F\u0919: \"${_issue.prefix}\" \u092C\u093E\u091F \u0938\u0941\u0930\u0941 \u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B`;\n if (_issue.format === \"ends_with\")\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u094D\u091F\u094D\u0930\u093F\u0919: \"${_issue.suffix}\" \u092E\u093E \u0938\u092E\u093E\u092A\u094D\u0924 \u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B`;\n if (_issue.format === \"includes\")\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u094D\u091F\u094D\u0930\u093F\u0919: \"${_issue.includes}\" \u0938\u092E\u093E\u0935\u0947\u0936 \u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B`;\n if (_issue.format === \"regex\")\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u094D\u091F\u094D\u0930\u093F\u0919: \u0922\u093E\u0901\u091A\u093E ${_issue.pattern} \u0938\u0901\u0917 \u092E\u0947\u0932 \u0916\u093E\u0928\u0941\u092A\u0930\u094D\u091B`;\n return `\u0905\u092E\u093E\u0928\u094D\u092F ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0938\u0902\u0916\u094D\u092F\u093E: ${issue.divisor} \u0915\u094B \u0917\u0941\u0923\u091C \u0939\u0941\u0928\u0941\u092A\u0930\u094D\u091B`;\n case \"unrecognized_keys\":\n return `\u0905\u092A\u0930\u093F\u091A\u093F\u0924 \u0915\u0941\u091E\u094D\u091C\u0940${issue.keys.length > 1 ? \"\u0939\u0930\u0942\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0915\u0941\u091E\u094D\u091C\u0940: ${issue.origin} \u092E\u093E`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0921\u093F\u0938\u094D\u0915\u094D\u0930\u093F\u092E\u093F\u0928\u0947\u091F\u0930 \u092E\u093E\u0928: \u0905\u092A\u0947\u0915\u094D\u0937\u093F\u0924 ${opts}`;\n }\n return \"\u0905\u092E\u093E\u0928\u094D\u092F \u0907\u0928\u092A\u0941\u091F\";\n case \"invalid_element\":\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u092E\u093E\u0928: ${issue.origin} \u092E\u093E`;\n default:\n return `\u0905\u092E\u093E\u0928\u094D\u092F \u0907\u0928\u092A\u0941\u091F`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"tekens\", verb: \"heeft\" },\n file: { unit: \"bytes\", verb: \"heeft\" },\n array: { unit: \"elementen\", verb: \"heeft\" },\n set: { unit: \"elementen\", verb: \"heeft\" },\n map: { unit: \"elementen\", verb: \"heeft\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"invoer\",\n email: \"emailadres\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO datum en tijd\",\n date: \"ISO datum\",\n time: \"ISO tijd\",\n duration: \"ISO duur\",\n ipv4: \"IPv4-adres\",\n ipv6: \"IPv6-adres\",\n mac: \"MAC-adres\",\n cidrv4: \"IPv4-bereik\",\n cidrv6: \"IPv6-bereik\",\n base64: \"base64-gecodeerde tekst\",\n base64url: \"base64 URL-gecodeerde tekst\",\n json_string: \"JSON string\",\n e164: \"E.164-nummer\",\n credit_card: \"creditcardnummer\",\n currency_code: \"valutacode\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"invoer\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"getal\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Ongeldige invoer: verwacht instanceof ${issue.expected}, ontving ${received}`;\n }\n return `Ongeldige invoer: verwacht ${expected}, ontving ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Ongeldige invoer: verwacht ${util.stringifyPrimitive(issue.values[0])}`;\n return `Ongeldige optie: verwacht \u00E9\u00E9n van ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n const longName = issue.origin === \"date\" ? \"laat\" : issue.origin === \"string\" ? \"lang\" : \"groot\";\n if (sizing)\n return `Te ${longName}: verwacht dat ${issue.origin ?? \"waarde\"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elementen\"} ${sizing.verb}`;\n return `Te ${longName}: verwacht dat ${issue.origin ?? \"waarde\"} ${adj}${issue.maximum.toString()} is`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n const shortName = issue.origin === \"date\" ? \"vroeg\" : issue.origin === \"string\" ? \"kort\" : \"klein\";\n if (sizing) {\n return `Te ${shortName}: verwacht dat ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} ${sizing.verb}`;\n }\n return `Te ${shortName}: verwacht dat ${issue.origin} ${adj}${issue.minimum.toString()} is`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `Ongeldige tekst: moet met \"${_issue.prefix}\" beginnen`;\n }\n if (_issue.format === \"ends_with\")\n return `Ongeldige tekst: moet op \"${_issue.suffix}\" eindigen`;\n if (_issue.format === \"includes\")\n return `Ongeldige tekst: moet \"${_issue.includes}\" bevatten`;\n if (_issue.format === \"regex\")\n return `Ongeldige tekst: moet overeenkomen met patroon ${_issue.pattern}`;\n return `Ongeldig: ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Ongeldig getal: moet een veelvoud van ${issue.divisor} zijn`;\n case \"unrecognized_keys\":\n return `Onbekende key${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Ongeldige key in ${issue.origin}`;\n case \"invalid_union\":\n return \"Ongeldige invoer\";\n case \"invalid_element\":\n return `Ongeldige waarde in ${issue.origin}`;\n default:\n return `Ongeldige invoer`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"teikn\", verb: \"\u00E5 ha\" },\n file: { unit: \"bytes\", verb: \"\u00E5 ha\" },\n array: { unit: \"element\", verb: \"\u00E5 innehalde\" },\n set: { unit: \"element\", verb: \"\u00E5 innehalde\" },\n map: { unit: \"element\", verb: \"\u00E5 innehalde\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"input\",\n email: \"e-postadresse\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO dato- og klokkeslett\",\n date: \"ISO-dato\",\n time: \"ISO-klokkeslett\",\n duration: \"ISO-varigheit\",\n ipv4: \"IPv4-adresse\",\n ipv6: \"IPv6-adresse\",\n mac: \"MAC-adresse\",\n cidrv4: \"IPv4-spekter\",\n cidrv6: \"IPv6-spekter\",\n base64: \"base64-enkoda streng\",\n base64url: \"base64url-enkoda streng\",\n json_string: \"JSON-streng\",\n e164: \"E.164-nummer\",\n credit_card: \"kredittkortnummer\",\n currency_code: \"valutakode\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"tal\",\n array: \"liste\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Ugyldig input: forventa instanceof ${issue.expected}, fekk ${received}`;\n }\n return `Ugyldig input: forventa ${expected}, fekk ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Ugyldig verdi: forventa ${util.stringifyPrimitive(issue.values[0])}`;\n return `Ugyldig val: forventa eitt av ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `For stor(t): forventa ${issue.origin ?? \"value\"} til \u00E5 ha ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"element\"}`;\n return `For stor(t): forventa ${issue.origin ?? \"value\"} til \u00E5 ha ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `For lite(n): forventa ${issue.origin} til \u00E5 ha ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `For lite(n): forventa ${issue.origin} til \u00E5 ha ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Ugyldig streng: m\u00E5 starte med \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Ugyldig streng: m\u00E5 slutte med \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Ugyldig streng: m\u00E5 innehalde \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Ugyldig streng: m\u00E5 matche m\u00F8nsteret ${_issue.pattern}`;\n return `Ugyldig ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Ugyldig tal: m\u00E5 vere eit multiplum av ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `${issue.keys.length > 1 ? \"Ukjende n\u00F8klar\" : \"Ukjend n\u00F8kkel\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Ugyldig n\u00F8kkel i ${issue.origin}`;\n case \"invalid_union\":\n return \"Ugyldig input\";\n case \"invalid_element\":\n return `Ugyldig verdi i ${issue.origin}`;\n default:\n return `Ugyldig input`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"tegn\", verb: \"\u00E5 ha\" },\n file: { unit: \"bytes\", verb: \"\u00E5 ha\" },\n array: { unit: \"elementer\", verb: \"\u00E5 inneholde\" },\n set: { unit: \"elementer\", verb: \"\u00E5 inneholde\" },\n map: { unit: \"elementer\", verb: \"\u00E5 inneholde\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"input\",\n email: \"e-postadresse\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO dato- og klokkeslett\",\n date: \"ISO-dato\",\n time: \"ISO-klokkeslett\",\n duration: \"ISO-varighet\",\n ipv4: \"IPv4-adresse\",\n ipv6: \"IPv6-adresse\",\n mac: \"MAC-adresse\",\n cidrv4: \"IPv4-spekter\",\n cidrv6: \"IPv6-spekter\",\n base64: \"base64-enkodet streng\",\n base64url: \"base64url-enkodet streng\",\n json_string: \"JSON-streng\",\n e164: \"E.164-nummer\",\n credit_card: \"kredittkortnummer\",\n currency_code: \"valutakode\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"tall\",\n array: \"liste\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Ugyldig input: forventet instanceof ${issue.expected}, fikk ${received}`;\n }\n return `Ugyldig input: forventet ${expected}, fikk ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Ugyldig verdi: forventet ${util.stringifyPrimitive(issue.values[0])}`;\n return `Ugyldig valg: forventet en av ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `For stor(t): forventet ${issue.origin ?? \"value\"} til \u00E5 ha ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elementer\"}`;\n return `For stor(t): forventet ${issue.origin ?? \"value\"} til \u00E5 ha ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `For lite(n): forventet ${issue.origin} til \u00E5 ha ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `For lite(n): forventet ${issue.origin} til \u00E5 ha ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Ugyldig streng: m\u00E5 starte med \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Ugyldig streng: m\u00E5 ende med \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Ugyldig streng: m\u00E5 inneholde \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Ugyldig streng: m\u00E5 matche m\u00F8nsteret ${_issue.pattern}`;\n return `Ugyldig ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Ugyldig tall: m\u00E5 v\u00E6re et multiplum av ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `${issue.keys.length > 1 ? \"Ukjente n\u00F8kler\" : \"Ukjent n\u00F8kkel\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Ugyldig n\u00F8kkel i ${issue.origin}`;\n case \"invalid_union\":\n return \"Ugyldig input\";\n case \"invalid_element\":\n return `Ugyldig verdi i ${issue.origin}`;\n default:\n return `Ugyldig input`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"harf\", verb: \"olmal\u0131d\u0131r\" },\n file: { unit: \"bayt\", verb: \"olmal\u0131d\u0131r\" },\n array: { unit: \"unsur\", verb: \"olmal\u0131d\u0131r\" },\n set: { unit: \"unsur\", verb: \"olmal\u0131d\u0131r\" },\n map: { unit: \"unsur\", verb: \"olmal\u0131d\u0131r\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"giren\",\n email: \"epostag\u00E2h\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO heng\u00E2m\u0131\",\n date: \"ISO tarihi\",\n time: \"ISO zaman\u0131\",\n duration: \"ISO m\u00FCddeti\",\n ipv4: \"IPv4 ni\u015F\u00E2n\u0131\",\n ipv6: \"IPv6 ni\u015F\u00E2n\u0131\",\n mac: \"MAC ni\u015F\u00E2n\u0131\",\n cidrv4: \"IPv4 menzili\",\n cidrv6: \"IPv6 menzili\",\n base64: \"base64-\u015Fifreli metin\",\n base64url: \"base64url-\u015Fifreli metin\",\n json_string: \"JSON metin\",\n e164: \"E.164 say\u0131s\u0131\",\n credit_card: \"i'tib\u00E2r kart\u0131 numaras\u0131\",\n currency_code: \"para birimi kodu\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"giren\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"numara\",\n array: \"saf\",\n null: \"gayb\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `F\u00E2sit giren: umulan instanceof ${issue.expected}, al\u0131nan ${received}`;\n }\n return `F\u00E2sit giren: umulan ${expected}, al\u0131nan ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `F\u00E2sit giren: umulan ${util.stringifyPrimitive(issue.values[0])}`;\n return `F\u00E2sit tercih: m\u00FBteberler ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Fazla b\u00FCy\u00FCk: ${issue.origin ?? \"value\"}, ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elements\"} sahip olmal\u0131yd\u0131.`;\n return `Fazla b\u00FCy\u00FCk: ${issue.origin ?? \"value\"}, ${adj}${issue.maximum.toString()} olmal\u0131yd\u0131.`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Fazla k\u00FC\u00E7\u00FCk: ${issue.origin}, ${adj}${issue.minimum.toString()} ${sizing.unit} sahip olmal\u0131yd\u0131.`;\n }\n return `Fazla k\u00FC\u00E7\u00FCk: ${issue.origin}, ${adj}${issue.minimum.toString()} olmal\u0131yd\u0131.`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `F\u00E2sit metin: \"${_issue.prefix}\" ile ba\u015Flamal\u0131.`;\n if (_issue.format === \"ends_with\")\n return `F\u00E2sit metin: \"${_issue.suffix}\" ile bitmeli.`;\n if (_issue.format === \"includes\")\n return `F\u00E2sit metin: \"${_issue.includes}\" ihtiv\u00E2 etmeli.`;\n if (_issue.format === \"regex\")\n return `F\u00E2sit metin: ${_issue.pattern} nak\u015F\u0131na uymal\u0131.`;\n return `F\u00E2sit ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `F\u00E2sit say\u0131: ${issue.divisor} kat\u0131 olmal\u0131yd\u0131.`;\n case \"unrecognized_keys\":\n return `Tan\u0131nmayan anahtar ${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} i\u00E7in tan\u0131nmayan anahtar var.`;\n case \"invalid_union\":\n return \"Giren tan\u0131namad\u0131.\";\n case \"invalid_element\":\n return `${issue.origin} i\u00E7in tan\u0131nmayan k\u0131ymet var.`;\n default:\n return `K\u0131ymet tan\u0131namad\u0131.`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u062A\u0648\u06A9\u064A\", verb: \"\u0648\u0644\u0631\u064A\" },\n file: { unit: \"\u0628\u0627\u06CC\u067C\u0633\", verb: \"\u0648\u0644\u0631\u064A\" },\n array: { unit: \"\u062A\u0648\u06A9\u064A\", verb: \"\u0648\u0644\u0631\u064A\" },\n set: { unit: \"\u062A\u0648\u06A9\u064A\", verb: \"\u0648\u0644\u0631\u064A\" },\n map: { unit: \"\u062A\u0648\u06A9\u064A\", verb: \"\u0648\u0644\u0631\u064A\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0648\u0631\u0648\u062F\u064A\",\n email: \"\u0628\u0631\u06CC\u069A\u0646\u0627\u0644\u06CC\u06A9\",\n url: \"\u06CC\u0648 \u0622\u0631 \u0627\u0644\",\n emoji: \"\u0627\u06CC\u0645\u0648\u062C\u064A\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u0646\u06CC\u067C\u0647 \u0627\u0648 \u0648\u062E\u062A\",\n date: \"\u0646\u06D0\u067C\u0647\",\n time: \"\u0648\u062E\u062A\",\n duration: \"\u0645\u0648\u062F\u0647\",\n ipv4: \"\u062F IPv4 \u067E\u062A\u0647\",\n ipv6: \"\u062F IPv6 \u067E\u062A\u0647\",\n mac: \"\u062F MAC \u067E\u062A\u0647\",\n cidrv4: \"\u062F IPv4 \u0633\u0627\u062D\u0647\",\n cidrv6: \"\u062F IPv6 \u0633\u0627\u062D\u0647\",\n base64: \"base64-encoded \u0645\u062A\u0646\",\n base64url: \"base64url-encoded \u0645\u062A\u0646\",\n json_string: \"JSON \u0645\u062A\u0646\",\n e164: \"\u062F E.164 \u0634\u0645\u06D0\u0631\u0647\",\n credit_card: \"\u062F \u06A9\u0631\u06CC\u0689\u06CC\u067C \u06A9\u0627\u0631\u062A \u0634\u0645\u06CC\u0631\u0647\",\n currency_code: \"\u062F \u0627\u0633\u0639\u0627\u0631\u0648 \u06A9\u0648\u0689\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0648\u0631\u0648\u062F\u064A\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0639\u062F\u062F\",\n array: \"\u0627\u0631\u06D0\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u0646\u0627\u0633\u0645 \u0648\u0631\u0648\u062F\u064A: \u0628\u0627\u06CC\u062F instanceof ${issue.expected} \u0648\u0627\u06CC, \u0645\u06AB\u0631 ${received} \u062A\u0631\u0644\u0627\u0633\u0647 \u0634\u0648`;\n }\n return `\u0646\u0627\u0633\u0645 \u0648\u0631\u0648\u062F\u064A: \u0628\u0627\u06CC\u062F ${expected} \u0648\u0627\u06CC, \u0645\u06AB\u0631 ${received} \u062A\u0631\u0644\u0627\u0633\u0647 \u0634\u0648`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1) {\n return `\u0646\u0627\u0633\u0645 \u0648\u0631\u0648\u062F\u064A: \u0628\u0627\u06CC\u062F ${util.stringifyPrimitive(issue.values[0])} \u0648\u0627\u06CC`;\n }\n return `\u0646\u0627\u0633\u0645 \u0627\u0646\u062A\u062E\u0627\u0628: \u0628\u0627\u06CC\u062F \u06CC\u0648 \u0644\u0647 ${util.joinValues(issue.values, \"|\")} \u0685\u062E\u0647 \u0648\u0627\u06CC`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0689\u06CC\u0631 \u0644\u0648\u06CC: ${issue.origin ?? \"\u0627\u0631\u0632\u069A\u062A\"} \u0628\u0627\u06CC\u062F ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0639\u0646\u0635\u0631\u0648\u0646\u0647\"} \u0648\u0644\u0631\u064A`;\n }\n return `\u0689\u06CC\u0631 \u0644\u0648\u06CC: ${issue.origin ?? \"\u0627\u0631\u0632\u069A\u062A\"} \u0628\u0627\u06CC\u062F ${adj}${issue.maximum.toString()} \u0648\u064A`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0689\u06CC\u0631 \u06A9\u0648\u0686\u0646\u06CC: ${issue.origin} \u0628\u0627\u06CC\u062F ${adj}${issue.minimum.toString()} ${sizing.unit} \u0648\u0644\u0631\u064A`;\n }\n return `\u0689\u06CC\u0631 \u06A9\u0648\u0686\u0646\u06CC: ${issue.origin} \u0628\u0627\u06CC\u062F ${adj}${issue.minimum.toString()} \u0648\u064A`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u0646\u0627\u0633\u0645 \u0645\u062A\u0646: \u0628\u0627\u06CC\u062F \u062F \"${_issue.prefix}\" \u0633\u0631\u0647 \u067E\u06CC\u0644 \u0634\u064A`;\n }\n if (_issue.format === \"ends_with\") {\n return `\u0646\u0627\u0633\u0645 \u0645\u062A\u0646: \u0628\u0627\u06CC\u062F \u062F \"${_issue.suffix}\" \u0633\u0631\u0647 \u067E\u0627\u06CC \u062A\u0647 \u0648\u0631\u0633\u064A\u0696\u064A`;\n }\n if (_issue.format === \"includes\") {\n return `\u0646\u0627\u0633\u0645 \u0645\u062A\u0646: \u0628\u0627\u06CC\u062F \"${_issue.includes}\" \u0648\u0644\u0631\u064A`;\n }\n if (_issue.format === \"regex\") {\n return `\u0646\u0627\u0633\u0645 \u0645\u062A\u0646: \u0628\u0627\u06CC\u062F \u062F ${_issue.pattern} \u0633\u0631\u0647 \u0645\u0637\u0627\u0628\u0642\u062A \u0648\u0644\u0631\u064A`;\n }\n return `${FormatDictionary[_issue.format] ?? issue.format} \u0646\u0627\u0633\u0645 \u062F\u06CC`;\n }\n case \"not_multiple_of\":\n return `\u0646\u0627\u0633\u0645 \u0639\u062F\u062F: \u0628\u0627\u06CC\u062F \u062F ${issue.divisor} \u0645\u0636\u0631\u0628 \u0648\u064A`;\n case \"unrecognized_keys\":\n return `\u0646\u0627\u0633\u0645 ${issue.keys.length > 1 ? \"\u06A9\u0644\u06CC\u0689\u0648\u0646\u0647\" : \"\u06A9\u0644\u06CC\u0689\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u0646\u0627\u0633\u0645 \u06A9\u0644\u06CC\u0689 \u067E\u0647 ${issue.origin} \u06A9\u06D0`;\n case \"invalid_union\":\n return `\u0646\u0627\u0633\u0645\u0647 \u0648\u0631\u0648\u062F\u064A`;\n case \"invalid_element\":\n return `\u0646\u0627\u0633\u0645 \u0639\u0646\u0635\u0631 \u067E\u0647 ${issue.origin} \u06A9\u06D0`;\n default:\n return `\u0646\u0627\u0633\u0645\u0647 \u0648\u0631\u0648\u062F\u064A`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"znak\u00F3w\", verb: \"mie\u0107\" },\n file: { unit: \"bajt\u00F3w\", verb: \"mie\u0107\" },\n array: { unit: \"element\u00F3w\", verb: \"mie\u0107\" },\n set: { unit: \"element\u00F3w\", verb: \"mie\u0107\" },\n map: { unit: \"element\u00F3w\", verb: \"mie\u0107\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"wyra\u017Cenie\",\n email: \"adres email\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"data i godzina w formacie ISO\",\n date: \"data w formacie ISO\",\n time: \"godzina w formacie ISO\",\n duration: \"czas trwania ISO\",\n ipv4: \"adres IPv4\",\n ipv6: \"adres IPv6\",\n mac: \"adres MAC\",\n cidrv4: \"zakres IPv4\",\n cidrv6: \"zakres IPv6\",\n base64: \"ci\u0105g znak\u00F3w zakodowany w formacie base64\",\n base64url: \"ci\u0105g znak\u00F3w zakodowany w formacie base64url\",\n json_string: \"ci\u0105g znak\u00F3w w formacie JSON\",\n e164: \"liczba E.164\",\n credit_card: \"numer karty kredytowej\",\n currency_code: \"kod waluty\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"wej\u015Bcie\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"liczba\",\n array: \"tablica\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Nieprawid\u0142owe dane wej\u015Bciowe: oczekiwano instanceof ${issue.expected}, otrzymano ${received}`;\n }\n return `Nieprawid\u0142owe dane wej\u015Bciowe: oczekiwano ${expected}, otrzymano ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Nieprawid\u0142owe dane wej\u015Bciowe: oczekiwano ${util.stringifyPrimitive(issue.values[0])}`;\n return `Nieprawid\u0142owa opcja: oczekiwano jednej z warto\u015Bci ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Za du\u017Ca warto\u015B\u0107: oczekiwano, \u017Ce ${issue.origin ?? \"warto\u015B\u0107\"} b\u0119dzie mie\u0107 ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"element\u00F3w\"}`;\n }\n return `Zbyt du\u017C(y/a/e): oczekiwano, \u017Ce ${issue.origin ?? \"warto\u015B\u0107\"} b\u0119dzie wynosi\u0107 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Za ma\u0142a warto\u015B\u0107: oczekiwano, \u017Ce ${issue.origin ?? \"warto\u015B\u0107\"} b\u0119dzie mie\u0107 ${adj}${issue.minimum.toString()} ${sizing.unit ?? \"element\u00F3w\"}`;\n }\n return `Zbyt ma\u0142(y/a/e): oczekiwano, \u017Ce ${issue.origin ?? \"warto\u015B\u0107\"} b\u0119dzie wynosi\u0107 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Nieprawid\u0142owy ci\u0105g znak\u00F3w: musi zaczyna\u0107 si\u0119 od \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Nieprawid\u0142owy ci\u0105g znak\u00F3w: musi ko\u0144czy\u0107 si\u0119 na \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Nieprawid\u0142owy ci\u0105g znak\u00F3w: musi zawiera\u0107 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Nieprawid\u0142owy ci\u0105g znak\u00F3w: musi odpowiada\u0107 wzorcowi ${_issue.pattern}`;\n return `Nieprawid\u0142ow(y/a/e) ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Nieprawid\u0142owa liczba: musi by\u0107 wielokrotno\u015Bci\u0105 ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Nierozpoznane klucze${issue.keys.length > 1 ? \"s\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Nieprawid\u0142owy klucz w ${issue.origin}`;\n case \"invalid_union\":\n return \"Nieprawid\u0142owe dane wej\u015Bciowe\";\n case \"invalid_element\":\n return `Nieprawid\u0142owa warto\u015B\u0107 w ${issue.origin}`;\n default:\n return `Nieprawid\u0142owe dane wej\u015Bciowe`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"caracteres\" },\n file: { unit: \"bytes\" },\n array: { unit: \"elementos\" },\n set: { unit: \"elementos\" },\n map: { unit: \"entradas\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"a entrada\",\n email: \"o endere\u00E7o de e-mail\",\n url: \"o URL\",\n emoji: \"o emoji\",\n uuid: \"o UUID\",\n uuidv4: \"o UUIDv4\",\n uuidv6: \"o UUIDv6\",\n nanoid: \"o nanoid\",\n guid: \"o GUID\",\n cuid: \"o cuid\",\n cuid2: \"o cuid2\",\n ulid: \"o ULID\",\n xid: \"o XID\",\n ksuid: \"o KSUID\",\n datetime: \"a data e hora ISO\",\n date: \"a data ISO\",\n time: \"a hora ISO\",\n duration: \"a dura\u00E7\u00E3o ISO\",\n ipv4: \"o endere\u00E7o IPv4\",\n ipv6: \"o endere\u00E7o IPv6\",\n mac: \"o endere\u00E7o MAC\",\n cidrv4: \"o intervalo de endere\u00E7os IPv4\",\n cidrv6: \"o intervalo de endere\u00E7os IPv6\",\n base64: \"o texto codificado em base64\",\n base64url: \"o texto codificado em base64url\",\n json_string: \"o texto JSON\",\n e164: \"o n\u00FAmero E.164\",\n credit_card: \"o n\u00FAmero de cart\u00E3o de cr\u00E9dito\",\n currency_code: \"o c\u00F3digo de moeda\",\n iban: \"o IBAN\",\n jwt: \"o JWT\",\n template_literal: \"a entrada\",\n };\n const Gender = {\n masculine: { definite: \"o\", indefinite: \"um\" },\n feminine: { definite: \"a\", indefinite: \"uma\" },\n };\n const TypeDictionary = {\n string: { name: \"texto\", articles: Gender.masculine },\n number: { name: \"n\u00FAmero\", articles: Gender.masculine },\n int: { name: \"n\u00FAmero inteiro\", articles: Gender.masculine },\n boolean: { name: \"valor booleano\", articles: Gender.masculine },\n bigint: { name: \"n\u00FAmero bigint\", articles: Gender.masculine },\n symbol: { name: \"s\u00EDmbolo\", articles: Gender.masculine },\n undefined: { name: 'valor \"undefined\"', articles: Gender.masculine },\n null: { name: 'valor \"nulo\"', articles: Gender.masculine },\n never: { name: 'valor \"never\"', articles: Gender.masculine },\n void: { name: 'valor \"void\"', articles: Gender.masculine },\n date: { name: \"data\", articles: Gender.feminine },\n array: { name: \"vetor\", articles: Gender.masculine },\n object: { name: \"objeto\", articles: Gender.masculine },\n tuple: { name: \"tuplo\", articles: Gender.masculine },\n record: { name: \"registo\", articles: Gender.masculine },\n map: { name: \"mapa\", articles: Gender.masculine },\n set: { name: \"conjunto\", articles: Gender.masculine },\n file: { name: \"ficheiro\", articles: Gender.masculine },\n nonoptional: { name: \"valor n\u00E3o opcional\", articles: Gender.masculine },\n nan: { name: 'valor \"NaN\"', articles: Gender.masculine }, // Compatibility: \"nan\" -> \"NaN\" for display\n function: { name: \"fun\u00E7\u00E3o\", articles: Gender.feminine },\n };\n function translateOriginWithArticle(type, articleType) {\n const translatedValue = TypeDictionary[type] ?? { name: `valor \"${type}\"`, articles: Gender.masculine };\n return `${translatedValue.articles[articleType]} ${translatedValue.name}`;\n }\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = translateOriginWithArticle(issue.expected, \"indefinite\");\n const receivedType = util.parsedType(issue.input);\n const received = translateOriginWithArticle(receivedType, \"indefinite\");\n return `Entrada inv\u00E1lida: esperava ${expected}, recebeu ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Entrada inv\u00E1lida: esperava ${util.stringifyPrimitive(issue.values[0])}`;\n return `Op\u00E7\u00E3o inv\u00E1lida: esperava uma das seguintes op\u00E7\u00F5es: ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Demasiado grande: esperava que ${translateOriginWithArticle(issue.origin, \"definite\")} tivesse ${adj} ${issue.maximum.toString()} ${sizing.unit ?? \"elementos\"}`;\n return `Demasiado grande: esperava que ${translateOriginWithArticle(issue.origin, \"definite\")} fosse ${adj} ${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Demasiado pequeno: esperava que ${translateOriginWithArticle(issue.origin, \"definite\")} tivesse ${adj} ${issue.minimum.toString()} ${sizing.unit ?? \"elementos\"}`;\n }\n return `Demasiado pequeno: esperava que ${translateOriginWithArticle(issue.origin, \"definite\")} fosse ${adj} ${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Texto inv\u00E1lido: deve come\u00E7ar por \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Texto inv\u00E1lido: deve terminar em \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Texto inv\u00E1lido: deve incluir \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Texto inv\u00E1lido: deve corresponder ao padr\u00E3o ${_issue.pattern}`;\n return `Formato d${FormatDictionary[_issue.format] ?? issue.format} inv\u00E1lido`;\n }\n case \"not_multiple_of\":\n return `N\u00FAmero inv\u00E1lido: deve ser m\u00FAltiplo de ${issue.divisor}`;\n case \"unrecognized_keys\": {\n const plural = issue.keys.length > 1 ? \"s\" : \"\";\n return `Chave${plural} inv\u00E1lida${plural}: ${util.joinValues(issue.keys, \", \")}`;\n }\n case \"invalid_key\":\n return `Entrada inv\u00E1lida n${translateOriginWithArticle(issue.origin, \"definite\")}`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `Valor de discrimina\u00E7\u00E3o inv\u00E1lido. Esperava ${opts}`;\n }\n return \"Entrada inv\u00E1lida\";\n case \"invalid_element\":\n return `Entrada inv\u00E1lida n${translateOriginWithArticle(issue.origin, \"definite\")}`;\n default:\n return `Entrada inv\u00E1lida`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"caracteres\" },\n file: { unit: \"bytes\" },\n array: { unit: \"elementos\" },\n set: { unit: \"elementos\" },\n map: { unit: \"entradas\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"a entrada\",\n email: \"o endere\u00E7o de e-mail\",\n url: \"o URL\",\n emoji: \"o emoji\",\n uuid: \"o UUID\",\n uuidv4: \"o UUIDv4\",\n uuidv6: \"o UUIDv6\",\n nanoid: \"o nanoid\",\n guid: \"o GUID\",\n cuid: \"o cuid\",\n cuid2: \"o cuid2\",\n ulid: \"o ULID\",\n xid: \"o XID\",\n ksuid: \"o KSUID\",\n datetime: \"a data e hora ISO\",\n date: \"a data ISO\",\n time: \"a hora ISO\",\n duration: \"a dura\u00E7\u00E3o ISO\",\n ipv4: \"o endere\u00E7o IPv4\",\n ipv6: \"o endere\u00E7o IPv6\",\n mac: \"o endere\u00E7o MAC\",\n cidrv4: \"a faixa de endere\u00E7os IPv4\",\n cidrv6: \"a faixa de endere\u00E7os IPv6\",\n base64: \"o texto codificado em base64\",\n base64url: \"o texto codificado em base64url\",\n json_string: \"o texto JSON\",\n e164: \"o n\u00FAmero E.164\",\n credit_card: \"o n\u00FAmero de cart\u00E3o de cr\u00E9dito\",\n currency_code: \"o c\u00F3digo de moeda\",\n iban: \"o IBAN\",\n jwt: \"o JWT\",\n template_literal: \"a entrada\",\n };\n const Gender = {\n masculine: { definite: \"o\", indefinite: \"um\" },\n feminine: { definite: \"a\", indefinite: \"uma\" },\n };\n const TypeDictionary = {\n string: { name: \"texto\", articles: Gender.masculine },\n number: { name: \"n\u00FAmero\", articles: Gender.masculine },\n int: { name: \"n\u00FAmero inteiro\", articles: Gender.masculine },\n boolean: { name: \"valor booleano\", articles: Gender.masculine },\n bigint: { name: \"n\u00FAmero bigint\", articles: Gender.masculine },\n symbol: { name: \"s\u00EDmbolo\", articles: Gender.masculine },\n undefined: { name: 'valor \"undefined\"', articles: Gender.masculine },\n null: { name: 'valor \"nulo\"', articles: Gender.masculine },\n never: { name: 'valor \"never\"', articles: Gender.masculine },\n void: { name: 'valor \"void\"', articles: Gender.masculine },\n date: { name: \"data\", articles: Gender.feminine },\n array: { name: \"vetor\", articles: Gender.masculine },\n object: { name: \"objeto\", articles: Gender.masculine },\n tuple: { name: \"tupla\", articles: Gender.feminine },\n record: { name: \"registro\", articles: Gender.masculine },\n map: { name: \"mapa\", articles: Gender.masculine },\n set: { name: \"conjunto\", articles: Gender.masculine },\n file: { name: \"arquivo\", articles: Gender.masculine },\n nonoptional: { name: \"valor n\u00E3o opcional\", articles: Gender.masculine },\n nan: { name: 'valor \"NaN\"', articles: Gender.masculine }, // Compatibility: \"nan\" -> \"NaN\" for display\n function: { name: \"fun\u00E7\u00E3o\", articles: Gender.feminine },\n };\n function translateOriginWithArticle(type, articleType) {\n const translatedValue = TypeDictionary[type] ?? { name: `valor \"${type}\"`, articles: Gender.masculine };\n return `${translatedValue.articles[articleType]} ${translatedValue.name}`;\n }\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = translateOriginWithArticle(issue.expected, \"indefinite\");\n const receivedType = util.parsedType(issue.input);\n const received = translateOriginWithArticle(receivedType, \"indefinite\");\n return `Entrada inv\u00E1lida: esperava ${expected}, recebeu ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Entrada inv\u00E1lida: esperava ${util.stringifyPrimitive(issue.values[0])}`;\n return `Op\u00E7\u00E3o inv\u00E1lida: esperava uma das seguintes op\u00E7\u00F5es: ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Grande demais: esperava que ${translateOriginWithArticle(issue.origin, \"definite\")} tivesse ${adj} ${issue.maximum.toString()} ${sizing.unit ?? \"elementos\"}`;\n return `Grande demais: esperava que ${translateOriginWithArticle(issue.origin, \"definite\")} fosse ${adj} ${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Pequeno demais: esperava que ${translateOriginWithArticle(issue.origin, \"definite\")} tivesse ${adj} ${issue.minimum.toString()} ${sizing.unit ?? \"elementos\"}`;\n }\n return `Pequeno demais: esperava que ${translateOriginWithArticle(issue.origin, \"definite\")} fosse ${adj} ${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `Texto inv\u00E1lido: deve come\u00E7ar com \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `Texto inv\u00E1lido: deve terminar com \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Texto inv\u00E1lido: deve incluir \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Texto inv\u00E1lido: deve corresponder ao padr\u00E3o ${_issue.pattern}`;\n return `Formato d${FormatDictionary[_issue.format] ?? issue.format} inv\u00E1lido`;\n }\n case \"not_multiple_of\":\n return `N\u00FAmero inv\u00E1lido: deve ser m\u00FAltiplo de ${issue.divisor}`;\n case \"unrecognized_keys\": {\n const plural = issue.keys.length > 1 ? \"s\" : \"\";\n return `Chave${plural} inv\u00E1lida${plural}: ${util.joinValues(issue.keys, \", \")}`;\n }\n case \"invalid_key\":\n return `Entrada inv\u00E1lida n${translateOriginWithArticle(issue.origin, \"definite\")}`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `Valor de discrimina\u00E7\u00E3o inv\u00E1lido. Esperava ${opts}`;\n }\n return \"Entrada inv\u00E1lida\";\n case \"invalid_element\":\n return `Entrada inv\u00E1lida n${translateOriginWithArticle(issue.origin, \"definite\")}`;\n default:\n return `Entrada inv\u00E1lida`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"caractere\", verb: \"s\u0103 aib\u0103\" },\n file: { unit: \"octe\u021Bi\", verb: \"s\u0103 aib\u0103\" },\n array: { unit: \"elemente\", verb: \"s\u0103 aib\u0103\" },\n set: { unit: \"elemente\", verb: \"s\u0103 aib\u0103\" },\n map: { unit: \"intr\u0103ri\", verb: \"s\u0103 aib\u0103\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"intrare\",\n email: \"adres\u0103 de email\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"dat\u0103 \u0219i or\u0103 ISO\",\n date: \"dat\u0103 ISO\",\n time: \"or\u0103 ISO\",\n duration: \"durat\u0103 ISO\",\n ipv4: \"adres\u0103 IPv4\",\n ipv6: \"adres\u0103 IPv6\",\n mac: \"adres\u0103 MAC\",\n cidrv4: \"interval IPv4\",\n cidrv6: \"interval IPv6\",\n base64: \"\u0219ir codat base64\",\n base64url: \"\u0219ir codat base64url\",\n json_string: \"\u0219ir JSON\",\n e164: \"num\u0103r E.164\",\n credit_card: \"num\u0103r de card de credit\",\n currency_code: \"cod valutar\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"intrare\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n string: \"\u0219ir\",\n number: \"num\u0103r\",\n boolean: \"boolean\",\n function: \"func\u021Bie\",\n array: \"matrice\",\n object: \"obiect\",\n undefined: \"nedefinit\",\n symbol: \"simbol\",\n bigint: \"num\u0103r mare\",\n void: \"void\",\n never: \"never\",\n map: \"hart\u0103\",\n set: \"set\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n return `Intrare invalid\u0103: a\u0219teptat ${expected}, primit ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Intrare invalid\u0103: a\u0219teptat ${util.stringifyPrimitive(issue.values[0])}`;\n return `Op\u021Biune invalid\u0103: a\u0219teptat una dintre ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Prea mare: a\u0219teptat ca ${issue.origin ?? \"valoarea\"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elemente\"}`;\n return `Prea mare: a\u0219teptat ca ${issue.origin ?? \"valoarea\"} s\u0103 fie ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Prea mic: a\u0219teptat ca ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Prea mic: a\u0219teptat ca ${issue.origin} s\u0103 fie ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u0218ir invalid: trebuie s\u0103 \u00EEnceap\u0103 cu \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u0218ir invalid: trebuie s\u0103 se termine cu \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u0218ir invalid: trebuie s\u0103 includ\u0103 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u0218ir invalid: trebuie s\u0103 se potriveasc\u0103 cu modelul ${_issue.pattern}`;\n return `Format invalid: ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Num\u0103r invalid: trebuie s\u0103 fie multiplu de ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Chei nerecunoscute: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Cheie invalid\u0103 \u00EEn ${issue.origin}`;\n case \"invalid_union\":\n return \"Intrare invalid\u0103\";\n case \"invalid_element\":\n return `Valoare invalid\u0103 \u00EEn ${issue.origin}`;\n default:\n return `Intrare invalid\u0103`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nfunction getRussianPlural(count, one, few, many) {\n const absCount = Math.abs(count);\n const lastDigit = absCount % 10;\n const lastTwoDigits = absCount % 100;\n if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {\n return many;\n }\n if (lastDigit === 1) {\n return one;\n }\n if (lastDigit >= 2 && lastDigit <= 4) {\n return few;\n }\n return many;\n}\nconst error = () => {\n const Sizable = {\n string: {\n unit: {\n one: \"\u0441\u0438\u043C\u0432\u043E\u043B\",\n few: \"\u0441\u0438\u043C\u0432\u043E\u043B\u0430\",\n many: \"\u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432\",\n },\n verb: \"\u0438\u043C\u0435\u0442\u044C\",\n },\n file: {\n unit: {\n one: \"\u0431\u0430\u0439\u0442\",\n few: \"\u0431\u0430\u0439\u0442\u0430\",\n many: \"\u0431\u0430\u0439\u0442\",\n },\n verb: \"\u0438\u043C\u0435\u0442\u044C\",\n },\n array: {\n unit: {\n one: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\",\n few: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\",\n many: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\",\n },\n verb: \"\u0438\u043C\u0435\u0442\u044C\",\n },\n set: {\n unit: {\n one: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\",\n few: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\",\n many: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\",\n },\n verb: \"\u0438\u043C\u0435\u0442\u044C\",\n },\n map: {\n unit: {\n one: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\",\n few: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\",\n many: \"\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\",\n },\n verb: \"\u0438\u043C\u0435\u0442\u044C\",\n },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0432\u0432\u043E\u0434\",\n email: \"email \u0430\u0434\u0440\u0435\u0441\",\n url: \"URL\",\n emoji: \"\u044D\u043C\u043E\u0434\u0437\u0438\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0434\u0430\u0442\u0430 \u0438 \u0432\u0440\u0435\u043C\u044F\",\n date: \"ISO \u0434\u0430\u0442\u0430\",\n time: \"ISO \u0432\u0440\u0435\u043C\u044F\",\n duration: \"ISO \u0434\u043B\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C\",\n ipv4: \"IPv4 \u0430\u0434\u0440\u0435\u0441\",\n ipv6: \"IPv6 \u0430\u0434\u0440\u0435\u0441\",\n mac: \"MAC \u0430\u0434\u0440\u0435\u0441\",\n cidrv4: \"IPv4 \u0434\u0438\u0430\u043F\u0430\u0437\u043E\u043D\",\n cidrv6: \"IPv6 \u0434\u0438\u0430\u043F\u0430\u0437\u043E\u043D\",\n base64: \"\u0441\u0442\u0440\u043E\u043A\u0430 \u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0435 base64\",\n base64url: \"\u0441\u0442\u0440\u043E\u043A\u0430 \u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0435 base64url\",\n json_string: \"JSON \u0441\u0442\u0440\u043E\u043A\u0430\",\n e164: \"\u043D\u043E\u043C\u0435\u0440 E.164\",\n credit_card: \"\u043D\u043E\u043C\u0435\u0440 \u043A\u0440\u0435\u0434\u0438\u0442\u043D\u043E\u0439 \u043A\u0430\u0440\u0442\u044B\",\n currency_code: \"\u043A\u043E\u0434 \u0432\u0430\u043B\u044E\u0442\u044B\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0432\u0432\u043E\u0434\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0447\u0438\u0441\u043B\u043E\",\n array: \"\u043C\u0430\u0441\u0441\u0438\u0432\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0432\u0432\u043E\u0434: \u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C instanceof ${issue.expected}, \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u043E ${received}`;\n }\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0432\u0432\u043E\u0434: \u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C ${expected}, \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u043E ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0432\u0432\u043E\u0434: \u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0432\u0430\u0440\u0438\u0430\u043D\u0442: \u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0434\u043D\u043E \u0438\u0437 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n const maxValue = Number(issue.maximum);\n const unit = getRussianPlural(maxValue, sizing.unit.one, sizing.unit.few, sizing.unit.many);\n return `\u0421\u043B\u0438\u0448\u043A\u043E\u043C \u0431\u043E\u043B\u044C\u0448\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435: \u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C, \u0447\u0442\u043E ${issue.origin ?? \"\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\"} \u0431\u0443\u0434\u0435\u0442 \u0438\u043C\u0435\u0442\u044C ${adj}${issue.maximum.toString()} ${unit}`;\n }\n return `\u0421\u043B\u0438\u0448\u043A\u043E\u043C \u0431\u043E\u043B\u044C\u0448\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435: \u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C, \u0447\u0442\u043E ${issue.origin ?? \"\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\"} \u0431\u0443\u0434\u0435\u0442 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n const minValue = Number(issue.minimum);\n const unit = getRussianPlural(minValue, sizing.unit.one, sizing.unit.few, sizing.unit.many);\n return `\u0421\u043B\u0438\u0448\u043A\u043E\u043C \u043C\u0430\u043B\u0435\u043D\u044C\u043A\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435: \u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C, \u0447\u0442\u043E ${issue.origin} \u0431\u0443\u0434\u0435\u0442 \u0438\u043C\u0435\u0442\u044C ${adj}${issue.minimum.toString()} ${unit}`;\n }\n return `\u0421\u043B\u0438\u0448\u043A\u043E\u043C \u043C\u0430\u043B\u0435\u043D\u044C\u043A\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435: \u043E\u0436\u0438\u0434\u0430\u043B\u043E\u0441\u044C, \u0447\u0442\u043E ${issue.origin} \u0431\u0443\u0434\u0435\u0442 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430: \u0434\u043E\u043B\u0436\u043D\u0430 \u043D\u0430\u0447\u0438\u043D\u0430\u0442\u044C\u0441\u044F \u0441 \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430: \u0434\u043E\u043B\u0436\u043D\u0430 \u0437\u0430\u043A\u0430\u043D\u0447\u0438\u0432\u0430\u0442\u044C\u0441\u044F \u043D\u0430 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430: \u0434\u043E\u043B\u0436\u043D\u0430 \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430: \u0434\u043E\u043B\u0436\u043D\u0430 \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043E\u0432\u0430\u0442\u044C \u0448\u0430\u0431\u043B\u043E\u043D\u0443 ${_issue.pattern}`;\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u043E\u0435 \u0447\u0438\u0441\u043B\u043E: \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043A\u0440\u0430\u0442\u043D\u044B\u043C ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u041D\u0435\u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u043D\u043D${issue.keys.length > 1 ? \"\u044B\u0435\" : \"\u044B\u0439\"} \u043A\u043B\u044E\u0447${issue.keys.length > 1 ? \"\u0438\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u043A\u043B\u044E\u0447 \u0432 ${issue.origin}`;\n case \"invalid_union\":\n return \"\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0435 \u0432\u0445\u043E\u0434\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435\";\n case \"invalid_element\":\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0432 ${issue.origin}`;\n default:\n return `\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0435 \u0432\u0445\u043E\u0434\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"znakov\", verb: \"ma\u0165\" },\n file: { unit: \"bajtov\", verb: \"ma\u0165\" },\n array: { unit: \"prvkov\", verb: \"ma\u0165\" },\n set: { unit: \"prvkov\", verb: \"ma\u0165\" },\n map: { unit: \"polo\u017Eiek\", verb: \"ma\u0165\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"regul\u00E1rny v\u00FDraz\",\n email: \"e-mailov\u00E1 adresa\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"d\u00E1tum a \u010Das vo form\u00E1te ISO\",\n date: \"d\u00E1tum vo form\u00E1te ISO\",\n time: \"\u010Das vo form\u00E1te ISO\",\n duration: \"doba trvania ISO\",\n ipv4: \"IPv4 adresa\",\n ipv6: \"IPv6 adresa\",\n mac: \"MAC adresa\",\n cidrv4: \"rozsah IPv4\",\n cidrv6: \"rozsah IPv6\",\n base64: \"re\u0165azec zak\u00F3dovan\u00FD vo form\u00E1te base64\",\n base64url: \"re\u0165azec zak\u00F3dovan\u00FD vo form\u00E1te base64url\",\n json_string: \"re\u0165azec vo form\u00E1te JSON\",\n e164: \"\u010D\u00EDslo E.164\",\n credit_card: \"\u010D\u00EDslo kreditnej karty\",\n currency_code: \"k\u00F3d meny\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"vstup\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u010D\u00EDslo\",\n string: \"re\u0165azec\",\n function: \"funkcia\",\n array: \"pole\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Neplatn\u00FD vstup: o\u010Dak\u00E1van\u00E9 instanceof ${issue.expected}, obdr\u017Ean\u00E9 ${received}`;\n }\n return `Neplatn\u00FD vstup: o\u010Dak\u00E1van\u00E9 ${expected}, obdr\u017Ean\u00E9 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Neplatn\u00FD vstup: o\u010Dak\u00E1van\u00E9 ${util.stringifyPrimitive(issue.values[0])}`;\n return `Neplatn\u00FD vstup: o\u010Dak\u00E1van\u00E1 jedna z hodn\u00F4t ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Hodnota je pr\u00EDli\u0161 ve\u013Ek\u00E1: ${issue.origin ?? \"hodnota\"} mus\u00ED ma\u0165 ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"prvkov\"}`;\n }\n return `Hodnota je pr\u00EDli\u0161 ve\u013Ek\u00E1: ${issue.origin ?? \"hodnota\"} mus\u00ED by\u0165 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Hodnota je pr\u00EDli\u0161 mal\u00E1: ${issue.origin ?? \"hodnota\"} mus\u00ED ma\u0165 ${adj}${issue.minimum.toString()} ${sizing.unit ?? \"prvkov\"}`;\n }\n return `Hodnota je pr\u00EDli\u0161 mal\u00E1: ${issue.origin ?? \"hodnota\"} mus\u00ED by\u0165 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Neplatn\u00FD re\u0165azec: mus\u00ED za\u010D\u00EDna\u0165 na \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Neplatn\u00FD re\u0165azec: mus\u00ED kon\u010Di\u0165 na \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Neplatn\u00FD re\u0165azec: mus\u00ED obsahova\u0165 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Neplatn\u00FD re\u0165azec: mus\u00ED zodpoveda\u0165 vzoru ${_issue.pattern}`;\n return `Neplatn\u00FD form\u00E1t ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Neplatn\u00E9 \u010D\u00EDslo: mus\u00ED by\u0165 n\u00E1sobkom ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Nezn\u00E1me kl\u00FA\u010De: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Neplatn\u00FD kl\u00FA\u010D v ${issue.origin}`;\n case \"invalid_union\":\n return \"Neplatn\u00FD vstup\";\n case \"invalid_element\":\n return `Neplatn\u00E1 hodnota v ${issue.origin}`;\n default:\n return `Neplatn\u00FD vstup`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"znakov\", verb: \"imeti\" },\n file: { unit: \"bajtov\", verb: \"imeti\" },\n array: { unit: \"elementov\", verb: \"imeti\" },\n set: { unit: \"elementov\", verb: \"imeti\" },\n map: { unit: \"elementov\", verb: \"imeti\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"vnos\",\n email: \"e-po\u0161tni naslov\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO datum in \u010Das\",\n date: \"ISO datum\",\n time: \"ISO \u010Das\",\n duration: \"ISO trajanje\",\n ipv4: \"IPv4 naslov\",\n ipv6: \"IPv6 naslov\",\n mac: \"MAC naslov\",\n cidrv4: \"obseg IPv4\",\n cidrv6: \"obseg IPv6\",\n base64: \"base64 kodiran niz\",\n base64url: \"base64url kodiran niz\",\n json_string: \"JSON niz\",\n e164: \"E.164 \u0161tevilka\",\n credit_card: \"\u0161tevilka kreditne kartice\",\n currency_code: \"koda valute\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"vnos\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0161tevilo\",\n array: \"tabela\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Neveljaven vnos: pri\u010Dakovano instanceof ${issue.expected}, prejeto ${received}`;\n }\n return `Neveljaven vnos: pri\u010Dakovano ${expected}, prejeto ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Neveljaven vnos: pri\u010Dakovano ${util.stringifyPrimitive(issue.values[0])}`;\n return `Neveljavna mo\u017Enost: pri\u010Dakovano eno izmed ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Preveliko: pri\u010Dakovano, da bo ${issue.origin ?? \"vrednost\"} imelo ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"elementov\"}`;\n return `Preveliko: pri\u010Dakovano, da bo ${issue.origin ?? \"vrednost\"} ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Premajhno: pri\u010Dakovano, da bo ${issue.origin} imelo ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Premajhno: pri\u010Dakovano, da bo ${issue.origin} ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `Neveljaven niz: mora se za\u010Deti z \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `Neveljaven niz: mora se kon\u010Dati z \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Neveljaven niz: mora vsebovati \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Neveljaven niz: mora ustrezati vzorcu ${_issue.pattern}`;\n return `Neveljaven ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Neveljavno \u0161tevilo: mora biti ve\u010Dkratnik ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Neprepoznan${issue.keys.length > 1 ? \"i klju\u010Di\" : \" klju\u010D\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Neveljaven klju\u010D v ${issue.origin}`;\n case \"invalid_union\":\n return \"Neveljaven vnos\";\n case \"invalid_element\":\n return `Neveljavna vrednost v ${issue.origin}`;\n default:\n return \"Neveljaven vnos\";\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"tecken\", verb: \"att ha\" },\n file: { unit: \"bytes\", verb: \"att ha\" },\n array: { unit: \"objekt\", verb: \"att inneh\u00E5lla\" },\n set: { unit: \"objekt\", verb: \"att inneh\u00E5lla\" },\n map: { unit: \"objekt\", verb: \"att inneh\u00E5lla\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"regulj\u00E4rt uttryck\",\n email: \"e-postadress\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO-datum och tid\",\n date: \"ISO-datum\",\n time: \"ISO-tid\",\n duration: \"ISO-varaktighet\",\n ipv4: \"IPv4-adress\",\n ipv6: \"IPv6-adress\",\n mac: \"MAC-adress\",\n cidrv4: \"IPv4-spektrum\",\n cidrv6: \"IPv6-spektrum\",\n base64: \"base64-kodad str\u00E4ng\",\n base64url: \"base64url-kodad str\u00E4ng\",\n json_string: \"JSON-str\u00E4ng\",\n e164: \"E.164-nummer\",\n credit_card: \"kreditkortsnummer\",\n currency_code: \"valutakod\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"mall-literal\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"antal\",\n array: \"lista\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Ogiltig inmatning: f\u00F6rv\u00E4ntat instanceof ${issue.expected}, fick ${received}`;\n }\n return `Ogiltig inmatning: f\u00F6rv\u00E4ntat ${expected}, fick ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Ogiltig inmatning: f\u00F6rv\u00E4ntat ${util.stringifyPrimitive(issue.values[0])}`;\n return `Ogiltigt val: f\u00F6rv\u00E4ntade en av ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `F\u00F6r stor(t): f\u00F6rv\u00E4ntade ${issue.origin ?? \"v\u00E4rdet\"} att ha ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"element\"}`;\n }\n return `F\u00F6r stor(t): f\u00F6rv\u00E4ntat ${issue.origin ?? \"v\u00E4rdet\"} att ha ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `F\u00F6r lite(t): f\u00F6rv\u00E4ntade ${issue.origin ?? \"v\u00E4rdet\"} att ha ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `F\u00F6r lite(t): f\u00F6rv\u00E4ntade ${issue.origin ?? \"v\u00E4rdet\"} att ha ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `Ogiltig str\u00E4ng: m\u00E5ste b\u00F6rja med \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `Ogiltig str\u00E4ng: m\u00E5ste sluta med \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Ogiltig str\u00E4ng: m\u00E5ste inneh\u00E5lla \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Ogiltig str\u00E4ng: m\u00E5ste matcha m\u00F6nstret \"${_issue.pattern}\"`;\n return `Ogiltig(t) ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Ogiltigt tal: m\u00E5ste vara en multipel av ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `${issue.keys.length > 1 ? \"Ok\u00E4nda nycklar\" : \"Ok\u00E4nd nyckel\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Ogiltig nyckel i ${issue.origin ?? \"v\u00E4rdet\"}`;\n case \"invalid_union\":\n return \"Ogiltig input\";\n case \"invalid_element\":\n return `Ogiltigt v\u00E4rde i ${issue.origin ?? \"v\u00E4rdet\"}`;\n default:\n return `Ogiltig input`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0B8E\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BCD\u0B95\u0BB3\u0BCD\", verb: \"\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD\" },\n file: { unit: \"\u0BAA\u0BC8\u0B9F\u0BCD\u0B9F\u0BC1\u0B95\u0BB3\u0BCD\", verb: \"\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD\" },\n array: { unit: \"\u0B89\u0BB1\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD\", verb: \"\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD\" },\n set: { unit: \"\u0B89\u0BB1\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD\", verb: \"\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD\" },\n map: { unit: \"\u0B89\u0BB1\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD\", verb: \"\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0B89\u0BB3\u0BCD\u0BB3\u0BC0\u0B9F\u0BC1\",\n email: \"\u0BAE\u0BBF\u0BA9\u0BCD\u0BA9\u0B9E\u0BCD\u0B9A\u0BB2\u0BCD \u0BAE\u0BC1\u0B95\u0BB5\u0BB0\u0BBF\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u0BA4\u0BC7\u0BA4\u0BBF \u0BA8\u0BC7\u0BB0\u0BAE\u0BCD\",\n date: \"ISO \u0BA4\u0BC7\u0BA4\u0BBF\",\n time: \"ISO \u0BA8\u0BC7\u0BB0\u0BAE\u0BCD\",\n duration: \"ISO \u0B95\u0BBE\u0BB2 \u0B85\u0BB3\u0BB5\u0BC1\",\n ipv4: \"IPv4 \u0BAE\u0BC1\u0B95\u0BB5\u0BB0\u0BBF\",\n ipv6: \"IPv6 \u0BAE\u0BC1\u0B95\u0BB5\u0BB0\u0BBF\",\n mac: \"MAC \u0BAE\u0BC1\u0B95\u0BB5\u0BB0\u0BBF\",\n cidrv4: \"IPv4 \u0BB5\u0BB0\u0BAE\u0BCD\u0BAA\u0BC1\",\n cidrv6: \"IPv6 \u0BB5\u0BB0\u0BAE\u0BCD\u0BAA\u0BC1\",\n base64: \"base64-encoded \u0B9A\u0BB0\u0BAE\u0BCD\",\n base64url: \"base64url-encoded \u0B9A\u0BB0\u0BAE\u0BCD\",\n json_string: \"JSON \u0B9A\u0BB0\u0BAE\u0BCD\",\n e164: \"E.164 \u0B8E\u0BA3\u0BCD\",\n credit_card: \"\u0B95\u0B9F\u0BA9\u0BCD \u0B85\u0B9F\u0BCD\u0B9F\u0BC8 \u0B8E\u0BA3\u0BCD\",\n currency_code: \"\u0BA8\u0BBE\u0BA3\u0BAF\u0B95\u0BCD \u0B95\u0BC1\u0BB1\u0BBF\u0BAF\u0BC0\u0B9F\u0BC1\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"input\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0B8E\u0BA3\u0BCD\",\n array: \"\u0B85\u0BA3\u0BBF\",\n null: \"\u0BB5\u0BC6\u0BB1\u0BC1\u0BAE\u0BC8\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B89\u0BB3\u0BCD\u0BB3\u0BC0\u0B9F\u0BC1: \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 instanceof ${issue.expected}, \u0BAA\u0BC6\u0BB1\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${received}`;\n }\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B89\u0BB3\u0BCD\u0BB3\u0BC0\u0B9F\u0BC1: \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${expected}, \u0BAA\u0BC6\u0BB1\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B89\u0BB3\u0BCD\u0BB3\u0BC0\u0B9F\u0BC1: \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0BB5\u0BBF\u0BB0\u0BC1\u0BAA\u0BCD\u0BAA\u0BAE\u0BCD: \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${util.joinValues(issue.values, \"|\")} \u0B87\u0BB2\u0BCD \u0B92\u0BA9\u0BCD\u0BB1\u0BC1`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0BAE\u0BBF\u0B95 \u0BAA\u0BC6\u0BB0\u0BBF\u0BAF\u0BA4\u0BC1: \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${issue.origin ?? \"\u0BAE\u0BA4\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0B89\u0BB1\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD\"} \u0B86\u0B95 \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`;\n }\n return `\u0BAE\u0BBF\u0B95 \u0BAA\u0BC6\u0BB0\u0BBF\u0BAF\u0BA4\u0BC1: \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${issue.origin ?? \"\u0BAE\u0BA4\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\"} ${adj}${issue.maximum.toString()} \u0B86\u0B95 \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0BAE\u0BBF\u0B95\u0B9A\u0BCD \u0B9A\u0BBF\u0BB1\u0BBF\u0BAF\u0BA4\u0BC1: \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} \u0B86\u0B95 \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`; //\n }\n return `\u0BAE\u0BBF\u0B95\u0B9A\u0BCD \u0B9A\u0BBF\u0BB1\u0BBF\u0BAF\u0BA4\u0BC1: \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1 ${issue.origin} ${adj}${issue.minimum.toString()} \u0B86\u0B95 \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B9A\u0BB0\u0BAE\u0BCD: \"${_issue.prefix}\" \u0B87\u0BB2\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`;\n if (_issue.format === \"ends_with\")\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B9A\u0BB0\u0BAE\u0BCD: \"${_issue.suffix}\" \u0B87\u0BB2\u0BCD \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0B9F\u0BC8\u0BAF \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`;\n if (_issue.format === \"includes\")\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B9A\u0BB0\u0BAE\u0BCD: \"${_issue.includes}\" \u0B90 \u0B89\u0BB3\u0BCD\u0BB3\u0B9F\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`;\n if (_issue.format === \"regex\")\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B9A\u0BB0\u0BAE\u0BCD: ${_issue.pattern} \u0BAE\u0BC1\u0BB1\u0BC8\u0BAA\u0BBE\u0B9F\u0BCD\u0B9F\u0BC1\u0B9F\u0BA9\u0BCD \u0BAA\u0BCA\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`;\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B8E\u0BA3\u0BCD: ${issue.divisor} \u0B87\u0BA9\u0BCD \u0BAA\u0BB2\u0BAE\u0BBE\u0B95 \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD`;\n case \"unrecognized_keys\":\n return `\u0B85\u0B9F\u0BC8\u0BAF\u0BBE\u0BB3\u0BAE\u0BCD \u0BA4\u0BC6\u0BB0\u0BBF\u0BAF\u0BBE\u0BA4 \u0BB5\u0BBF\u0B9A\u0BC8${issue.keys.length > 1 ? \"\u0B95\u0BB3\u0BCD\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} \u0B87\u0BB2\u0BCD \u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0BB5\u0BBF\u0B9A\u0BC8`;\n case \"invalid_union\":\n return \"\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B89\u0BB3\u0BCD\u0BB3\u0BC0\u0B9F\u0BC1\";\n case \"invalid_element\":\n return `${issue.origin} \u0B87\u0BB2\u0BCD \u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0BAE\u0BA4\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1`;\n default:\n return `\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0B89\u0BB3\u0BCD\u0BB3\u0BC0\u0B9F\u0BC1`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n // singular units after numerals in Tajik\n const Sizable = {\n string: { unit: \"\u0430\u043B\u043E\u043C\u0430\u0442\", verb: \"\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434\" },\n file: { unit: \"\u0431\u0430\u0439\u0442\", verb: \"\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434\" },\n array: { unit: \"\u0443\u043D\u0441\u0443\u0440\", verb: \"\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434\" },\n set: { unit: \"\u0443\u043D\u0441\u0443\u0440\", verb: \"\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434\" },\n map: { unit: \"\u0441\u0430\u0431\u0442\", verb: \"\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0432\u0443\u0440\u0443\u0434\",\n email: \"\u0441\u0443\u0440\u043E\u0493\u0430\u0438 email\",\n url: \"URL\",\n emoji: \"\u044D\u043C\u043E\u04B7\u0438\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u0441\u0430\u043D\u0430\u0432\u0443 \u0432\u0430\u049B\u0442\u0438 ISO\",\n date: \"\u0441\u0430\u043D\u0430\u0438 ISO\",\n time: \"\u0432\u0430\u049B\u0442\u0438 ISO\",\n duration: \"\u0434\u0430\u0432\u043E\u043C\u043D\u043E\u043A\u0438\u0438 ISO\",\n ipv4: \"\u0441\u0443\u0440\u043E\u0493\u0430\u0438 IPv4\",\n ipv6: \"\u0441\u0443\u0440\u043E\u0493\u0430\u0438 IPv6\",\n mac: \"\u0441\u0443\u0440\u043E\u0493\u0430\u0438 MAC\",\n cidrv4: \"\u043C\u0430\u04B3\u0434\u0443\u0434\u0430\u0438 IPv4\",\n cidrv6: \"\u043C\u0430\u04B3\u0434\u0443\u0434\u0430\u0438 IPv6\",\n base64: \"\u0441\u0430\u0442\u0440\u0438 \u0434\u0430\u0440 \u0444\u043E\u0440\u043C\u0430\u0442\u0438 base64\",\n base64url: \"\u0441\u0430\u0442\u0440\u0438 \u0434\u0430\u0440 \u0444\u043E\u0440\u043C\u0430\u0442\u0438 base64url\",\n json_string: \"\u0441\u0430\u0442\u0440\u0438 JSON\",\n e164: \"\u0440\u0430\u049B\u0430\u043C\u0438 E.164\",\n credit_card: \"\u0440\u0430\u049B\u0430\u043C\u0438 \u043A\u043E\u0440\u0442\u0438 \u043A\u0440\u0435\u0434\u0438\u0442\u04E3\",\n currency_code: \"\u0440\u0430\u043C\u0437\u0438 \u0430\u0441\u044A\u043E\u0440\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0432\u0443\u0440\u0443\u0434\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0440\u0430\u049B\u0430\u043C\",\n string: \"\u0441\u0430\u0442\u0440\",\n array: \"\u043C\u0430\u0441\u0441\u0438\u0432\",\n object: \"\u043E\u0431\u044A\u0435\u043A\u0442\",\n date: \"\u0441\u0430\u043D\u0430\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n return `\u0412\u0443\u0440\u0443\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: ${expected} \u0438\u043D\u0442\u0438\u0437\u043E\u0440 \u043C\u0435\u0440\u0430\u0444\u0442, ${received} \u0433\u0438\u0440\u0438\u0444\u0442\u0430 \u0448\u0443\u0434`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0412\u0443\u0440\u0443\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: ${util.stringifyPrimitive(issue.values[0])} \u0438\u043D\u0442\u0438\u0437\u043E\u0440 \u043C\u0435\u0440\u0430\u0444\u0442`;\n return `\u0418\u043D\u0442\u0438\u0445\u043E\u0431\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u044F\u043A\u0435 \u0430\u0437 ${util.joinValues(issue.values, \"|\")} \u0438\u043D\u0442\u0438\u0437\u043E\u0440 \u043C\u0435\u0440\u0430\u0444\u0442`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0425\u0435\u043B\u0435 \u043A\u0430\u043B\u043E\u043D: ${issue.origin ?? \"\u049B\u0438\u043C\u0430\u0442\"} \u0431\u043E\u044F\u0434 ${adj}${issue.maximum.toString()} ${sizing.unit} ${sizing.verb}`;\n return `\u0425\u0435\u043B\u0435 \u043A\u0430\u043B\u043E\u043D: ${issue.origin ?? \"\u049B\u0438\u043C\u0430\u0442\"} \u0431\u043E\u044F\u0434 ${adj}${issue.maximum.toString()} \u0431\u043E\u0448\u0430\u0434`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0425\u0435\u043B\u0435 \u0445\u0443\u0440\u0434: ${issue.origin} \u0431\u043E\u044F\u0434 ${adj}${issue.minimum.toString()} ${sizing.unit} ${sizing.verb}`;\n return `\u0425\u0435\u043B\u0435 \u0445\u0443\u0440\u0434: ${issue.origin} \u0431\u043E\u044F\u0434 ${adj}${issue.minimum.toString()} \u0431\u043E\u0448\u0430\u0434`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u0421\u0430\u0442\u0440\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \u0431\u043E \"${_issue.prefix}\" \u043E\u0493\u043E\u0437 \u0448\u0430\u0432\u0430\u0434`;\n if (_issue.format === \"ends_with\")\n return `\u0421\u0430\u0442\u0440\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \u0431\u043E \"${_issue.suffix}\" \u0430\u043D\u04B7\u043E\u043C \u0451\u0431\u0430\u0434`;\n if (_issue.format === \"includes\")\n return `\u0421\u0430\u0442\u0440\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \"${_issue.includes}\"-\u0440\u043E \u0434\u0430\u0440 \u0431\u0430\u0440 \u0433\u0438\u0440\u0430\u0434`;\n if (_issue.format === \"regex\")\n return `\u0421\u0430\u0442\u0440\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \u0431\u0430 \u043D\u0430\u043C\u0443\u043D\u0430\u0438 ${_issue.pattern} \u043C\u0443\u0432\u043E\u0444\u0438\u049B\u0430\u0442 \u043A\u0443\u043D\u0430\u0434`;\n return `${FormatDictionary[_issue.format] ?? issue.format}-\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442`;\n }\n case \"not_multiple_of\":\n return `\u0420\u0430\u049B\u0430\u043C\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \u0431\u0430 ${issue.divisor} \u0431\u0435 \u0431\u0430\u049B\u0438\u044F \u0442\u0430\u049B\u0441\u0438\u043C \u0448\u0430\u0432\u0430\u0434`;\n case \"unrecognized_keys\":\n return `\u041A\u0430\u043B\u0438\u0434${issue.keys.length > 1 ? \"\u04B3\u043E\u0438\" : \"\u0438\"} \u043D\u043E\u043C\u0430\u044A\u043B\u0443\u043C: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u041A\u0430\u043B\u0438\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442 \u0434\u0430\u0440 ${issue.origin}`;\n case \"invalid_union\":\n if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) {\n const opts = issue.options.map((o) => `'${o}'`).join(\" | \");\n return `\u049A\u0438\u043C\u0430\u0442\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442\u0438 \u0434\u0438\u0441\u043A\u0440\u0438\u043C\u0438\u043D\u0430\u0442\u043E\u0440: ${opts} \u0438\u043D\u0442\u0438\u0437\u043E\u0440 \u043C\u0435\u0440\u0430\u0444\u0442`;\n }\n return \"\u0412\u0443\u0440\u0443\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442\";\n case \"invalid_element\":\n return `\u049A\u0438\u043C\u0430\u0442\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442 \u0434\u0430\u0440 ${issue.origin}`;\n default:\n return `\u0412\u0443\u0440\u0443\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\", verb: \"\u0E04\u0E27\u0E23\u0E21\u0E35\" },\n file: { unit: \"\u0E44\u0E1A\u0E15\u0E4C\", verb: \"\u0E04\u0E27\u0E23\u0E21\u0E35\" },\n array: { unit: \"\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\", verb: \"\u0E04\u0E27\u0E23\u0E21\u0E35\" },\n set: { unit: \"\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\", verb: \"\u0E04\u0E27\u0E23\u0E21\u0E35\" },\n map: { unit: \"\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\", verb: \"\u0E04\u0E27\u0E23\u0E21\u0E35\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E17\u0E35\u0E48\u0E1B\u0E49\u0E2D\u0E19\",\n email: \"\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48\u0E2D\u0E35\u0E40\u0E21\u0E25\",\n url: \"URL\",\n emoji: \"\u0E2D\u0E34\u0E42\u0E21\u0E08\u0E34\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E40\u0E27\u0E25\u0E32\u0E41\u0E1A\u0E1A ISO\",\n date: \"\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E41\u0E1A\u0E1A ISO\",\n time: \"\u0E40\u0E27\u0E25\u0E32\u0E41\u0E1A\u0E1A ISO\",\n duration: \"\u0E0A\u0E48\u0E27\u0E07\u0E40\u0E27\u0E25\u0E32\u0E41\u0E1A\u0E1A ISO\",\n ipv4: \"\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48 IPv4\",\n ipv6: \"\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48 IPv6\",\n mac: \"\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48 MAC\",\n cidrv4: \"\u0E0A\u0E48\u0E27\u0E07 IP \u0E41\u0E1A\u0E1A IPv4\",\n cidrv6: \"\u0E0A\u0E48\u0E27\u0E07 IP \u0E41\u0E1A\u0E1A IPv6\",\n base64: \"\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E41\u0E1A\u0E1A Base64\",\n base64url: \"\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E41\u0E1A\u0E1A Base64 \u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A URL\",\n json_string: \"\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E41\u0E1A\u0E1A JSON\",\n e164: \"\u0E40\u0E1A\u0E2D\u0E23\u0E4C\u0E42\u0E17\u0E23\u0E28\u0E31\u0E1E\u0E17\u0E4C\u0E23\u0E30\u0E2B\u0E27\u0E48\u0E32\u0E07\u0E1B\u0E23\u0E30\u0E40\u0E17\u0E28 (E.164)\",\n credit_card: \"\u0E2B\u0E21\u0E32\u0E22\u0E40\u0E25\u0E02\u0E1A\u0E31\u0E15\u0E23\u0E40\u0E04\u0E23\u0E14\u0E34\u0E15\",\n currency_code: \"\u0E23\u0E2B\u0E31\u0E2A\u0E2A\u0E01\u0E38\u0E25\u0E40\u0E07\u0E34\u0E19\",\n iban: \"IBAN\",\n jwt: \"\u0E42\u0E17\u0E40\u0E04\u0E19 JWT\",\n template_literal: \"\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E17\u0E35\u0E48\u0E1B\u0E49\u0E2D\u0E19\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0E15\u0E31\u0E27\u0E40\u0E25\u0E02\",\n array: \"\u0E2D\u0E32\u0E23\u0E4C\u0E40\u0E23\u0E22\u0E4C (Array)\",\n null: \"\u0E44\u0E21\u0E48\u0E21\u0E35\u0E04\u0E48\u0E32 (null)\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E04\u0E27\u0E23\u0E40\u0E1B\u0E47\u0E19 instanceof ${issue.expected} \u0E41\u0E15\u0E48\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A ${received}`;\n }\n return `\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E04\u0E27\u0E23\u0E40\u0E1B\u0E47\u0E19 ${expected} \u0E41\u0E15\u0E48\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0E04\u0E48\u0E32\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E04\u0E27\u0E23\u0E40\u0E1B\u0E47\u0E19 ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u0E15\u0E31\u0E27\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E04\u0E27\u0E23\u0E40\u0E1B\u0E47\u0E19\u0E2B\u0E19\u0E36\u0E48\u0E07\u0E43\u0E19 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19\" : \"\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0E40\u0E01\u0E34\u0E19\u0E01\u0E33\u0E2B\u0E19\u0E14: ${issue.origin ?? \"\u0E04\u0E48\u0E32\"} \u0E04\u0E27\u0E23\u0E21\u0E35${adj} ${issue.maximum.toString()} ${sizing.unit ?? \"\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\"}`;\n return `\u0E40\u0E01\u0E34\u0E19\u0E01\u0E33\u0E2B\u0E19\u0E14: ${issue.origin ?? \"\u0E04\u0E48\u0E32\"} \u0E04\u0E27\u0E23\u0E21\u0E35${adj} ${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \"\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22\" : \"\u0E21\u0E32\u0E01\u0E01\u0E27\u0E48\u0E32\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32\u0E01\u0E33\u0E2B\u0E19\u0E14: ${issue.origin} \u0E04\u0E27\u0E23\u0E21\u0E35${adj} ${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32\u0E01\u0E33\u0E2B\u0E19\u0E14: ${issue.origin} \u0E04\u0E27\u0E23\u0E21\u0E35${adj} ${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E15\u0E49\u0E2D\u0E07\u0E02\u0E36\u0E49\u0E19\u0E15\u0E49\u0E19\u0E14\u0E49\u0E27\u0E22 \"${_issue.prefix}\"`;\n }\n if (_issue.format === \"ends_with\")\n return `\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E15\u0E49\u0E2D\u0E07\u0E25\u0E07\u0E17\u0E49\u0E32\u0E22\u0E14\u0E49\u0E27\u0E22 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35 \"${_issue.includes}\" \u0E2D\u0E22\u0E39\u0E48\u0E43\u0E19\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21`;\n if (_issue.format === \"regex\")\n return `\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E15\u0E49\u0E2D\u0E07\u0E15\u0E23\u0E07\u0E01\u0E31\u0E1A\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E17\u0E35\u0E48\u0E01\u0E33\u0E2B\u0E19\u0E14 ${_issue.pattern}`;\n return `\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u0E15\u0E31\u0E27\u0E40\u0E25\u0E02\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19\u0E08\u0E33\u0E19\u0E27\u0E19\u0E17\u0E35\u0E48\u0E2B\u0E32\u0E23\u0E14\u0E49\u0E27\u0E22 ${issue.divisor} \u0E44\u0E14\u0E49\u0E25\u0E07\u0E15\u0E31\u0E27`;\n case \"unrecognized_keys\":\n return `\u0E1E\u0E1A\u0E04\u0E35\u0E22\u0E4C\u0E17\u0E35\u0E48\u0E44\u0E21\u0E48\u0E23\u0E39\u0E49\u0E08\u0E31\u0E01: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u0E04\u0E35\u0E22\u0E4C\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07\u0E43\u0E19 ${issue.origin}`;\n case \"invalid_union\":\n return \"\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07: \u0E44\u0E21\u0E48\u0E15\u0E23\u0E07\u0E01\u0E31\u0E1A\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E22\u0E39\u0E40\u0E19\u0E35\u0E22\u0E19\u0E17\u0E35\u0E48\u0E01\u0E33\u0E2B\u0E19\u0E14\u0E44\u0E27\u0E49\";\n case \"invalid_element\":\n return `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07\u0E43\u0E19 ${issue.origin}`;\n default:\n return `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"simwol\", verb: \"bolmaly\" },\n file: { unit: \"ba\u00FDt\", verb: \"bolmaly\" },\n array: { unit: \"elementler\", verb: \"bolmaly\" },\n set: { unit: \"elementler\", verb: \"bolmaly\" },\n map: { unit: \"elementler\", verb: \"bolmaly\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"giri\u015F\",\n email: \"e-po\u00E7ta salgysy\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO sene we wagt\",\n date: \"ISO sene\",\n time: \"ISO wagt\",\n duration: \"ISO wagt aralygy\",\n ipv4: \"IPv4 salgysy\",\n ipv6: \"IPv6 salgysy\",\n mac: \"MAC salgysy\",\n cidrv4: \"IPv4 aralygy\",\n cidrv6: \"IPv6 aralygy\",\n base64: \"base64 bilen \u015Fifrlenen setir\",\n base64url: \"base64url bilen \u015Fifrlenen setir\",\n json_string: \"JSON setiri\",\n e164: \"E.164 nomeri\",\n credit_card: \"kredit kartyny\u0148 nomeri\",\n currency_code: \"wal\u00FDuta kody\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u015Fablon\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n return `N\u00E4dogry baha: gara\u015Fylan ${expected} \u00FDerine ${received} alyndy`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `N\u00E4dogry baha: ${util.stringifyPrimitive(issue.values[0])} bolmaly`;\n return `N\u00E4dogry sa\u00FDlaw: a\u015Fakdakylardan biri bolmaly: ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Has uly: gara\u015Fyl\u00FDan ${issue.origin ?? \"baha\"} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? \"element\"}`;\n return `Has uly: gara\u015Fyl\u00FDan ${issue.origin ?? \"baha\"} ${adj} ${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Has ki\u00E7i: gara\u015Fyl\u00FDan ${issue.origin} ${adj} ${issue.minimum.toString()} ${sizing.unit}`;\n return `Has ki\u00E7i: gara\u015Fyl\u00FDan ${issue.origin} ${adj} ${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `N\u00E4dogry setir: \"${_issue.prefix}\" bilen ba\u015Flamaly`;\n if (_issue.format === \"ends_with\")\n return `N\u00E4dogry setir: \"${_issue.suffix}\" bilen gutarmaly`;\n if (_issue.format === \"includes\")\n return `N\u00E4dogry setir: \"${_issue.includes}\" saklamaly`;\n if (_issue.format === \"regex\")\n return `N\u00E4dogry setir: ${_issue.pattern} nusga la\u00FDyk bolmaly`;\n return `N\u00E4dogry ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `N\u00E4dogry san: ${issue.divisor} bilen galyndysyz b\u00F6l\u00FCnmeli`;\n case \"unrecognized_keys\":\n return `Tanalma\u00FDan a\u00E7ar${issue.keys.length > 1 ? \"lar\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} i\u00E7inde n\u00E4dogry a\u00E7ar`;\n case \"invalid_union\":\n return \"N\u00E4dogry baha\";\n case \"invalid_element\":\n return `${issue.origin} i\u00E7inde n\u00E4dogry baha`;\n default:\n return `N\u00E4dogry baha`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"karakter\", verb: \"olmal\u0131\" },\n file: { unit: \"bayt\", verb: \"olmal\u0131\" },\n array: { unit: \"\u00F6\u011Fe\", verb: \"olmal\u0131\" },\n set: { unit: \"\u00F6\u011Fe\", verb: \"olmal\u0131\" },\n map: { unit: \"\u00F6\u011Fe\", verb: \"olmal\u0131\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"girdi\",\n email: \"e-posta adresi\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO tarih ve saat\",\n date: \"ISO tarih\",\n time: \"ISO saat\",\n duration: \"ISO s\u00FCre\",\n ipv4: \"IPv4 adresi\",\n ipv6: \"IPv6 adresi\",\n mac: \"MAC adresi\",\n cidrv4: \"IPv4 aral\u0131\u011F\u0131\",\n cidrv6: \"IPv6 aral\u0131\u011F\u0131\",\n base64: \"base64 ile \u015Fifrelenmi\u015F metin\",\n base64url: \"base64url ile \u015Fifrelenmi\u015F metin\",\n json_string: \"JSON dizesi\",\n e164: \"E.164 say\u0131s\u0131\",\n credit_card: \"kredi kart\u0131 numaras\u0131\",\n currency_code: \"para birimi kodu\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u015Eablon dizesi\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Ge\u00E7ersiz de\u011Fer: beklenen instanceof ${issue.expected}, al\u0131nan ${received}`;\n }\n return `Ge\u00E7ersiz de\u011Fer: beklenen ${expected}, al\u0131nan ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Ge\u00E7ersiz de\u011Fer: beklenen ${util.stringifyPrimitive(issue.values[0])}`;\n return `Ge\u00E7ersiz se\u00E7enek: a\u015Fa\u011F\u0131dakilerden biri olmal\u0131: ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u00C7ok b\u00FCy\u00FCk: beklenen ${issue.origin ?? \"de\u011Fer\"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u00F6\u011Fe\"}`;\n return `\u00C7ok b\u00FCy\u00FCk: beklenen ${issue.origin ?? \"de\u011Fer\"} ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u00C7ok k\u00FC\u00E7\u00FCk: beklenen ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n return `\u00C7ok k\u00FC\u00E7\u00FCk: beklenen ${issue.origin} ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Ge\u00E7ersiz metin: \"${_issue.prefix}\" ile ba\u015Flamal\u0131`;\n if (_issue.format === \"ends_with\")\n return `Ge\u00E7ersiz metin: \"${_issue.suffix}\" ile bitmeli`;\n if (_issue.format === \"includes\")\n return `Ge\u00E7ersiz metin: \"${_issue.includes}\" i\u00E7ermeli`;\n if (_issue.format === \"regex\")\n return `Ge\u00E7ersiz metin: ${_issue.pattern} desenine uymal\u0131`;\n return `Ge\u00E7ersiz ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Ge\u00E7ersiz say\u0131: ${issue.divisor} ile tam b\u00F6l\u00FCnebilmeli`;\n case \"unrecognized_keys\":\n return `Tan\u0131nmayan anahtar${issue.keys.length > 1 ? \"lar\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} i\u00E7inde ge\u00E7ersiz anahtar`;\n case \"invalid_union\":\n return \"Ge\u00E7ersiz de\u011Fer\";\n case \"invalid_element\":\n return `${issue.origin} i\u00E7inde ge\u00E7ersiz de\u011Fer`;\n default:\n return `Ge\u00E7ersiz de\u011Fer`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432\", verb: \"\u043C\u0430\u0442\u0438\u043C\u0435\" },\n file: { unit: \"\u0431\u0430\u0439\u0442\u0456\u0432\", verb: \"\u043C\u0430\u0442\u0438\u043C\u0435\" },\n array: { unit: \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0456\u0432\", verb: \"\u043C\u0430\u0442\u0438\u043C\u0435\" },\n set: { unit: \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0456\u0432\", verb: \"\u043C\u0430\u0442\u0438\u043C\u0435\" },\n map: { unit: \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0456\u0432\", verb: \"\u043C\u0430\u0442\u0438\u043C\u0435\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0432\u0445\u0456\u0434\u043D\u0456 \u0434\u0430\u043D\u0456\",\n email: \"\u0430\u0434\u0440\u0435\u0441\u0430 \u0435\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u043E\u0457 \u043F\u043E\u0448\u0442\u0438\",\n url: \"URL\",\n emoji: \"\u0435\u043C\u043E\u0434\u0437\u0456\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u0434\u0430\u0442\u0430 \u0442\u0430 \u0447\u0430\u0441 ISO\",\n date: \"\u0434\u0430\u0442\u0430 ISO\",\n time: \"\u0447\u0430\u0441 ISO\",\n duration: \"\u0442\u0440\u0438\u0432\u0430\u043B\u0456\u0441\u0442\u044C ISO\",\n ipv4: \"\u0430\u0434\u0440\u0435\u0441\u0430 IPv4\",\n ipv6: \"\u0430\u0434\u0440\u0435\u0441\u0430 IPv6\",\n mac: \"\u0430\u0434\u0440\u0435\u0441\u0430 MAC\",\n cidrv4: \"\u0434\u0456\u0430\u043F\u0430\u0437\u043E\u043D IPv4\",\n cidrv6: \"\u0434\u0456\u0430\u043F\u0430\u0437\u043E\u043D IPv6\",\n base64: \"\u0440\u044F\u0434\u043E\u043A \u0443 \u043A\u043E\u0434\u0443\u0432\u0430\u043D\u043D\u0456 base64\",\n base64url: \"\u0440\u044F\u0434\u043E\u043A \u0443 \u043A\u043E\u0434\u0443\u0432\u0430\u043D\u043D\u0456 base64url\",\n json_string: \"\u0440\u044F\u0434\u043E\u043A JSON\",\n e164: \"\u043D\u043E\u043C\u0435\u0440 E.164\",\n credit_card: \"\u043D\u043E\u043C\u0435\u0440 \u043A\u0440\u0435\u0434\u0438\u0442\u043D\u043E\u0457 \u043A\u0430\u0440\u0442\u043A\u0438\",\n currency_code: \"\u043A\u043E\u0434 \u0432\u0430\u043B\u044E\u0442\u0438\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0432\u0445\u0456\u0434\u043D\u0456 \u0434\u0430\u043D\u0456\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0447\u0438\u0441\u043B\u043E\",\n array: \"\u043C\u0430\u0441\u0438\u0432\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0456 \u0432\u0445\u0456\u0434\u043D\u0456 \u0434\u0430\u043D\u0456: \u043E\u0447\u0456\u043A\u0443\u0454\u0442\u044C\u0441\u044F instanceof ${issue.expected}, \u043E\u0442\u0440\u0438\u043C\u0430\u043D\u043E ${received}`;\n }\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0456 \u0432\u0445\u0456\u0434\u043D\u0456 \u0434\u0430\u043D\u0456: \u043E\u0447\u0456\u043A\u0443\u0454\u0442\u044C\u0441\u044F ${expected}, \u043E\u0442\u0440\u0438\u043C\u0430\u043D\u043E ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0456 \u0432\u0445\u0456\u0434\u043D\u0456 \u0434\u0430\u043D\u0456: \u043E\u0447\u0456\u043A\u0443\u0454\u0442\u044C\u0441\u044F ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0430 \u043E\u043F\u0446\u0456\u044F: \u043E\u0447\u0456\u043A\u0443\u0454\u0442\u044C\u0441\u044F \u043E\u0434\u043D\u0435 \u0437 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0417\u0430\u043D\u0430\u0434\u0442\u043E \u0432\u0435\u043B\u0438\u043A\u0435: \u043E\u0447\u0456\u043A\u0443\u0454\u0442\u044C\u0441\u044F, \u0449\u043E ${issue.origin ?? \"\u0437\u043D\u0430\u0447\u0435\u043D\u043D\u044F\"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0456\u0432\"}`;\n return `\u0417\u0430\u043D\u0430\u0434\u0442\u043E \u0432\u0435\u043B\u0438\u043A\u0435: \u043E\u0447\u0456\u043A\u0443\u0454\u0442\u044C\u0441\u044F, \u0449\u043E ${issue.origin ?? \"\u0437\u043D\u0430\u0447\u0435\u043D\u043D\u044F\"} \u0431\u0443\u0434\u0435 ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0417\u0430\u043D\u0430\u0434\u0442\u043E \u043C\u0430\u043B\u0435: \u043E\u0447\u0456\u043A\u0443\u0454\u0442\u044C\u0441\u044F, \u0449\u043E ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u0417\u0430\u043D\u0430\u0434\u0442\u043E \u043C\u0430\u043B\u0435: \u043E\u0447\u0456\u043A\u0443\u0454\u0442\u044C\u0441\u044F, \u0449\u043E ${issue.origin} \u0431\u0443\u0434\u0435 ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0438\u0439 \u0440\u044F\u0434\u043E\u043A: \u043F\u043E\u0432\u0438\u043D\u0435\u043D \u043F\u043E\u0447\u0438\u043D\u0430\u0442\u0438\u0441\u044F \u0437 \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0438\u0439 \u0440\u044F\u0434\u043E\u043A: \u043F\u043E\u0432\u0438\u043D\u0435\u043D \u0437\u0430\u043A\u0456\u043D\u0447\u0443\u0432\u0430\u0442\u0438\u0441\u044F \u043D\u0430 \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0438\u0439 \u0440\u044F\u0434\u043E\u043A: \u043F\u043E\u0432\u0438\u043D\u0435\u043D \u043C\u0456\u0441\u0442\u0438\u0442\u0438 \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0438\u0439 \u0440\u044F\u0434\u043E\u043A: \u043F\u043E\u0432\u0438\u043D\u0435\u043D \u0432\u0456\u0434\u043F\u043E\u0432\u0456\u0434\u0430\u0442\u0438 \u0448\u0430\u0431\u043B\u043E\u043D\u0443 ${_issue.pattern}`;\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0438\u0439 ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0435 \u0447\u0438\u0441\u043B\u043E: \u043F\u043E\u0432\u0438\u043D\u043D\u043E \u0431\u0443\u0442\u0438 \u043A\u0440\u0430\u0442\u043D\u0438\u043C ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `\u041D\u0435\u0440\u043E\u0437\u043F\u0456\u0437\u043D\u0430\u043D\u0438\u0439 \u043A\u043B\u044E\u0447${issue.keys.length > 1 ? \"\u0456\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0438\u0439 \u043A\u043B\u044E\u0447 \u0443 ${issue.origin}`;\n case \"invalid_union\":\n return \"\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0456 \u0432\u0445\u0456\u0434\u043D\u0456 \u0434\u0430\u043D\u0456\";\n case \"invalid_element\":\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u043D\u044F \u0443 ${issue.origin}`;\n default:\n return `\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0456 \u0432\u0445\u0456\u0434\u043D\u0456 \u0434\u0430\u043D\u0456`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import uk from \"./uk.js\";\n/** @deprecated Use `uk` instead. */\nexport default function () {\n return uk();\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u062D\u0631\u0648\u0641\", verb: \"\u06C1\u0648\u0646\u0627\" },\n file: { unit: \"\u0628\u0627\u0626\u0679\u0633\", verb: \"\u06C1\u0648\u0646\u0627\" },\n array: { unit: \"\u0622\u0626\u0679\u0645\u0632\", verb: \"\u06C1\u0648\u0646\u0627\" },\n set: { unit: \"\u0622\u0626\u0679\u0645\u0632\", verb: \"\u06C1\u0648\u0646\u0627\" },\n map: { unit: \"\u0622\u0626\u0679\u0645\u0632\", verb: \"\u06C1\u0648\u0646\u0627\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0627\u0646 \u067E\u0679\",\n email: \"\u0627\u06CC \u0645\u06CC\u0644 \u0627\u06CC\u0688\u0631\u06CC\u0633\",\n url: \"\u06CC\u0648 \u0622\u0631 \u0627\u06CC\u0644\",\n emoji: \"\u0627\u06CC\u0645\u0648\u062C\u06CC\",\n uuid: \"\u06CC\u0648 \u06CC\u0648 \u0622\u0626\u06CC \u0688\u06CC\",\n uuidv4: \"\u06CC\u0648 \u06CC\u0648 \u0622\u0626\u06CC \u0688\u06CC \u0648\u06CC 4\",\n uuidv6: \"\u06CC\u0648 \u06CC\u0648 \u0622\u0626\u06CC \u0688\u06CC \u0648\u06CC 6\",\n nanoid: \"\u0646\u06CC\u0646\u0648 \u0622\u0626\u06CC \u0688\u06CC\",\n guid: \"\u062C\u06CC \u06CC\u0648 \u0622\u0626\u06CC \u0688\u06CC\",\n cuid: \"\u0633\u06CC \u06CC\u0648 \u0622\u0626\u06CC \u0688\u06CC\",\n cuid2: \"\u0633\u06CC \u06CC\u0648 \u0622\u0626\u06CC \u0688\u06CC 2\",\n ulid: \"\u06CC\u0648 \u0627\u06CC\u0644 \u0622\u0626\u06CC \u0688\u06CC\",\n xid: \"\u0627\u06CC\u06A9\u0633 \u0622\u0626\u06CC \u0688\u06CC\",\n ksuid: \"\u06A9\u06D2 \u0627\u06CC\u0633 \u06CC\u0648 \u0622\u0626\u06CC \u0688\u06CC\",\n datetime: \"\u0622\u0626\u06CC \u0627\u06CC\u0633 \u0627\u0648 \u0688\u06CC\u0679 \u0679\u0627\u0626\u0645\",\n date: \"\u0622\u0626\u06CC \u0627\u06CC\u0633 \u0627\u0648 \u062A\u0627\u0631\u06CC\u062E\",\n time: \"\u0622\u0626\u06CC \u0627\u06CC\u0633 \u0627\u0648 \u0648\u0642\u062A\",\n duration: \"\u0622\u0626\u06CC \u0627\u06CC\u0633 \u0627\u0648 \u0645\u062F\u062A\",\n ipv4: \"\u0622\u0626\u06CC \u067E\u06CC \u0648\u06CC 4 \u0627\u06CC\u0688\u0631\u06CC\u0633\",\n ipv6: \"\u0622\u0626\u06CC \u067E\u06CC \u0648\u06CC 6 \u0627\u06CC\u0688\u0631\u06CC\u0633\",\n mac: \"\u0627\u06CC\u0645 \u0627\u06D2 \u0633\u06CC \u0627\u06CC\u0688\u0631\u06CC\u0633\",\n cidrv4: \"\u0622\u0626\u06CC \u067E\u06CC \u0648\u06CC 4 \u0631\u06CC\u0646\u062C\",\n cidrv6: \"\u0622\u0626\u06CC \u067E\u06CC \u0648\u06CC 6 \u0631\u06CC\u0646\u062C\",\n base64: \"\u0628\u06CC\u0633 64 \u0627\u0646 \u06A9\u0648\u0688\u0688 \u0633\u0679\u0631\u0646\u06AF\",\n base64url: \"\u0628\u06CC\u0633 64 \u06CC\u0648 \u0622\u0631 \u0627\u06CC\u0644 \u0627\u0646 \u06A9\u0648\u0688\u0688 \u0633\u0679\u0631\u0646\u06AF\",\n json_string: \"\u062C\u06D2 \u0627\u06CC\u0633 \u0627\u0648 \u0627\u06CC\u0646 \u0633\u0679\u0631\u0646\u06AF\",\n e164: \"\u0627\u06CC 164 \u0646\u0645\u0628\u0631\",\n credit_card: \"\u06A9\u0631\u06CC\u0688\u0679 \u06A9\u0627\u0631\u0688 \u0646\u0645\u0628\u0631\",\n currency_code: \"\u06A9\u0631\u0646\u0633\u06CC \u06A9\u0648\u0688\",\n iban: \"IBAN\",\n jwt: \"\u062C\u06D2 \u0688\u0628\u0644\u06CC\u0648 \u0679\u06CC\",\n template_literal: \"\u0627\u0646 \u067E\u0679\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u0646\u0645\u0628\u0631\",\n array: \"\u0622\u0631\u06D2\",\n null: \"\u0646\u0644\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u063A\u0644\u0637 \u0627\u0646 \u067E\u0679: instanceof ${issue.expected} \u0645\u062A\u0648\u0642\u0639 \u062A\u06BE\u0627\u060C ${received} \u0645\u0648\u0635\u0648\u0644 \u06C1\u0648\u0627`;\n }\n return `\u063A\u0644\u0637 \u0627\u0646 \u067E\u0679: ${expected} \u0645\u062A\u0648\u0642\u0639 \u062A\u06BE\u0627\u060C ${received} \u0645\u0648\u0635\u0648\u0644 \u06C1\u0648\u0627`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u063A\u0644\u0637 \u0627\u0646 \u067E\u0679: ${util.stringifyPrimitive(issue.values[0])} \u0645\u062A\u0648\u0642\u0639 \u062A\u06BE\u0627`;\n return `\u063A\u0644\u0637 \u0622\u067E\u0634\u0646: ${util.joinValues(issue.values, \"|\")} \u0645\u06CC\u06BA \u0633\u06D2 \u0627\u06CC\u06A9 \u0645\u062A\u0648\u0642\u0639 \u062A\u06BE\u0627`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u0628\u06C1\u062A \u0628\u0691\u0627: ${issue.origin ?? \"\u0648\u06CC\u0644\u06CC\u0648\"} \u06A9\u06D2 ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u0639\u0646\u0627\u0635\u0631\"} \u06C1\u0648\u0646\u06D2 \u0645\u062A\u0648\u0642\u0639 \u062A\u06BE\u06D2`;\n return `\u0628\u06C1\u062A \u0628\u0691\u0627: ${issue.origin ?? \"\u0648\u06CC\u0644\u06CC\u0648\"} \u06A9\u0627 ${adj}${issue.maximum.toString()} \u06C1\u0648\u0646\u0627 \u0645\u062A\u0648\u0642\u0639 \u062A\u06BE\u0627`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u0628\u06C1\u062A \u0686\u06BE\u0648\u0679\u0627: ${issue.origin} \u06A9\u06D2 ${adj}${issue.minimum.toString()} ${sizing.unit} \u06C1\u0648\u0646\u06D2 \u0645\u062A\u0648\u0642\u0639 \u062A\u06BE\u06D2`;\n }\n return `\u0628\u06C1\u062A \u0686\u06BE\u0648\u0679\u0627: ${issue.origin} \u06A9\u0627 ${adj}${issue.minimum.toString()} \u06C1\u0648\u0646\u0627 \u0645\u062A\u0648\u0642\u0639 \u062A\u06BE\u0627`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u063A\u0644\u0637 \u0633\u0679\u0631\u0646\u06AF: \"${_issue.prefix}\" \u0633\u06D2 \u0634\u0631\u0648\u0639 \u06C1\u0648\u0646\u0627 \u0686\u0627\u06C1\u06CC\u06D2`;\n }\n if (_issue.format === \"ends_with\")\n return `\u063A\u0644\u0637 \u0633\u0679\u0631\u0646\u06AF: \"${_issue.suffix}\" \u067E\u0631 \u062E\u062A\u0645 \u06C1\u0648\u0646\u0627 \u0686\u0627\u06C1\u06CC\u06D2`;\n if (_issue.format === \"includes\")\n return `\u063A\u0644\u0637 \u0633\u0679\u0631\u0646\u06AF: \"${_issue.includes}\" \u0634\u0627\u0645\u0644 \u06C1\u0648\u0646\u0627 \u0686\u0627\u06C1\u06CC\u06D2`;\n if (_issue.format === \"regex\")\n return `\u063A\u0644\u0637 \u0633\u0679\u0631\u0646\u06AF: \u067E\u06CC\u0679\u0631\u0646 ${_issue.pattern} \u0633\u06D2 \u0645\u06CC\u0686 \u06C1\u0648\u0646\u0627 \u0686\u0627\u06C1\u06CC\u06D2`;\n return `\u063A\u0644\u0637 ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u063A\u0644\u0637 \u0646\u0645\u0628\u0631: ${issue.divisor} \u06A9\u0627 \u0645\u0636\u0627\u0639\u0641 \u06C1\u0648\u0646\u0627 \u0686\u0627\u06C1\u06CC\u06D2`;\n case \"unrecognized_keys\":\n return `\u063A\u06CC\u0631 \u062A\u0633\u0644\u06CC\u0645 \u0634\u062F\u06C1 \u06A9\u06CC${issue.keys.length > 1 ? \"\u0632\" : \"\"}: ${util.joinValues(issue.keys, \"\u060C \")}`;\n case \"invalid_key\":\n return `${issue.origin} \u0645\u06CC\u06BA \u063A\u0644\u0637 \u06A9\u06CC`;\n case \"invalid_union\":\n return \"\u063A\u0644\u0637 \u0627\u0646 \u067E\u0679\";\n case \"invalid_element\":\n return `${issue.origin} \u0645\u06CC\u06BA \u063A\u0644\u0637 \u0648\u06CC\u0644\u06CC\u0648`;\n default:\n return `\u063A\u0644\u0637 \u0627\u0646 \u067E\u0679`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"belgi\", verb: \"bo\u2018lishi kerak\" },\n file: { unit: \"bayt\", verb: \"bo\u2018lishi kerak\" },\n array: { unit: \"element\", verb: \"bo\u2018lishi kerak\" },\n set: { unit: \"element\", verb: \"bo\u2018lishi kerak\" },\n map: { unit: \"yozuv\", verb: \"bo\u2018lishi kerak\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"kirish\",\n email: \"elektron pochta manzili\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO sana va vaqti\",\n date: \"ISO sana\",\n time: \"ISO vaqt\",\n duration: \"ISO davomiylik\",\n ipv4: \"IPv4 manzil\",\n ipv6: \"IPv6 manzil\",\n mac: \"MAC manzil\",\n cidrv4: \"IPv4 diapazon\",\n cidrv6: \"IPv6 diapazon\",\n base64: \"base64 kodlangan satr\",\n base64url: \"base64url kodlangan satr\",\n json_string: \"JSON satr\",\n e164: \"E.164 raqam\",\n credit_card: \"kredit karta raqami\",\n currency_code: \"valyuta kodi\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"kirish\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"raqam\",\n array: \"massiv\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `Noto\u2018g\u2018ri kirish: kutilgan instanceof ${issue.expected}, qabul qilingan ${received}`;\n }\n return `Noto\u2018g\u2018ri kirish: kutilgan ${expected}, qabul qilingan ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `Noto\u2018g\u2018ri kirish: kutilgan ${util.stringifyPrimitive(issue.values[0])}`;\n return `Noto\u2018g\u2018ri variant: quyidagilardan biri kutilgan ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Juda katta: kutilgan ${issue.origin ?? \"qiymat\"} ${adj}${issue.maximum.toString()} ${sizing.unit} ${sizing.verb}`;\n return `Juda katta: kutilgan ${issue.origin ?? \"qiymat\"} ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Juda kichik: kutilgan ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} ${sizing.verb}`;\n }\n return `Juda kichik: kutilgan ${issue.origin} ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Noto\u2018g\u2018ri satr: \"${_issue.prefix}\" bilan boshlanishi kerak`;\n if (_issue.format === \"ends_with\")\n return `Noto\u2018g\u2018ri satr: \"${_issue.suffix}\" bilan tugashi kerak`;\n if (_issue.format === \"includes\")\n return `Noto\u2018g\u2018ri satr: \"${_issue.includes}\" ni o\u2018z ichiga olishi kerak`;\n if (_issue.format === \"regex\")\n return `Noto\u2018g\u2018ri satr: ${_issue.pattern} shabloniga mos kelishi kerak`;\n return `Noto\u2018g\u2018ri ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `Noto\u2018g\u2018ri raqam: ${issue.divisor} ning karralisi bo\u2018lishi kerak`;\n case \"unrecognized_keys\":\n return `Noma\u2019lum kalit${issue.keys.length > 1 ? \"lar\" : \"\"}: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} dagi kalit noto\u2018g\u2018ri`;\n case \"invalid_union\":\n return \"Noto\u2018g\u2018ri kirish\";\n case \"invalid_element\":\n return `${issue.origin} da noto\u2018g\u2018ri qiymat`;\n default:\n return `Noto\u2018g\u2018ri kirish`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"k\u00FD t\u1EF1\", verb: \"c\u00F3\" },\n file: { unit: \"byte\", verb: \"c\u00F3\" },\n array: { unit: \"ph\u1EA7n t\u1EED\", verb: \"c\u00F3\" },\n set: { unit: \"ph\u1EA7n t\u1EED\", verb: \"c\u00F3\" },\n map: { unit: \"ph\u1EA7n t\u1EED\", verb: \"c\u00F3\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u0111\u1EA7u v\u00E0o\",\n email: \"\u0111\u1ECBa ch\u1EC9 email\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ng\u00E0y gi\u1EDD ISO\",\n date: \"ng\u00E0y ISO\",\n time: \"gi\u1EDD ISO\",\n duration: \"kho\u1EA3ng th\u1EDDi gian ISO\",\n ipv4: \"\u0111\u1ECBa ch\u1EC9 IPv4\",\n ipv6: \"\u0111\u1ECBa ch\u1EC9 IPv6\",\n mac: \"\u0111\u1ECBa ch\u1EC9 MAC\",\n cidrv4: \"d\u1EA3i IPv4\",\n cidrv6: \"d\u1EA3i IPv6\",\n base64: \"chu\u1ED7i m\u00E3 h\u00F3a base64\",\n base64url: \"chu\u1ED7i m\u00E3 h\u00F3a base64url\",\n json_string: \"chu\u1ED7i JSON\",\n e164: \"s\u1ED1 E.164\",\n credit_card: \"s\u1ED1 th\u1EBB t\u00EDn d\u1EE5ng\",\n currency_code: \"m\u00E3 ti\u1EC1n t\u1EC7\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u0111\u1EA7u v\u00E0o\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"s\u1ED1\",\n array: \"m\u1EA3ng\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u0110\u1EA7u v\u00E0o kh\u00F4ng h\u1EE3p l\u1EC7: mong \u0111\u1EE3i instanceof ${issue.expected}, nh\u1EADn \u0111\u01B0\u1EE3c ${received}`;\n }\n return `\u0110\u1EA7u v\u00E0o kh\u00F4ng h\u1EE3p l\u1EC7: mong \u0111\u1EE3i ${expected}, nh\u1EADn \u0111\u01B0\u1EE3c ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u0110\u1EA7u v\u00E0o kh\u00F4ng h\u1EE3p l\u1EC7: mong \u0111\u1EE3i ${util.stringifyPrimitive(issue.values[0])}`;\n return `T\u00F9y ch\u1ECDn kh\u00F4ng h\u1EE3p l\u1EC7: mong \u0111\u1EE3i m\u1ED9t trong c\u00E1c gi\u00E1 tr\u1ECB ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `Qu\u00E1 l\u1EDBn: mong \u0111\u1EE3i ${issue.origin ?? \"gi\u00E1 tr\u1ECB\"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"ph\u1EA7n t\u1EED\"}`;\n return `Qu\u00E1 l\u1EDBn: mong \u0111\u1EE3i ${issue.origin ?? \"gi\u00E1 tr\u1ECB\"} ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `Qu\u00E1 nh\u1ECF: mong \u0111\u1EE3i ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `Qu\u00E1 nh\u1ECF: mong \u0111\u1EE3i ${issue.origin} ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `Chu\u1ED7i kh\u00F4ng h\u1EE3p l\u1EC7: ph\u1EA3i b\u1EAFt \u0111\u1EA7u b\u1EB1ng \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `Chu\u1ED7i kh\u00F4ng h\u1EE3p l\u1EC7: ph\u1EA3i k\u1EBFt th\u00FAc b\u1EB1ng \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `Chu\u1ED7i kh\u00F4ng h\u1EE3p l\u1EC7: ph\u1EA3i bao g\u1ED3m \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `Chu\u1ED7i kh\u00F4ng h\u1EE3p l\u1EC7: ph\u1EA3i kh\u1EDBp v\u1EDBi m\u1EABu ${_issue.pattern}`;\n return `${FormatDictionary[_issue.format] ?? issue.format} kh\u00F4ng h\u1EE3p l\u1EC7`;\n }\n case \"not_multiple_of\":\n return `S\u1ED1 kh\u00F4ng h\u1EE3p l\u1EC7: ph\u1EA3i l\u00E0 b\u1ED9i s\u1ED1 c\u1EE7a ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `Kh\u00F3a kh\u00F4ng \u0111\u01B0\u1EE3c nh\u1EADn d\u1EA1ng: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `Kh\u00F3a kh\u00F4ng h\u1EE3p l\u1EC7 trong ${issue.origin}`;\n case \"invalid_union\":\n return \"\u0110\u1EA7u v\u00E0o kh\u00F4ng h\u1EE3p l\u1EC7\";\n case \"invalid_element\":\n return `Gi\u00E1 tr\u1ECB kh\u00F4ng h\u1EE3p l\u1EC7 trong ${issue.origin}`;\n default:\n return `\u0110\u1EA7u v\u00E0o kh\u00F4ng h\u1EE3p l\u1EC7`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u5B57\u7B26\", verb: \"\u5305\u542B\" },\n file: { unit: \"\u5B57\u8282\", verb: \"\u5305\u542B\" },\n array: { unit: \"\u9879\", verb: \"\u5305\u542B\" },\n set: { unit: \"\u9879\", verb: \"\u5305\u542B\" },\n map: { unit: \"\u9879\", verb: \"\u5305\u542B\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u8F93\u5165\",\n email: \"\u7535\u5B50\u90AE\u4EF6\",\n url: \"URL\",\n emoji: \"\u8868\u60C5\u7B26\u53F7\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO\u65E5\u671F\u65F6\u95F4\",\n date: \"ISO\u65E5\u671F\",\n time: \"ISO\u65F6\u95F4\",\n duration: \"ISO\u65F6\u957F\",\n ipv4: \"IPv4\u5730\u5740\",\n ipv6: \"IPv6\u5730\u5740\",\n mac: \"MAC\u5730\u5740\",\n cidrv4: \"IPv4\u7F51\u6BB5\",\n cidrv6: \"IPv6\u7F51\u6BB5\",\n base64: \"base64\u7F16\u7801\u5B57\u7B26\u4E32\",\n base64url: \"base64url\u7F16\u7801\u5B57\u7B26\u4E32\",\n json_string: \"JSON\u5B57\u7B26\u4E32\",\n e164: \"E.164\u53F7\u7801\",\n credit_card: \"\u4FE1\u7528\u5361\u53F7\",\n currency_code: \"\u8D27\u5E01\u4EE3\u7801\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u8F93\u5165\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"\u6570\u5B57\",\n array: \"\u6570\u7EC4\",\n null: \"\u7A7A\u503C(null)\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u65E0\u6548\u8F93\u5165\uFF1A\u671F\u671B instanceof ${issue.expected}\uFF0C\u5B9E\u9645\u63A5\u6536 ${received}`;\n }\n return `\u65E0\u6548\u8F93\u5165\uFF1A\u671F\u671B ${expected}\uFF0C\u5B9E\u9645\u63A5\u6536 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u65E0\u6548\u8F93\u5165\uFF1A\u671F\u671B ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u65E0\u6548\u9009\u9879\uFF1A\u671F\u671B\u4EE5\u4E0B\u4E4B\u4E00 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u6570\u503C\u8FC7\u5927\uFF1A\u671F\u671B ${issue.origin ?? \"\u503C\"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u4E2A\u5143\u7D20\"}`;\n return `\u6570\u503C\u8FC7\u5927\uFF1A\u671F\u671B ${issue.origin ?? \"\u503C\"} ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u6570\u503C\u8FC7\u5C0F\uFF1A\u671F\u671B ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u6570\u503C\u8FC7\u5C0F\uFF1A\u671F\u671B ${issue.origin} ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u65E0\u6548\u5B57\u7B26\u4E32\uFF1A\u5FC5\u987B\u4EE5 \"${_issue.prefix}\" \u5F00\u5934`;\n if (_issue.format === \"ends_with\")\n return `\u65E0\u6548\u5B57\u7B26\u4E32\uFF1A\u5FC5\u987B\u4EE5 \"${_issue.suffix}\" \u7ED3\u5C3E`;\n if (_issue.format === \"includes\")\n return `\u65E0\u6548\u5B57\u7B26\u4E32\uFF1A\u5FC5\u987B\u5305\u542B \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u65E0\u6548\u5B57\u7B26\u4E32\uFF1A\u5FC5\u987B\u6EE1\u8DB3\u6B63\u5219\u8868\u8FBE\u5F0F ${_issue.pattern}`;\n return `\u65E0\u6548${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u65E0\u6548\u6570\u5B57\uFF1A\u5FC5\u987B\u662F ${issue.divisor} \u7684\u500D\u6570`;\n case \"unrecognized_keys\":\n return `\u51FA\u73B0\u672A\u77E5\u7684\u952E(key): ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `${issue.origin} \u4E2D\u7684\u952E(key)\u65E0\u6548`;\n case \"invalid_union\":\n return \"\u65E0\u6548\u8F93\u5165\";\n case \"invalid_element\":\n return `${issue.origin} \u4E2D\u5305\u542B\u65E0\u6548\u503C(value)`;\n default:\n return `\u65E0\u6548\u8F93\u5165`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u5B57\u5143\", verb: \"\u64C1\u6709\" },\n file: { unit: \"\u4F4D\u5143\u7D44\", verb: \"\u64C1\u6709\" },\n array: { unit: \"\u9805\u76EE\", verb: \"\u64C1\u6709\" },\n set: { unit: \"\u9805\u76EE\", verb: \"\u64C1\u6709\" },\n map: { unit: \"\u9805\u76EE\", verb: \"\u64C1\u6709\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u8F38\u5165\",\n email: \"\u90F5\u4EF6\u5730\u5740\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"ISO \u65E5\u671F\u6642\u9593\",\n date: \"ISO \u65E5\u671F\",\n time: \"ISO \u6642\u9593\",\n duration: \"ISO \u671F\u9593\",\n ipv4: \"IPv4 \u4F4D\u5740\",\n ipv6: \"IPv6 \u4F4D\u5740\",\n mac: \"MAC \u4F4D\u5740\",\n cidrv4: \"IPv4 \u7BC4\u570D\",\n cidrv6: \"IPv6 \u7BC4\u570D\",\n base64: \"base64 \u7DE8\u78BC\u5B57\u4E32\",\n base64url: \"base64url \u7DE8\u78BC\u5B57\u4E32\",\n json_string: \"JSON \u5B57\u4E32\",\n e164: \"E.164 \u6578\u503C\",\n credit_card: \"\u4FE1\u7528\u5361\u865F\",\n currency_code: \"\u8CA8\u5E63\u4EE3\u78BC\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u8F38\u5165\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u7121\u6548\u7684\u8F38\u5165\u503C\uFF1A\u9810\u671F\u70BA instanceof ${issue.expected}\uFF0C\u4F46\u6536\u5230 ${received}`;\n }\n return `\u7121\u6548\u7684\u8F38\u5165\u503C\uFF1A\u9810\u671F\u70BA ${expected}\uFF0C\u4F46\u6536\u5230 ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u7121\u6548\u7684\u8F38\u5165\u503C\uFF1A\u9810\u671F\u70BA ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u7121\u6548\u7684\u9078\u9805\uFF1A\u9810\u671F\u70BA\u4EE5\u4E0B\u5176\u4E2D\u4E4B\u4E00 ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `\u6578\u503C\u904E\u5927\uFF1A\u9810\u671F ${issue.origin ?? \"\u503C\"} \u61C9\u70BA ${adj}${issue.maximum.toString()} ${sizing.unit ?? \"\u500B\u5143\u7D20\"}`;\n return `\u6578\u503C\u904E\u5927\uFF1A\u9810\u671F ${issue.origin ?? \"\u503C\"} \u61C9\u70BA ${adj}${issue.maximum.toString()}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing) {\n return `\u6578\u503C\u904E\u5C0F\uFF1A\u9810\u671F ${issue.origin} \u61C9\u70BA ${adj}${issue.minimum.toString()} ${sizing.unit}`;\n }\n return `\u6578\u503C\u904E\u5C0F\uFF1A\u9810\u671F ${issue.origin} \u61C9\u70BA ${adj}${issue.minimum.toString()}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\") {\n return `\u7121\u6548\u7684\u5B57\u4E32\uFF1A\u5FC5\u9808\u4EE5 \"${_issue.prefix}\" \u958B\u982D`;\n }\n if (_issue.format === \"ends_with\")\n return `\u7121\u6548\u7684\u5B57\u4E32\uFF1A\u5FC5\u9808\u4EE5 \"${_issue.suffix}\" \u7D50\u5C3E`;\n if (_issue.format === \"includes\")\n return `\u7121\u6548\u7684\u5B57\u4E32\uFF1A\u5FC5\u9808\u5305\u542B \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u7121\u6548\u7684\u5B57\u4E32\uFF1A\u5FC5\u9808\u7B26\u5408\u683C\u5F0F ${_issue.pattern}`;\n return `\u7121\u6548\u7684 ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `\u7121\u6548\u7684\u6578\u5B57\uFF1A\u5FC5\u9808\u70BA ${issue.divisor} \u7684\u500D\u6578`;\n case \"unrecognized_keys\":\n return `\u7121\u6CD5\u8B58\u5225\u7684\u9375\u503C${issue.keys.length > 1 ? \"\u5011\" : \"\"}\uFF1A${util.joinValues(issue.keys, \"\u3001\")}`;\n case \"invalid_key\":\n return `${issue.origin} \u4E2D\u6709\u7121\u6548\u7684\u9375\u503C`;\n case \"invalid_union\":\n return \"\u7121\u6548\u7684\u8F38\u5165\u503C\";\n case \"invalid_element\":\n return `${issue.origin} \u4E2D\u6709\u7121\u6548\u7684\u503C`;\n default:\n return `\u7121\u6548\u7684\u8F38\u5165\u503C`;\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "import * as util from \"../core/util.js\";\nconst error = () => {\n const Sizable = {\n string: { unit: \"\u00E0mi\", verb: \"n\u00ED\" },\n file: { unit: \"bytes\", verb: \"n\u00ED\" },\n array: { unit: \"nkan\", verb: \"n\u00ED\" },\n set: { unit: \"nkan\", verb: \"n\u00ED\" },\n map: { unit: \"nkan\", verb: \"n\u00ED\" },\n };\n function getSizing(origin) {\n return Sizable[origin] ?? null;\n }\n const FormatDictionary = {\n regex: \"\u1EB9\u0300r\u1ECD \u00ECb\u00E1w\u1ECDl\u00E9\",\n email: \"\u00E0d\u00EDr\u1EB9\u0301s\u00EC \u00ECm\u1EB9\u0301l\u00EC\",\n url: \"URL\",\n emoji: \"emoji\",\n uuid: \"UUID\",\n uuidv4: \"UUIDv4\",\n uuidv6: \"UUIDv6\",\n nanoid: \"nanoid\",\n guid: \"GUID\",\n cuid: \"cuid\",\n cuid2: \"cuid2\",\n ulid: \"ULID\",\n xid: \"XID\",\n ksuid: \"KSUID\",\n datetime: \"\u00E0k\u00F3k\u00F2 ISO\",\n date: \"\u1ECDj\u1ECD\u0301 ISO\",\n time: \"\u00E0k\u00F3k\u00F2 ISO\",\n duration: \"\u00E0k\u00F3k\u00F2 t\u00F3 p\u00E9 ISO\",\n ipv4: \"\u00E0d\u00EDr\u1EB9\u0301s\u00EC IPv4\",\n ipv6: \"\u00E0d\u00EDr\u1EB9\u0301s\u00EC IPv6\",\n mac: \"\u00E0d\u00EDr\u1EB9\u0301s\u00EC MAC\",\n cidrv4: \"\u00E0gb\u00E8gb\u00E8 IPv4\",\n cidrv6: \"\u00E0gb\u00E8gb\u00E8 IPv6\",\n base64: \"\u1ECD\u0300r\u1ECD\u0300 t\u00ED a k\u1ECD\u0301 n\u00ED base64\",\n base64url: \"\u1ECD\u0300r\u1ECD\u0300 base64url\",\n json_string: \"\u1ECD\u0300r\u1ECD\u0300 JSON\",\n e164: \"n\u1ECD\u0301mb\u00E0 E.164\",\n credit_card: \"n\u1ECDmba kaadi gbese\",\n currency_code: \"koodu ow\u00F3\",\n iban: \"IBAN\",\n jwt: \"JWT\",\n template_literal: \"\u1EB9\u0300r\u1ECD \u00ECb\u00E1w\u1ECDl\u00E9\",\n };\n const TypeDictionary = {\n nan: \"NaN\",\n number: \"n\u1ECD\u0301mb\u00E0\",\n array: \"akop\u1ECD\",\n };\n return (issue) => {\n switch (issue.code) {\n case \"invalid_type\": {\n const expected = TypeDictionary[issue.expected] ?? issue.expected;\n const receivedType = util.parsedType(issue.input);\n const received = TypeDictionary[receivedType] ?? receivedType;\n if (/^[A-Z]/.test(issue.expected)) {\n return `\u00CCb\u00E1w\u1ECDl\u00E9 a\u1E63\u00EC\u1E63e: a n\u00ED l\u00E1ti fi instanceof ${issue.expected}, \u00E0m\u1ECD\u0300 a r\u00ED ${received}`;\n }\n return `\u00CCb\u00E1w\u1ECDl\u00E9 a\u1E63\u00EC\u1E63e: a n\u00ED l\u00E1ti fi ${expected}, \u00E0m\u1ECD\u0300 a r\u00ED ${received}`;\n }\n case \"invalid_value\":\n if (issue.values.length === 1)\n return `\u00CCb\u00E1w\u1ECDl\u00E9 a\u1E63\u00EC\u1E63e: a n\u00ED l\u00E1ti fi ${util.stringifyPrimitive(issue.values[0])}`;\n return `\u00C0\u1E63\u00E0y\u00E0n a\u1E63\u00EC\u1E63e: yan \u1ECD\u0300kan l\u00E1ra ${util.joinValues(issue.values, \"|\")}`;\n case \"too_big\": {\n const adj = issue.inclusive ? \"<=\" : \"<\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `T\u00F3 p\u1ECD\u0300 j\u00F9: a n\u00ED l\u00E1ti j\u1EB9\u0301 p\u00E9 ${issue.origin ?? \"iye\"} ${sizing.verb} ${adj}${issue.maximum} ${sizing.unit}`;\n return `T\u00F3 p\u1ECD\u0300 j\u00F9: a n\u00ED l\u00E1ti j\u1EB9\u0301 ${adj}${issue.maximum}`;\n }\n case \"too_small\": {\n const adj = issue.inclusive ? \">=\" : \">\";\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `K\u00E9r\u00E9 ju: a n\u00ED l\u00E1ti j\u1EB9\u0301 p\u00E9 ${issue.origin} ${sizing.verb} ${adj}${issue.minimum} ${sizing.unit}`;\n return `K\u00E9r\u00E9 ju: a n\u00ED l\u00E1ti j\u1EB9\u0301 ${adj}${issue.minimum}`;\n }\n case \"invalid_format\": {\n const _issue = issue;\n if (_issue.format === \"starts_with\")\n return `\u1ECC\u0300r\u1ECD\u0300 a\u1E63\u00EC\u1E63e: gb\u1ECD\u0301d\u1ECD\u0300 b\u1EB9\u0300r\u1EB9\u0300 p\u1EB9\u0300l\u00FA \"${_issue.prefix}\"`;\n if (_issue.format === \"ends_with\")\n return `\u1ECC\u0300r\u1ECD\u0300 a\u1E63\u00EC\u1E63e: gb\u1ECD\u0301d\u1ECD\u0300 par\u00ED p\u1EB9\u0300l\u00FA \"${_issue.suffix}\"`;\n if (_issue.format === \"includes\")\n return `\u1ECC\u0300r\u1ECD\u0300 a\u1E63\u00EC\u1E63e: gb\u1ECD\u0301d\u1ECD\u0300 n\u00ED \"${_issue.includes}\"`;\n if (_issue.format === \"regex\")\n return `\u1ECC\u0300r\u1ECD\u0300 a\u1E63\u00EC\u1E63e: gb\u1ECD\u0301d\u1ECD\u0300 b\u00E1 \u00E0p\u1EB9\u1EB9r\u1EB9 mu ${_issue.pattern}`;\n return `A\u1E63\u00EC\u1E63e: ${FormatDictionary[_issue.format] ?? issue.format}`;\n }\n case \"not_multiple_of\":\n return `N\u1ECD\u0301mb\u00E0 a\u1E63\u00EC\u1E63e: gb\u1ECD\u0301d\u1ECD\u0300 j\u1EB9\u0301 \u00E8y\u00E0 p\u00EDp\u00EDn ti ${issue.divisor}`;\n case \"unrecognized_keys\":\n return `B\u1ECDt\u00ECn\u00EC \u00E0\u00ECm\u1ECD\u0300: ${util.joinValues(issue.keys, \", \")}`;\n case \"invalid_key\":\n return `B\u1ECDt\u00ECn\u00EC a\u1E63\u00EC\u1E63e n\u00EDn\u00FA ${issue.origin}`;\n case \"invalid_union\":\n return \"\u00CCb\u00E1w\u1ECDl\u00E9 a\u1E63\u00EC\u1E63e\";\n case \"invalid_element\":\n return `Iye a\u1E63\u00EC\u1E63e n\u00EDn\u00FA ${issue.origin}`;\n default:\n return \"\u00CCb\u00E1w\u1ECDl\u00E9 a\u1E63\u00EC\u1E63e\";\n }\n };\n};\nexport default function () {\n return {\n localeError: error(),\n };\n}\n", "export { default as ar } from \"./ar.js\";\nexport { default as az } from \"./az.js\";\nexport { default as be } from \"./be.js\";\nexport { default as bg } from \"./bg.js\";\nexport { default as bn } from \"./bn.js\";\nexport { default as ca } from \"./ca.js\";\nexport { default as ckb } from \"./ckb.js\";\nexport { default as cs } from \"./cs.js\";\nexport { default as da } from \"./da.js\";\nexport { default as de } from \"./de.js\";\nexport { default as el } from \"./el.js\";\nexport { default as en } from \"./en.js\";\nexport { default as eo } from \"./eo.js\";\nexport { default as es } from \"./es.js\";\nexport { default as fa } from \"./fa.js\";\nexport { default as fi } from \"./fi.js\";\nexport { default as fr } from \"./fr.js\";\nexport { default as frCA } from \"./fr-CA.js\";\nexport { default as gu } from \"./gu.js\";\nexport { default as he } from \"./he.js\";\nexport { default as hi } from \"./hi.js\";\nexport { default as hr } from \"./hr.js\";\nexport { default as hu } from \"./hu.js\";\nexport { default as hy } from \"./hy.js\";\nexport { default as id } from \"./id.js\";\nexport { default as is } from \"./is.js\";\nexport { default as it } from \"./it.js\";\nexport { default as ja } from \"./ja.js\";\nexport { default as ka } from \"./ka.js\";\nexport { default as kh } from \"./kh.js\";\nexport { default as km } from \"./km.js\";\nexport { default as kn } from \"./kn.js\";\nexport { default as ko } from \"./ko.js\";\nexport { default as lt } from \"./lt.js\";\nexport { default as mk } from \"./mk.js\";\nexport { default as ms } from \"./ms.js\";\nexport { default as ne } from \"./ne.js\";\nexport { default as nl } from \"./nl.js\";\nexport { default as nn } from \"./nn.js\";\nexport { default as no } from \"./no.js\";\nexport { default as ota } from \"./ota.js\";\nexport { default as ps } from \"./ps.js\";\nexport { default as pl } from \"./pl.js\";\nexport { default as pt } from \"./pt.js\";\nexport { default as ptBR } from \"./pt-BR.js\";\nexport { default as ro } from \"./ro.js\";\nexport { default as ru } from \"./ru.js\";\nexport { default as sk } from \"./sk.js\";\nexport { default as sl } from \"./sl.js\";\nexport { default as sv } from \"./sv.js\";\nexport { default as ta } from \"./ta.js\";\nexport { default as tg } from \"./tg.js\";\nexport { default as th } from \"./th.js\";\nexport { default as tk } from \"./tk.js\";\nexport { default as tr } from \"./tr.js\";\nexport { default as ua } from \"./ua.js\";\nexport { default as uk } from \"./uk.js\";\nexport { default as ur } from \"./ur.js\";\nexport { default as uz } from \"./uz.js\";\nexport { default as vi } from \"./vi.js\";\nexport { default as zhCN } from \"./zh-CN.js\";\nexport { default as zhTW } from \"./zh-TW.js\";\nexport { default as yo } from \"./yo.js\";\n", "var _a;\nexport const $output = /*@__PURE__*/ Symbol(\"ZodOutput\");\nexport const $input = /*@__PURE__*/ Symbol(\"ZodInput\");\nexport class $ZodRegistry {\n constructor() {\n this._map = new WeakMap();\n this._idmap = new Map();\n }\n add(schema, ..._meta) {\n const meta = _meta[0];\n this._map.set(schema, meta);\n if (meta && typeof meta === \"object\" && \"id\" in meta) {\n this._idmap.set(meta.id, schema);\n }\n return this;\n }\n clear() {\n this._map = new WeakMap();\n this._idmap = new Map();\n return this;\n }\n remove(schema) {\n const meta = this._map.get(schema);\n if (meta && typeof meta === \"object\" && \"id\" in meta) {\n this._idmap.delete(meta.id);\n }\n this._map.delete(schema);\n return this;\n }\n get(schema) {\n // return this._map.get(schema) as any;\n // inherit metadata\n const p = schema._zod.parent;\n if (p) {\n const pm = { ...(this.get(p) ?? {}) };\n delete pm.id; // do not inherit id\n const f = { ...pm, ...this._map.get(schema) };\n return Object.keys(f).length ? f : undefined;\n }\n return this._map.get(schema);\n }\n has(schema) {\n return this._map.has(schema);\n }\n}\n// registries\nexport function registry() {\n return new $ZodRegistry();\n}\n(_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());\nexport const globalRegistry = globalThis.__zod_globalRegistry;\n", "import { $ZodAsyncError } from \"./core.js\";\nimport { Doc } from \"./doc.js\";\nimport { isBackEdge, isRecursiveSchema } from \"./memoizer.js\";\nimport * as regexes from \"./regexes.js\";\nimport { isValidBase64, isValidBase64URL, isValidCIDRv6, isValidCreditCard, isValidIBAN, isValidIPv6, isValidJWT, mergeValues, stripTabAndNewline, urlHostnameOk, urlProtocolOk, validateURL, } from \"./schemas.js\";\nimport * as util from \"./util.js\";\n/** @internal Sentinel the compiled fast path returns when validation fails. */\nexport const INVALID = Symbol.for(\"zod.compile.invalid\");\n// Set on the parse ctx when a compiled wrapper falls back to the runtime, so nested compiled wrappers skip their fast paths for the rest of that parse.\nconst FALLBACK_FLAG = Symbol.for(\"zod.compile.fallback\");\n/** Raised when the schema contains async refinements or transforms. Surfaces only under `compile(schema, { strict: true })`. */\nexport class ZodCompileAsyncError extends Error {\n constructor(message = \"z.compile does not support async refinements, transforms, or checks\") {\n super(message);\n this.name = \"ZodCompileAsyncError\";\n }\n}\n/**\n * Raised when the schema contains a feature whose semantics the fast path\n * can't fully model. Both the shim in `zod/compile` and the default\n * `compile()` fall back to the runtime parser for that schema; only\n * `compile(schema, { strict: true })` lets it surface.\n */\nexport class ZodCompileUnsupportedError extends Error {\n constructor(feature, islandable = true) {\n super(`z.compile does not support ${feature}; this schema must use the runtime parser`);\n this.name = \"ZodCompileUnsupportedError\";\n this.islandable = islandable;\n }\n}\n/**\n * Build the validator `validate` calls: the same codegen as the parser with the output construction\n * dropped. A schema the flag cannot express reuses the parser, which still answers correctly \u2014 it\n * just builds a value nothing reads.\n */\nfunction compileValidator(schema, parser) {\n try {\n return compileFn(schema, { assertOnly: true });\n }\n catch {\n return parser;\n }\n}\n/**\n * AOT-compile a Zod schema. Returns a clone whose `_zod.run` calls a generated\n * fast path first and falls back to the original runtime parser on failure.\n *\n * - Forward direction only. Backward (encode), async, and `skipChecks` paths\n * bypass the fast path and use the runtime directly.\n * - Never throws. A schema the fast path can't model is returned unchanged and\n * keeps using the runtime parser. Pass `{ strict: true }` to get the refusal\n * as a thrown `ZodCompileUnsupportedError` / `ZodCompileAsyncError` instead.\n * - The original schema is unchanged. The clone shares children by reference.\n */\nexport function compile(schema, options) {\n try {\n const parser = compileFn(schema);\n const clone = withParser(schema, parser);\n // withParser leaves the parser as its own validator; the generated assert-only variant is better when we have one\n clone._zod.bag.validator = compileValidator(schema, parser);\n return clone;\n }\n catch (err) {\n if (options?.strict)\n throw err;\n // a schema we can't compile still has to work, so hand it back untouched on the runtime parser \u2014 the same silent fallback global mode already does\n return schema;\n }\n}\n/**\n * Install an already-generated parser as a schema's fast path. Returns a clone; the original is\n * unchanged.\n *\n * The parser takes the input and returns the parsed value, or `INVALID` to hand the parse to the\n * runtime. It must be synchronous and forward-direction, and it must build fresh output rather than\n * return its input \u2014 Zod cannot check either, and a wrong *success* is returned to the caller as-is.\n *\n * `compile()` is the ordinary entry point. This is for a build-time or native compiler that produces\n * a parser where `new Function` is unavailable.\n */\nexport function withParser(schema, parser) {\n // generated code never receives the parse context, so only the runtime can close a reference cycle; compileFn refuses these too\n if (isRecursiveSchema(schema)) {\n throw new ZodCompileUnsupportedError(\"a schema whose subtree contains a reference cycle\");\n }\n const clone = util.clone(schema);\n // Capture the source-of-truth runtime eagerly. If schema._zod.run is itself a shim installed by global-mode (`__originalRun` set), unwrap past it. Otherwise capturing the live property lazily would let a later self- replacement of schema._zod.run feed our wrapper back into itself.\n const liveRun = schema._zod.run;\n const originalRun = liveRun.__originalRun ?? liveRun;\n // Delegate to the *original* schema's run on bypass/fallback, not the clone's. The original closed over its own `inst` at construction time, and issue payloads use that reference to derive things like the class name for `z.instanceof(Test)`; calling the clone's freshly-initialized run would push issues with `inst === clone` and diverge from the original schema's error messages.\n const wrapped = (payload, ctx) => {\n if (ctx?.async ||\n ctx?.direction === \"backward\" ||\n ctx?.skipChecks ||\n ctx?.[FALLBACK_FLAG]) {\n return originalRun(payload, ctx);\n }\n // A memoized back-edge: only the runtime can close a reference cycle, and a transform on one must raise $ZodCyclicError from its own parse.\n if (ctx && isBackEdge(ctx, payload.value)) {\n return originalRun(payload, ctx);\n }\n const out = parser(payload.value);\n if (out !== INVALID) {\n payload.value = out;\n return payload;\n }\n // Mark this parse as runtime-driven: under global mode every nested schema carries its own compiled wrapper, and without the flag the parent's runtime fallback re-enters each child's fast path, running user callbacks a third time on invalid input.\n if (ctx)\n ctx[FALLBACK_FLAG] = true;\n return originalRun(payload, ctx);\n };\n // Let later compiles of (or through) this run unwrap to the true runtime \u2014 both the global shim and repeated z.compile calls rely on this. The bag also carries the parser and the validator, so the standalone validate can skip the payload and wrapper on the happy path.\n wrapped.__originalRun = originalRun;\n clone._zod.bag.fallbackRun = originalRun;\n // a supplied parser answers `validate` too: one implementation means parse and validate cannot disagree, and its undefined `definite` keeps the runtime re-parse on every rejection\n clone._zod.bag.validator = parser;\n clone._zod.run = wrapped;\n // The fast parse/safeParse closures fall back through the source schema's methods. If the source is shim- or wrapper-managed, those methods route into a compiled run and would execute user callbacks a third time on invalid input \u2014 the plain method \u2192 wrapper path is exactly 2x, so skip.\n if (!liveRun.__originalRun)\n installCompiledUserMethods(clone, schema, parser);\n return clone;\n}\nfunction installCompiledUserMethods(target, source, parser) {\n const targetAny = target;\n const sourceAny = source;\n if (typeof sourceAny.safeParse === \"function\") {\n const originalSafeParse = sourceAny.safeParse;\n targetAny.safeParse = (data, params) => {\n const out = parser(data);\n if (out !== INVALID) {\n return { success: true, data: out };\n }\n return originalSafeParse(data, params);\n };\n }\n if (typeof sourceAny.parse === \"function\") {\n const originalParse = sourceAny.parse;\n targetAny.parse = (data, params) => {\n const out = parser(data);\n if (out !== INVALID) {\n return out;\n }\n return originalParse(data, params);\n };\n }\n}\n/**\n * @internal Generate the standalone compiled function: a parser by default, a validator under\n * `assertOnly`. Returns the parsed value, `true` where nothing reads the output, or `INVALID`. Consumers use `compile()`.\n */\nexport function compileFn(schema, options) {\n // Cycle-breaking is keyed on the parse context, which generated code never receives. `shape` can be a getter that throws (z.pick() with an unrecognized mask key), so treat \"can't tell\" as recursive.\n let recursive = true;\n try {\n recursive = isRecursiveSchema(schema);\n }\n catch { }\n if (recursive) {\n throw new ZodCompileUnsupportedError(\"a schema whose subtree contains a reference cycle\");\n }\n const ctx = {\n constants: new Map(),\n constantCounter: 0,\n varCounter: 0,\n definite: true,\n };\n const doc = new Doc([\"input\"]);\n const outputAccessor = generateCheck(doc, ctx, schema, \"input\", !options?.assertOnly);\n // In assert mode a root that built nothing has already returned INVALID on every failure, so reaching the end means valid.\n doc.write(outputAccessor === null ? `return true;` : `return ${outputAccessor};`);\n // Build the function with hoisted constants Always include INVALID as the first constant\n const constantNames = [\"INVALID\", ...ctx.constants.keys()];\n const constantValues = [INVALID, ...ctx.constants.values()];\n const code = doc.content.join(\"\\n\");\n const fullCode = options?.debug\n ? constantNames.length > 0\n ? `// Constants: ${constantNames.join(\", \")}\\n${code}`\n : code\n : \"\";\n const F = Function;\n const factoryCode = `return (input) => {\\n${code}\\n}`;\n let fn;\n try {\n const factory = new F(...constantNames, factoryCode);\n fn = factory(...constantValues);\n }\n catch (err) {\n // Malformed generated code (or a CSP environment rejecting `new Function`) surfaces as a typed error so the global shim falls back to the runtime instead of crashing with a raw SyntaxError/EvalError.\n throw new ZodCompileUnsupportedError(`this schema (generated code failed to evaluate: ${err.message})`);\n }\n if (options?.debug) {\n fn.code = fullCode;\n }\n fn.definite = ctx.definite;\n return fn;\n}\nfunction addConstant(ctx, value) {\n // Check if we already have this constant\n for (const [name, v] of ctx.constants) {\n if (v === value)\n return name;\n }\n const name = `c${ctx.constantCounter++}`;\n ctx.constants.set(name, value);\n return name;\n}\n/** Hoists a user-supplied callback. Anything the schema's author wrote can throw, and generated code can reject an earlier sibling before ever reaching it, so this clears `definite` \u2014 a rejection is then no longer proof that the interpreter would have rejected rather than thrown. */\nfunction addUserConstant(ctx, fn) {\n ctx.definite = false;\n return addConstant(ctx, fn);\n}\nfunction newVar(ctx) {\n return `v${ctx.varCounter++}`;\n}\n// Runs a child schema as a black box: its value, or INVALID for a failure or an async run.\nfunction runtimeRun(schema, value) {\n const result = schema._zod.run({ value, issues: [] }, {});\n if (result && typeof result.then === \"function\")\n return INVALID;\n const r = result;\n return r.issues.length === 0 ? r.value : INVALID;\n}\n// `null` means the node built no value because nothing reads it. The overloads keep that case out of the 20-odd callers that always want one, so only a caller passing needsValue has to handle it.\nfunction compileChild(doc, ctx, schema, accessor, needsValue = true) {\n const contentLen = doc.content.length;\n const constantCount = ctx.constants.size;\n const constantCounter = ctx.constantCounter;\n const varCounter = ctx.varCounter;\n try {\n return generateCheck(doc, ctx, schema, accessor, needsValue);\n }\n catch (err) {\n if (!(err instanceof ZodCompileUnsupportedError) || !err.islandable)\n throw err;\n doc.content.length = contentLen;\n if (ctx.constants.size > constantCount) {\n const trailing = Array.from(ctx.constants.keys()).slice(constantCount);\n for (const k of trailing)\n ctx.constants.delete(k);\n }\n ctx.constantCounter = constantCounter;\n ctx.varCounter = varCounter;\n return emitRuntimeIsland(doc, ctx, schema, accessor);\n }\n}\nfunction emitRuntimeIsland(doc, ctx, schema, accessor) {\n // an islanded child answers INVALID for an async run too, which the interpreter throws for\n ctx.definite = false;\n const schemaConst = addConstant(ctx, schema);\n const runConst = addConstant(ctx, runtimeRun);\n const outVar = newVar(ctx);\n doc.write(`const ${outVar} = ${runConst}(${schemaConst}, ${accessor});`);\n doc.write(`if (${outVar} === INVALID) return INVALID;`);\n return outVar;\n}\n// Check classes whose `when` is auto-defaulted at init (checks.ts `when ??=`).\nconst WHEN_DEFAULTED_CHECKS = new Set([\n \"max_size\",\n \"min_size\",\n \"size_equals\",\n \"max_length\",\n \"min_length\",\n \"length_equals\",\n]);\nfunction generateChecks(doc, ctx, schema, accessor) {\n const schemaChecks = schema._zod.def.checks;\n if (!schemaChecks || schemaChecks.length === 0)\n return accessor;\n // Track current accessor - may change if overwrite checks are encountered\n let currentAccessor = accessor;\n for (const check of schemaChecks) {\n const def = check._zod.def;\n // A custom `when` skips a check the fast path always runs; the one auto-defaulted on size/length classes matches its bail-on-first-failure.\n if (def.when && !WHEN_DEFAULTED_CHECKS.has(def.check)) {\n throw new ZodCompileUnsupportedError(`check with a custom \"when\" condition`);\n }\n switch (def.check) {\n case \"greater_than\":\n generateGreaterThanCheck(doc, ctx, def, currentAccessor);\n break;\n case \"less_than\":\n generateLessThanCheck(doc, ctx, def, currentAccessor);\n break;\n case \"multiple_of\":\n generateMultipleOfCheck(doc, ctx, def, currentAccessor);\n break;\n case \"number_format\":\n generateNumberFormatCheck(doc, def, currentAccessor);\n break;\n case \"min_length\": {\n const min = numericOperand(def.minimum, \"min_length\");\n const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length >= ${min} && ${currentAccessor}.length < ${def.minimum * 2}`);\n doc.write(`if (${len} < ${min}) return INVALID;`);\n break;\n }\n case \"max_length\": {\n const max = numericOperand(def.maximum, \"max_length\");\n const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length > ${max}`);\n doc.write(`if (${len} > ${max}) return INVALID;`);\n break;\n }\n case \"length_equals\": {\n const exact = numericOperand(def.length, \"length_equals\");\n const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length >= ${exact} && ${currentAccessor}.length <= ${def.length * 2}`);\n doc.write(`if (${len} !== ${exact}) return INVALID;`);\n break;\n }\n case \"min_size\":\n doc.write(`if (${currentAccessor}.size < ${numericOperand(def.minimum, \"min_size\")}) return INVALID;`);\n break;\n case \"max_size\":\n doc.write(`if (${currentAccessor}.size > ${numericOperand(def.maximum, \"max_size\")}) return INVALID;`);\n break;\n case \"size_equals\":\n doc.write(`if (${currentAccessor}.size !== ${numericOperand(def.size, \"size_equals\")}) return INVALID;`);\n break;\n case \"string_format\":\n currentAccessor = generateStringFormatCheck(doc, ctx, def, currentAccessor);\n break;\n case \"custom\":\n currentAccessor = generateCustomRefineCheck(doc, ctx, check, currentAccessor);\n break;\n case \"bigint_format\":\n generateBigIntFormatCheck(doc, def, currentAccessor);\n break;\n case \"mime_type\":\n generateMimeTypeCheck(doc, ctx, def, currentAccessor);\n break;\n case \"property\":\n generatePropertyCheck(doc, ctx, def, currentAccessor);\n break;\n case \"properties\":\n generatePropertiesChecks(doc, ctx, def, currentAccessor);\n break;\n case \"overwrite\": {\n // Overwrite transforms the value - create new variable for transformed result\n const newAccessor = newVar(ctx);\n generateOverwriteCheck(doc, ctx, check, currentAccessor, newAccessor);\n currentAccessor = newAccessor;\n break;\n }\n default: {\n void def;\n throw new ZodCompileUnsupportedError(`check type ${def.check}`);\n }\n }\n }\n return currentAccessor;\n}\n// Emit the length operand for a length check, mirroring `$ZodCheckMinLength` and friends: strings measure in code points, everything else in `.length`. `inDoubt` is the caller's cheap UTF-16 bound test \u2014 outside it the unit count already settles the comparison, so the scan is skipped.\nfunction codePointLengthVar(doc, ctx, accessor, inDoubt) {\n const cpLen = addConstant(ctx, util.codePointLength);\n const v = newVar(ctx);\n doc.write(`const ${v} = typeof ${accessor} === \"string\" && ${inDoubt} ? ${cpLen}(${accessor}) : ${accessor}.length;`);\n return v;\n}\n// Emit a source operand for a gt/lt bound. Numbers inline; Dates hoist as a constant (relational operators compare via valueOf). NaN and Invalid Date bounds can't compile to a comparison that matches runtime semantics.\n/**\n * A count bound reaches generated source verbatim, so a non-number would be\n * emitted as code rather than as a value \u2014 `min('0) {} evil(); if (0')` writes an\n * arbitrary statement into the function body. TypeScript types these as `number`\n * and fromJSONSchema guards them, so this is a backstop rather than a live hole,\n * but generated source is the one place a wrong type stops being a type error.\n */\nfunction numericOperand(value, label) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new ZodCompileUnsupportedError(`${label} bound of type ${typeof value}`);\n }\n return `${value}`;\n}\nfunction comparisonOperand(ctx, value) {\n if (typeof value === \"bigint\")\n return `${value}n`;\n if (typeof value === \"number\") {\n if (Number.isNaN(value))\n throw new ZodCompileUnsupportedError(\"comparison check with NaN bound\");\n return `${value}`;\n }\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n throw new ZodCompileUnsupportedError(\"comparison check with Invalid Date bound\");\n }\n return addConstant(ctx, value);\n }\n throw new ZodCompileUnsupportedError(`comparison check bound of type ${typeof value}`);\n}\nfunction generateGreaterThanCheck(doc, ctx, def, accessor) {\n const op = def.inclusive ? \"<\" : \"<=\";\n doc.write(`if (${accessor} ${op} ${comparisonOperand(ctx, def.value)}) return INVALID;`);\n}\nfunction generateLessThanCheck(doc, ctx, def, accessor) {\n const op = def.inclusive ? \">\" : \">=\";\n doc.write(`if (${accessor} ${op} ${comparisonOperand(ctx, def.value)}) return INVALID;`);\n}\nfunction generateMultipleOfCheck(doc, ctx, def, accessor) {\n if (typeof def.value === \"bigint\") {\n // a zero divisor has no compiled form: `x % 0n` throws\n if (def.value === BigInt(0))\n throw new ZodCompileUnsupportedError(\"multiple_of check with a zero divisor\");\n doc.write(`if (${accessor} % ${def.value}n !== 0n) return INVALID;`);\n }\n else {\n // Float `%` has well-known precision issues for sub-integer steps\n // (`1.5 % 0.1`, `2.5e-7 % 1e-7`). Defer to util.floatSafeRemainder so the\n // exact tolerance logic stays in one place \u2014 single function call is fine\n // since `multipleOf` runs at most once per number.\n const remainder = addConstant(ctx, util.floatSafeRemainder);\n doc.write(`if (${remainder}(${accessor}, ${numericOperand(def.value, \"multiple_of\")}) !== 0) return INVALID;`);\n }\n}\nfunction generateNumberFormatCheck(doc, def, accessor) {\n const format = def.format;\n switch (format) {\n case \"safeint\":\n doc.write(`if (!Number.isSafeInteger(${accessor})) return INVALID;`);\n break;\n case \"int32\":\n doc.write(`if (!Number.isInteger(${accessor}) || ${accessor} < -2147483648 || ${accessor} > 2147483647) return INVALID;`);\n break;\n case \"uint32\":\n doc.write(`if (!Number.isInteger(${accessor}) || ${accessor} < 0 || ${accessor} > 4294967295) return INVALID;`);\n break;\n case \"float32\":\n // Float32 range per util.NUMBER_FORMAT_RANGES\n doc.write(`if (!Number.isFinite(${accessor}) || ${accessor} < -3.4028234663852886e38 || ${accessor} > 3.4028234663852886e38) return INVALID;`);\n break;\n case \"float64\":\n doc.write(`if (!Number.isFinite(${accessor})) return INVALID;`);\n break;\n default: {\n void format;\n throw new ZodCompileUnsupportedError(`number format ${format}`);\n }\n }\n}\nfunction generateBigIntFormatCheck(doc, def, accessor) {\n const format = def.format;\n if (!format)\n return; // undefined format means no range check\n switch (format) {\n case \"int64\":\n doc.write(`if (${accessor} < -9223372036854775808n || ${accessor} > 9223372036854775807n) return INVALID;`);\n break;\n case \"uint64\":\n doc.write(`if (${accessor} < 0n || ${accessor} > 18446744073709551615n) return INVALID;`);\n break;\n default: {\n void format;\n throw new ZodCompileUnsupportedError(`bigint format ${format}`);\n }\n }\n}\nfunction generateMimeTypeCheck(doc, ctx, def, accessor) {\n const mimeTypes = def.mime;\n if (mimeTypes && mimeTypes.length > 0) {\n const mimeSet = addConstant(ctx, new Set(mimeTypes));\n doc.write(`if (!${mimeSet}.has(${accessor}.type)) return INVALID;`);\n }\n}\n// asserts each named property in place; children compile assert-only because z.properties never rebuilds its input\nfunction generatePropertiesChecks(doc, ctx, def, accessor) {\n // a custom `when` gates the assertion at runtime; inside a union a wrongly-run branch is absorbed as a branch failure rather than falling back, so refuse at codegen\n if (def.when) {\n throw new ZodCompileUnsupportedError(`check with a custom \"when\" condition`);\n }\n // matches the runtime gate: the base schema already typed the value, so only a nullish one is rejected\n doc.write(`if (${accessor} == null) return INVALID;`);\n const shape = def.shape;\n for (const key of Reflect.ownKeys(shape)) {\n // a symbol has no source literal, so it is hoisted as a constant\n const keyExpr = typeof key === \"symbol\" ? addConstant(ctx, key) : util.esc(key);\n // cache the property read so a getter runs exactly once, matching the runtime\n const inputVar = newVar(ctx);\n doc.write(`const ${inputVar} = ${accessor}[${keyExpr}];`);\n compileChild(doc, ctx, shape[key], inputVar, false);\n }\n}\nfunction generatePropertyCheck(doc, ctx, def, accessor) {\n const propAccessor = `${accessor}[${JSON.stringify(def.property)}]`;\n generateCheck(doc, ctx, def.schema, propAccessor);\n}\nfunction generateOverwriteCheck(doc, ctx, check, currentAccessor, newAccessor) {\n const tx = check._zod.def.tx;\n if (!tx) {\n throw new ZodCompileUnsupportedError(\"overwrite check without a transform function\");\n }\n // Check for async transform\n if (isAsyncFunction(tx)) {\n throw new ZodCompileAsyncError(\"z.compile: async overwrite transforms are not supported\");\n }\n // Hoist the transform function as a constant and apply it\n const txConst = addConstant(ctx, tx);\n doc.write(`const ${newAccessor} = ${txConst}(${currentAccessor});`);\n}\n/** A predicate that hands back a thenable is an async check reached synchronously, and the interpreter throws `$ZodAsyncError` for it. Returning INVALID instead would be a bail-out, and a union reads a bail-out as a rejected branch and answers with a later one \u2014 so the throw has to survive into generated code. */\nfunction throwAsync() {\n throw new $ZodAsyncError();\n}\n/** Shared `addIssue` for the spoofed payloads a refine, check or transform receives. Allocating one per call \u2014 a fresh closure plus a `this`-bound method on a fresh literal \u2014 pinned every payload-allocating schema at ~2.7M ops/sec against 135M for a plain object literal. It captures nothing per call; it only reaches `this.issues`. */\nfunction pushIssue(issue) {\n this.issues.push(issue);\n}\nfunction generateCustomRefineCheck(doc, ctx, check, accessor) {\n const def = check._zod.def;\n if (def.fn) {\n // Simple predicate function (from .refine())\n if (isAsyncFunction(def.fn)) {\n throw new ZodCompileAsyncError(\"z.compile: async .refine() predicates are not supported\");\n }\n const fnConst = addUserConstant(ctx, def.fn);\n const throwAsyncConst = addConstant(ctx, throwAsync);\n const resVar = newVar(ctx);\n doc.write(`const ${resVar} = ${fnConst}(${accessor});`);\n // A thenable is truthy, so it would otherwise read as a pass. It is not a rejection either: the interpreter throws, and INVALID inside a union would just hand the parse to the next branch.\n doc.write(`if (${resVar} instanceof Promise) ${throwAsyncConst}();`);\n doc.write(`if (!${resVar}) return INVALID;`);\n // A `.refine()` predicate only answers yes or no; it cannot rewrite the value.\n return accessor;\n }\n if (check._zod.check) {\n if (isAsyncFunction(check._zod.check)) {\n throw new ZodCompileAsyncError(\"z.compile: async .superRefine() / check functions are not supported\");\n }\n // SuperRefine or other check function - need to spoof context Create a helper that runs the check and returns true if no issues\n const checkFn = check._zod.check;\n // `$RefinementCtx` extends the parse payload, so a check may rewrite\n // `ctx.value` as well as push issues \u2014 `.superRefine((v, ctx) => { ctx.value =\n // v.trim() })` is a value transform. Returning only a boolean discarded that\n // write and emitted the untrimmed input. Hand the value back and thread it on.\n const helperFn = (value) => {\n const fakePayload = { value, issues: [], addIssue: pushIssue };\n const result = checkFn(fakePayload);\n // Throw rather than return INVALID: the interpreter throws here, and a union would read INVALID as a rejected branch.\n if (result instanceof Promise)\n throwAsync();\n return fakePayload.issues.length === 0 ? fakePayload.value : INVALID;\n };\n const helperConst = addUserConstant(ctx, helperFn);\n const outVar = newVar(ctx);\n doc.write(`const ${outVar} = ${helperConst}(${accessor});`);\n doc.write(`if (${outVar} === INVALID) return INVALID;`);\n return outVar;\n }\n throw new ZodCompileUnsupportedError(\"custom check without a predicate or check function\");\n}\n/**\n * Built-in formats that validate with nothing but `def.pattern`, so compiling\n * the regex reproduces the runtime exactly. Deliberately an allowlist: a format\n * missing from it loses its fast path, while a format wrongly added to it\n * silently accepts input the runtime rejects. Formats that layer extra\n * validation over a shape-only pattern (`credit_card`, `base64`, `ipv6`, \u2026) are\n * handled above by hoisting the runtime validator itself.\n */\nconst PATTERN_IS_COMPLETE = new Set([\n \"cidrv4\",\n \"cuid\",\n \"cuid2\",\n \"date\",\n \"datetime\",\n \"duration\",\n \"e164\",\n \"email\",\n \"emoji\",\n \"ends_with\",\n \"guid\",\n \"includes\",\n \"ipv4\",\n \"ksuid\",\n \"lowercase\",\n \"mac\",\n \"nanoid\",\n \"regex\",\n \"starts_with\",\n \"time\",\n \"ulid\",\n \"uppercase\",\n \"uuid\",\n \"xid\",\n]);\nfunction generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {\n // Some string formats do runtime validation beyond their advertised pattern. For cheap pure utility checks, hoist the runtime function and call it so the fast path stays correct without cloning the utility logic into codegen.\n const fmt = def.format;\n if (fmt === \"base64\") {\n const validator = addConstant(ctx, isValidBase64);\n doc.write(`if (!${validator}(${accessor})) return INVALID;`);\n return accessor;\n }\n if (fmt === \"base64url\") {\n const validator = addConstant(ctx, isValidBase64URL);\n doc.write(`if (!${validator}(${accessor})) return INVALID;`);\n return accessor;\n }\n if (fmt === \"jwt\") {\n const validator = addConstant(ctx, isValidJWT);\n const alg = addConstant(ctx, def.alg ?? null);\n doc.write(`if (!${validator}(${accessor}, ${alg})) return INVALID;`);\n return accessor;\n }\n if (fmt === \"ipv6\") {\n const validator = addConstant(ctx, isValidIPv6);\n doc.write(`if (!${validator}(${accessor})) return INVALID;`);\n return accessor;\n }\n if (fmt === \"cidrv6\") {\n const validator = addConstant(ctx, isValidCIDRv6);\n doc.write(`if (!${validator}(${accessor})) return INVALID;`);\n return accessor;\n }\n if (fmt === \"credit_card\") {\n const validator = addConstant(ctx, isValidCreditCard);\n doc.write(`if (!${validator}(${accessor})) return INVALID;`);\n return accessor;\n }\n if (fmt === \"iban\") {\n const validator = addConstant(ctx, isValidIBAN);\n doc.write(`if (!${validator}(${accessor})) return INVALID;`);\n return accessor;\n }\n const formatDef = def;\n if (fmt === \"url\" ||\n fmt === \"httpurl\" ||\n formatDef.normalize ||\n formatDef.hostname !== undefined ||\n formatDef.protocol !== undefined) {\n // Same three predicates the runtime calls, in the same order, so there is no second URL implementation to drift. Which options exist is known now, so the calls the runtime makes conditionally are emitted conditionally instead.\n const parseConst = addConstant(ctx, validateURL);\n const defConst = addConstant(ctx, def);\n const trimVar = newVar(ctx);\n const urlVar = newVar(ctx);\n doc.write(`const ${trimVar} = ${accessor}.trim();`);\n doc.write(`const ${urlVar} = ${parseConst}(${trimVar}, ${defConst});`);\n doc.write(`if (typeof ${urlVar} === \"number\") return INVALID;`);\n if (formatDef.hostname !== undefined) {\n const hostnameConst = addConstant(ctx, urlHostnameOk);\n doc.write(`if (!${hostnameConst}(${urlVar}, ${defConst}.hostname)) return INVALID;`);\n }\n if (formatDef.protocol !== undefined) {\n const protocolConst = addConstant(ctx, urlProtocolOk);\n doc.write(`if (!${protocolConst}(${urlVar}, ${defConst}.protocol)) return INVALID;`);\n }\n if (!needsValue)\n return null;\n const outputVar = newVar(ctx);\n const outputExpr = formatDef.normalize ? `${urlVar}.href` : `${addConstant(ctx, stripTabAndNewline)}(${trimVar})`;\n doc.write(`const ${outputVar} = ${outputExpr};`);\n return outputVar;\n }\n // A custom string format carries the predicate the runtime actually calls. Hoist and call it instead of testing `def.pattern`: the two only coincide when the format was built from a RegExp, and relying on that coupling is how supplemental validation gets dropped.\n const customFn = def.fn;\n if (customFn) {\n if (isAsyncFunction(customFn))\n throw new ZodCompileUnsupportedError(`async string format ${fmt}`);\n const fnConst = addConstant(ctx, customFn);\n doc.write(`if (!${fnConst}(${accessor})) return INVALID;`);\n return accessor;\n }\n // Formats whose `pattern` IS the whole check. An allowlist rather than `if (def.pattern)`, because credit_card, base64 and ipv6 carry a shape-only pattern and validate the rest separately.\n if (PATTERN_IS_COMPLETE.has(fmt) && def.pattern) {\n const patternConst = addConstant(ctx, def.pattern);\n doc.write(`${patternConst}.lastIndex = 0;`);\n doc.write(`if (!${patternConst}.test(${accessor})) return INVALID;`);\n return accessor;\n }\n const format = def.format;\n switch (format) {\n case \"regex\":\n // A regex check with a pattern returned above. Reaching here means there is no pattern to test, and accepting unconditionally would pass every input, so hand the schema back to the runtime.\n throw new ZodCompileUnsupportedError(\"regex format without a pattern\");\n case \"lowercase\":\n doc.write(`if (${accessor} !== ${accessor}.toLowerCase()) return INVALID;`);\n break;\n case \"uppercase\":\n doc.write(`if (${accessor} !== ${accessor}.toUpperCase()) return INVALID;`);\n break;\n case \"includes\":\n doc.write(`if (!${accessor}.includes(${util.esc(def.includes)})) return INVALID;`);\n break;\n case \"starts_with\": {\n const prefix = def.prefix;\n doc.write(`if (${accessor}.slice(0, ${prefix.length}) !== ${util.esc(prefix)}) return INVALID;`);\n break;\n }\n case \"ends_with\": {\n const suffix = def.suffix;\n doc.write(`if (${accessor}.slice(-${suffix.length}) !== ${util.esc(suffix)}) return INVALID;`);\n break;\n }\n default: {\n void format;\n throw new ZodCompileUnsupportedError(`string format ${format}`);\n }\n }\n return accessor;\n}\nfunction generateCheck(doc, ctx, schema, accessor, needsValue = true) {\n const def = schema._zod.def;\n const type = def.type;\n // A coercing schema would compile to the bare type test and reject what it should convert; inside a union that reads as a rejected branch, so refuse at codegen.\n if (def.coerce) {\n throw new ZodCompileUnsupportedError(`coercion (z.coerce.${type}())`);\n }\n // A node builds its output when its caller reads one, or when it carries checks of its own, since a check reads what was built. One polarity for the whole walk: this is what the node does, and it is what its children are told they need.\n const buildsValue = needsValue || !!def.checks?.length;\n let typeAccessor;\n switch (type) {\n case \"string\":\n typeAccessor = generateStringCheck(doc, ctx, schema, accessor, buildsValue);\n break;\n case \"number\":\n typeAccessor = generateNumberCheck(doc, schema, accessor);\n break;\n case \"boolean\":\n typeAccessor = generateBooleanCheck(doc, accessor);\n break;\n case \"bigint\":\n typeAccessor = generateBigIntCheck(doc, schema, accessor);\n break;\n case \"symbol\":\n typeAccessor = generateSymbolCheck(doc, accessor);\n break;\n case \"undefined\":\n typeAccessor = generateUndefinedCheck(doc, accessor);\n break;\n case \"null\":\n typeAccessor = generateNullCheck(doc, accessor);\n break;\n case \"any\":\n case \"unknown\":\n // No check needed - pass through\n typeAccessor = accessor;\n break;\n case \"never\":\n doc.write(\"return INVALID;\");\n typeAccessor = accessor;\n break;\n case \"void\":\n typeAccessor = generateVoidCheck(doc, accessor);\n break;\n case \"nan\":\n typeAccessor = generateNaNCheck(doc, accessor);\n break;\n case \"date\":\n typeAccessor = generateDateCheck(doc, accessor);\n break;\n case \"object\":\n typeAccessor = generateObjectCheck(doc, ctx, schema, accessor, buildsValue);\n break;\n case \"optional\":\n typeAccessor = generateOptionalCheck(doc, ctx, schema, accessor, buildsValue);\n break;\n case \"nullable\":\n typeAccessor = generateNullableCheck(doc, ctx, schema, accessor, buildsValue);\n break;\n case \"array\":\n typeAccessor = generateArrayCheck(doc, ctx, schema, accessor, buildsValue);\n break;\n case \"literal\":\n typeAccessor = generateLiteralCheck(doc, ctx, schema, accessor);\n break;\n case \"enum\":\n typeAccessor = generateEnumCheck(doc, ctx, schema, accessor);\n break;\n case \"readonly\": {\n const innerOut = generateWrapperCheck(doc, ctx, schema, accessor);\n // Runtime freezes the parsed value (schemas.ts handleReadonlyResult).\n const frozenVar = newVar(ctx);\n doc.write(`const ${frozenVar} = Object.freeze(${innerOut});`);\n typeAccessor = frozenVar;\n break;\n }\n case \"success\":\n // Runtime output is `issues.length === 0`. The fast path only reaches\n // here when the inner check passed (failure returns INVALID and the\n // runtime fallback reproduces the inner issues), so the output is\n // always `true`.\n generateWrapperCheck(doc, ctx, schema, accessor);\n typeAccessor = \"true\";\n break;\n case \"default\":\n case \"prefault\":\n typeAccessor = generateDefaultCheck(doc, ctx, schema, accessor);\n break;\n case \"nonoptional\":\n typeAccessor = generateNonOptionalCheck(doc, ctx, schema, accessor);\n break;\n case \"tuple\":\n typeAccessor = generateTupleCheck(doc, ctx, schema, accessor);\n break;\n case \"union\":\n typeAccessor = generateUnionCheck(doc, ctx, schema, accessor);\n break;\n case \"intersection\":\n typeAccessor = generateIntersectionCheck(doc, ctx, schema, accessor);\n break;\n case \"record\":\n typeAccessor = generateRecordCheck(doc, ctx, schema, accessor);\n break;\n case \"map\":\n typeAccessor = generateMapCheck(doc, ctx, schema, accessor);\n break;\n case \"set\":\n typeAccessor = generateSetCheck(doc, ctx, schema, accessor);\n break;\n case \"file\":\n typeAccessor = generateFileCheck(doc, accessor);\n break;\n case \"template_literal\":\n typeAccessor = generateTemplateLiteralCheck(doc, ctx, schema, accessor);\n break;\n case \"lazy\":\n typeAccessor = generateLazyCheck(doc, ctx, schema, accessor);\n break;\n case \"pipe\":\n typeAccessor = generatePipeCheck(doc, ctx, schema, accessor);\n break;\n case \"custom\":\n typeAccessor = generateCustomCheck(doc, ctx, schema, accessor);\n break;\n case \"transform\":\n typeAccessor = generateTransformCheck(doc, ctx, schema, accessor);\n break;\n case \"catch\":\n typeAccessor = generateCatchCheck(doc, ctx, schema, accessor);\n break;\n default: {\n void type;\n throw new ZodCompileUnsupportedError(`schema type ${type}`);\n }\n }\n // a node that built nothing has no checks to run: not building requires an empty check list\n if (typeAccessor === null)\n return null;\n // Generate checks after the type-specific validation (may transform value)\n return generateChecks(doc, ctx, schema, typeAccessor);\n}\nfunction generateStringCheck(doc, ctx, schema, accessor, needsValue = true) {\n doc.write(`if (typeof ${accessor} !== \"string\") return INVALID;`);\n // z.email() carries its format on the def, z.string().email() in def.checks; both route here so the format table has no second copy to drift from.\n const def = schema._zod.def;\n if (def.format === undefined)\n return accessor;\n return generateStringFormatCheck(doc, ctx, def, accessor, needsValue);\n}\nfunction generateNumberCheck(doc, schema, accessor) {\n // Runtime z.number() rejects NaN and \u00B1Infinity. Number.isFinite covers both.\n doc.write(`if (typeof ${accessor} !== \"number\" || !Number.isFinite(${accessor})) return INVALID;`);\n // Mini factories like z.int(), z.int32(), z.uint32(), z.float32() bake a number_format check into the schema def itself (not into def.checks). Apply the same constraint here.\n const def = schema._zod.def;\n if (def.check === \"number_format\" && def.format) {\n generateNumberFormatCheck(doc, { format: def.format }, accessor);\n }\n return accessor;\n}\nfunction generateBooleanCheck(doc, accessor) {\n doc.write(`if (typeof ${accessor} !== \"boolean\") return INVALID;`);\n return accessor;\n}\nfunction generateBigIntCheck(doc, schema, accessor) {\n doc.write(`if (typeof ${accessor} !== \"bigint\") return INVALID;`);\n // Handle bigint format (int64, uint64) directly on the schema def\n const def = schema._zod.def;\n if (def.format) {\n switch (def.format) {\n case \"int64\":\n doc.write(`if (${accessor} < -9223372036854775808n || ${accessor} > 9223372036854775807n) return INVALID;`);\n break;\n case \"uint64\":\n doc.write(`if (${accessor} < 0n || ${accessor} > 18446744073709551615n) return INVALID;`);\n break;\n }\n }\n return accessor;\n}\nfunction generateSymbolCheck(doc, accessor) {\n doc.write(`if (typeof ${accessor} !== \"symbol\") return INVALID;`);\n return accessor;\n}\nfunction generateUndefinedCheck(doc, accessor) {\n doc.write(`if (${accessor} !== undefined) return INVALID;`);\n return accessor;\n}\nfunction generateNullCheck(doc, accessor) {\n doc.write(`if (${accessor} !== null) return INVALID;`);\n return accessor;\n}\nfunction generateVoidCheck(doc, accessor) {\n doc.write(`if (${accessor} !== undefined) return INVALID;`);\n return accessor;\n}\nfunction generateNaNCheck(doc, accessor) {\n doc.write(`if (typeof ${accessor} !== \"number\" || !Number.isNaN(${accessor})) return INVALID;`);\n return accessor;\n}\nfunction generateDateCheck(doc, accessor) {\n doc.write(`if (!(${accessor} instanceof Date) || Number.isNaN(${accessor}.getTime())) return INVALID;`);\n return accessor;\n}\nfunction generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {\n const def = schema._zod.def;\n // Check that input is a non-null, non-array object\n doc.write(`if (typeof ${accessor} !== \"object\" || ${accessor} === null || Array.isArray(${accessor})) return INVALID;`);\n const shape = def.shape;\n const keys = Object.keys(shape);\n const symbolKeys = Object.getOwnPropertySymbols(shape);\n // a symbol has no source literal, so it is hoisted as a constant; `keys` stays string-only where the emitted code uses `for...in`\n const allKeys = symbolKeys.length ? [...keys, ...symbolKeys] : keys;\n const keyExpr = (k) => (typeof k === \"symbol\" ? addConstant(ctx, k) : util.esc(k));\n const propKey = (k) => (typeof k === \"symbol\" ? `[${keyExpr(k)}]` : util.esc(k));\n const propShape = shape;\n // `__proto__` as an own shape key can't be expressed in an output object literal (the literal form sets the prototype instead of an own property).\n if (keys.includes(\"__proto__\")) {\n throw new ZodCompileUnsupportedError('object shape key \"__proto__\"');\n }\n // Map from key to output accessor for that property\n const propOutputs = new Map();\n // Validate each property and collect output accessors\n for (const key of allKeys) {\n const propSchema = propShape[key];\n const kx = keyExpr(key);\n // Always cache the property read: the runtime reads input[key] exactly once, so a getter must not be re-read by checks or output assembly.\n const inputVar = newVar(ctx);\n doc.write(`const ${inputVar} = ${accessor}[${kx}];`);\n if (propSchema._zod.optin !== undefined) {\n // Any optin rung means the key may be omitted. The runtime runs the property anyway and ignores issues only when the key is genuinely absent, which is what makes exactOptional compositional.\n const outputVar = newVar(ctx);\n doc.write(`let ${outputVar} = (() => {`);\n doc.indented((d) => {\n const outputAccessor = compileChild(d, ctx, propSchema, inputVar);\n d.write(`return ${outputAccessor};`);\n });\n doc.write(`})();`);\n if (propSchema._zod.optout === \"optional\") {\n doc.write(`if (${outputVar} === INVALID) {`);\n doc.indented((d) => {\n d.write(`if (${kx} in ${accessor}) return INVALID;`);\n d.write(`${outputVar} = undefined;`);\n });\n doc.write(`}`);\n }\n else {\n doc.write(`if (${outputVar} === INVALID) return INVALID;`);\n }\n propOutputs.set(key, outputVar);\n }\n else {\n if (requiresPresenceCheck(propSchema)) {\n doc.write(`if (!(${kx} in ${accessor})) return INVALID;`);\n }\n // Generate check and get output accessor\n const outputAccessor = compileChild(doc, ctx, propSchema, inputVar, buildsValue);\n if (outputAccessor !== null)\n propOutputs.set(key, outputAccessor);\n }\n }\n // Handle catchall\n const catchall = def.catchall;\n let unknownKeysMode = \"none\";\n if (catchall) {\n const catchallType = catchall._zod.def.type;\n if (catchallType === \"never\") {\n // Strict: one `for...in`, as the runtime does, so inherited enumerable keys count. An undeclared `__proto__` is reported here and excluded only from the output (#6221); an own-key count would wrongly reject a class instance.\n const condition = keys.map((k) => `k !== ${util.esc(k)}`).join(\" && \") || \"true\";\n doc.write(`for (const k in ${accessor}) {`);\n doc.indented((d) => {\n d.write(`if (${condition}) return INVALID;`);\n });\n doc.write(`}`);\n }\n else if ((catchallType === \"unknown\" || catchallType === \"any\") && !catchall._zod.def.checks?.length) {\n unknownKeysMode = \"passthrough\";\n }\n else {\n unknownKeysMode = \"schema\";\n }\n }\n // else: strip mode (no catchall) - unknown keys ignored, only include known keys\n // defaulted required outputs keep their keys even when undefined\n const outputVar = newVar(ctx);\n const hasConditionalKeys = allKeys.some((k) => mayOmitUndefined(propShape[k]) || dropsWhenAbsent(propShape[k]));\n // Assert mode: every declared key is validated above, so the output literal and the unknown-key copy are pure waste. A `never` catchall already emitted its rejection loop; a schema catchall still has to validate the values it would otherwise have stored.\n if (!buildsValue) {\n if (unknownKeysMode === \"schema\") {\n const knownSet = keys.length > 0 ? addConstant(ctx, new Set(keys)) : null;\n doc.write(`for (const k in ${accessor}) {`);\n doc.indented((d) => {\n d.write(`if (k === \"__proto__\") continue;`);\n if (knownSet)\n d.write(`if (${knownSet}.has(k)) continue;`);\n const valVar = newVar(ctx);\n d.write(`const ${valVar} = ${accessor}[k];`);\n compileChild(d, ctx, catchall, valVar, false);\n });\n doc.write(`}`);\n }\n return null;\n }\n if (!hasConditionalKeys) {\n const propLiterals = allKeys.map((k) => `${propKey(k)}: ${propOutputs.get(k)}`).join(\", \");\n doc.write(`const ${outputVar} = { ${propLiterals} };`);\n }\n else {\n doc.write(`const ${outputVar} = {};`);\n for (const k of allKeys) {\n const kx = keyExpr(k);\n const out = propOutputs.get(k);\n if (dropsWhenAbsent(propShape[k])) {\n doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);\n }\n else if (mayOmitUndefined(propShape[k])) {\n doc.write(`if (${out} !== undefined || ${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);\n }\n else {\n doc.write(`${outputVar}[${kx}] = ${out};`);\n }\n }\n }\n if (unknownKeysMode !== \"none\") {\n // Unknown keys are written directly into the output after shape keys \u2014 for...in (like the runtime) so inherited enumerables participate.\n const knownSet = keys.length > 0 ? addConstant(ctx, new Set(keys)) : null;\n doc.write(`for (const k in ${accessor}) {`);\n doc.indented((d) => {\n // Skip __proto__: assigning obj[\"__proto__\"] on a plain {} replaces the prototype via the setter rather than adding an own property. Mirrors the runtime catchall fix (#5898).\n d.write(`if (k === \"__proto__\") continue;`);\n if (knownSet)\n d.write(`if (${knownSet}.has(k)) continue;`);\n if (unknownKeysMode === \"passthrough\") {\n d.write(`${outputVar}[k] = ${accessor}[k];`);\n }\n else {\n const valVar = newVar(ctx);\n d.write(`const ${valVar} = ${accessor}[k];`);\n const catchallOut = compileChild(d, ctx, catchall, valVar);\n d.write(`${outputVar}[k] = ${catchallOut};`);\n }\n });\n doc.write(`}`);\n }\n return outputVar;\n}\nfunction generateOptionalCheck(doc, ctx, schema, accessor, buildsValue = true) {\n const def = schema._zod.def;\n if (isExactOptional(schema)) {\n return generateCheck(doc, ctx, def.innerType, accessor, buildsValue);\n }\n // Same question $ZodOptional asks: only the top rung of the optin ladder substitutes a value for an absent input, so only it is worth running on `undefined`. Every other rung leaves the value intact, which is the skip branch below.\n if (def.innerType._zod.optin === \"defaulted\") {\n const outputVar = newVar(ctx);\n const branchVar = newVar(ctx);\n doc.write(`let ${outputVar};`);\n doc.write(`if (${accessor} === undefined) {`);\n doc.indented((d) => {\n d.write(`const ${branchVar} = (() => {`);\n d.indented((d2) => {\n const innerOutput = generateCheck(d2, ctx, def.innerType, accessor);\n d2.write(`return ${innerOutput};`);\n });\n d.write(`})();`);\n d.write(`if (${branchVar} !== INVALID) ${outputVar} = ${branchVar};`);\n });\n doc.write(`} else {`);\n doc.indented((d) => {\n const innerOutput = generateCheck(d, ctx, def.innerType, accessor);\n d.write(`${outputVar} = ${innerOutput};`);\n });\n doc.write(`}`);\n return outputVar;\n }\n const outputVar = buildsValue ? newVar(ctx) : null;\n if (outputVar)\n doc.write(`let ${outputVar};`);\n doc.write(`if (${accessor} !== undefined) {`);\n doc.indented((d) => {\n const innerOutput = generateCheck(d, ctx, def.innerType, accessor, buildsValue);\n if (outputVar && innerOutput !== null)\n d.write(`${outputVar} = ${innerOutput};`);\n });\n doc.write(`}`);\n return outputVar;\n}\nfunction isExactOptional(schema) {\n return schema._zod.traits?.has(\"$ZodExactOptional\") === true;\n}\n// A value-level fast path reads an absent key as `undefined`, so z.undefined(), z.any() and unions containing undefined would accept a missing property the runtime rejects.\nfunction requiresPresenceCheck(schema) {\n return schema._zod.optin === undefined && fastPathAcceptsAbsence(schema);\n}\nfunction fastPathAcceptsAbsence(schema) {\n // An island is handed `input[key]` and cannot tell absent from explicitly undefined, so report absence-accepting and let the object emit the presence guard (#6405).\n if (schema._zod.def.coerce)\n return true;\n const def = schema._zod.def;\n switch (def.type) {\n case \"any\":\n case \"unknown\":\n case \"undefined\":\n case \"void\":\n case \"default\":\n case \"prefault\":\n case \"transform\":\n case \"custom\":\n case \"lazy\":\n return true;\n case \"string\":\n case \"number\":\n case \"boolean\":\n case \"bigint\":\n case \"symbol\":\n case \"null\":\n case \"never\":\n case \"nan\":\n case \"date\":\n case \"object\":\n case \"array\":\n case \"tuple\":\n case \"record\":\n case \"map\":\n case \"set\":\n case \"file\":\n case \"template_literal\":\n return false;\n case \"nonoptional\":\n // Normally rejects an absent key, but not when something inside supplies a value for it: `.default(v).optional().nonoptional()` accepts absence and yields v. Defer to the inner \u2014 over-reporting here only costs a presence check, and a fast path that wrongly rejects still falls back to the runtime.\n return def.innerType ? fastPathAcceptsAbsence(def.innerType) : false;\n case \"literal\":\n return !!def.values?.includes(undefined);\n case \"enum\":\n return !!schema._zod.values?.has(undefined);\n case \"optional\":\n case \"nullable\":\n case \"readonly\":\n case \"success\":\n return def.innerType ? fastPathAcceptsAbsence(def.innerType) : true;\n case \"catch\":\n // catch always produces a value (inner may fail \u2192 catchValue substitutes), so it accepts an absent key regardless of inner.\n return true;\n case \"union\":\n return def.options ? def.options.some(fastPathAcceptsAbsence) : true;\n case \"intersection\":\n if (!def.left || !def.right)\n return true;\n return fastPathAcceptsAbsence(def.left) && fastPathAcceptsAbsence(def.right);\n case \"pipe\":\n return def.in ? fastPathAcceptsAbsence(def.in) : true;\n default:\n return true;\n }\n}\n/** The middle rung permits absence without supplying anything in its place, so an absent key contributes nothing \u2014 mirrors the leading gate in `handlePropertyResult`. */\nfunction dropsWhenAbsent(schema) {\n return schema._zod.optin === \"optional\" && schema._zod.optout === \"optional\";\n}\nfunction mayOmitUndefined(schema) {\n return (schema._zod.optin !== \"defaulted\" || schema._zod.optout === \"optional\") && mayOutputUndefined(schema);\n}\n// whether a schema's success-path output can be undefined\nfunction mayOutputUndefined(schema) {\n const def = schema._zod.def;\n switch (def.type) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n case \"bigint\":\n case \"symbol\":\n case \"null\":\n case \"nan\":\n case \"date\":\n case \"object\":\n case \"array\":\n case \"tuple\":\n case \"record\":\n case \"map\":\n case \"set\":\n case \"file\":\n case \"template_literal\":\n case \"never\":\n case \"success\":\n return false;\n case \"literal\":\n return !!def.values?.includes(undefined);\n case \"enum\":\n return !!schema._zod.values?.has(undefined);\n case \"optional\":\n return true;\n case \"nullable\":\n case \"readonly\":\n case \"nonoptional\":\n return def.innerType ? mayOutputUndefined(def.innerType) : true;\n case \"union\":\n return def.options ? def.options.some(mayOutputUndefined) : true;\n case \"intersection\":\n return !def.left || !def.right || mayOutputUndefined(def.left) || mayOutputUndefined(def.right);\n case \"pipe\":\n return def.out ? mayOutputUndefined(def.out) : true;\n default:\n // any/unknown/undefined/void/default/prefault/transform/custom/lazy/catch\n return true;\n }\n}\nfunction generateNullableCheck(doc, ctx, schema, accessor, buildsValue = true) {\n const def = schema._zod.def;\n const outputVar = buildsValue ? newVar(ctx) : null;\n if (outputVar)\n doc.write(`let ${outputVar} = null;`);\n doc.write(`if (${accessor} !== null) {`);\n doc.indented((d) => {\n const innerOutput = generateCheck(d, ctx, def.innerType, accessor, buildsValue);\n if (outputVar && innerOutput !== null)\n d.write(`${outputVar} = ${innerOutput};`);\n });\n doc.write(`}`);\n return outputVar;\n}\nfunction generateSizeGate(doc, schema, size) {\n for (const [max, check] of util.sizeCaps(schema._zod.def.checks)) {\n doc.write(`if (${size} > ${numericOperand(max, check._zod.def.check)}) return INVALID;`);\n }\n}\nfunction generateArrayCheck(doc, ctx, schema, accessor, buildsValue = true) {\n const def = schema._zod.def;\n doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);\n generateSizeGate(doc, schema, `${accessor}.length`);\n // Build a new array with validated/transformed elements.\n const outputVar = buildsValue ? newVar(ctx) : null;\n const iVar = newVar(ctx);\n const elemVar = newVar(ctx);\n if (outputVar)\n doc.write(`const ${outputVar} = new Array(${accessor}.length);`);\n doc.write(`for (let ${iVar} = 0; ${iVar} < ${accessor}.length; ${iVar}++) {`);\n doc.indented((d) => {\n d.write(`const ${elemVar} = ${accessor}[${iVar}];`);\n const elemOutput = compileChild(d, ctx, def.element, elemVar, buildsValue);\n if (outputVar && elemOutput !== null)\n d.write(`${outputVar}[${iVar}] = ${elemOutput};`);\n });\n doc.write(`}`);\n return outputVar;\n}\nfunction generateLiteralCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n const values = def.values;\n // Anything but a single value goes through Set.has: multi-value so every value participates, empty so nothing does \u2014 values[0] would be undefined and compile to an `!== undefined` check that accepts it. Single-value stays inlined for speed.\n if (values.length !== 1) {\n const literalSet = addConstant(ctx, new Set(values));\n doc.write(`if (!${literalSet}.has(${accessor})) return INVALID;`);\n return accessor;\n }\n const value = values[0];\n // `$ZodLiteral` matches with `values.has`, i.e. SameValueZero, so NaN matches itself. `x !== NaN` is true for every input, which would reject everything \u2014 hand it to the same Set form the multi-value path uses.\n if (typeof value === \"number\" && Number.isNaN(value)) {\n const literalSet = addConstant(ctx, new Set(values));\n doc.write(`if (!${literalSet}.has(${accessor})) return INVALID;`);\n return accessor;\n }\n if (typeof value === \"string\") {\n doc.write(`if (${accessor} !== ${util.esc(value)}) return INVALID;`);\n }\n else if (typeof value === \"number\" || typeof value === \"boolean\") {\n doc.write(`if (${accessor} !== ${value}) return INVALID;`);\n }\n else if (value === null) {\n doc.write(`if (${accessor} !== null) return INVALID;`);\n }\n else if (value === undefined) {\n doc.write(`if (${accessor} !== undefined) return INVALID;`);\n }\n else if (typeof value === \"bigint\") {\n doc.write(`if (${accessor} !== ${value}n) return INVALID;`);\n }\n else {\n throw new ZodCompileUnsupportedError(`literal type ${typeof value}`);\n }\n return accessor;\n}\nfunction generateEnumCheck(doc, ctx, schema, accessor) {\n const values = schema._zod.values;\n // z.partialRecord and friends clear `_zod.values`, leaving no set to test membership against. Throw rather than emit INVALID so a union falls back whole instead of counting a false rejection.\n if (!values) {\n throw new ZodCompileUnsupportedError(\"enum schema without enumerated values\");\n }\n const enumSet = addConstant(ctx, values);\n doc.write(`if (!${enumSet}.has(${accessor})) return INVALID;`);\n return accessor;\n}\nfunction generateWrapperCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n return generateCheck(doc, ctx, def.innerType, accessor);\n}\nfunction generateDefaultCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n // `defaultValue` is an accessor on schemas built through the classic/mini\n // factories and a plain data property on ones rebuilt programmatically\n // (deepPartial and friends). Read it off the def either way \u2014 taking only\n // `descriptor.get` silently dropped the default for the second kind, so\n // `.default(v)` compiled to `undefined` instead of `v`.\n const descriptor = Object.getOwnPropertyDescriptor(schema._zod.def, \"defaultValue\");\n const defaultGetter = descriptor\n ? () => schema._zod.def.defaultValue\n : undefined;\n // prefault differs from default: undefined-input is first replaced with the prefault value, then run through the inner schema.\n if (schema._zod.def.type === \"prefault\") {\n if (!defaultGetter) {\n return generateCheck(doc, ctx, def.innerType, accessor);\n }\n const defaultFn = addConstant(ctx, defaultGetter);\n const inputVar = newVar(ctx);\n doc.write(`let ${inputVar} = ${accessor};`);\n doc.write(`if (${accessor} === undefined) ${inputVar} = ${defaultFn}();`);\n return generateCheck(doc, ctx, def.innerType, inputVar);\n }\n const outputVar = newVar(ctx);\n // Default allows undefined (replaces with default value), otherwise validates inner type\n if (defaultGetter) {\n const defaultFn = addConstant(ctx, defaultGetter);\n const cloneFn = addConstant(ctx, util.shallowClone);\n doc.write(`let ${outputVar};`);\n doc.write(`if (${accessor} === undefined) {`);\n doc.indented((d) => {\n // Shallow-clone the default so callers can mutate the result without affecting subsequent parses (#5855 \u2014 also covers Map/Set).\n d.write(`${outputVar} = ${cloneFn}(${defaultFn}());`);\n });\n doc.write(`} else {`);\n doc.indented((d) => {\n const innerOutput = generateCheck(d, ctx, def.innerType, accessor);\n d.write(`${outputVar} = ${innerOutput} === undefined ? ${cloneFn}(${defaultFn}()) : ${innerOutput};`);\n });\n doc.write(`}`);\n }\n else {\n doc.write(`let ${outputVar};`);\n doc.write(`if (${accessor} !== undefined) {`);\n doc.indented((d) => {\n const innerOutput = generateCheck(d, ctx, def.innerType, accessor);\n d.write(`${outputVar} = ${innerOutput};`);\n });\n doc.write(`}`);\n }\n return outputVar;\n}\nfunction generateNonOptionalCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n // The runtime inspects what the inner produced, not what it was given: a catch can turn a defined input into undefined, a default an absent one into a value.\n const innerOutput = generateCheck(doc, ctx, def.innerType, accessor);\n const outputVar = newVar(ctx);\n doc.write(`const ${outputVar} = ${innerOutput};`);\n doc.write(`if (${outputVar} === undefined) return INVALID;`);\n return outputVar;\n}\nfunction generateTupleCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n const items = def.items;\n const rest = def.rest;\n doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);\n // Mirror the runtime's getTupleOptStart: find the first index where every subsequent slot accepts `undefined` (i.e. is optional on input). Anything shorter than this is too_small; trailing absent slots are legal.\n const optinStart = getTupleOptStart(items, \"optin\");\n const optoutStart = getTupleOptStart(items, \"optout\");\n // Length bounds\n if (rest) {\n // With rest: minimum length is the last required input slot\n doc.write(`if (${accessor}.length < ${optinStart}) return INVALID;`);\n }\n else {\n // No rest: input must be in [optinStart, items.length]\n doc.write(`if (${accessor}.length < ${optinStart} || ${accessor}.length > ${items.length}) return INVALID;`);\n }\n // Build the output in assignment order so absent optional-output tail slots can truncate while default/prefault slots still fill missing positions.\n const outputVar = newVar(ctx);\n doc.write(`const ${outputVar} = [];`);\n // Validate and collect each fixed item\n for (let i = 0; i < items.length; i++) {\n const itemSchema = items[i];\n if (i >= optoutStart) {\n doc.write(`if (${outputVar}.length === ${i}) {`);\n doc.indented((d) => {\n d.write(`if (${i} < ${accessor}.length) {`);\n d.indented((d2) => {\n const elemVar = newVar(ctx);\n d2.write(`const ${elemVar} = ${accessor}[${i}];`);\n const elemOutput = compileChild(d2, ctx, itemSchema, elemVar);\n d2.write(`${outputVar}[${i}] = ${elemOutput};`);\n });\n d.write(`} else {`);\n d.indented((d2) => {\n // Middle rung: absence supplies nothing in its place, so truncate rather than running the item on `undefined` and keeping what it invents. Mirrors the leading gate in `handleTupleResults`.\n if (dropsWhenAbsent(itemSchema)) {\n d2.write(`${outputVar}.length = ${i};`);\n return;\n }\n const elemVar = newVar(ctx);\n const branchVar = newVar(ctx);\n d2.write(`const ${elemVar} = undefined;`);\n d2.write(`const ${branchVar} = (() => {`);\n d2.indented((d3) => {\n const elemOutput = compileChild(d3, ctx, itemSchema, elemVar);\n d3.write(`return ${elemOutput};`);\n });\n d2.write(`})();`);\n d2.write(`if (${branchVar} === INVALID || ${branchVar} === undefined) ${outputVar}.length = ${i};`);\n d2.write(`else ${outputVar}[${i}] = ${branchVar};`);\n });\n d.write(`}`);\n });\n doc.write(`}`);\n }\n else {\n const elemVar = newVar(ctx);\n doc.write(`const ${elemVar} = ${accessor}[${i}];`);\n const elemOutput = compileChild(doc, ctx, itemSchema, elemVar);\n doc.write(`${outputVar}[${i}] = ${elemOutput};`);\n }\n }\n // Validate and collect rest elements if present\n if (rest) {\n const iVar = newVar(ctx);\n const elemVar = newVar(ctx);\n doc.write(`for (let ${iVar} = ${items.length}; ${iVar} < ${accessor}.length; ${iVar}++) {`);\n doc.indented((d) => {\n d.write(`const ${elemVar} = ${accessor}[${iVar}];`);\n const elemOutput = compileChild(d, ctx, rest, elemVar);\n d.write(`${outputVar}[${iVar}] = ${elemOutput};`);\n });\n doc.write(`}`);\n }\n return outputVar;\n}\nfunction getTupleOptStart(items, key) {\n for (let i = items.length - 1; i >= 0; i--) {\n // Mirrors the runtime: optin is a three-rung ladder so any rung above `undefined` permits an absent slot; optout stays two-valued.\n const omittable = key === \"optin\" ? items[i]._zod.optin !== undefined : items[i]._zod.optout === \"optional\";\n if (!omittable)\n return i + 1;\n }\n return 0;\n}\nfunction generateUnionCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n const options = def.options;\n if (def.discriminator) {\n return generateDiscriminatedUnionCheck(doc, ctx, def, accessor);\n }\n // z.xor requires *exactly one* option to match. Match-counting in the fast path is only sound if every branch is exactly as strict as the runtime \u2014 any falsely-rejecting branch silently turns a multi-match rejection into an accept. Force the runtime for this rare combinator.\n if (def.inclusive === false) {\n throw new ZodCompileUnsupportedError(\"exclusive unions (z.xor)\");\n }\n if (options.length === 0) {\n doc.write(\"return INVALID;\");\n return accessor;\n }\n if (options.length === 1) {\n return generateCheck(doc, ctx, options[0], accessor);\n }\n // Check if all options are bare literals - use Set optimization. A literal option carrying checks (e.g. .refine) must take the general path or the Set would accept values its checks reject.\n const allLiterals = options.every((opt) => opt._zod.def.type === \"literal\" && !opt._zod.def.checks?.length);\n if (allLiterals) {\n const values = new Set(options.flatMap((opt) => opt._zod.def.values));\n const valuesConst = addConstant(ctx, values);\n doc.write(`if (!${valuesConst}.has(${accessor})) return INVALID;`);\n return accessor;\n }\n // General case: try each option until one succeeds Use IIFEs that return the output or INVALID\n const outputVar = newVar(ctx);\n doc.write(`let ${outputVar};`);\n for (let i = 0; i < options.length; i++) {\n const opt = options[i];\n if (i === 0) {\n doc.write(`${outputVar} = (() => {`);\n }\n else {\n doc.write(`if (${outputVar} === INVALID) ${outputVar} = (() => {`);\n }\n doc.indented((d) => {\n // Generate check inside IIFE - returns INVALID on failure\n const branchOutput = generateCheck(d, ctx, opt, accessor);\n d.write(`return ${branchOutput};`);\n });\n doc.write(`})();`);\n }\n doc.write(`if (${outputVar} === INVALID) return INVALID;`);\n return outputVar;\n}\nfunction generateDiscriminatedUnionCheck(doc, ctx, def, accessor) {\n if (def.unionFallback) {\n throw new ZodCompileUnsupportedError(\"discriminated union with unionFallback\");\n }\n if (def.options.length === 0) {\n doc.write(\"return INVALID;\");\n return accessor;\n }\n const discVar = newVar(ctx);\n const outputVar = newVar(ctx);\n doc.write(`const ${discVar} = ${accessor}?.[${util.esc(def.discriminator)}];`);\n doc.write(`let ${outputVar};`);\n let firstBranch = true;\n const claimed = new Set();\n for (const option of def.options) {\n const values = option._zod.propValues?.[def.discriminator];\n if (!values || values.size === 0) {\n throw new ZodCompileUnsupportedError(\"discriminated union option without static discriminator values\");\n }\n // let the interpreter handle collisions instead of compiling first-match dispatch\n for (const value of values) {\n if (claimed.has(value)) {\n throw new ZodCompileUnsupportedError(`duplicate discriminator value ${String(value)}`);\n }\n claimed.add(value);\n }\n const conditions = Array.from(values, (value) => literalEquality(ctx, discVar, value));\n const prefix = firstBranch ? \"if\" : \"else if\";\n doc.write(`${prefix} (${conditions.join(\" || \")}) {`);\n doc.indented((d) => {\n const branchOutput = generateCheck(d, ctx, option, accessor);\n d.write(`${outputVar} = ${branchOutput};`);\n });\n doc.write(`}`);\n firstBranch = false;\n }\n doc.write(`else { return INVALID; }`);\n return outputVar;\n}\nfunction literalEquality(ctx, accessor, value) {\n if (typeof value === \"string\")\n return `${accessor} === ${util.esc(value)}`;\n if (typeof value === \"number\") {\n if (Number.isNaN(value))\n return `Number.isNaN(${accessor})`;\n return `${accessor} === ${value}`;\n }\n if (typeof value === \"boolean\")\n return `${accessor} === ${value}`;\n if (value === null)\n return `${accessor} === null`;\n if (value === undefined)\n return `${accessor} === undefined`;\n if (typeof value === \"bigint\")\n return `${accessor} === ${value}n`;\n if (typeof value === \"symbol\") {\n const symbolConst = addConstant(ctx, value);\n return `${accessor} === ${symbolConst}`;\n }\n throw new ZodCompileUnsupportedError(`literal discriminator value ${String(value)}`);\n}\nfunction generateIntersectionCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n // An unmergeable merge, and a child failing before the merge is even reached, both return INVALID for a case the interpreter answers with a throw.\n ctx.definite = false;\n const leftOutput = compileChild(doc, ctx, def.left, accessor);\n const rightOutput = compileChild(doc, ctx, def.right, accessor);\n // Hoist the runtime merge helper so recursive object/array merge semantics stay in one place. If the merge is invalid, return INVALID and let the runtime fallback construct canonical errors.\n const mergeConst = addConstant(ctx, mergeValues);\n const mergedVar = newVar(ctx);\n doc.write(`const ${mergedVar} = ${mergeConst}(${leftOutput}, ${rightOutput});`);\n doc.write(`if (!${mergedVar}.valid) return INVALID;`);\n return `${mergedVar}.data`;\n}\nfunction generateRecordCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n // Use util.isPlainObject (rejects Date, Map, Set, class instances, etc.) to match runtime behavior. Hoisted call instead of inline so this stays a single source of truth with the runtime parser.\n const isPlainObjectConst = addConstant(ctx, util.isPlainObject);\n doc.write(`if (!${isPlainObjectConst}(${accessor})) return INVALID;`);\n const outputVar = newVar(ctx);\n const kVar = newVar(ctx);\n const valVar = newVar(ctx);\n doc.write(`const ${outputVar} = {};`);\n // Exhaustive record. The runtime gates this on `values && !def.partial`, since z.partialRecord keeps its value set but makes every key optional; a loose record passes unrecognized keys through, which the per-key scan cannot express.\n const recordDef = def;\n const keyValues = recordDef.partial ? undefined : def.keyType._zod.values;\n if (keyValues) {\n const inputKeys = [];\n for (const key of keyValues) {\n if (!(typeof key === \"string\" || typeof key === \"number\" || typeof key === \"symbol\")) {\n throw new ZodCompileUnsupportedError(`record key value ${String(key)}`);\n }\n const inputKey = typeof key === \"number\" ? key.toString() : key;\n if (inputKey === \"__proto__\") {\n // `out[\"__proto__\"] = v` would hit the prototype setter on the output.\n throw new ZodCompileUnsupportedError('record key \"__proto__\"');\n }\n inputKeys.push(inputKey);\n const keyConst = addConstant(ctx, key);\n const outKey = generateCheck(doc, ctx, def.keyType, keyConst);\n // Read the property once. Passing the raw expression let compileChild validate one read while the output write performed a second, so a getter could hand back a value nothing had checked.\n const valueVar = newVar(ctx);\n doc.write(`const ${valueVar} = ${accessor}[${literalPropertyKey(ctx, inputKey)}];`);\n const valOutput = compileChild(doc, ctx, def.valueType, valueVar);\n doc.write(`${outputVar}[${outKey}] = ${valOutput};`);\n }\n // `mode: \"loose\"` changes only what happens to unrecognized keys, so it belongs here rather than the per-present-key scan. Passing them through matches the runtime, which skips `__proto__`.\n const knownKeysConst = addConstant(ctx, new Set(inputKeys));\n doc.write(`for (const ${kVar} in ${accessor}) {`);\n doc.indented((d) => {\n d.write(`if (${knownKeysConst}.has(${kVar})) continue;`);\n if (recordDef.mode === \"loose\") {\n d.write(`if (${kVar} !== \"__proto__\") ${outputVar}[${kVar}] = ${accessor}[${kVar}];`);\n }\n else {\n d.write(`return INVALID;`);\n }\n });\n doc.write(`}`);\n return outputVar;\n }\n // The bare-string shortcut below only tests `typeof key === \"string\"`, so it\n // is correct exclusively for a `z.string()` carrying nothing else. A string\n // *format* lives on the def rather than in `checks` \u2014 `z.record(z.email(), \u2026)`\n // reads as a plain string here \u2014 and coercion rewrites the key, so both have\n // to take the general path or the shortcut accepts keys the runtime rejects.\n const keyDef = def.keyType._zod.def;\n const keyIsBareString = keyDef.type === \"string\" && keyDef.format === undefined && !keyDef.coerce && (keyDef.checks?.length ?? 0) === 0;\n if (!keyIsBareString) {\n // A key schema with no value set is a constraint every key must satisfy\n // (`z.email()`, `z.string().min(3)`, `z.number()`, a template literal).\n // The runtime runs it against each own enumerable key and writes the value\n // under the key it produced, so compile it once and call it per key.\n const isLoose = def.mode === \"loose\";\n // the key compiles in its own context, so carry its verdict out: a key schema that can answer INVALID undecidably makes this validator undecidable too\n const keyFn = compileFn(def.keyType);\n if (keyFn.definite === false)\n ctx.definite = false;\n const keyFast = addConstant(ctx, keyFn);\n const numericConst = addConstant(ctx, regexes.number);\n const outKeyVar = newVar(ctx);\n // the body runs once per string key and once per symbol key, since a key schema can accept symbols\n emitOwnKeys(doc, ctx, accessor, kVar, (d) => {\n d.write(`let ${outKeyVar} = ${keyFast}(${kVar});`);\n // Numeric-string retry, mirroring the runtime: a key the schema rejects as a string is tried again as a number, so z.record(z.number(), \u2026) matches the numeric keys JavaScript stringified on the way in.\n d.write(`if (${outKeyVar} === INVALID && typeof ${kVar} === \"string\" && ${numericConst}.test(${kVar})) ${outKeyVar} = ${keyFast}(Number(${kVar}));`);\n if (isLoose) {\n // A loose record keeps a key its schema rejects, copying the value across unvalidated rather than failing the parse.\n d.write(`if (${outKeyVar} === INVALID) { ${outputVar}[${kVar}] = ${accessor}[${kVar}]; continue; }`);\n }\n else {\n d.write(`if (${outKeyVar} === INVALID) return INVALID;`);\n }\n // The guard above tested the input key, but the schema can normalize an ordinary key into __proto__; re-check the one actually written under.\n d.write(`if (${outKeyVar} === \"__proto__\") continue;`);\n // Read once: the raw expression would be evaluated again by the output write below, so an accessor could return an unvalidated second value.\n const valueVar = newVar(ctx);\n d.write(`const ${valueVar} = ${accessor}[${kVar}];`);\n const valOutput = compileChild(d, ctx, def.valueType, valueVar);\n d.write(`${outputVar}[${outKeyVar}] = ${valOutput};`);\n });\n return outputVar;\n }\n // Plain z.string() keys: every own enumerable string key's value is validated, and an own enumerable symbol key fails the string key schema, as it does in the runtime's Reflect.ownKeys walk.\n emitOwnKeys(doc, ctx, accessor, kVar, (d) => {\n d.write(`const ${valVar} = ${accessor}[${kVar}];`);\n const valOutput = compileChild(d, ctx, def.valueType, valVar);\n d.write(`${outputVar}[${kVar}] = ${valOutput};`);\n }, `return INVALID;`);\n return outputVar;\n}\n// Walks the own enumerable keys of a plain object in Reflect.ownKeys order \u2014 strings from getOwnPropertyNames, then symbols \u2014 instead of Reflect.ownKeys, whose accumulator made that walk 3\u20136x the cost of the loop it fed. Both snapshots are taken before any value is read and every key is rechecked with propertyIsEnumerable when visited, exactly the runtime's walk, so a getter that adds, deletes, hides or reveals a key mid-walk sees the runtime's verdict; for-in and Object.keys were no faster and each lost a case (for-in enumerates the prototype chain after the own keys, Object.keys drops a key that is non-enumerable at snapshot time). `body` is written once for the string loop and once for the symbol loop unless `onSymbol` replaces the latter.\nfunction emitOwnKeys(doc, ctx, accessor, kVar, body, onSymbol) {\n const propIsEnumerableConst = addConstant(ctx, Object.prototype.propertyIsEnumerable);\n const symsVar = newVar(ctx);\n const keysVar = newVar(ctx);\n const iVar = newVar(ctx);\n doc.write(`const ${symsVar} = Object.getOwnPropertySymbols(${accessor});`);\n doc.write(`const ${keysVar} = Object.getOwnPropertyNames(${accessor});`);\n doc.write(`for (let ${iVar} = 0; ${iVar} < ${keysVar}.length; ${iVar}++) {`);\n doc.indented((d) => {\n d.write(`const ${kVar} = ${keysVar}[${iVar}];`);\n d.write(`if (${kVar} === \"__proto__\" || !${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);\n body(d);\n });\n doc.write(`}`);\n doc.write(`for (let ${iVar} = 0; ${iVar} < ${symsVar}.length; ${iVar}++) {`);\n doc.indented((d) => {\n d.write(`const ${kVar} = ${symsVar}[${iVar}];`);\n d.write(`if (!${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);\n if (onSymbol)\n d.write(onSymbol);\n else\n body(d);\n });\n doc.write(`}`);\n}\nfunction literalPropertyKey(ctx, key) {\n if (typeof key === \"string\")\n return util.esc(key);\n return addConstant(ctx, key);\n}\nfunction generateMapCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n doc.write(`if (!(${accessor} instanceof Map)) return INVALID;`);\n generateSizeGate(doc, schema, `${accessor}.size`);\n const outputVar = newVar(ctx);\n const kVar = newVar(ctx);\n const valVar = newVar(ctx);\n doc.write(`const ${outputVar} = new Map();`);\n doc.write(`for (const [${kVar}, ${valVar}] of ${accessor}) {`);\n doc.indented((d) => {\n const keyOutput = generateCheck(d, ctx, def.keyType, kVar);\n const valOutput = generateCheck(d, ctx, def.valueType, valVar);\n d.write(`${outputVar}.set(${keyOutput}, ${valOutput});`);\n });\n doc.write(`}`);\n return outputVar;\n}\nfunction generateSetCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n doc.write(`if (!(${accessor} instanceof Set)) return INVALID;`);\n generateSizeGate(doc, schema, `${accessor}.size`);\n const outputVar = newVar(ctx);\n const valVar = newVar(ctx);\n doc.write(`const ${outputVar} = new Set();`);\n doc.write(`for (const ${valVar} of ${accessor}) {`);\n doc.indented((d) => {\n const valOutput = generateCheck(d, ctx, def.valueType, valVar);\n d.write(`${outputVar}.add(${valOutput});`);\n });\n doc.write(`}`);\n return outputVar;\n}\nfunction generateFileCheck(doc, accessor) {\n // Runtime $ZodFile is a bare `instanceof File`, including the implicit global lookup. The previous duck-typed fallback accepted arbitrary {name, size} objects in File-less environments \u2014 behavior the runtime never had.\n doc.write(`if (!(${accessor} instanceof File)) return INVALID;`);\n return accessor;\n}\nfunction generateTemplateLiteralCheck(doc, ctx, schema, accessor) {\n doc.write(`if (typeof ${accessor} !== \"string\") return INVALID;`);\n // Template literal schemas have a pre-computed pattern in _zod.pattern\n const pattern = schema._zod.pattern;\n if (pattern) {\n const patternConst = addConstant(ctx, pattern);\n doc.write(`${patternConst}.lastIndex = 0;`);\n doc.write(`if (!${patternConst}.test(${accessor})) return INVALID;`);\n }\n return accessor;\n}\nfunction generateLazyCheck(doc, ctx, schema, accessor) {\n // For lazy schemas, we use a cached parser that falls back to runtime Zod parsing This handles recursive schemas correctly by avoiding infinite compilation loops\n const def = schema._zod.def;\n const getterConst = addUserConstant(ctx, def.getter);\n const cacheConst = addConstant(ctx, { parser: null });\n doc.write(`if (!${cacheConst}.parser) {`);\n doc.indented((d) => {\n d.write(`const inner = ${getterConst}();`);\n d.write(`${cacheConst}.parser = function(input) {`);\n d.indented((d2) => {\n // Use runtime Zod parsing - this correctly handles recursive schemas Pass an empty ctx like runtimeRun does \u2014 runtime parsers read ctx.skipChecks/ctx.direction unconditionally and crash on undefined.\n d2.write(`const result = inner._zod.run({ value: input, issues: [] }, {});`);\n d2.write(`return result.issues.length === 0 ? result.value : INVALID;`);\n });\n d.write(`};`);\n });\n doc.write(`}`);\n const outputVar = newVar(ctx);\n doc.write(`const ${outputVar} = ${cacheConst}.parser(${accessor});`);\n doc.write(`if (${outputVar} === INVALID) return INVALID;`);\n return outputVar;\n}\nfunction generatePipeCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n // Validate input type first\n const inputOutput = generateCheck(doc, ctx, def.in, accessor);\n if (def.transform) {\n // Apply transform and validate output. The transform may read its second `payload` argument (codec transforms like z.stringbool() push issues there) so wrap the call in a helper that spoofs a payload. Pushed issues signal INVALID and the wrapper falls back to the runtime, and a plain function handing back a promise answers INVALID too \u2014 union parity, but not a decidable rejection at the top level.\n if (isAsyncFunction(def.transform)) {\n throw new ZodCompileAsyncError(\"z.compile: async transforms in pipes are not supported\");\n }\n const transformFn = def.transform;\n const helperFn = (value) => {\n // `addIssue` has to be here: a transform reporting through it is reporting, not failing. Without it the call threw a TypeError that the old catch swallowed into a fallback, so every ctx.addIssue transform quietly lost its fast path and the real error was never visible.\n const fakePayload = { value, issues: [], addIssue: pushIssue };\n // A throw is deliberately not caught. The interpreter lets one propagate out of the whole parse; swallowing it into INVALID turned a thrown error into a merely-rejected union branch, so a later branch answered instead.\n const result = transformFn(value, fakePayload);\n if (result instanceof Promise)\n return INVALID;\n return fakePayload.issues.length === 0 ? result : INVALID;\n };\n const helperConst = addUserConstant(ctx, helperFn);\n const transformedVar = newVar(ctx);\n doc.write(`const ${transformedVar} = ${helperConst}(${inputOutput});`);\n doc.write(`if (${transformedVar} === INVALID) return INVALID;`);\n return generateCheck(doc, ctx, def.out, transformedVar);\n }\n else {\n // No transform - validate output type on same value\n return generateCheck(doc, ctx, def.out, inputOutput);\n }\n}\nfunction isAsyncFunction(fn) {\n return (typeof fn === \"function\" &&\n (fn.constructor.name === \"AsyncFunction\" ||\n fn[Symbol.toStringTag] === \"AsyncFunction\"));\n}\nfunction generateCustomCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n if (def.fn) {\n // Check for async function\n if (isAsyncFunction(def.fn)) {\n throw new ZodCompileAsyncError(\"z.compile: async custom predicates are not supported\");\n }\n // Custom schema with a predicate function (e.g. z.instanceof). `isAsyncFunction` above is syntactic, so a plain function returning a promise reaches here, and a promise is truthy \u2014 it would read as a pass where the interpreter throws.\n const fnConst = addUserConstant(ctx, def.fn);\n const throwAsyncConst = addConstant(ctx, throwAsync);\n const resVar = newVar(ctx);\n doc.write(`const ${resVar} = ${fnConst}(${accessor});`);\n doc.write(`if (${resVar} instanceof Promise) ${throwAsyncConst}();`);\n doc.write(`if (!${resVar}) return INVALID;`);\n }\n else {\n throw new ZodCompileUnsupportedError(\"custom schema without a predicate function\");\n }\n return accessor;\n}\n// Runtime helper for a compiled `catch`: runs the inner schema once and returns its value when it succeeded. Anything else \u2014 a failure the catch would handle, or an async inner \u2014 returns INVALID so the interpreter takes over.\nfunction runtimeCatch(innerSchema, catchValue, value) {\n const result = innerSchema._zod.run({ value, issues: [] }, {});\n if (result && typeof result.then === \"function\")\n return INVALID;\n const r = result;\n if (r.issues.length === 0)\n return r.value;\n // Only reached for a catch value that ignores the parse context \u2014 codegen refuses the rest \u2014 so there are no issues to finalize and nothing here needs the caller's error map.\n return catchValue();\n}\nfunction generateCatchCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n // An untagged catchValue is a user callback, and one reading `ctx.error` needs the caller's per-parse error map. Catch *succeeds*, so a wrong message there is unobservable \u2014 refuse at codegen, and not islandable either, since `runtimeRun` has no context to hand it.\n if (!def.catchValue[util.CONSTANT_CATCH]) {\n throw new ZodCompileUnsupportedError(\"catch with a callback (only a constant catch value compiles)\", false);\n }\n const outputVar = newVar(ctx);\n doc.write(`let ${outputVar} = (() => {`);\n doc.indented((d) => {\n const innerOut = compileChild(d, ctx, def.innerType, accessor);\n d.write(`return ${innerOut};`);\n });\n doc.write(`})();`);\n const innerConst = addConstant(ctx, def.innerType);\n const catchConst = addUserConstant(ctx, def.catchValue);\n const catchHelperConst = addConstant(ctx, runtimeCatch);\n doc.write(`if (${outputVar} === INVALID) {`);\n doc.indented((d) => {\n d.write(`${outputVar} = ${catchHelperConst}(${innerConst}, ${catchConst}, ${accessor});`);\n d.write(`if (${outputVar} === INVALID) return INVALID;`);\n });\n doc.write(`}`);\n return outputVar;\n}\nfunction generateTransformCheck(doc, ctx, schema, accessor) {\n const def = schema._zod.def;\n if (def.transform) {\n // Check for async transform\n if (isAsyncFunction(def.transform)) {\n throw new ZodCompileAsyncError(\"z.compile: async transforms are not supported\");\n }\n // Create a helper that runs the transform and returns the result or INVALID on error\n const transformFn = def.transform;\n const helperFn = (value) => {\n const fakePayload = { value, issues: [], addIssue: pushIssue };\n // As in the pipe helper: a throw propagates, because the interpreter lets it out of the whole parse rather than treating it as a failed branch.\n const result = transformFn(value, fakePayload);\n if (result instanceof Promise)\n return INVALID;\n return fakePayload.issues.length === 0 ? result : INVALID;\n };\n const helperConst = addUserConstant(ctx, helperFn);\n const outputVar = newVar(ctx);\n doc.write(`const ${outputVar} = ${helperConst}(${accessor});`);\n doc.write(`if (${outputVar} === INVALID) return INVALID;`);\n return outputVar;\n }\n return accessor;\n}\n", "import * as checks from \"./checks.js\";\nimport * as registries from \"./registries.js\";\nimport * as schemas from \"./schemas.js\";\nimport * as util from \"./util.js\";\nfunction snapshotChecks(def) {\n if (def.checks)\n def.checks = [...def.checks];\n return def;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _string(Class, params) {\n return new Class(snapshotChecks({ type: \"string\", ...util.normalizeParams(params) }));\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedString(Class, params) {\n return new Class(snapshotChecks({ type: \"string\", coerce: true, ...util.normalizeParams(params) }));\n}\n// @__NO_SIDE_EFFECTS__\nexport function _email(Class, params) {\n return new Class({\n type: \"string\",\n format: \"email\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _guid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"guid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uuid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"uuid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uuidv4(Class, params) {\n return new Class({\n type: \"string\",\n format: \"uuid\",\n check: \"string_format\",\n abort: false,\n version: \"v4\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uuidv6(Class, params) {\n return new Class({\n type: \"string\",\n format: \"uuid\",\n check: \"string_format\",\n abort: false,\n version: \"v6\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uuidv7(Class, params) {\n return new Class({\n type: \"string\",\n format: \"uuid\",\n check: \"string_format\",\n abort: false,\n version: \"v7\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _url(Class, params) {\n return new Class({\n type: \"string\",\n format: \"url\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _emoji(Class, params) {\n return new Class({\n type: \"string\",\n format: \"emoji\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _nanoid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"nanoid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n/**\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link _cuid2} instead.\n * See https://github.com/paralleldrive/cuid.\n */\n// @__NO_SIDE_EFFECTS__\nexport function _cuid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"cuid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _cuid2(Class, params) {\n return new Class({\n type: \"string\",\n format: \"cuid2\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _ulid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"ulid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _xid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"xid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _ksuid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"ksuid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _ipv4(Class, params) {\n return new Class({\n type: \"string\",\n format: \"ipv4\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _ipv6(Class, params) {\n return new Class({\n type: \"string\",\n format: \"ipv6\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _mac(Class, params) {\n return new Class({\n type: \"string\",\n format: \"mac\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _cidrv4(Class, params) {\n return new Class({\n type: \"string\",\n format: \"cidrv4\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _cidrv6(Class, params) {\n return new Class({\n type: \"string\",\n format: \"cidrv6\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _base64(Class, params) {\n return new Class({\n type: \"string\",\n format: \"base64\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _base64url(Class, params) {\n return new Class({\n type: \"string\",\n format: \"base64url\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _e164(Class, params) {\n return new Class({\n type: \"string\",\n format: \"e164\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _creditCard(Class, params) {\n return new Class({\n type: \"string\",\n format: \"credit_card\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _iban(Class, params) {\n return new Class({\n type: \"string\",\n format: \"iban\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _jwt(Class, params) {\n return new Class({\n type: \"string\",\n format: \"jwt\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\nexport const TimePrecision = {\n Any: null,\n Minute: -1,\n Second: 0,\n Millisecond: 3,\n Microsecond: 6,\n};\n// @__NO_SIDE_EFFECTS__\nexport function _isoDateTime(Class, params) {\n return new Class({\n type: \"string\",\n format: \"datetime\",\n check: \"string_format\",\n offset: false,\n local: false,\n precision: null,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _isoDate(Class, params) {\n return new Class({\n type: \"string\",\n format: \"date\",\n check: \"string_format\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _isoTime(Class, params) {\n return new Class({\n type: \"string\",\n format: \"time\",\n check: \"string_format\",\n precision: null,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _isoDuration(Class, params) {\n return new Class({\n type: \"string\",\n format: \"duration\",\n check: \"string_format\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _number(Class, params) {\n return new Class(snapshotChecks({ type: \"number\", checks: [], ...util.normalizeParams(params) }));\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedNumber(Class, params) {\n return new Class(snapshotChecks({ type: \"number\", coerce: true, checks: [], ...util.normalizeParams(params) }));\n}\n// @__NO_SIDE_EFFECTS__\nexport function _int(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"safeint\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _float32(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"float32\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _float64(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"float64\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _int32(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"int32\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uint32(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"uint32\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _boolean(Class, params) {\n return new Class({\n type: \"boolean\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedBoolean(Class, params) {\n return new Class({\n type: \"boolean\",\n coerce: true,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _bigint(Class, params) {\n return new Class({\n type: \"bigint\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedBigint(Class, params) {\n return new Class({\n type: \"bigint\",\n coerce: true,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _int64(Class, params) {\n return new Class({\n type: \"bigint\",\n check: \"bigint_format\",\n abort: false,\n format: \"int64\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uint64(Class, params) {\n return new Class({\n type: \"bigint\",\n check: \"bigint_format\",\n abort: false,\n format: \"uint64\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _symbol(Class, params) {\n return new Class({\n type: \"symbol\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _undefined(Class, params) {\n return new Class({\n type: \"undefined\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _null(Class, params) {\n return new Class({\n type: \"null\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _any(Class) {\n return new Class({\n type: \"any\",\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _unknown(Class) {\n return new Class({\n type: \"unknown\",\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _never(Class, params) {\n return new Class({\n type: \"never\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _void(Class, params) {\n return new Class({\n type: \"void\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _date(Class, params) {\n return new Class({\n type: \"date\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedDate(Class, params) {\n return new Class({\n type: \"date\",\n coerce: true,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _nan(Class, params) {\n return new Class({\n type: \"nan\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _lt(value, params) {\n return new checks.$ZodCheckLessThan({\n check: \"less_than\",\n ...util.normalizeParams(params),\n value,\n inclusive: false,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _lte(value, params) {\n return new checks.$ZodCheckLessThan({\n check: \"less_than\",\n ...util.normalizeParams(params),\n value,\n inclusive: true,\n });\n}\nexport { \n/** @deprecated Use `z.lte()` instead. */\n_lte as _max, };\n// @__NO_SIDE_EFFECTS__\nexport function _gt(value, params) {\n return new checks.$ZodCheckGreaterThan({\n check: \"greater_than\",\n ...util.normalizeParams(params),\n value,\n inclusive: false,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _gte(value, params) {\n return new checks.$ZodCheckGreaterThan({\n check: \"greater_than\",\n ...util.normalizeParams(params),\n value,\n inclusive: true,\n });\n}\nexport { \n/** @deprecated Use `z.gte()` instead. */\n_gte as _min, };\n// @__NO_SIDE_EFFECTS__\nexport function _positive(params) {\n return _gt(0, params);\n}\n// negative\n// @__NO_SIDE_EFFECTS__\nexport function _negative(params) {\n return _lt(0, params);\n}\n// nonpositive\n// @__NO_SIDE_EFFECTS__\nexport function _nonpositive(params) {\n return _lte(0, params);\n}\n// nonnegative\n// @__NO_SIDE_EFFECTS__\nexport function _nonnegative(params) {\n return _gte(0, params);\n}\n// @__NO_SIDE_EFFECTS__\nexport function _multipleOf(value, params) {\n return new checks.$ZodCheckMultipleOf({\n check: \"multiple_of\",\n ...util.normalizeParams(params),\n value,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _maxSize(maximum, params) {\n return new checks.$ZodCheckMaxSize({\n check: \"max_size\",\n ...util.normalizeParams(params),\n maximum,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _minSize(minimum, params) {\n return new checks.$ZodCheckMinSize({\n check: \"min_size\",\n ...util.normalizeParams(params),\n minimum,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _size(size, params) {\n return new checks.$ZodCheckSizeEquals({\n check: \"size_equals\",\n ...util.normalizeParams(params),\n size,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _maxLength(maximum, params) {\n const ch = new checks.$ZodCheckMaxLength({\n check: \"max_length\",\n ...util.normalizeParams(params),\n maximum,\n });\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _minLength(minimum, params) {\n return new checks.$ZodCheckMinLength({\n check: \"min_length\",\n ...util.normalizeParams(params),\n minimum,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _length(length, params) {\n return new checks.$ZodCheckLengthEquals({\n check: \"length_equals\",\n ...util.normalizeParams(params),\n length,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _regex(pattern, params) {\n return new checks.$ZodCheckRegex({\n check: \"string_format\",\n format: \"regex\",\n ...util.normalizeParams(params),\n pattern,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _lowercase(params) {\n return new checks.$ZodCheckLowerCase({\n check: \"string_format\",\n format: \"lowercase\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uppercase(params) {\n return new checks.$ZodCheckUpperCase({\n check: \"string_format\",\n format: \"uppercase\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _includes(includes, params) {\n return new checks.$ZodCheckIncludes({\n check: \"string_format\",\n format: \"includes\",\n ...util.normalizeParams(params),\n includes,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _startsWith(prefix, params) {\n return new checks.$ZodCheckStartsWith({\n check: \"string_format\",\n format: \"starts_with\",\n ...util.normalizeParams(params),\n prefix,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _endsWith(suffix, params) {\n return new checks.$ZodCheckEndsWith({\n check: \"string_format\",\n format: \"ends_with\",\n ...util.normalizeParams(params),\n suffix,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _property(property, schema, params) {\n return new checks.$ZodCheckProperty({\n check: \"property\",\n property,\n schema,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _properties(shape, params) {\n return new checks.$ZodCheckProperties({\n check: \"properties\",\n shape,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _mime(types, params) {\n return new checks.$ZodCheckMimeType({\n check: \"mime_type\",\n mime: types,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _overwrite(tx) {\n return new checks.$ZodCheckOverwrite({\n check: \"overwrite\",\n tx,\n });\n}\n// normalize\n// @__NO_SIDE_EFFECTS__\nexport function _normalize(form) {\n return _overwrite((input) => input.normalize(form));\n}\n// trim\n// @__NO_SIDE_EFFECTS__\nexport function _trim() {\n return _overwrite((input) => input.trim());\n}\n// toLowerCase\n// @__NO_SIDE_EFFECTS__\nexport function _toLowerCase() {\n return _overwrite((input) => input.toLowerCase());\n}\n// toUpperCase\n// @__NO_SIDE_EFFECTS__\nexport function _toUpperCase() {\n return _overwrite((input) => input.toUpperCase());\n}\n// slugify\n// @__NO_SIDE_EFFECTS__\nexport function _slugify() {\n return _overwrite((input) => util.slugify(input));\n}\n// @__NO_SIDE_EFFECTS__\nexport function _array(Class, element, params) {\n return new Class({\n type: \"array\",\n element,\n // get element() {\n // return element;\n // },\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _union(Class, options, params) {\n return new Class({\n type: \"union\",\n options,\n ...util.normalizeParams(params),\n });\n}\nexport function _xor(Class, options, params) {\n return new Class({\n type: \"union\",\n options,\n inclusive: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _discriminatedUnion(Class, discriminator, options, params) {\n return new Class({\n type: \"union\",\n options: options,\n discriminator,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _intersection(Class, left, right) {\n return new Class({\n type: \"intersection\",\n left,\n right,\n });\n}\n// export function _tuple(\n// Class: util.SchemaClass,\n// items: [],\n// params?: string | $ZodTupleParams\n// ): schemas.$ZodTuple<[], null>;\n// @__NO_SIDE_EFFECTS__\nexport function _tuple(Class, items, _paramsOrRest, _params) {\n const hasRest = _paramsOrRest instanceof schemas.$ZodType;\n const params = hasRest ? _params : _paramsOrRest;\n const rest = hasRest ? _paramsOrRest : null;\n return new Class({\n type: \"tuple\",\n items,\n rest,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _record(Class, keyType, valueType, params) {\n return new Class({\n type: \"record\",\n keyType,\n valueType,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _map(Class, keyType, valueType, params) {\n return new Class({\n type: \"map\",\n keyType,\n valueType,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _set(Class, valueType, params) {\n return new Class({\n type: \"set\",\n valueType,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _enum(Class, values, params) {\n const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values;\n // if (Array.isArray(values)) {\n // for (const value of values) {\n // entries[value] = value;\n // }\n // } else {\n // Object.assign(entries, values);\n // }\n // const entries: util.EnumLike = {};\n // for (const val of values) {\n // entries[val] = val;\n // }\n return new Class({\n type: \"enum\",\n entries,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\n/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead.\n *\n * ```ts\n * enum Colors { red, green, blue }\n * z.enum(Colors);\n * ```\n */\nexport function _nativeEnum(Class, entries, params) {\n return new Class({\n type: \"enum\",\n entries,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _literal(Class, value, params) {\n return new Class({\n type: \"literal\",\n values: Array.isArray(value) ? value : [value],\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _file(Class, params) {\n return new Class({\n type: \"file\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _transform(Class, fn) {\n return new Class({\n type: \"transform\",\n transform: fn,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _optional(Class, innerType) {\n return new Class({\n type: \"optional\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _nullable(Class, innerType) {\n return new Class({\n type: \"nullable\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _default(Class, innerType, defaultValue) {\n return new Class({\n type: \"default\",\n innerType,\n get defaultValue() {\n return typeof defaultValue === \"function\" ? defaultValue() : util.shallowClone(defaultValue);\n },\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _nonoptional(Class, innerType, params) {\n return new Class({\n type: \"nonoptional\",\n innerType,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _success(Class, innerType) {\n return new Class({\n type: \"success\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _catch(Class, innerType, catchValue) {\n return new Class({\n type: \"catch\",\n innerType,\n catchValue: (typeof catchValue === \"function\" ? catchValue : util.constantCatch(catchValue)),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _pipe(Class, in_, out) {\n return new Class({\n type: \"pipe\",\n in: in_,\n out,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _readonly(Class, innerType) {\n return new Class({\n type: \"readonly\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _templateLiteral(Class, parts, params) {\n return new Class({\n type: \"template_literal\",\n parts,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _lazy(Class, getter) {\n return new Class({\n type: \"lazy\",\n getter,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _promise(Class, innerType) {\n return new Class({\n type: \"promise\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _custom(Class, fn, _params) {\n const norm = util.normalizeParams(_params);\n norm.abort ?? (norm.abort = true); // default to abort:false\n const schema = new Class({\n type: \"custom\",\n check: \"custom\",\n fn: fn,\n ...norm,\n });\n return schema;\n}\n// same as _custom but defaults to abort:false\n// @__NO_SIDE_EFFECTS__\nexport function _refine(Class, fn, _params) {\n const schema = new Class({\n type: \"custom\",\n check: \"custom\",\n fn: fn,\n ...util.normalizeParams(_params),\n });\n return schema;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _superRefine(fn, params) {\n const ch = _check((payload) => {\n payload.addIssue = (issue) => {\n if (typeof issue === \"string\") {\n payload.issues.push(util.issue(issue, payload.value, ch._zod.def));\n }\n else {\n // for Zod 3 backwards compatibility\n const _issue = issue;\n if (_issue.fatal)\n _issue.continue = false;\n _issue.code ?? (_issue.code = \"custom\");\n if (!(\"input\" in _issue))\n _issue.input = payload.value;\n _issue.inst ?? (_issue.inst = ch);\n _issue.continue ?? (_issue.continue = !ch._zod.def.abort); // abort is always undefined, so this is always true...\n payload.issues.push(util.issue(_issue));\n }\n };\n return fn(payload.value, payload);\n }, params);\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _check(fn, params) {\n const ch = new checks.$ZodCheck({\n check: \"custom\",\n ...util.normalizeParams(params),\n });\n ch._zod.check = fn;\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function describe(description) {\n const ch = new checks.$ZodCheck({ check: \"describe\" });\n ch._zod.onattach = [\n (inst) => {\n const existing = registries.globalRegistry.get(inst) ?? {};\n registries.globalRegistry.add(inst, { ...existing, description });\n },\n ];\n ch._zod.check = () => { }; // no-op check\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function meta(metadata) {\n const ch = new checks.$ZodCheck({ check: \"meta\" });\n ch._zod.onattach = [\n (inst) => {\n const existing = registries.globalRegistry.get(inst) ?? {};\n registries.globalRegistry.add(inst, { ...existing, ...metadata });\n },\n ];\n ch._zod.check = () => { }; // no-op check\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _stringbool(Classes, _params) {\n const params = util.normalizeParams(_params);\n let truthyArray = params.truthy ?? [\"true\", \"1\", \"yes\", \"on\", \"y\", \"enabled\"];\n let falsyArray = params.falsy ?? [\"false\", \"0\", \"no\", \"off\", \"n\", \"disabled\"];\n if (params.case !== \"sensitive\") {\n truthyArray = truthyArray.map((v) => (typeof v === \"string\" ? v.toLowerCase() : v));\n falsyArray = falsyArray.map((v) => (typeof v === \"string\" ? v.toLowerCase() : v));\n }\n const truthySet = new Set(truthyArray);\n const falsySet = new Set(falsyArray);\n const _Codec = Classes.Codec ?? schemas.$ZodCodec;\n const _Boolean = Classes.Boolean ?? schemas.$ZodBoolean;\n const _String = Classes.String ?? schemas.$ZodString;\n const stringSchema = new _String({ type: \"string\", error: params.error });\n const booleanSchema = new _Boolean({ type: \"boolean\", error: params.error });\n const codec = new _Codec({\n type: \"pipe\",\n in: stringSchema,\n out: booleanSchema,\n transform: ((input, payload) => {\n let data = input;\n if (params.case !== \"sensitive\")\n data = data.toLowerCase();\n if (truthySet.has(data)) {\n return true;\n }\n else if (falsySet.has(data)) {\n return false;\n }\n else {\n payload.issues.push({\n code: \"invalid_value\",\n expected: \"stringbool\",\n values: [...truthySet, ...falsySet],\n input: payload.value,\n inst: codec,\n continue: false,\n });\n return {};\n }\n }),\n reverseTransform: ((input, _payload) => {\n if (input === true) {\n return truthyArray[0] || \"true\";\n }\n else {\n return falsyArray[0] || \"false\";\n }\n }),\n error: params.error,\n });\n codec._zod.bag.truthy = truthyArray;\n codec._zod.bag.falsy = falsyArray;\n codec._zod.bag.case = params.case ?? \"insensitive\";\n return codec;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _stringFormat(Class, format, fnOrRegex, _params = {}) {\n const params = util.normalizeParams(_params);\n const def = {\n check: \"string_format\",\n type: \"string\",\n format,\n fn: typeof fnOrRegex === \"function\" ? fnOrRegex : (val) => fnOrRegex.test(val),\n ...params,\n };\n if (fnOrRegex instanceof RegExp) {\n def.pattern = fnOrRegex;\n }\n const inst = new Class(def);\n return inst;\n}\n", "import { globalRegistry } from \"./registries.js\";\nimport { assignProp } from \"./util.js\";\nfunction assignProps(target, ...sources) {\n for (const source of sources) {\n for (const key of Reflect.ownKeys(source)) {\n if (Object.prototype.propertyIsEnumerable.call(source, key)) {\n assignProp(target, key, source[key]);\n }\n }\n }\n return target;\n}\n// function initializeContext(inputs: JSONSchemaGeneratorParams): ToJSONSchemaContext {\n// return {\n// processor: inputs.processor,\n// metadataRegistry: inputs.metadata ?? globalRegistry,\n// target: inputs.target ?? \"draft-2020-12\",\n// unrepresentable: inputs.unrepresentable ?? \"throw\",\n// };\n// }\nexport function initializeContext(params) {\n // Normalize target: convert old non-hyphenated versions to hyphenated versions\n let target = params?.target ?? \"draft-2020-12\";\n if (target === \"draft-4\")\n target = \"draft-04\";\n if (target === \"draft-7\")\n target = \"draft-07\";\n return {\n processors: params.processors ?? {},\n metadataRegistry: params?.metadata ?? globalRegistry,\n target,\n unrepresentable: params?.unrepresentable ?? \"throw\",\n override: params?.override ?? (() => { }),\n io: params?.io ?? \"output\",\n counter: 0,\n seen: new Map(),\n sharedDefsExtractedFor: undefined,\n sharedEmitDoneFor: undefined,\n cycles: params?.cycles ?? \"ref\",\n reused: params?.reused ?? \"inline\",\n intersections: [],\n deferred: [],\n external: params?.external ?? undefined,\n };\n}\n/**\n * Applies the `unrepresentable` setting at a site that has no JSON Schema equivalent. Throws\n * `message` unless the setting (or the handler's return value) says otherwise. Returns `true` if a\n * custom JSON Schema was written into `json`, in which case the caller must not write its own.\n */\nexport function handleUnrepresentable(schema, ctx, json, params, message) {\n const result = typeof ctx.unrepresentable === \"function\"\n ? ctx.unrepresentable({ zodSchema: schema, path: params.path, message })\n : ctx.unrepresentable;\n if (result === \"any\")\n return false;\n if (result === undefined || result === \"throw\")\n throw new Error(message);\n Object.assign(json, result);\n return true;\n}\n// never rename this back to `process`: bundler polyfills inject a top-level `const process` that a lexical declaration of the same name collides with (#6397)\nexport function processSchema(schema, ctx, _params = { path: [], schemaPath: [] }) {\n var _a;\n const def = schema._zod.def;\n // check for schema in seens\n const seen = ctx.seen.get(schema);\n if (seen) {\n seen.count++;\n // check if cycle\n const isCycle = _params.schemaPath.includes(schema);\n if (isCycle) {\n seen.cycle = _params.path;\n }\n return seen.schema;\n }\n // initialize\n const result = { schema: {}, count: 1, cycle: undefined, path: _params.path };\n ctx.seen.set(schema, result);\n ctx.sharedDefsExtractedFor = undefined;\n ctx.sharedEmitDoneFor = undefined;\n // custom method overrides default behavior\n const overrideSchema = schema._zod.toJSONSchema?.();\n if (overrideSchema) {\n result.schema = overrideSchema;\n }\n else {\n const params = {\n ..._params,\n schemaPath: [..._params.schemaPath, schema],\n path: _params.path,\n };\n if (schema._zod.processJSONSchema) {\n schema._zod.processJSONSchema(ctx, result.schema, params);\n }\n else {\n const _json = result.schema;\n const processor = ctx.processors[def.type];\n if (!processor) {\n throw new Error(`[toJSONSchema]: Non-representable type encountered: ${def.type}`);\n }\n processor(schema, ctx, _json, params);\n }\n const parent = schema._zod.parent;\n if (parent) {\n // Also set ref if processor didn't (for inheritance)\n if (!result.ref)\n result.ref = parent;\n processSchema(parent, ctx, params);\n ctx.seen.get(parent).isParent = true;\n }\n }\n // metadata\n const meta = ctx.metadataRegistry.get(schema);\n if (meta)\n assignProps(result.schema, meta);\n if (ctx.io === \"input\" && isTransforming(schema)) {\n // examples/defaults only apply to output type of pipe\n delete result.schema.examples;\n delete result.schema.default;\n }\n // set prefault as default\n if (ctx.io === \"input\" && \"_prefault\" in result.schema)\n (_a = result.schema).default ?? (_a.default = result.schema._prefault);\n delete result.schema._prefault;\n // pulling fresh from ctx.seen in case it was overwritten\n const _result = ctx.seen.get(schema);\n return _result.schema;\n}\n/** @deprecated Renamed to `processSchema`. An export alias declares no binding, so it is safe to keep. */\nexport { processSchema as process };\n// Escape a reference token for use in a JSON Pointer fragment (RFC 6901): `~` becomes `~0` and `/` becomes `~1`. The `~` replacement must run first.\nfunction encodeJSONPointerSegment(segment) {\n return segment.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n}\nexport function extractDefs(ctx, schema\n// params: EmitParams\n) {\n // iterate over seen map;\n const root = ctx.seen.get(schema);\n if (!root)\n throw new Error(\"Unprocessed schema. This is a bug in Zod.\");\n // With `external` set, every registered schema resolves through the external branch of `makeURI`, so the root branch below produces the same ref the external branch would \u2014 this pass is identical whichever schema it is called with, and only needs to run once.\n if (ctx.external && ctx.sharedDefsExtractedFor === ctx.external)\n return;\n // Track ids to detect duplicates across different schemas\n const idToSchema = new Map();\n for (const entry of ctx.seen.entries()) {\n const id = ctx.metadataRegistry.get(entry[0])?.id;\n if (id) {\n const existing = idToSchema.get(id);\n if (existing && existing !== entry[0]) {\n throw new Error(`Duplicate schema id \"${id}\" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);\n }\n idToSchema.set(id, entry[0]);\n }\n }\n // returns a ref to the schema defId will be empty if the ref points to an external schema (or #)\n const makeURI = (entry) => {\n // comparing the seen objects because sometimes multiple schemas map to the same seen object. e.g. lazy\n // external is configured\n const defsSegment = ctx.target === \"draft-2020-12\" ? \"$defs\" : \"definitions\";\n if (ctx.external) {\n const externalId = ctx.external.registry.get(entry[0])?.id; // ?? \"__shared\";// `__schema${ctx.counter++}`;\n // check if schema is in the external registry\n const uriGenerator = ctx.external.uri ?? ((id) => id);\n if (externalId) {\n return { ref: uriGenerator(externalId) };\n }\n // otherwise, add to __shared\n const id = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;\n entry[1].defId = id; // set defId so it will be reused if needed\n return { defId: id, ref: `${uriGenerator(\"__shared\")}#/${defsSegment}/${encodeJSONPointerSegment(id)}` };\n }\n const uriPrefix = `#`;\n const defUriPrefix = `${uriPrefix}/${defsSegment}/`;\n // an id-less root has nowhere to be extracted to, so it stays inline and self-references as `#`\n if (entry[1] === root && !entry[1].schema.id) {\n return { ref: uriPrefix };\n }\n // self-contained schema\n const defId = entry[1].schema.id ?? `__schema${ctx.counter++}`;\n return { defId, ref: defUriPrefix + encodeJSONPointerSegment(defId) };\n };\n // stored cached version in `def` property remove all properties, set $ref\n const extractToDef = (entry) => {\n // if the schema is already a reference, do not extract it\n if (entry[1].schema.$ref) {\n return;\n }\n const seen = entry[1];\n const { ref, defId } = makeURI(entry);\n seen.def = { ...seen.schema };\n // defId won't be set if the schema is a reference to an external schema or if the schema is the root schema\n if (defId)\n seen.defId = defId;\n // wipe away all properties except $ref\n const schema = seen.schema;\n for (const key in schema) {\n delete schema[key];\n }\n schema.$ref = ref;\n };\n // throw on cycles\n // break cycles\n if (ctx.cycles === \"throw\") {\n for (const entry of ctx.seen.entries()) {\n const seen = entry[1];\n if (seen.cycle) {\n throw new Error(\"Cycle detected: \" +\n `#/${seen.cycle?.join(\"/\")}/` +\n '\\n\\nSet the `cycles` parameter to `\"ref\"` to resolve cyclical schemas with defs.');\n }\n }\n }\n // extract schemas into $defs\n for (const entry of ctx.seen.entries()) {\n const seen = entry[1];\n // convert root schema to # $ref\n if (schema === entry[0]) {\n extractToDef(entry); // this has special handling for the root schema\n continue;\n }\n // extract schemas that are in the external registry\n if (ctx.external) {\n const ext = ctx.external.registry.get(entry[0])?.id;\n if (schema !== entry[0] && ext) {\n extractToDef(entry);\n continue;\n }\n }\n // extract schemas with `id` meta\n const id = ctx.metadataRegistry.get(entry[0])?.id;\n if (id) {\n extractToDef(entry);\n continue;\n }\n // break cycles\n if (seen.cycle) {\n // any\n extractToDef(entry);\n continue;\n }\n // extract reused schemas\n if (seen.count > 1) {\n if (ctx.reused === \"ref\") {\n extractToDef(entry);\n }\n }\n }\n if (ctx.external)\n ctx.sharedDefsExtractedFor = ctx.external;\n}\n/** Rewrites `anyOf: [{type: \"a\"}, {type: \"b\"}]` to `type: [\"a\", \"b\"]`, which every JSON Schema draft treats as equivalent and most consumers render far better for the nullable case. Only branches that are a bare type assertion qualify \u2014 anything carrying a constraint, `$ref`, `const` or metadata is left alone. Runs after `flattenRef`, so a branch an override decorated or `$defs` extraction turned into a `$ref` is no longer bare and correctly stays in `anyOf`. `oneOf` is excluded: `integer` and `number` overlap, so \"exactly one\" and \"at least one\" are not the same there. OpenAPI 3.0 is excluded: its `type` must be a single string. */\nfunction compactTypeUnion(schema) {\n const options = schema.anyOf;\n if (!Array.isArray(options) || options.length === 0 || schema.type !== undefined)\n return;\n const types = [];\n for (const option of options) {\n if (!option || typeof option !== \"object\")\n return;\n // A branch that is itself a compactible union folds into this one \u2014 nested `anyOf` and a flat `type` array say the same thing. Compacting it first also makes the result independent of the order this pass walks the seen map in.\n compactTypeUnion(option);\n const keys = Object.keys(option);\n if (keys.length !== 1 || keys[0] !== \"type\")\n return;\n const type = option.type;\n for (const member of Array.isArray(type) ? type : [type]) {\n if (typeof member !== \"string\")\n return;\n if (!types.includes(member))\n types.push(member);\n }\n }\n delete schema.anyOf;\n // A `type` array must be non-empty and unique (metaschema); a single member is spelled as a bare string.\n schema.type = types.length === 1 ? types[0] : types;\n}\n/** Keywords `foldIntersection` knows how to combine. Anything else \u2014 `$ref`, `patternProperties`,\n * an annotation like `description` \u2014 makes a member unfoldable, so a constraint this does not\n * understand leaves the `allOf` alone instead of being silently dropped or misattributed. */\nconst FOLDABLE_KEYS = new Set([\"type\", \"properties\", \"required\", \"additionalProperties\"]);\nconst UNION_KEYS = [\"oneOf\", \"anyOf\"];\n/** A member's constraint on a key it does not declare itself. A `catchall` states one; `false`, an absent `additionalProperties`, and the empty schema a loose object emits state nothing. */\nfunction undeclaredConstraint(member) {\n const extra = member.additionalProperties;\n if (extra === undefined || extra === false || typeof extra !== \"object\" || extra === null)\n return null;\n return Object.keys(extra).length ? extra : null;\n}\n/** Combines object members into the single object they describe together, or returns `null` if any of them carries a keyword outside {@link FOLDABLE_KEYS}. */\nfunction foldObjects(members) {\n const objects = [];\n for (const member of members) {\n // A boolean subschema is legal JSON Schema and carries no keywords to fold.\n if (typeof member !== \"object\" || member.type !== \"object\")\n return null;\n for (const key in member) {\n if (!FOLDABLE_KEYS.has(key))\n return null;\n }\n objects.push(member);\n }\n const properties = {};\n const required = new Set();\n for (const object of objects) {\n for (const key in object.properties) {\n // `in` would report a `__proto__` key as already present via the prototype chain and skip it.\n if (Object.prototype.hasOwnProperty.call(properties, key))\n continue;\n // Every member constrains this key: the ones that declare it say how, and a `catchall` member constrains it too even though it does not name it. The key has to satisfy all of them, which is the same intersection one level down.\n const parts = [];\n for (const other of objects) {\n const part = other.properties?.[key] ?? undeclaredConstraint(other);\n if (part === null || part === undefined)\n continue;\n if (!parts.some((seen) => JSON.stringify(seen) === JSON.stringify(part)))\n parts.push(part);\n }\n const merged = parts.length === 1\n ? parts[0]\n : (foldObjects(parts) ?? { allOf: parts });\n assignProp(properties, key, merged);\n }\n for (const key of object.required ?? [])\n required.add(key);\n }\n const folded = { type: \"object\", properties };\n if (required.size)\n folded.required = [...required];\n // A key no member declares is rejected only when every member rejects it, so the fold is closed only when every member is. Otherwise it carries whatever the `catchall` members demand of such a key.\n if (objects.every((object) => object.additionalProperties === false)) {\n folded.additionalProperties = false;\n }\n else {\n const constraints = [];\n for (const object of objects) {\n const constraint = undeclaredConstraint(object);\n if (constraint && !constraints.some((seen) => JSON.stringify(seen) === JSON.stringify(constraint)))\n constraints.push(constraint);\n }\n if (constraints.length === 1)\n folded.additionalProperties = constraints[0];\n else if (constraints.length > 1)\n folded.additionalProperties = { allOf: constraints };\n }\n return folded;\n}\n/** `additionalProperties` in an `allOf` member sees only that member's own `properties`, so two\n * closed object members reject each other's keys and the schema validates nothing. Zod's parser\n * pools the key sets instead \u2014 `handleIntersectionResults` reports a key as unrecognized only when\n * *every* side rejects it \u2014 so the emitted schema has to pool them too, and folding the members\n * into one object is the encoding that says so on every target.\n *\n * This runs from `finalize`, after `extractDefs`, which is what keeps it clear of the `$ref`\n * machinery: a member extracted into `$defs` is already a `$ref` by now and declines to fold, so it\n * keeps its reference and its own closedness rather than being inlined as a stale copy. */\nfunction foldIntersection(json) {\n const allOf = json.allOf;\n if (!Array.isArray(allOf) || allOf.length < 2)\n return;\n // An `override` runs before this pass and may have written object keywords onto the intersection itself. Those are deliberate, so decline rather than overwrite them.\n for (const key of FOLDABLE_KEYS)\n if (key in json)\n return;\n // An intersection distributes over a union: `A & (X | Y)` is `(A & X) | (A & Y)`. Only the first union is distributed over; a second one stays among the members every branch folds against, where it fails the object check and declines the whole intersection rather than multiplying out.\n const unions = allOf.filter((m) => UNION_KEYS.some((k) => Array.isArray(m[k])));\n let folded = null;\n if (!unions.length) {\n folded = foldObjects(allOf);\n }\n else {\n const union = unions[0];\n const keyword = UNION_KEYS.find((k) => Array.isArray(union[k]));\n if (Object.keys(union).length !== 1)\n return;\n const rest = allOf.filter((m) => m !== union);\n const branches = union[keyword].map((branch) => foldObjects([...rest, branch]));\n if (branches.some((b) => !b))\n return;\n folded = { [keyword]: branches };\n }\n if (!folded)\n return;\n delete json.allOf;\n assignProps(json, folded);\n}\nexport function finalize(ctx, schema) {\n const root = ctx.seen.get(schema);\n if (!root)\n throw new Error(\"Unprocessed schema. This is a bug in Zod.\");\n // flatten refs - inherit properties from parent schemas\n const flattenRef = (zodSchema) => {\n const seen = ctx.seen.get(zodSchema);\n // already processed\n if (seen.ref === null)\n return;\n const schema = seen.def ?? seen.schema;\n const _cached = { ...schema };\n const ref = seen.ref;\n seen.ref = null; // prevent infinite recursion\n if (ref) {\n flattenRef(ref);\n const refSeen = ctx.seen.get(ref);\n const refSchema = refSeen.schema;\n // merge referenced schema into current\n if (refSchema.$ref && (ctx.target === \"draft-07\" || ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\")) {\n // older drafts can't combine $ref with other properties\n schema.allOf = schema.allOf ?? [];\n schema.allOf.push(refSchema);\n }\n else {\n assignProps(schema, refSchema);\n }\n // restore child's own properties (child wins)\n assignProps(schema, _cached);\n const isParentRef = zodSchema._zod.parent === ref;\n // For parent chain, child is a refinement - remove parent-only properties\n if (isParentRef) {\n for (const key in schema) {\n if (key === \"$ref\" || key === \"allOf\")\n continue;\n if (!(key in _cached)) {\n delete schema[key];\n }\n }\n }\n // When ref was extracted to $defs, remove properties that match the definition\n if (refSchema.$ref && refSeen.def) {\n for (const key in schema) {\n if (key === \"$ref\" || key === \"allOf\")\n continue;\n if (key in refSeen.def && JSON.stringify(schema[key]) === JSON.stringify(refSeen.def[key])) {\n delete schema[key];\n }\n }\n }\n }\n // If parent was extracted (has $ref), propagate $ref to this schema. This handles cases like: readonly().meta({id}).describe() where processor sets ref to innerType but parent should be referenced\n const parent = zodSchema._zod.parent;\n if (parent && parent !== ref) {\n // Ensure parent is processed first so its def has inherited properties\n flattenRef(parent);\n const parentSeen = ctx.seen.get(parent);\n if (parentSeen?.schema.$ref) {\n schema.$ref = parentSeen.schema.$ref;\n // De-duplicate with parent's definition\n if (parentSeen.def) {\n for (const key in schema) {\n if (key === \"$ref\" || key === \"allOf\")\n continue;\n if (key in parentSeen.def && JSON.stringify(schema[key]) === JSON.stringify(parentSeen.def[key])) {\n delete schema[key];\n }\n }\n }\n }\n }\n // execute overrides\n ctx.override({\n zodSchema: zodSchema,\n jsonSchema: schema,\n path: seen.path ?? [],\n });\n };\n // Flattening walks the whole map and clears each `ref` as it goes, so a second call over the same map is a no-op scan. Skip it outright once it has run for a registry conversion.\n if (!ctx.external || ctx.sharedEmitDoneFor !== ctx.external) {\n for (const entry of [...ctx.seen.entries()].reverse()) {\n flattenRef(entry[0]);\n }\n if (ctx.target !== \"openapi-3.0\") {\n for (const entry of ctx.seen.entries()) {\n compactTypeUnion(entry[1].def ?? entry[1].schema);\n }\n }\n for (const rewrite of ctx.deferred)\n rewrite();\n // After flattening, every member that was extracted is a `$ref`, so the fold sees the final shape. A schema that inherits an intersection \u2014 through `z.lazy`, or any `ref` chain \u2014 holds the same `allOf` array, so fold by array identity to catch every copy.\n if (ctx.intersections.length) {\n const carriers = new Map();\n for (const seen of ctx.seen.values()) {\n for (const json of [seen.schema, seen.def]) {\n const allOf = json?.allOf;\n if (!Array.isArray(allOf))\n continue;\n const existing = carriers.get(allOf);\n if (existing)\n existing.push(json);\n else\n carriers.set(allOf, [json]);\n }\n }\n for (const allOf of ctx.intersections) {\n for (const json of carriers.get(allOf) ?? [])\n foldIntersection(json);\n }\n }\n }\n const result = {};\n if (ctx.target === \"draft-2020-12\") {\n result.$schema = \"https://json-schema.org/draft/2020-12/schema\";\n }\n else if (ctx.target === \"draft-07\") {\n result.$schema = \"http://json-schema.org/draft-07/schema#\";\n }\n else if (ctx.target === \"draft-04\") {\n result.$schema = \"http://json-schema.org/draft-04/schema#\";\n }\n else if (ctx.target === \"openapi-3.0\") {\n // OpenAPI 3.0 schema objects should not include a $schema property\n }\n else {\n // Arbitrary string values are allowed but won't have a $schema property set\n }\n if (ctx.external?.uri) {\n const id = ctx.external.registry.get(schema)?.id;\n if (!id)\n throw new Error(\"Schema is missing an `id` property\");\n result.$id = ctx.external.uri(id);\n }\n // when the root was extracted into $defs, `root.schema` is the `$ref` wrapper and `root.def` is the body that now lives under $defs\n assignProps(result, root.defId ? root.schema : (root.def ?? root.schema));\n // The `id` in `.meta()` is a Zod-specific registration tag used to extract schemas into $defs \u2014 it is not user-facing JSON Schema metadata. Strip it from the output body where it would otherwise leak. The id is preserved implicitly via the $defs key (and via $ref paths).\n const rootMetaId = ctx.metadataRegistry.get(schema)?.id;\n if (rootMetaId !== undefined && result.id === rootMetaId)\n delete result.id;\n // build defs object. With `external`, `defs` is the shared object every schema writes into, so the same entries are reassigned on every call. Without it, `defs` is fresh per call and must be rebuilt.\n const defs = ctx.external?.defs ?? {};\n if (!ctx.external || ctx.sharedEmitDoneFor !== ctx.external) {\n for (const entry of ctx.seen.entries()) {\n const seen = entry[1];\n if (seen.def && seen.defId) {\n if (seen.def.id === seen.defId)\n delete seen.def.id;\n assignProp(defs, seen.defId, seen.def);\n }\n }\n }\n if (ctx.external)\n ctx.sharedEmitDoneFor = ctx.external;\n // set definitions in result\n if (ctx.external) {\n }\n else {\n if (Object.keys(defs).length > 0) {\n if (ctx.target === \"draft-2020-12\") {\n result.$defs = defs;\n }\n else {\n result.definitions = defs;\n }\n }\n }\n try {\n // this \"finalizes\" this schema and ensures all cycles are removed each call to finalize() is functionally independent though the seen map is shared\n const finalized = JSON.parse(JSON.stringify(result));\n Object.defineProperty(finalized, \"~standard\", {\n value: {\n ...schema[\"~standard\"],\n jsonSchema: {\n input: createStandardJSONSchemaMethod(schema, \"input\", ctx.processors),\n output: createStandardJSONSchemaMethod(schema, \"output\", ctx.processors),\n },\n },\n enumerable: false,\n writable: false,\n });\n return finalized;\n }\n catch (_err) {\n throw new Error(\"Error converting schema to JSON.\");\n }\n}\nfunction isTransforming(_schema, _ctx) {\n const ctx = _ctx ?? { seen: new Set() };\n if (ctx.seen.has(_schema))\n return false;\n ctx.seen.add(_schema);\n const def = _schema._zod.def;\n if (def.type === \"transform\")\n return true;\n if (def.type === \"array\")\n return isTransforming(def.element, ctx);\n if (def.type === \"set\")\n return isTransforming(def.valueType, ctx);\n if (def.type === \"lazy\")\n return isTransforming(def.getter(), ctx);\n if (def.type === \"promise\" ||\n def.type === \"optional\" ||\n def.type === \"nonoptional\" ||\n def.type === \"nullable\" ||\n def.type === \"readonly\" ||\n def.type === \"default\" ||\n def.type === \"prefault\" ||\n def.type === \"catch\") {\n return isTransforming(def.innerType, ctx);\n }\n if (def.type === \"intersection\") {\n return isTransforming(def.left, ctx) || isTransforming(def.right, ctx);\n }\n if (def.type === \"record\" || def.type === \"map\") {\n return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);\n }\n if (def.type === \"pipe\") {\n if (_schema._zod.traits.has(\"$ZodCodec\"))\n return true;\n return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);\n }\n if (def.type === \"object\") {\n for (const key in def.shape) {\n if (isTransforming(def.shape[key], ctx))\n return true;\n }\n return false;\n }\n if (def.type === \"union\") {\n for (const option of def.options) {\n if (isTransforming(option, ctx))\n return true;\n }\n return false;\n }\n if (def.type === \"tuple\") {\n for (const item of def.items) {\n if (isTransforming(item, ctx))\n return true;\n }\n if (def.rest && isTransforming(def.rest, ctx))\n return true;\n return false;\n }\n return false;\n}\n/**\n * Creates a toJSONSchema method for a schema instance.\n * This encapsulates the logic of initializing context, processing, extracting defs, and finalizing.\n */\nexport const createToJSONSchemaMethod = (schema, processors = {}) => (params) => {\n const ctx = initializeContext({ ...params, processors });\n processSchema(schema, ctx);\n extractDefs(ctx, schema);\n return finalize(ctx, schema);\n};\nexport const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {\n const { libraryOptions, target } = params ?? {};\n const ctx = initializeContext({ ...(libraryOptions ?? {}), target, io, processors });\n processSchema(schema, ctx);\n extractDefs(ctx, schema);\n return finalize(ctx, schema);\n};\n", "import * as regexes from \"./regexes.js\";\nimport { base64Charset, base64urlCharset } from \"./schemas.js\";\nimport { extractDefs, finalize, handleUnrepresentable, initializeContext, processSchema, } from \"./to-json-schema.js\";\nimport { BIGINT_FORMAT_RANGES, NUMBER_FORMAT_RANGES, assignProp, getEnumValues } from \"./util.js\";\nconst narrowMin = (agg, key, value) => {\n if (agg[key] === undefined || value > agg[key])\n agg[key] = value;\n};\nconst narrowMax = (agg, key, value) => {\n if (agg[key] === undefined || value < agg[key])\n agg[key] = value;\n};\nconst narrowBoth = (agg, value) => {\n narrowMin(agg, \"minimum\", value);\n narrowMax(agg, \"maximum\", value);\n};\nconst addDivisor = (agg, value) => {\n agg.multipleOf ?? (agg.multipleOf = []);\n if (!agg.multipleOf.includes(value))\n agg.multipleOf.push(value);\n};\nconst addPattern = (agg, pattern) => {\n agg.patterns ?? (agg.patterns = new Set());\n agg.patterns.add(pattern);\n};\nconst intersectMime = (agg, mime) => {\n agg.mime = agg.mime ? agg.mime.filter((m) => mime.includes(m)) : [...mime];\n};\n// last-wins, matching the bag's historical write order; the flag keeps an integer format from being lost to a later float one\nconst setFormat = (agg, format) => {\n agg.format = format;\n if (format.includes(\"int\"))\n agg.isInt = true;\n};\nconst minContributor = (agg, def) => narrowMin(agg, \"minimum\", def.minimum);\nconst maxContributor = (agg, def) => narrowMax(agg, \"maximum\", def.maximum);\nconst formatContributor = (ranges) => (agg, def) => {\n setFormat(agg, def.format);\n const [minimum, maximum] = ranges[def.format];\n narrowMin(agg, \"minimum\", minimum);\n narrowMax(agg, \"maximum\", maximum);\n};\nconst contributors = {\n greater_than: (agg, def) => narrowMin(agg, def.inclusive ? \"minimum\" : \"exclusiveMinimum\", def.value),\n less_than: (agg, def) => narrowMax(agg, def.inclusive ? \"maximum\" : \"exclusiveMaximum\", def.value),\n multiple_of: (agg, def) => addDivisor(agg, def.value),\n number_format: formatContributor(NUMBER_FORMAT_RANGES),\n bigint_format: formatContributor(BIGINT_FORMAT_RANGES),\n min_length: minContributor,\n max_length: maxContributor,\n length_equals: (agg, def) => narrowBoth(agg, def.length),\n min_size: minContributor,\n max_size: maxContributor,\n size_equals: (agg, def) => narrowBoth(agg, def.size),\n string_format: (agg, def) => {\n setFormat(agg, def.format);\n if (def.pattern)\n addPattern(agg, def.pattern);\n if (def.format === \"base64\" || def.format === \"base64url\")\n agg.contentEncoding = def.format;\n if (def.local || def.precision === -1)\n agg.laxFormat = true;\n },\n mime_type: (agg, def) => intersectMime(agg, def.mime),\n};\nexport function aggregateChecks(schema) {\n const agg = {};\n const def = schema._zod.def;\n // a format schema is its own first check, same rule as $ZodType init\n const list = schema._zod.traits.has(\"$ZodCheck\")\n ? [schema, ...(def.checks ?? [])]\n : (def.checks ?? []);\n for (const ch of list)\n contributors[ch._zod.def.check]?.(agg, ch._zod.def);\n // reconcile with the bag so third-party onattach contributions still land; first-party residue is never tighter than the fold, so merging it back is idempotent for one and additive for the other\n const bag = schema._zod.bag;\n if (bag.minimum !== undefined)\n narrowMin(agg, \"minimum\", bag.minimum);\n if (bag.exclusiveMinimum !== undefined)\n narrowMin(agg, \"exclusiveMinimum\", bag.exclusiveMinimum);\n if (bag.maximum !== undefined)\n narrowMax(agg, \"maximum\", bag.maximum);\n if (bag.exclusiveMaximum !== undefined)\n narrowMax(agg, \"exclusiveMaximum\", bag.exclusiveMaximum);\n if (bag.multipleOf !== undefined)\n addDivisor(agg, bag.multipleOf);\n if (bag.format !== undefined) {\n agg.format ?? (agg.format = bag.format);\n if (bag.format.includes(\"int\"))\n agg.isInt = true;\n }\n if (bag.mime)\n intersectMime(agg, bag.mime);\n for (const pattern of bag.patterns ?? [])\n addPattern(agg, pattern);\n return agg;\n}\nconst formatMap = {\n guid: \"uuid\",\n url: \"uri\",\n datetime: \"date-time\",\n json_string: \"json-string\",\n regex: \"\", // do not set\n};\n// ==================== SIMPLE TYPE PROCESSORS ====================\n// the runtime patterns are lax so parse paths never overflow the regex stack; the emitted schema swaps in the exact block forms, which zod itself never executes\nconst exactPatterns = new Map([\n [base64Charset, regexes.base64],\n [base64urlCharset, regexes.base64url],\n]);\nconst exactPattern = (p) => exactPatterns.get(p) ?? p;\nexport const stringProcessor = (schema, ctx, _json, _params) => {\n const json = _json;\n json.type = \"string\";\n const { minimum, maximum, format, patterns, contentEncoding, laxFormat } = aggregateChecks(schema);\n if (typeof minimum === \"number\")\n json.minLength = minimum;\n if (typeof maximum === \"number\")\n json.maxLength = maximum;\n // custom pattern overrides format\n if (format) {\n json.format = formatMap[format] ?? format;\n if (json.format === \"\")\n delete json.format; // empty format is not valid\n // `z.iso.time()` is never full-time, and `laxFormat` carries the datetime shapes that also accept what their keyword forbids\n if (format === \"time\" || laxFormat) {\n delete json.format;\n }\n }\n if (contentEncoding)\n json.contentEncoding = contentEncoding;\n if (patterns && patterns.size > 0) {\n const patternList = [...patterns].map(exactPattern);\n if (patternList.length === 1)\n json.pattern = patternList[0].source;\n else if (patternList.length > 1) {\n json.allOf = [\n ...patternList.map((regex) => ({\n ...(ctx.target === \"draft-07\" || ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\"\n ? { type: \"string\" }\n : {}),\n pattern: regex.source,\n })),\n ];\n }\n }\n};\nexport const numberProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const { minimum, maximum, multipleOf, exclusiveMaximum, exclusiveMinimum, isInt } = aggregateChecks(schema);\n json.type = isInt ? \"integer\" : \"number\";\n // when both minimum and exclusiveMinimum exist, pick the more restrictive one\n const exMin = typeof exclusiveMinimum === \"number\" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);\n const exMax = typeof exclusiveMaximum === \"number\" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);\n const legacy = ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\";\n if (exMin) {\n if (legacy) {\n json.minimum = exclusiveMinimum;\n json.exclusiveMinimum = true;\n }\n else {\n json.exclusiveMinimum = exclusiveMinimum;\n }\n }\n else if (typeof minimum === \"number\") {\n json.minimum = minimum;\n }\n if (exMax) {\n if (legacy) {\n json.maximum = exclusiveMaximum;\n json.exclusiveMaximum = true;\n }\n else {\n json.exclusiveMaximum = exclusiveMaximum;\n }\n }\n else if (typeof maximum === \"number\") {\n json.maximum = maximum;\n }\n if (multipleOf) {\n // JSON Schema requires a divisor strictly greater than zero, and a non-finite one does not survive JSON at all. A negative divisor accepts exactly what its absolute value accepts, so it still maps; zero, NaN and Infinity have no keyword form.\n const divisors = new Set();\n for (const divisor of multipleOf) {\n if (Number.isFinite(divisor) && divisor !== 0)\n divisors.add(Math.abs(divisor));\n else\n handleUnrepresentable(schema, ctx, json, params, `A multipleOf divisor of ${divisor} cannot be represented in JSON Schema`);\n }\n // chained divisors are a conjunction the keyword cannot carry alone, so extras ride an allOf, same as stacked patterns\n const [first, ...rest] = divisors;\n if (first !== undefined)\n json.multipleOf = first;\n if (rest.length)\n json.allOf = [...(json.allOf ?? []), ...rest.map((m) => ({ multipleOf: m }))];\n }\n};\nexport const booleanProcessor = (_schema, _ctx, json, _params) => {\n json.type = \"boolean\";\n};\nexport const bigintProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"BigInt cannot be represented in JSON Schema\");\n};\nexport const symbolProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Symbols cannot be represented in JSON Schema\");\n};\nexport const nullProcessor = (_schema, ctx, json, _params) => {\n if (ctx.target === \"openapi-3.0\") {\n json.type = \"string\";\n json.nullable = true;\n json.enum = [null];\n }\n else {\n json.type = \"null\";\n }\n};\nexport const undefinedProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Undefined cannot be represented in JSON Schema\");\n};\nexport const voidProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Void cannot be represented in JSON Schema\");\n};\nexport const neverProcessor = (_schema, _ctx, json, _params) => {\n json.not = {};\n};\nexport const anyProcessor = (_schema, _ctx, _json, _params) => {\n // empty schema accepts anything\n};\nexport const unknownProcessor = (_schema, _ctx, _json, _params) => {\n // empty schema accepts anything\n};\nexport const dateProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Date cannot be represented in JSON Schema\");\n};\nexport const enumProcessor = (schema, _ctx, json, _params) => {\n const def = schema._zod.def;\n const values = getEnumValues(def.entries);\n // an empty enum accepts nothing, same as z.never()\n if (values.length === 0) {\n json.not = {};\n return;\n }\n // Number enums can have both string and number values\n if (values.every((v) => typeof v === \"number\"))\n json.type = \"number\";\n if (values.every((v) => typeof v === \"string\"))\n json.type = \"string\";\n json.enum = values;\n};\nexport const literalProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n // a literal with no values accepts nothing, same as z.never()\n if (def.values.length === 0) {\n json.not = {};\n return;\n }\n const vals = [];\n for (const val of def.values) {\n if (val === undefined) {\n // a custom schema replaces the whole literal, so there is nothing left to accumulate\n if (handleUnrepresentable(schema, ctx, json, params, \"Literal `undefined` cannot be represented in JSON Schema\"))\n return;\n // otherwise do not add to vals\n }\n else if (typeof val === \"bigint\") {\n if (handleUnrepresentable(schema, ctx, json, params, \"BigInt literals cannot be represented in JSON Schema\"))\n return;\n vals.push(Number(val));\n }\n else {\n vals.push(val);\n }\n }\n if (vals.length === 0) {\n // do nothing (an undefined literal was stripped)\n }\n else if (vals.length === 1) {\n const val = vals[0];\n json.type = val === null ? \"null\" : typeof val;\n if (ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\") {\n json.enum = [val];\n }\n else {\n json.const = val;\n }\n }\n else {\n if (vals.every((v) => typeof v === \"number\"))\n json.type = \"number\";\n if (vals.every((v) => typeof v === \"string\"))\n json.type = \"string\";\n if (vals.every((v) => typeof v === \"boolean\"))\n json.type = \"boolean\";\n if (vals.every((v) => v === null))\n json.type = \"null\";\n json.enum = vals;\n }\n};\nexport const nanProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"NaN cannot be represented in JSON Schema\");\n};\nexport const templateLiteralProcessor = (schema, _ctx, json, _params) => {\n const _json = json;\n const pattern = schema._zod.pattern;\n if (!pattern)\n throw new Error(\"Pattern not found in template literal\");\n _json.type = \"string\";\n _json.pattern = pattern.source;\n};\nexport const fileProcessor = (schema, _ctx, json, _params) => {\n const _json = json;\n _json.type = \"string\";\n _json.format = \"binary\";\n _json.contentEncoding = \"binary\";\n const { minimum, maximum, mime } = aggregateChecks(schema);\n if (minimum !== undefined)\n _json.minLength = minimum;\n if (maximum !== undefined)\n _json.maxLength = maximum;\n if (!mime)\n return;\n // an empty intersection means the mime checks share no value, so nothing passes at runtime; `anyOf` must be non-empty, so the false schema is `not: {}`\n if (mime.length === 0)\n _json.not = {};\n else if (mime.length === 1)\n _json.contentMediaType = mime[0];\n // only contentMediaType differs, so the shared props stay at the root\n else\n _json.anyOf = mime.map((m) => ({ contentMediaType: m }));\n};\nexport const successProcessor = (_schema, _ctx, json, _params) => {\n json.type = \"boolean\";\n};\nexport const customProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Custom types cannot be represented in JSON Schema\");\n};\nexport const functionProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Function types cannot be represented in JSON Schema\");\n};\nexport const transformProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Transforms cannot be represented in JSON Schema\");\n};\nexport const mapProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Map cannot be represented in JSON Schema\");\n};\nexport const setProcessor = (schema, ctx, json, params) => {\n handleUnrepresentable(schema, ctx, json, params, \"Set cannot be represented in JSON Schema\");\n};\n// ==================== COMPOSITE TYPE PROCESSORS ====================\nexport const arrayProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const def = schema._zod.def;\n const { minimum, maximum } = aggregateChecks(schema);\n if (typeof minimum === \"number\")\n json.minItems = minimum;\n if (typeof maximum === \"number\")\n json.maxItems = maximum;\n json.type = \"array\";\n json.items = processSchema(def.element, ctx, {\n ...params,\n path: [...params.path, \"items\"],\n });\n};\n// Transform and catch set `optin = \"optional\"` at runtime so the parser lets them observe an\n// absent key, but their declared input type stays required. An input JSON Schema describes the\n// declared type, so resolve past them to the schema that actually carries the optionality.\n// Used by both `objectProcessor` (for `required`) and `tupleProcessor` (for `minItems`); see\n// wiki/optionality.md, \"The JSON Schema emitter reads the *static* value\".\nfunction inputOptin(schema) {\n const def = schema._zod.def;\n if (def.type === \"pipe\" && def.in._zod.traits.has(\"$ZodTransform\")) {\n return inputOptin(def.out);\n }\n if (def.type === \"catch\") {\n return inputOptin(def.innerType);\n }\n return schema._zod.optin;\n}\nexport const objectProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const def = schema._zod.def;\n const shape = def.shape;\n // dropping it while still emitting `additionalProperties: false` would emit a schema that rejects data this one requires\n const symbolKeys = Object.getOwnPropertySymbols(shape);\n if (symbolKeys.length &&\n handleUnrepresentable(schema, ctx, json, params, \"Symbol keys cannot be represented in JSON Schema\")) {\n return;\n }\n json.type = \"object\";\n json.properties = {};\n for (const key in shape) {\n // assignProp so a __proto__ key becomes an own property instead of hitting the inherited setter on the plain {} we build into\n assignProp(json.properties, key, processSchema(shape[key], ctx, {\n ...params,\n path: [...params.path, \"properties\", key],\n }));\n }\n // required keys\n const requiredKeys = [];\n for (const key of Object.keys(shape)) {\n const field = def.shape[key];\n if (ctx.io === \"input\" ? inputOptin(field) === undefined : field._zod.optout === undefined) {\n requiredKeys.push(key);\n }\n }\n if (requiredKeys.length > 0) {\n json.required = requiredKeys;\n }\n // catchall\n if (def.catchall?._zod.def.type === \"never\") {\n // strict\n json.additionalProperties = false;\n }\n else if (!def.catchall) {\n // regular\n if (ctx.io === \"output\")\n json.additionalProperties = false;\n }\n else if (def.catchall) {\n json.additionalProperties = processSchema(def.catchall, ctx, {\n ...params,\n path: [...params.path, \"additionalProperties\"],\n });\n }\n};\nexport const unionProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n // Exclusive unions (inclusive === false) use oneOf (exactly one match) instead of anyOf (one or more matches). This includes both z.xor() and discriminated unions\n const isExclusive = def.inclusive === false;\n const options = def.options.map((x, i) => processSchema(x, ctx, {\n ...params,\n path: [...params.path, isExclusive ? \"oneOf\" : \"anyOf\", i],\n }));\n if (isExclusive) {\n json.oneOf = options;\n }\n else {\n json.anyOf = options;\n }\n};\nexport const intersectionProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n const a = processSchema(def.left, ctx, {\n ...params,\n path: [...params.path, \"allOf\", 0],\n });\n const b = processSchema(def.right, ctx, {\n ...params,\n path: [...params.path, \"allOf\", 1],\n });\n const isSimpleIntersection = (val) => \"allOf\" in val && Object.keys(val).length === 1;\n const allOf = [\n ...(isSimpleIntersection(a) ? a.allOf : [a]),\n ...(isSimpleIntersection(b) ? b.allOf : [b]),\n ];\n json.allOf = allOf;\n // Recorded innermost first, so a nested intersection has already folded by the time this one is considered. The array is the handle rather than the schema, because a wrapper that inherits this schema shares the same array; `finalize` folds every object holding it. See `foldIntersection`.\n ctx.intersections.push(allOf);\n};\nexport const tupleProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const def = schema._zod.def;\n json.type = \"array\";\n const prefixPath = ctx.target === \"draft-2020-12\" ? \"prefixItems\" : \"items\";\n const restPath = ctx.target === \"draft-2020-12\" ? \"items\" : ctx.target === \"openapi-3.0\" ? \"items\" : \"additionalItems\";\n const prefixItems = def.items.map((x, i) => processSchema(x, ctx, {\n ...params,\n path: [...params.path, prefixPath, i],\n }));\n const rest = def.rest\n ? processSchema(def.rest, ctx, {\n ...params,\n path: [...params.path, restPath, ...(ctx.target === \"openapi-3.0\" ? [def.items.length] : [])],\n })\n : null;\n let minItems = def.items.length;\n while (minItems > 0) {\n const item = def.items[minItems - 1];\n const optional = ctx.io === \"input\" ? inputOptin(item) !== undefined : item._zod.optout === \"optional\";\n if (!optional)\n break;\n minItems--;\n }\n const maxItems = def.items.length;\n const isClosed = !def.rest;\n if (ctx.target === \"draft-2020-12\") {\n json.prefixItems = prefixItems;\n if (isClosed) {\n json.items = false;\n }\n else if (rest) {\n json.items = rest;\n }\n if (minItems > 0)\n json.minItems = minItems;\n if (isClosed)\n json.maxItems = maxItems;\n }\n else if (ctx.target === \"openapi-3.0\") {\n json.items = {\n anyOf: prefixItems,\n };\n if (rest) {\n json.items.anyOf.push(rest);\n }\n if (minItems > 0)\n json.minItems = minItems;\n if (isClosed)\n json.maxItems = maxItems;\n }\n else {\n json.items = prefixItems;\n if (isClosed) {\n json.additionalItems = false;\n }\n else if (rest) {\n json.additionalItems = rest;\n }\n if (minItems > 0)\n json.minItems = minItems;\n if (isClosed)\n json.maxItems = maxItems;\n }\n // explicit user-defined length checks take precedence\n const { minimum, maximum } = aggregateChecks(schema);\n if (typeof minimum === \"number\")\n json.minItems = minimum;\n if (typeof maximum === \"number\")\n json.maxItems = maximum;\n};\n/** JSON object keys are always strings, so a numeric record key schema is re-expressed over the\n * numeric-string form the record parser matches. Deferred to `finalize`, after the flatten: a key\n * behind a wrapper only carries its own `type` before then, and a union key only has its branches.\n *\n * A numeric bound cannot apply to a property name, so `minimum` and its siblings are dropped rather\n * than carried over: keeping them beside `type: \"string\"` reproduces the match-nothing schema this\n * exists to fix. A key that carries one therefore emits wider than the record parses \u2014 `z.record(z.number().min(5), V)`\n * accepts `\"3\"` \u2014 which is the deliberate trade, since throwing on it would reject an ordinary schema\n * outright. */\nfunction stringifyKeyNames(bySchema, json, visited) {\n // an extracted key that rewrites cannot go on sharing its definition \u2014 the string form a key position needs is not the number form every other reference wants \u2014 so it inlines. One that does not rewrite keeps the `$ref`.\n if (json.$ref) {\n // a recursive key holds its own reference inside its definition, so a node already on the path is left alone rather than resolved again\n if (visited.has(json))\n return json;\n visited.add(json);\n const def = bySchema.get(json)?.def;\n if (!def)\n return json;\n const inlined = stringifyKeyNames(bySchema, def, visited);\n return inlined === def ? json : inlined;\n }\n for (const keyword of [\"anyOf\", \"oneOf\"]) {\n const branches = json[keyword];\n if (!Array.isArray(branches))\n continue;\n const mapped = branches.map((branch) => stringifyKeyNames(bySchema, branch, visited));\n // rebuilding regardless would detach a key that had nothing to re-express, dropping its `$ref` and leaking the internal `id`\n if (mapped.some((branch, i) => branch !== branches[i]))\n json = { ...json, [keyword]: mapped };\n }\n // a member that already admits a string leaves the key unconstrained, so the node's own type re-expresses only when every member is numeric\n const types = Array.isArray(json.type) ? json.type : [json.type];\n const numericType = !types.includes(\"string\") && types.some((t) => t === \"number\" || t === \"integer\");\n // a heterogeneous key carries no type at all, so its numeric members are caught here instead\n const values = json.enum ?? (json.const !== undefined ? [json.const] : undefined);\n if (!numericType && !values?.some((v) => typeof v === \"number\"))\n return json;\n const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json;\n if (rest.enum)\n rest.enum = rest.enum.map((v) => (typeof v === \"number\" ? String(v) : v));\n else if (typeof rest.const === \"number\")\n rest.const = String(rest.const);\n // a heterogeneous key keeps its absent type: the stringified members already say what a key may be\n if (!numericType)\n return rest;\n rest.type = \"string\";\n if (!values)\n rest.pattern = (types.includes(\"number\") ? regexes.number : regexes.integer).source;\n return rest;\n}\n/** Every record of one conversion, so the carriers are found in a single pass rather than once per record. */\nconst pendingRecords = new WeakMap();\nfunction rewriteKeyNames(ctx) {\n // an extracted key is resolved by the object `extractToDef` left in its place, so the map is built once rather than searched per reference. `_zod.toJSONSchema` can hand the same object to two schemas, so the first entry carrying a body wins, as a search would have found it.\n const bySchema = new Map();\n for (const entry of ctx.seen.values()) {\n if (entry.def && !bySchema.has(entry.schema))\n bySchema.set(entry.schema, entry);\n }\n const rewrites = new Map();\n for (const record of pendingRecords.get(ctx) ?? []) {\n const seen = ctx.seen.get(record);\n const names = (seen?.def ?? seen?.schema)?.propertyNames;\n if (!names || names === true || rewrites.has(names))\n continue;\n const rewritten = stringifyKeyNames(bySchema, names, new Set());\n if (rewritten !== names)\n rewrites.set(names, rewritten);\n }\n if (!rewrites.size)\n return;\n // the flatten has already copied each record's own properties onto every wrapper by reference, and an extracted body is another such copy, so every carrier holding a rewritten key is updated together\n for (const entry of ctx.seen.values()) {\n for (const carrier of [entry.schema, entry.def]) {\n const rewritten = carrier && rewrites.get(carrier.propertyNames);\n if (rewritten)\n carrier.propertyNames = rewritten;\n }\n }\n}\nexport const recordProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const def = schema._zod.def;\n json.type = \"object\";\n // For looseRecord with regex patterns, use patternProperties. This correctly represents \"only validate keys matching the pattern\" semantics and composes well with allOf (intersections)\n const keyType = def.keyType;\n const patterns = aggregateChecks(keyType).patterns;\n if (def.mode === \"loose\" && patterns && patterns.size > 0) {\n // Use patternProperties for looseRecord with regex patterns\n const valueSchema = processSchema(def.valueType, ctx, {\n ...params,\n path: [...params.path, \"patternProperties\", \"*\"],\n });\n json.patternProperties = {};\n for (const pattern of patterns) {\n assignProp(json.patternProperties, exactPattern(pattern).source, valueSchema);\n }\n }\n else {\n // Default behavior: use propertyNames + additionalProperties\n if (ctx.target === \"draft-07\" || ctx.target === \"draft-2020-12\") {\n json.propertyNames = processSchema(def.keyType, ctx, {\n ...params,\n path: [...params.path, \"propertyNames\"],\n });\n let pending = pendingRecords.get(ctx);\n if (!pending) {\n pending = [];\n pendingRecords.set(ctx, pending);\n ctx.deferred.push(() => rewriteKeyNames(ctx));\n }\n pending.push(schema);\n }\n json.additionalProperties = processSchema(def.valueType, ctx, {\n ...params,\n path: [...params.path, \"additionalProperties\"],\n });\n }\n // Add required for keys with discrete values (enum, literal, etc.)\n const keyValues = keyType._zod.values;\n // Every key shares one value schema, so an optional-in value makes the whole key set omittable on input. Output keeps them: the exhaustive branch assigns every key, even one whose value came back undefined.\n const omittableOnInput = ctx.io === \"input\" && inputOptin(def.valueType) !== undefined;\n if (keyValues && !def.partial && !omittableOnInput) {\n const validKeyValues = [...keyValues].filter((v) => typeof v === \"string\" || typeof v === \"number\");\n if (validKeyValues.length > 0) {\n json.required = validKeyValues.map(String);\n }\n }\n};\nexport const nullableProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n const inner = processSchema(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n if (ctx.target === \"openapi-3.0\") {\n seen.ref = def.innerType;\n json.nullable = true;\n }\n else {\n json.anyOf = [inner, { type: \"null\" }];\n }\n};\nexport const nonoptionalProcessor = (schema, ctx, _json, params) => {\n const def = schema._zod.def;\n processSchema(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n};\n/** Round-trips a default value through JSON so the emitted schema is guaranteed to be valid JSON.\n * A BigInt has no reliable encoding, so it goes through `unrepresentable` like any other\n * unrepresentable value. Returns a sentinel when the caller must not write a default of its own. */\nconst UNREPRESENTABLE_DEFAULT = Symbol();\nfunction serializeDefaultValue(value, schema, ctx, json, params) {\n let unrepresentable = false;\n const serialized = JSON.stringify(value, (_, val) => {\n if (typeof val !== \"bigint\")\n return val;\n unrepresentable = true;\n return null;\n });\n if (!unrepresentable)\n return JSON.parse(serialized);\n handleUnrepresentable(schema, ctx, json, params, \"BigInt defaults cannot be represented in JSON Schema\");\n return UNREPRESENTABLE_DEFAULT;\n}\nexport const defaultProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n processSchema(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n const value = serializeDefaultValue(def.defaultValue, schema, ctx, json, params);\n if (value !== UNREPRESENTABLE_DEFAULT)\n json.default = value;\n};\nexport const prefaultProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n processSchema(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n if (ctx.io !== \"input\")\n return;\n const value = serializeDefaultValue(def.defaultValue, schema, ctx, json, params);\n if (value !== UNREPRESENTABLE_DEFAULT)\n json._prefault = value;\n};\nexport const catchProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n processSchema(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n let catchValue;\n try {\n catchValue = def.catchValue(undefined);\n }\n catch {\n handleUnrepresentable(schema, ctx, json, params, \"Dynamic catch values are not supported in JSON Schema\");\n return;\n }\n json.default = catchValue;\n};\nexport const pipeProcessor = (schema, ctx, _json, params) => {\n const def = schema._zod.def;\n const inIsTransform = def.in._zod.traits.has(\"$ZodTransform\");\n const innerType = ctx.io === \"input\" ? (inIsTransform ? def.out : def.in) : def.out;\n processSchema(innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = innerType;\n};\nexport const readonlyProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n processSchema(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n json.readOnly = true;\n};\nexport const promiseProcessor = (schema, ctx, _json, params) => {\n const def = schema._zod.def;\n processSchema(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n};\nexport const optionalProcessor = (schema, ctx, _json, params) => {\n const def = schema._zod.def;\n processSchema(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n};\nexport const lazyProcessor = (schema, ctx, _json, params) => {\n const innerType = schema._zod.innerType;\n processSchema(innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = innerType;\n};\n// ==================== ALL PROCESSORS ====================\nexport const allProcessors = {\n string: stringProcessor,\n number: numberProcessor,\n boolean: booleanProcessor,\n bigint: bigintProcessor,\n symbol: symbolProcessor,\n null: nullProcessor,\n undefined: undefinedProcessor,\n void: voidProcessor,\n never: neverProcessor,\n any: anyProcessor,\n unknown: unknownProcessor,\n date: dateProcessor,\n enum: enumProcessor,\n literal: literalProcessor,\n nan: nanProcessor,\n template_literal: templateLiteralProcessor,\n file: fileProcessor,\n success: successProcessor,\n custom: customProcessor,\n function: functionProcessor,\n transform: transformProcessor,\n map: mapProcessor,\n set: setProcessor,\n array: arrayProcessor,\n object: objectProcessor,\n union: unionProcessor,\n intersection: intersectionProcessor,\n tuple: tupleProcessor,\n record: recordProcessor,\n nullable: nullableProcessor,\n nonoptional: nonoptionalProcessor,\n default: defaultProcessor,\n prefault: prefaultProcessor,\n catch: catchProcessor,\n pipe: pipeProcessor,\n readonly: readonlyProcessor,\n promise: promiseProcessor,\n optional: optionalProcessor,\n lazy: lazyProcessor,\n};\nexport function toJSONSchema(input, params) {\n if (\"_idmap\" in input) {\n // Registry case\n const registry = input;\n const ctx = initializeContext({ ...params, processors: allProcessors });\n const defs = {};\n // First pass: process all schemas to build the seen map\n for (const entry of registry._idmap.entries()) {\n const [_, schema] = entry;\n processSchema(schema, ctx);\n }\n const schemas = {};\n const external = {\n registry,\n uri: params?.uri,\n defs,\n };\n // Update the context with external configuration\n ctx.external = external;\n // Second pass: emit each schema\n for (const entry of registry._idmap.entries()) {\n const [key, schema] = entry;\n extractDefs(ctx, schema);\n assignProp(schemas, key, finalize(ctx, schema));\n }\n if (Object.keys(defs).length > 0) {\n const defsSegment = ctx.target === \"draft-2020-12\" ? \"$defs\" : \"definitions\";\n schemas.__shared = {\n [defsSegment]: defs,\n };\n }\n return { schemas };\n }\n // Single schema case\n const ctx = initializeContext({ ...params, processors: allProcessors });\n processSchema(input, ctx);\n extractDefs(ctx, input);\n return finalize(ctx, input);\n}\n", "import { allProcessors } from \"./json-schema-processors.js\";\nimport { extractDefs, finalize, initializeContext, processSchema, } from \"./to-json-schema.js\";\n/**\n * Legacy class-based interface for JSON Schema generation.\n * This class wraps the new functional implementation to provide backward compatibility.\n *\n * @deprecated Use the `toJSONSchema` function instead for new code.\n *\n * @example\n * ```typescript\n * // Legacy usage (still supported)\n * const gen = new JSONSchemaGenerator({ target: \"draft-07\" });\n * gen.process(schema);\n * const result = gen.emit(schema);\n *\n * // Preferred modern usage\n * const result = toJSONSchema(schema, { target: \"draft-07\" });\n * ```\n */\nexport class JSONSchemaGenerator {\n /** @deprecated Access via ctx instead */\n get metadataRegistry() {\n return this.ctx.metadataRegistry;\n }\n /** @deprecated Access via ctx instead */\n get target() {\n return this.ctx.target;\n }\n // annotated so the .d.cts emits an indexed access rather than an inline `import()` of an ESM path\n /** @deprecated Access via ctx instead */\n get unrepresentable() {\n return this.ctx.unrepresentable;\n }\n /** @deprecated Access via ctx instead */\n get override() {\n return this.ctx.override;\n }\n /** @deprecated Access via ctx instead */\n get io() {\n return this.ctx.io;\n }\n /** @deprecated Access via ctx instead */\n get counter() {\n return this.ctx.counter;\n }\n set counter(value) {\n this.ctx.counter = value;\n }\n /** @deprecated Access via ctx instead */\n get seen() {\n return this.ctx.seen;\n }\n constructor(params) {\n // Normalize target for internal context\n let normalizedTarget = params?.target ?? \"draft-2020-12\";\n if (normalizedTarget === \"draft-4\")\n normalizedTarget = \"draft-04\";\n if (normalizedTarget === \"draft-7\")\n normalizedTarget = \"draft-07\";\n this.ctx = initializeContext({\n processors: allProcessors,\n target: normalizedTarget,\n ...(params?.metadata && { metadata: params.metadata }),\n ...(params?.unrepresentable && { unrepresentable: params.unrepresentable }),\n ...(params?.override && { override: params.override }),\n ...(params?.io && { io: params.io }),\n });\n }\n /**\n * Process a schema to prepare it for JSON Schema generation.\n * This must be called before emit().\n */\n process(schema, _params = { path: [], schemaPath: [] }) {\n return processSchema(schema, this.ctx, _params);\n }\n /**\n * Emit the final JSON Schema after processing.\n * Must call process() first.\n */\n emit(schema, _params) {\n // Apply emit params to the context\n if (_params) {\n if (_params.cycles)\n this.ctx.cycles = _params.cycles;\n if (_params.reused)\n this.ctx.reused = _params.reused;\n if (_params.external)\n this.ctx.external = _params.external;\n }\n // extractDefs/finalize skip their whole-map passes when they have already run for this `external`, but they also branch on `cycles`, `reused`, `seen.count` and the metadata registry \u2014 any of which can change between emits, including with no params at all. Drop the guards so the passes re-run. The registry conversion calls extractDefs/finalize directly and never routes through here, so it keeps skipping them.\n this.ctx.sharedDefsExtractedFor = undefined;\n this.ctx.sharedEmitDoneFor = undefined;\n extractDefs(this.ctx, schema);\n const result = finalize(this.ctx, schema);\n // Strip ~standard property to match old implementation's return type\n const { \"~standard\": _, ...plainResult } = result;\n return plainResult;\n }\n}\n", "export {};\n", "export * from \"./core.js\";\nexport * from \"./parse.js\";\nexport * from \"./errors.js\";\nexport * from \"./schemas.js\";\nexport * from \"./memoizer.js\";\nexport * from \"./checks.js\";\nexport * from \"./versions.js\";\nexport * as util from \"./util.js\";\nexport { toZod } from \"./util.js\";\nexport * as regexes from \"./regexes.js\";\nexport * as locales from \"../locales/index.js\";\nexport * from \"./registries.js\";\nexport * from \"./doc.js\";\nexport * from \"./compile.js\";\nexport * from \"./api.js\";\nexport * from \"./to-json-schema.js\";\nexport { toJSONSchema } from \"./json-schema-processors.js\";\nexport { JSONSchemaGenerator } from \"./json-schema-generator.js\";\nexport * as JSONSchema from \"./json-schema.js\";\n", "export { _lt as lt, _lte as lte, _gt as gt, _gte as gte, _positive as positive, _negative as negative, _nonpositive as nonpositive, _nonnegative as nonnegative, _multipleOf as multipleOf, _maxSize as maxSize, _minSize as minSize, _size as size, _maxLength as maxLength, _minLength as minLength, _length as length, _regex as regex, _lowercase as lowercase, _uppercase as uppercase, _includes as includes, _startsWith as startsWith, _endsWith as endsWith, _property as property, _properties as properties, _mime as mime, _overwrite as overwrite, _normalize as normalize, _trim as trim, _toLowerCase as toLowerCase, _toUpperCase as toUpperCase, _slugify as slugify, } from \"../core/index.js\";\n", "import * as core from \"../core/index.js\";\nimport { $ZodError } from \"../core/index.js\";\nimport * as util from \"../core/util.js\";\n/* Prototypes that already carry the lazy helper methods. Seeded with the\n * intrinsics so that `init` on a foreign object \u2014 it accepts any object \u2014\n * can never install an accessor onto a prototype we do not own. */\nconst _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);\n/* Helper methods live as non-enumerable lazy getters on the shared\n * prototype instead of own properties on every instance. On first\n * access the getter allocates the per-instance closure and caches it\n * as a non-enumerable own property, so detached usage still works and\n * the allocation only happens for methods actually touched. */\nfunction _lazyMethod(proto, key, make) {\n Object.defineProperty(proto, key, {\n configurable: true,\n enumerable: false,\n get() {\n const value = make(this);\n Object.defineProperty(this, key, { value, configurable: true, writable: true });\n return value;\n },\n set(value) {\n Object.defineProperty(this, key, { value, configurable: true, writable: true });\n },\n });\n}\nconst initializer = (inst, issues) => {\n $ZodError.init(inst, issues);\n inst.name = \"ZodError\";\n const proto = Object.getPrototypeOf(inst);\n if (_installedErrorProtos.has(proto))\n return;\n _installedErrorProtos.add(proto);\n _lazyMethod(proto, \"format\", (self) => (mapper) => core.formatError(self, mapper));\n _lazyMethod(proto, \"flatten\", (self) => (mapper) => core.flattenError(self, mapper));\n _lazyMethod(proto, \"addIssue\", (self) => (issue) => {\n self.issues.push(issue);\n self.message = JSON.stringify(self.issues, util.jsonStringifyReplacer, 2);\n });\n _lazyMethod(proto, \"addIssues\", (self) => (issues) => {\n self.issues.push(...issues);\n self.message = JSON.stringify(self.issues, util.jsonStringifyReplacer, 2);\n });\n Object.defineProperty(proto, \"isEmpty\", {\n configurable: true,\n enumerable: false,\n get() {\n return this.issues.length === 0;\n },\n });\n};\nexport const ZodError = /*@__PURE__*/ core.$constructor(\"ZodError\", initializer);\nexport const ZodRealError = /*@__PURE__*/ core.$constructor(\"ZodError\", initializer, undefined, {\n Parent: Error,\n});\n// /** @deprecated Use `z.core.$ZodErrorMapCtx` instead. */\n// export type ErrorMapCtx = core.$ZodErrorMapCtx;\n", "import * as core from \"../core/index.js\";\nimport { ZodRealError } from \"./errors.js\";\nexport const parse = /* @__PURE__ */ core._parse(ZodRealError);\nexport const parseAsync = /* @__PURE__ */ core._parseAsync(ZodRealError);\nexport const safeParse = /* @__PURE__ */ core._safeParse(ZodRealError);\nexport const safeParseAsync = /* @__PURE__ */ core._safeParseAsync(ZodRealError);\nexport { validate, validateAsync } from \"../core/index.js\";\n// Codec functions\nexport const encode = /* @__PURE__ */ core._encode(ZodRealError);\nexport const decode = /* @__PURE__ */ core._decode(ZodRealError);\nexport const encodeAsync = /* @__PURE__ */ core._encodeAsync(ZodRealError);\nexport const decodeAsync = /* @__PURE__ */ core._decodeAsync(ZodRealError);\nexport const safeEncode = /* @__PURE__ */ core._safeEncode(ZodRealError);\nexport const safeDecode = /* @__PURE__ */ core._safeDecode(ZodRealError);\nexport const safeEncodeAsync = /* @__PURE__ */ core._safeEncodeAsync(ZodRealError);\nexport const safeDecodeAsync = /* @__PURE__ */ core._safeDecodeAsync(ZodRealError);\n", "import * as core from \"../core/index.js\";\nimport { util } from \"../core/index.js\";\nimport * as processors from \"../core/json-schema-processors.js\";\nimport * as regexes from \"../core/regexes.js\";\nimport { createStandardJSONSchemaMethod, createToJSONSchemaMethod } from \"../core/to-json-schema.js\";\nimport en from \"../locales/en.js\";\nimport * as checks from \"./checks.js\";\nimport * as parse from \"./parse.js\";\n// Register English as the default locale on first ZodType construction. Hooked into the `ZodType` `$constructor` (rather than a top-level `config(en())` in `external.ts`) so bundlers honoring `sideEffects: false` can't tree-shake it out \u2014 see #5953, #5725. An explicit `z.config(z.locales.xx())` call wins regardless of order, since this only sets the default when none is present.\nfunction _ensureDefaultLocale() {\n if (!core.globalConfig.localeError)\n core.config(en());\n}\n// the default memoizer is read by the core container init, which runs before `ZodType.init`, so each container calls this first\nfunction _ensureDefaultMemoizer() {\n if (!core.globalConfig.memoizer)\n core.config({ memoizer: core.memoizer() });\n}\nexport const ZodType = /*@__PURE__*/ core.$constructor(\"ZodType\", (inst, def) => {\n _ensureDefaultLocale();\n core.$ZodType.init(inst, def);\n inst.def = def;\n inst.type = def.type;\n return inst;\n}, {\n check(...chks) {\n const def = this.def;\n return this.clone(util.mergeDefs(def, {\n checks: [\n ...(def.checks ?? []),\n ...chks.map((ch) => typeof ch === \"function\" ? { _zod: { check: ch, def: { check: \"custom\" }, onattach: [] } } : ch),\n ],\n }), { parent: true });\n },\n with(...chks) {\n return this.check(...chks);\n },\n clone(def, params) {\n return core.clone(this, def, params);\n },\n brand() {\n return this;\n },\n register(reg, meta) {\n reg.add(this, meta);\n return this;\n },\n refine(check, params) {\n return this.check(refine(check, params));\n },\n superRefine(refinement, params) {\n return this.check(superRefine(refinement, params));\n },\n overwrite(fn) {\n return this.check(checks.overwrite(fn));\n },\n optional() {\n return optional(this);\n },\n exactOptional() {\n return exactOptional(this);\n },\n nullable() {\n return nullable(this);\n },\n nullish() {\n return optional(nullable(this));\n },\n nonoptional(params) {\n return nonoptional(this, params);\n },\n array() {\n return array(this);\n },\n or(arg) {\n return union([this, arg]);\n },\n and(arg) {\n return intersection(this, arg);\n },\n transform(tx) {\n return pipe(this, transform(tx));\n },\n default(d) {\n return _default(this, d);\n },\n prefault(d) {\n return prefault(this, d);\n },\n catch(params) {\n return _catch(this, params);\n },\n pipe(target) {\n return pipe(this, target);\n },\n readonly() {\n return readonly(this);\n },\n describe(description) {\n const cl = this.clone();\n core.globalRegistry.add(cl, { description });\n return cl;\n },\n meta(...args) {\n // overloaded: meta() returns the registered metadata, meta(data) returns a clone with `data` registered. The mapped type picks up the second overload, so we accept variadic any-args and return `any` to satisfy both at runtime.\n if (args.length === 0)\n return core.globalRegistry.get(this);\n const cl = this.clone();\n core.globalRegistry.add(cl, args[0]);\n return cl;\n },\n isOptional() {\n return this.safeParse(undefined).success;\n },\n isNullable() {\n return this.safeParse(null).success;\n },\n apply(fn, ...args) {\n return args.length === 0 ? fn(this) : fn(this, ...args);\n },\n // Overrides core's `~standard` to add `jsonSchema`. Must stay a prototype entry: redefining it per instance demotes instances to dictionary mode.\n get \"~standard\"() {\n return util.hide(this, \"~standard\", {\n ...core.standardProps(this),\n jsonSchema: {\n input: createStandardJSONSchemaMethod(this, \"input\"),\n output: createStandardJSONSchemaMethod(this, \"output\"),\n },\n });\n },\n set \"~standard\"(value) {\n util.own(this, \"~standard\", value);\n },\n parse: function _parse(data, params) {\n return parse.parse(this, data, params, { callee: _parse });\n },\n parseAsync: async function _parseAsync(data, params) {\n return await parse.parseAsync(this, data, params, { callee: _parseAsync });\n },\n safeParse(data, params) {\n return parse.safeParse(this, data, params);\n },\n async safeParseAsync(data, params) {\n return parse.safeParseAsync(this, data, params);\n },\n // `spa` is an alias: same function object as `safeParseAsync`, as before.\n get spa() {\n return this?.safeParseAsync;\n },\n set spa(value) {\n util.own(this, \"spa\", value);\n },\n validate(data, params) {\n return parse.validate(this, data, params);\n },\n validateAsync(data, params) {\n return parse.validateAsync(this, data, params);\n },\n encode: function _encode(data, params) {\n return parse.encode(this, data, params, { callee: _encode });\n },\n decode: function _decode(data, params) {\n return parse.decode(this, data, params, { callee: _decode });\n },\n encodeAsync: async function _encodeAsync(data, params) {\n return await parse.encodeAsync(this, data, params, { callee: _encodeAsync });\n },\n decodeAsync: async function _decodeAsync(data, params) {\n return await parse.decodeAsync(this, data, params, { callee: _decodeAsync });\n },\n safeEncode(data, params) {\n return parse.safeEncode(this, data, params);\n },\n safeDecode(data, params) {\n return parse.safeDecode(this, data, params);\n },\n async safeEncodeAsync(data, params) {\n return parse.safeEncodeAsync(this, data, params);\n },\n async safeDecodeAsync(data, params) {\n return parse.safeDecodeAsync(this, data, params);\n },\n toJSONSchema(params) {\n return createToJSONSchemaMethod(this, {})(params);\n },\n // Reads through to the registry on every access, so it must not cache.\n get description() {\n return core.globalRegistry.get(this)?.description;\n },\n // No setter: `schema._def = x` throws, as it did when `_def` was a non-writable own property.\n get _def() {\n return this._zod.def;\n },\n});\n/** @internal */\nexport const _ZodString = /*@__PURE__*/ core.$constructor(\"_ZodString\", (inst, def) => {\n core.$ZodString.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.stringProcessor(inst, ctx, json, params);\n}, \n/*@__PURE__*/ util.derived({\n format: (inst) => processors.aggregateChecks(inst).format ?? null,\n minLength: (inst) => processors.aggregateChecks(inst).minimum ?? null,\n maxLength: (inst) => processors.aggregateChecks(inst).maximum ?? null,\n}, {\n regex(...args) {\n return this.check(checks.regex(...args));\n },\n includes(...args) {\n return this.check(checks.includes(...args));\n },\n startsWith(...args) {\n return this.check(checks.startsWith(...args));\n },\n endsWith(...args) {\n return this.check(checks.endsWith(...args));\n },\n min(...args) {\n return this.check(checks.minLength(...args));\n },\n max(...args) {\n return this.check(checks.maxLength(...args));\n },\n length(...args) {\n return this.check(checks.length(...args));\n },\n nonempty(...args) {\n return this.check(checks.minLength(1, ...args));\n },\n lowercase(params) {\n return this.check(checks.lowercase(params));\n },\n uppercase(params) {\n return this.check(checks.uppercase(params));\n },\n trim() {\n return this.check(checks.trim());\n },\n normalize(...args) {\n return this.check(checks.normalize(...args));\n },\n toLowerCase() {\n return this.check(checks.toLowerCase());\n },\n toUpperCase() {\n return this.check(checks.toUpperCase());\n },\n slugify() {\n return this.check(checks.slugify());\n },\n}));\nexport const ZodString = /*@__PURE__*/ core.$constructor(\"ZodString\", (inst, def) => {\n core.$ZodString.init(inst, def);\n _ZodString.init(inst, def);\n}, {\n email(params) {\n return this.check(core._email(ZodEmail, params));\n },\n url(params) {\n return this.check(core._url(ZodURL, params));\n },\n jwt(params) {\n return this.check(core._jwt(ZodJWT, params));\n },\n emoji(params) {\n return this.check(core._emoji(ZodEmoji, params));\n },\n guid(params) {\n return this.check(core._guid(ZodGUID, params));\n },\n uuid(params) {\n return this.check(core._uuid(ZodUUID, params));\n },\n uuidv4(params) {\n return this.check(core._uuidv4(ZodUUID, params));\n },\n uuidv6(params) {\n return this.check(core._uuidv6(ZodUUID, params));\n },\n uuidv7(params) {\n return this.check(core._uuidv7(ZodUUID, params));\n },\n nanoid(params) {\n return this.check(core._nanoid(ZodNanoID, params));\n },\n cuid(params) {\n return this.check(core._cuid(ZodCUID, params));\n },\n cuid2(params) {\n return this.check(core._cuid2(ZodCUID2, params));\n },\n ulid(params) {\n return this.check(core._ulid(ZodULID, params));\n },\n base64(params) {\n return this.check(core._base64(ZodBase64, params));\n },\n base64url(params) {\n return this.check(core._base64url(ZodBase64URL, params));\n },\n xid(params) {\n return this.check(core._xid(ZodXID, params));\n },\n ksuid(params) {\n return this.check(core._ksuid(ZodKSUID, params));\n },\n ipv4(params) {\n return this.check(core._ipv4(ZodIPv4, params));\n },\n ipv6(params) {\n return this.check(core._ipv6(ZodIPv6, params));\n },\n cidrv4(params) {\n return this.check(core._cidrv4(ZodCIDRv4, params));\n },\n cidrv6(params) {\n return this.check(core._cidrv6(ZodCIDRv6, params));\n },\n e164(params) {\n return this.check(core._e164(ZodE164, params));\n },\n datetime(params) {\n return this.check(core._isoDateTime(ZodISODateTime, params));\n },\n date(params) {\n return this.check(core._isoDate(ZodISODate, params));\n },\n time(params) {\n return this.check(core._isoTime(ZodISOTime, params));\n },\n duration(params) {\n return this.check(core._isoDuration(ZodISODuration, params));\n },\n});\nexport function string(params) {\n return core._string(ZodString, params);\n}\nexport const ZodStringFormat = /*@__PURE__*/ core.$constructor(\"ZodStringFormat\", (inst, def) => {\n core.$ZodStringFormat.init(inst, def);\n _ZodString.init(inst, def);\n});\nexport const ZodISODateTime = /*@__PURE__*/ core.$constructor(\"ZodISODateTime\", (inst, def) => {\n core.$ZodISODateTime.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport const ZodISODate = /*@__PURE__*/ core.$constructor(\"ZodISODate\", (inst, def) => {\n core.$ZodISODate.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport const ZodISOTime = /*@__PURE__*/ core.$constructor(\"ZodISOTime\", (inst, def) => {\n core.$ZodISOTime.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport const ZodISODuration = /*@__PURE__*/ core.$constructor(\"ZodISODuration\", (inst, def) => {\n core.$ZodISODuration.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport const ZodEmail = /*@__PURE__*/ core.$constructor(\"ZodEmail\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodEmail.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function email(params) {\n return core._email(ZodEmail, params);\n}\nexport const ZodGUID = /*@__PURE__*/ core.$constructor(\"ZodGUID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodGUID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function guid(params) {\n return core._guid(ZodGUID, params);\n}\nexport const ZodUUID = /*@__PURE__*/ core.$constructor(\"ZodUUID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodUUID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function uuid(params) {\n return core._uuid(ZodUUID, params);\n}\nexport function uuidv4(params) {\n return core._uuidv4(ZodUUID, params);\n}\n// ZodUUIDv6\nexport function uuidv6(params) {\n return core._uuidv6(ZodUUID, params);\n}\n// ZodUUIDv7\nexport function uuidv7(params) {\n return core._uuidv7(ZodUUID, params);\n}\nexport const ZodURL = /*@__PURE__*/ core.$constructor(\"ZodURL\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodURL.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function url(params) {\n return core._url(ZodURL, params);\n}\nexport function httpUrl(params) {\n return core._url(ZodURL, {\n protocol: regexes.httpProtocol,\n hostname: regexes.domain,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodEmoji = /*@__PURE__*/ core.$constructor(\"ZodEmoji\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodEmoji.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function emoji(params) {\n return core._emoji(ZodEmoji, params);\n}\nexport const ZodNanoID = /*@__PURE__*/ core.$constructor(\"ZodNanoID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodNanoID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function nanoid(params) {\n return core._nanoid(ZodNanoID, params);\n}\n/**\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link ZodCUID2} instead.\n * See https://github.com/paralleldrive/cuid.\n */\nexport const ZodCUID = /*@__PURE__*/ core.$constructor(\"ZodCUID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodCUID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\n/**\n * Validates a CUID v1 string.\n *\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link cuid2 | `z.cuid2()`} instead.\n * See https://github.com/paralleldrive/cuid.\n */\nexport function cuid(params) {\n return core._cuid(ZodCUID, params);\n}\nexport const ZodCUID2 = /*@__PURE__*/ core.$constructor(\"ZodCUID2\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodCUID2.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function cuid2(params) {\n return core._cuid2(ZodCUID2, params);\n}\nexport const ZodULID = /*@__PURE__*/ core.$constructor(\"ZodULID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodULID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function ulid(params) {\n return core._ulid(ZodULID, params);\n}\nexport const ZodXID = /*@__PURE__*/ core.$constructor(\"ZodXID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodXID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function xid(params) {\n return core._xid(ZodXID, params);\n}\nexport const ZodKSUID = /*@__PURE__*/ core.$constructor(\"ZodKSUID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodKSUID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function ksuid(params) {\n return core._ksuid(ZodKSUID, params);\n}\nexport const ZodIPv4 = /*@__PURE__*/ core.$constructor(\"ZodIPv4\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodIPv4.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function ipv4(params) {\n return core._ipv4(ZodIPv4, params);\n}\nexport const ZodMAC = /*@__PURE__*/ core.$constructor(\"ZodMAC\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodMAC.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function mac(params) {\n return core._mac(ZodMAC, params);\n}\nexport const ZodIPv6 = /*@__PURE__*/ core.$constructor(\"ZodIPv6\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodIPv6.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function ipv6(params) {\n return core._ipv6(ZodIPv6, params);\n}\nexport const ZodCIDRv4 = /*@__PURE__*/ core.$constructor(\"ZodCIDRv4\", (inst, def) => {\n core.$ZodCIDRv4.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function cidrv4(params) {\n return core._cidrv4(ZodCIDRv4, params);\n}\nexport const ZodCIDRv6 = /*@__PURE__*/ core.$constructor(\"ZodCIDRv6\", (inst, def) => {\n core.$ZodCIDRv6.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function cidrv6(params) {\n return core._cidrv6(ZodCIDRv6, params);\n}\nexport const ZodBase64 = /*@__PURE__*/ core.$constructor(\"ZodBase64\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodBase64.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function base64(params) {\n return core._base64(ZodBase64, params);\n}\nexport const ZodBase64URL = /*@__PURE__*/ core.$constructor(\"ZodBase64URL\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodBase64URL.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function base64url(params) {\n return core._base64url(ZodBase64URL, params);\n}\nexport const ZodE164 = /*@__PURE__*/ core.$constructor(\"ZodE164\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodE164.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function e164(params) {\n return core._e164(ZodE164, params);\n}\nexport const ZodCreditCard = /*@__PURE__*/ core.$constructor(\"ZodCreditCard\", (inst, def) => {\n core.$ZodCreditCard.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function creditCard(params) {\n return core._creditCard(ZodCreditCard, params);\n}\nexport const ZodIBAN = /*@__PURE__*/ core.$constructor(\"ZodIBAN\", (inst, def) => {\n core.$ZodIBAN.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function iban(params) {\n return core._iban(ZodIBAN, params);\n}\nexport const ZodJWT = /*@__PURE__*/ core.$constructor(\"ZodJWT\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodJWT.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function jwt(params) {\n return core._jwt(ZodJWT, params);\n}\nexport const ZodCustomStringFormat = /*@__PURE__*/ core.$constructor(\"ZodCustomStringFormat\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodCustomStringFormat.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function stringFormat(format, fnOrRegex, _params = {}) {\n return core._stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);\n}\nexport function hostname(_params) {\n return core._stringFormat(ZodCustomStringFormat, \"hostname\", regexes.hostname, _params);\n}\nexport function hex(_params) {\n return core._stringFormat(ZodCustomStringFormat, \"hex\", regexes.hex, _params);\n}\nexport function currencyCode(_params) {\n return core._stringFormat(ZodCustomStringFormat, \"currency_code\", regexes.currencyCode, _params);\n}\nexport function hash(alg, params) {\n const enc = params?.enc ?? \"hex\";\n const format = `${alg}_${enc}`;\n const regex = core.regexes[format];\n if (!regex)\n throw new Error(`Unrecognized hash format: ${format}`);\n return core._stringFormat(ZodCustomStringFormat, format, regex, params);\n}\nexport const ZodNumber = /*@__PURE__*/ core.$constructor(\"ZodNumber\", (inst, def) => {\n core.$ZodNumber.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.numberProcessor(inst, ctx, json, params);\n inst.isFinite = true;\n}, \n/*@__PURE__*/ util.derived({\n minValue: (inst) => {\n const { minimum, exclusiveMinimum } = processors.aggregateChecks(inst);\n return Math.max(minimum ?? Number.NEGATIVE_INFINITY, exclusiveMinimum ?? Number.NEGATIVE_INFINITY);\n },\n maxValue: (inst) => {\n const { maximum, exclusiveMaximum } = processors.aggregateChecks(inst);\n return Math.min(maximum ?? Number.POSITIVE_INFINITY, exclusiveMaximum ?? Number.POSITIVE_INFINITY);\n },\n isInt: (inst) => {\n const { isInt, multipleOf } = processors.aggregateChecks(inst);\n return !!isInt || !!multipleOf?.some(Number.isSafeInteger);\n },\n format: (inst) => processors.aggregateChecks(inst).format ?? null,\n}, {\n gt(value, params) {\n return this.check(checks.gt(value, params));\n },\n gte(value, params) {\n return this.check(checks.gte(value, params));\n },\n min(value, params) {\n return this.check(checks.gte(value, params));\n },\n lt(value, params) {\n return this.check(checks.lt(value, params));\n },\n lte(value, params) {\n return this.check(checks.lte(value, params));\n },\n max(value, params) {\n return this.check(checks.lte(value, params));\n },\n int(params) {\n return this.check(int(params));\n },\n safe(params) {\n return this.check(int(params));\n },\n positive(params) {\n return this.check(checks.gt(0, params));\n },\n nonnegative(params) {\n return this.check(checks.gte(0, params));\n },\n negative(params) {\n return this.check(checks.lt(0, params));\n },\n nonpositive(params) {\n return this.check(checks.lte(0, params));\n },\n multipleOf(value, params) {\n return this.check(checks.multipleOf(value, params));\n },\n step(value, params) {\n return this.check(checks.multipleOf(value, params));\n },\n finite() {\n return this;\n },\n}));\nexport function number(params) {\n return core._number(ZodNumber, params);\n}\nexport const ZodNumberFormat = /*@__PURE__*/ core.$constructor(\"ZodNumberFormat\", (inst, def) => {\n core.$ZodNumberFormat.init(inst, def);\n ZodNumber.init(inst, def);\n});\nexport function int(params) {\n return core._int(ZodNumberFormat, params);\n}\nexport function float32(params) {\n return core._float32(ZodNumberFormat, params);\n}\nexport function float64(params) {\n return core._float64(ZodNumberFormat, params);\n}\nexport function int32(params) {\n return core._int32(ZodNumberFormat, params);\n}\nexport function uint32(params) {\n return core._uint32(ZodNumberFormat, params);\n}\nexport const ZodBoolean = /*@__PURE__*/ core.$constructor(\"ZodBoolean\", (inst, def) => {\n core.$ZodBoolean.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.booleanProcessor(inst, ctx, json, params);\n});\nexport function boolean(params) {\n return core._boolean(ZodBoolean, params);\n}\nexport const ZodBigInt = /*@__PURE__*/ core.$constructor(\"ZodBigInt\", (inst, def) => {\n core.$ZodBigInt.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.bigintProcessor(inst, ctx, json, params);\n}, \n/*@__PURE__*/ util.derived({\n minValue: (inst) => processors.aggregateChecks(inst).minimum ?? null,\n maxValue: (inst) => processors.aggregateChecks(inst).maximum ?? null,\n format: (inst) => processors.aggregateChecks(inst).format ?? null,\n}, {\n gte(value, params) {\n return this.check(checks.gte(value, params));\n },\n min(value, params) {\n return this.check(checks.gte(value, params));\n },\n gt(value, params) {\n return this.check(checks.gt(value, params));\n },\n lt(value, params) {\n return this.check(checks.lt(value, params));\n },\n lte(value, params) {\n return this.check(checks.lte(value, params));\n },\n max(value, params) {\n return this.check(checks.lte(value, params));\n },\n positive(params) {\n return this.check(checks.gt(BigInt(0), params));\n },\n negative(params) {\n return this.check(checks.lt(BigInt(0), params));\n },\n nonpositive(params) {\n return this.check(checks.lte(BigInt(0), params));\n },\n nonnegative(params) {\n return this.check(checks.gte(BigInt(0), params));\n },\n multipleOf(value, params) {\n return this.check(checks.multipleOf(value, params));\n },\n}));\nexport function bigint(params) {\n return core._bigint(ZodBigInt, params);\n}\nexport const ZodBigIntFormat = /*@__PURE__*/ core.$constructor(\"ZodBigIntFormat\", (inst, def) => {\n core.$ZodBigIntFormat.init(inst, def);\n ZodBigInt.init(inst, def);\n});\nexport function int64(params) {\n return core._int64(ZodBigIntFormat, params);\n}\nexport function uint64(params) {\n return core._uint64(ZodBigIntFormat, params);\n}\nexport const ZodSymbol = /*@__PURE__*/ core.$constructor(\"ZodSymbol\", (inst, def) => {\n core.$ZodSymbol.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.symbolProcessor(inst, ctx, json, params);\n});\nexport function symbol(params) {\n return core._symbol(ZodSymbol, params);\n}\nexport const ZodUndefined = /*@__PURE__*/ core.$constructor(\"ZodUndefined\", (inst, def) => {\n core.$ZodUndefined.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.undefinedProcessor(inst, ctx, json, params);\n});\nfunction _undefined(params) {\n return core._undefined(ZodUndefined, params);\n}\nexport { _undefined as undefined };\nexport const ZodNull = /*@__PURE__*/ core.$constructor(\"ZodNull\", (inst, def) => {\n core.$ZodNull.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.nullProcessor(inst, ctx, json, params);\n});\nfunction _null(params) {\n return core._null(ZodNull, params);\n}\nexport { _null as null };\nexport const ZodAny = /*@__PURE__*/ core.$constructor(\"ZodAny\", (inst, def) => {\n core.$ZodAny.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.anyProcessor(inst, ctx, json, params);\n});\nexport function any() {\n return core._any(ZodAny);\n}\nexport const ZodUnknown = /*@__PURE__*/ core.$constructor(\"ZodUnknown\", (inst, def) => {\n core.$ZodUnknown.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.unknownProcessor(inst, ctx, json, params);\n});\nexport function unknown() {\n return core._unknown(ZodUnknown);\n}\nexport const ZodNever = /*@__PURE__*/ core.$constructor(\"ZodNever\", (inst, def) => {\n core.$ZodNever.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.neverProcessor(inst, ctx, json, params);\n});\nexport function never(params) {\n return core._never(ZodNever, params);\n}\nexport const ZodVoid = /*@__PURE__*/ core.$constructor(\"ZodVoid\", (inst, def) => {\n core.$ZodVoid.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.voidProcessor(inst, ctx, json, params);\n});\nfunction _void(params) {\n return core._void(ZodVoid, params);\n}\nexport { _void as void };\nexport const ZodDate = /*@__PURE__*/ core.$constructor(\"ZodDate\", (inst, def) => {\n core.$ZodDate.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.dateProcessor(inst, ctx, json, params);\n inst.min = (value, params) => inst.check(checks.gte(value, params));\n inst.max = (value, params) => inst.check(checks.lte(value, params));\n}, \n/*@__PURE__*/ util.derived({\n minDate: (inst) => {\n const { minimum } = processors.aggregateChecks(inst);\n return minimum ? new Date(minimum) : null;\n },\n maxDate: (inst) => {\n const { maximum } = processors.aggregateChecks(inst);\n return maximum ? new Date(maximum) : null;\n },\n}, {}));\nexport function date(params) {\n return core._date(ZodDate, params);\n}\nexport const ZodArray = /*@__PURE__*/ core.$constructor(\"ZodArray\", (inst, def) => {\n _ensureDefaultMemoizer();\n core.$ZodArray.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.arrayProcessor(inst, ctx, json, params);\n inst.element = def.element;\n}, {\n min(n, params) {\n return this.check(checks.minLength(n, params));\n },\n nonempty(params) {\n return this.check(checks.minLength(1, params));\n },\n max(n, params) {\n return this.check(checks.maxLength(n, params));\n },\n length(n, params) {\n return this.check(checks.length(n, params));\n },\n unwrap() {\n return this.element;\n },\n});\nexport function array(element, params) {\n return core._array(ZodArray, element, params);\n}\n// .keyof\nexport function keyof(schema) {\n const shape = schema._zod.def.shape;\n return _enum(Object.keys(shape));\n}\nexport const ZodObject = /*@__PURE__*/ core.$constructor(\"ZodObject\", (inst, def) => {\n _ensureDefaultMemoizer();\n core.$ZodObjectJIT.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.objectProcessor(inst, ctx, json, params);\n util.installLazyProp(inst, \"shape\", (self) => self._zod.def.shape, false);\n}, {\n keyof() {\n return _enum(Object.keys(this._zod.def.shape));\n },\n catchall(catchall) {\n // `mergeDefs` rather than a spread: spreading reads `shape`, and resolving it can mint a whole fresh subtree\n return this.clone(util.mergeDefs(this._zod.def, { catchall: catchall }));\n },\n passthrough() {\n return this.clone(util.mergeDefs(this._zod.def, { catchall: unknown() }));\n },\n loose() {\n return this.clone(util.mergeDefs(this._zod.def, { catchall: unknown() }));\n },\n strict() {\n return this.clone(util.mergeDefs(this._zod.def, { catchall: never() }));\n },\n strip() {\n return this.clone(util.mergeDefs(this._zod.def, { catchall: undefined }));\n },\n extend(incoming) {\n return util.extend(this, incoming);\n },\n safeExtend(incoming) {\n return util.safeExtend(this, incoming);\n },\n merge(other) {\n return util.merge(this, other);\n },\n pick(mask) {\n return util.pick(this, mask);\n },\n omit(mask) {\n return util.omit(this, mask);\n },\n partial(...args) {\n return util.partial(ZodOptional, this, args[0]);\n },\n exactPartial(...args) {\n return util.partial(ZodExactOptional, this, args[0], \"exactPartial\");\n },\n required(...args) {\n return util.required(ZodNonOptional, this, args[0]);\n },\n});\nexport function object(shape, params) {\n const def = {\n type: \"object\",\n shape: shape ?? {},\n ...util.normalizeParams(params),\n };\n return new ZodObject(def);\n}\n// strictObject\nexport function strictObject(shape, params) {\n return new ZodObject({\n type: \"object\",\n shape,\n catchall: never(),\n ...util.normalizeParams(params),\n });\n}\n// looseObject\nexport function looseObject(shape, params) {\n return new ZodObject({\n type: \"object\",\n shape,\n catchall: unknown(),\n ...util.normalizeParams(params),\n });\n}\nexport const ZodUnion = /*@__PURE__*/ core.$constructor(\"ZodUnion\", (inst, def) => {\n core.$ZodUnion.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.unionProcessor(inst, ctx, json, params);\n inst.options = def.options;\n});\nexport function union(options, params) {\n return new ZodUnion({\n type: \"union\",\n options: options,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodXor = /*@__PURE__*/ core.$constructor(\"ZodXor\", (inst, def) => {\n ZodUnion.init(inst, def);\n core.$ZodXor.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.unionProcessor(inst, ctx, json, params);\n inst.options = def.options;\n});\n/** Creates an exclusive union (XOR) where exactly one option must match.\n * Unlike regular unions that succeed when any option matches, xor fails if\n * zero or more than one option matches the input. */\nexport function xor(options, params) {\n return new ZodXor({\n type: \"union\",\n options: options,\n inclusive: false,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodDiscriminatedUnion = /*@__PURE__*/ core.$constructor(\"ZodDiscriminatedUnion\", (inst, def) => {\n ZodUnion.init(inst, def);\n core.$ZodDiscriminatedUnion.init(inst, def);\n});\nexport function discriminatedUnion(discriminator, options, params) {\n // const [options, params] = args;\n return new ZodDiscriminatedUnion({\n type: \"union\",\n options: options,\n discriminator,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodIntersection = /*@__PURE__*/ core.$constructor(\"ZodIntersection\", (inst, def) => {\n core.$ZodIntersection.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.intersectionProcessor(inst, ctx, json, params);\n});\nexport function intersection(left, right) {\n return new ZodIntersection({\n type: \"intersection\",\n left: left,\n right: right,\n });\n}\nexport const ZodTuple = /*@__PURE__*/ core.$constructor(\"ZodTuple\", (inst, def) => {\n _ensureDefaultMemoizer();\n core.$ZodTuple.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.tupleProcessor(inst, ctx, json, params);\n}, {\n rest(rest) {\n return this.clone({\n ...this._zod.def,\n rest: rest,\n });\n },\n partial() {\n const def = this._zod.def;\n // a refinement was authored against the full arity; partialing would run it on a shorter array\n if (def.checks?.length)\n throw new Error(\".partial() cannot be used on tuple schemas containing refinements\");\n return this.clone({\n ...def,\n items: def.items.map((item) => new ZodOptional({ type: \"optional\", innerType: item })),\n });\n },\n});\nexport function tuple(items, _paramsOrRest, _params) {\n const hasRest = _paramsOrRest instanceof core.$ZodType;\n const params = hasRest ? _params : _paramsOrRest;\n const rest = hasRest ? _paramsOrRest : null;\n return new ZodTuple({\n type: \"tuple\",\n items: items,\n rest,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodRecord = /*@__PURE__*/ core.$constructor(\"ZodRecord\", (inst, def) => {\n _ensureDefaultMemoizer();\n core.$ZodRecord.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.recordProcessor(inst, ctx, json, params);\n inst.keyType = def.keyType;\n inst.valueType = def.valueType;\n});\nexport function record(keyType, valueType, params) {\n // v3-compat: z.record(valueType, params?) \u2014 defaults keyType to z.string()\n if (!valueType || !valueType._zod) {\n return new ZodRecord({\n type: \"record\",\n keyType: string(),\n valueType: keyType,\n ...util.normalizeParams(valueType),\n });\n }\n return new ZodRecord({\n type: \"record\",\n keyType,\n valueType: valueType,\n ...util.normalizeParams(params),\n });\n}\n// type alksjf = core.output;\nexport function partialRecord(keyType, valueType, params) {\n return new ZodRecord({\n type: \"record\",\n keyType,\n valueType: valueType,\n ...util.normalizeParams(params),\n partial: true,\n });\n}\nexport function looseRecord(keyType, valueType, params) {\n return new ZodRecord({\n type: \"record\",\n keyType,\n valueType: valueType,\n mode: \"loose\",\n ...util.normalizeParams(params),\n });\n}\nexport const ZodMap = /*@__PURE__*/ core.$constructor(\"ZodMap\", (inst, def) => {\n _ensureDefaultMemoizer();\n core.$ZodMap.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.mapProcessor(inst, ctx, json, params);\n inst.keyType = def.keyType;\n inst.valueType = def.valueType;\n inst.min = (...args) => inst.check(core._minSize(...args));\n inst.nonempty = (params) => inst.check(core._minSize(1, params));\n inst.max = (...args) => inst.check(core._maxSize(...args));\n inst.size = (...args) => inst.check(core._size(...args));\n});\nexport function map(keyType, valueType, params) {\n return new ZodMap({\n type: \"map\",\n keyType: keyType,\n valueType: valueType,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodSet = /*@__PURE__*/ core.$constructor(\"ZodSet\", (inst, def) => {\n _ensureDefaultMemoizer();\n core.$ZodSet.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.setProcessor(inst, ctx, json, params);\n inst.min = (...args) => inst.check(core._minSize(...args));\n inst.nonempty = (params) => inst.check(core._minSize(1, params));\n inst.max = (...args) => inst.check(core._maxSize(...args));\n inst.size = (...args) => inst.check(core._size(...args));\n});\nexport function set(valueType, params) {\n return new ZodSet({\n type: \"set\",\n valueType: valueType,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodEnum = /*@__PURE__*/ core.$constructor(\"ZodEnum\", (inst, def) => {\n core.$ZodEnum.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.enumProcessor(inst, ctx, json, params);\n inst.enum = def.entries;\n // reuse the parsed value set so a numeric TS enum's reverse-mapping keys stay out\n inst.options = [...inst._zod.values];\n const keys = new Set(Object.keys(def.entries));\n inst.extract = (values, params) => {\n const newEntries = {};\n for (const value of values) {\n if (keys.has(value)) {\n newEntries[value] = def.entries[value];\n }\n else\n throw new Error(`Key ${value} not found in enum`);\n }\n return new ZodEnum({\n ...def,\n checks: [],\n ...util.normalizeParams(params),\n entries: newEntries,\n });\n };\n inst.exclude = (values, params) => {\n const newEntries = { ...def.entries };\n for (const value of values) {\n if (keys.has(value)) {\n delete newEntries[value];\n }\n else\n throw new Error(`Key ${value} not found in enum`);\n }\n return new ZodEnum({\n ...def,\n checks: [],\n ...util.normalizeParams(params),\n entries: newEntries,\n });\n };\n});\nfunction _enum(values, params) {\n const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values;\n return new ZodEnum({\n type: \"enum\",\n entries,\n ...util.normalizeParams(params),\n });\n}\nexport { _enum as enum };\n/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead.\n *\n * ```ts\n * enum Colors { red, green, blue }\n * z.enum(Colors);\n * ```\n */\nexport function nativeEnum(entries, params) {\n return new ZodEnum({\n type: \"enum\",\n entries,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodLiteral = /*@__PURE__*/ core.$constructor(\"ZodLiteral\", (inst, def) => {\n core.$ZodLiteral.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.literalProcessor(inst, ctx, json, params);\n inst.values = new Set(def.values);\n Object.defineProperty(inst, \"value\", {\n get() {\n if (def.values.length > 1) {\n throw new Error(\"This schema contains multiple valid literal values. Use `.values` instead.\");\n }\n return def.values[0];\n },\n });\n});\nexport function literal(value, params) {\n return new ZodLiteral({\n type: \"literal\",\n values: Array.isArray(value) ? value : [value],\n ...util.normalizeParams(params),\n });\n}\nexport const ZodFile = /*@__PURE__*/ core.$constructor(\"ZodFile\", (inst, def) => {\n core.$ZodFile.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.fileProcessor(inst, ctx, json, params);\n inst.min = (size, params) => inst.check(core._minSize(size, params));\n inst.max = (size, params) => inst.check(core._maxSize(size, params));\n inst.mime = (types, params) => inst.check(core._mime(Array.isArray(types) ? types : [types], params));\n});\nexport function file(params) {\n return core._file(ZodFile, params);\n}\nexport const ZodTransform = /*@__PURE__*/ core.$constructor(\"ZodTransform\", (inst, def) => {\n _ensureDefaultMemoizer();\n core.$ZodTransform.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.transformProcessor(inst, ctx, json, params);\n inst._zod.parse = (payload, _ctx) => {\n if (_ctx.direction === \"backward\") {\n throw new core.$ZodEncodeError(inst.constructor.name);\n }\n payload.addIssue = (issue) => {\n if (typeof issue === \"string\") {\n payload.issues.push(util.issue(issue, payload.value, def));\n }\n else {\n // for Zod 3 backwards compatibility\n const _issue = issue;\n if (_issue.fatal)\n _issue.continue = false;\n _issue.code ?? (_issue.code = \"custom\");\n if (!(\"input\" in _issue))\n _issue.input = payload.value;\n _issue.inst ?? (_issue.inst = inst);\n // _issue.continue ??= true;\n payload.issues.push(util.issue(_issue));\n }\n };\n const output = def.transform(payload.value, payload);\n if (output instanceof Promise) {\n return output.then((output) => {\n payload.value = output;\n return payload;\n });\n }\n payload.value = output;\n return payload;\n };\n});\nexport function transform(fn) {\n return new ZodTransform({\n type: \"transform\",\n transform: fn,\n });\n}\nexport const ZodOptional = /*@__PURE__*/ core.$constructor(\"ZodOptional\", (inst, def) => {\n core.$ZodOptional.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.optionalProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function optional(innerType) {\n return new ZodOptional({\n type: \"optional\",\n innerType: innerType,\n });\n}\nexport const ZodExactOptional = /*@__PURE__*/ core.$constructor(\"ZodExactOptional\", (inst, def) => {\n core.$ZodExactOptional.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.optionalProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function exactOptional(innerType) {\n return new ZodExactOptional({\n type: \"optional\",\n innerType: innerType,\n });\n}\nexport const ZodNullable = /*@__PURE__*/ core.$constructor(\"ZodNullable\", (inst, def) => {\n core.$ZodNullable.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.nullableProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function nullable(innerType) {\n return new ZodNullable({\n type: \"nullable\",\n innerType: innerType,\n });\n}\n// nullish\nexport function nullish(innerType) {\n return optional(nullable(innerType));\n}\nexport const ZodDefault = /*@__PURE__*/ core.$constructor(\"ZodDefault\", (inst, def) => {\n core.$ZodDefault.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.defaultProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n inst.removeDefault = inst.unwrap;\n});\nexport function _default(innerType, defaultValue) {\n return new ZodDefault({\n type: \"default\",\n innerType: innerType,\n get defaultValue() {\n return typeof defaultValue === \"function\" ? defaultValue() : util.shallowClone(defaultValue);\n },\n });\n}\nexport const ZodPrefault = /*@__PURE__*/ core.$constructor(\"ZodPrefault\", (inst, def) => {\n core.$ZodPrefault.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.prefaultProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function prefault(innerType, defaultValue) {\n return new ZodPrefault({\n type: \"prefault\",\n innerType: innerType,\n get defaultValue() {\n return typeof defaultValue === \"function\" ? defaultValue() : util.shallowClone(defaultValue);\n },\n });\n}\nexport const ZodNonOptional = /*@__PURE__*/ core.$constructor(\"ZodNonOptional\", (inst, def) => {\n core.$ZodNonOptional.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.nonoptionalProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function nonoptional(innerType, params) {\n return new ZodNonOptional({\n type: \"nonoptional\",\n innerType: innerType,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodSuccess = /*@__PURE__*/ core.$constructor(\"ZodSuccess\", (inst, def) => {\n core.$ZodSuccess.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.successProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function success(innerType) {\n return new ZodSuccess({\n type: \"success\",\n innerType: innerType,\n });\n}\nexport const ZodCatch = /*@__PURE__*/ core.$constructor(\"ZodCatch\", (inst, def) => {\n core.$ZodCatch.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.catchProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n inst.removeCatch = inst.unwrap;\n});\nfunction _catch(innerType, catchValue) {\n return new ZodCatch({\n type: \"catch\",\n innerType: innerType,\n catchValue: (typeof catchValue === \"function\" ? catchValue : core.util.constantCatch(catchValue)),\n });\n}\nexport { _catch as catch };\nexport const ZodNaN = /*@__PURE__*/ core.$constructor(\"ZodNaN\", (inst, def) => {\n core.$ZodNaN.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.nanProcessor(inst, ctx, json, params);\n});\nexport function nan(params) {\n return core._nan(ZodNaN, params);\n}\nexport const ZodPipe = /*@__PURE__*/ core.$constructor(\"ZodPipe\", (inst, def) => {\n core.$ZodPipe.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.pipeProcessor(inst, ctx, json, params);\n inst.in = def.in;\n inst.out = def.out;\n});\nexport function pipe(in_, out) {\n return new ZodPipe({\n type: \"pipe\",\n in: in_,\n out: out,\n // ...util.normalizeParams(params),\n });\n}\nexport const ZodCodec = /*@__PURE__*/ core.$constructor(\"ZodCodec\", (inst, def) => {\n ZodPipe.init(inst, def);\n core.$ZodCodec.init(inst, def);\n});\nexport function codec(in_, out, params) {\n return new ZodCodec({\n type: \"pipe\",\n in: in_,\n out: out,\n transform: params.decode,\n reverseTransform: params.encode,\n });\n}\nexport function invertCodec(codec) {\n const def = codec._zod.def;\n return new ZodCodec({\n type: \"pipe\",\n in: def.out,\n out: def.in,\n transform: def.reverseTransform,\n reverseTransform: def.transform,\n });\n}\nexport const ZodPreprocess = /*@__PURE__*/ core.$constructor(\"ZodPreprocess\", (inst, def) => {\n ZodPipe.init(inst, def);\n core.$ZodPreprocess.init(inst, def);\n});\nexport const ZodReadonly = /*@__PURE__*/ core.$constructor(\"ZodReadonly\", (inst, def) => {\n core.$ZodReadonly.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.readonlyProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function readonly(innerType) {\n return new ZodReadonly({\n type: \"readonly\",\n innerType: innerType,\n });\n}\nexport const ZodTemplateLiteral = /*@__PURE__*/ core.$constructor(\"ZodTemplateLiteral\", (inst, def) => {\n core.$ZodTemplateLiteral.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.templateLiteralProcessor(inst, ctx, json, params);\n});\nexport function templateLiteral(parts, params) {\n return new ZodTemplateLiteral({\n type: \"template_literal\",\n parts,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodLazy = /*@__PURE__*/ core.$constructor(\"ZodLazy\", (inst, def) => {\n core.$ZodLazy.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.lazyProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.getter();\n});\nexport function lazy(getter) {\n return new ZodLazy({\n type: \"lazy\",\n getter: getter,\n });\n}\nexport const ZodPromise = /*@__PURE__*/ core.$constructor(\"ZodPromise\", (inst, def) => {\n core.$ZodPromise.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.promiseProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function promise(innerType) {\n return new ZodPromise({\n type: \"promise\",\n innerType: innerType,\n });\n}\nexport const ZodFunction = /*@__PURE__*/ core.$constructor(\"ZodFunction\", (inst, def) => {\n core.$ZodFunction.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.functionProcessor(inst, ctx, json, params);\n});\nexport function _function(params) {\n return new ZodFunction({\n type: \"function\",\n input: Array.isArray(params?.input) ? tuple(params?.input) : (params?.input ?? array(unknown())),\n output: params?.output ?? unknown(),\n });\n}\nexport { _function as function };\nexport const ZodCustom = /*@__PURE__*/ core.$constructor(\"ZodCustom\", (inst, def) => {\n core.$ZodCustom.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.customProcessor(inst, ctx, json, params);\n});\n// custom checks\nexport function check(fn) {\n const ch = new core.$ZodCheck({\n check: \"custom\",\n // ...util.normalizeParams(params),\n });\n ch._zod.check = fn;\n return ch;\n}\nexport function custom(fn, _params) {\n return core._custom(ZodCustom, fn ?? (() => true), _params);\n}\nexport function refine(fn, _params = {}) {\n return core._refine(ZodCustom, fn, _params);\n}\n// superRefine\nexport function superRefine(fn, params) {\n return core._superRefine(fn, params);\n}\n// Re-export describe and meta from core\nexport const describe = core.describe;\nexport const meta = core.meta;\nexport const ZodInstanceOf = /*@__PURE__*/ core.$constructor(\"ZodInstanceOf\", (inst, def) => {\n ZodCustom.init(inst, def);\n}, {\n properties(shape, params) {\n // asserts in place, so the narrowed output type is truthful without a wrapper\n return this.check(core._properties(shape, params));\n },\n});\nfunction _instanceof(cls, params = {}) {\n const inst = new ZodInstanceOf({\n type: \"custom\",\n check: \"custom\",\n fn: (data) => data instanceof cls,\n abort: true,\n ...util.normalizeParams(params),\n });\n inst._zod.bag.Class = cls;\n // Override check to emit invalid_type instead of custom\n inst._zod.check = (payload) => {\n if (!(payload.value instanceof cls)) {\n payload.issues.push({\n code: \"invalid_type\",\n expected: cls.name,\n input: payload.value,\n inst,\n path: [...(inst._zod.def.path ?? [])],\n });\n }\n };\n return inst;\n}\nexport { _instanceof as instanceof };\n// stringbool\nexport const stringbool = (...args) => core._stringbool({\n Codec: ZodCodec,\n Boolean: ZodBoolean,\n String: ZodString,\n}, ...args);\nexport function json(params) {\n const jsonSchema = lazy(() => {\n return union([string(params), number(), boolean(), _null(), array(jsonSchema), record(string(), jsonSchema)]);\n });\n return jsonSchema;\n}\n// preprocess\nexport function preprocess(fn, schema) {\n return new ZodPreprocess({\n type: \"pipe\",\n in: transform(fn),\n out: schema,\n });\n}\n", "// Zod 3 compat layer\nimport * as core from \"../core/index.js\";\n/** @deprecated Use the raw string literal codes instead, e.g. \"invalid_type\". */\nexport const ZodIssueCode = {\n invalid_type: \"invalid_type\",\n too_big: \"too_big\",\n too_small: \"too_small\",\n invalid_format: \"invalid_format\",\n not_multiple_of: \"not_multiple_of\",\n unrecognized_keys: \"unrecognized_keys\",\n invalid_union: \"invalid_union\",\n invalid_key: \"invalid_key\",\n invalid_element: \"invalid_element\",\n invalid_value: \"invalid_value\",\n custom: \"custom\",\n};\nexport { $brand, config } from \"../core/index.js\";\n/** @deprecated Use `z.config(params)` instead. */\nexport function setErrorMap(map) {\n core.config({\n customError: map,\n });\n}\n/** @deprecated Use `z.config()` instead. */\nexport function getErrorMap() {\n return core.config().customError;\n}\n/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */\nexport var ZodFirstPartyTypeKind;\n(function (ZodFirstPartyTypeKind) {\n})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));\n", "import * as core from \"../core/index.js\";\nimport { ZodISODate, ZodISODateTime, ZodISODuration, ZodISOTime } from \"./schemas.js\";\nexport { ZodISODate, ZodISODateTime, ZodISODuration, ZodISOTime } from \"./schemas.js\";\nexport function datetime(params) {\n return core._isoDateTime(ZodISODateTime, params);\n}\nexport function date(params) {\n return core._isoDate(ZodISODate, params);\n}\nexport function time(params) {\n return core._isoTime(ZodISOTime, params);\n}\nexport function duration(params) {\n return core._isoDuration(ZodISODuration, params);\n}\n", "import { globalRegistry } from \"../core/registries.js\";\nimport { assignProp, isPlainObject } from \"../core/util.js\";\nimport * as _checks from \"./checks.js\";\nimport * as _iso from \"./iso.js\";\nimport * as _schemas from \"./schemas.js\";\n// Local z object to avoid circular dependency with ../index.js\nconst z = {\n ..._schemas,\n ..._checks,\n iso: _iso,\n};\n// Keys that are recognized and handled by the conversion logic\nconst RECOGNIZED_KEYS = /*@__PURE__*/ new Set([\n // Schema identification\n \"$schema\",\n \"$ref\",\n \"$defs\",\n \"definitions\",\n // Core schema keywords\n \"$id\",\n \"id\",\n \"$comment\",\n \"$anchor\",\n \"$vocabulary\",\n \"$dynamicRef\",\n \"$dynamicAnchor\",\n // Type\n \"type\",\n \"enum\",\n \"const\",\n // Composition\n \"anyOf\",\n \"oneOf\",\n \"allOf\",\n \"not\",\n // Object\n \"properties\",\n \"required\",\n \"additionalProperties\",\n \"patternProperties\",\n \"propertyNames\",\n \"minProperties\",\n \"maxProperties\",\n // Array\n \"items\",\n \"prefixItems\",\n \"additionalItems\",\n \"minItems\",\n \"maxItems\",\n \"uniqueItems\",\n \"contains\",\n \"minContains\",\n \"maxContains\",\n // String\n \"minLength\",\n \"maxLength\",\n \"pattern\",\n \"format\",\n // Number\n \"minimum\",\n \"maximum\",\n \"exclusiveMinimum\",\n \"exclusiveMaximum\",\n \"multipleOf\",\n // Already handled metadata\n \"description\",\n \"default\",\n // Content\n \"contentEncoding\",\n \"contentMediaType\",\n \"contentSchema\",\n // Unsupported (error-throwing)\n \"unevaluatedItems\",\n \"unevaluatedProperties\",\n \"if\",\n \"then\",\n \"else\",\n \"dependentSchemas\",\n \"dependentRequired\",\n // OpenAPI\n \"nullable\",\n \"readOnly\",\n]);\nfunction detectVersion(schema, defaultTarget) {\n const $schema = schema.$schema;\n if ($schema === \"https://json-schema.org/draft/2020-12/schema\") {\n return \"draft-2020-12\";\n }\n if ($schema === \"http://json-schema.org/draft-07/schema#\") {\n return \"draft-7\";\n }\n if ($schema === \"http://json-schema.org/draft-04/schema#\") {\n return \"draft-4\";\n }\n // Use defaultTarget if provided, otherwise default to draft-2020-12\n return defaultTarget ?? \"draft-2020-12\";\n}\n// Positional schemas constrain the elements that are present; only minItems makes them required.\nfunction applyMinItems(items, minItems) {\n return items.map((item, index) => (index < minItems ? item : item.optional()));\n}\n// Inverse of the encoding applied to $ref pointer segments in to-json-schema.ts. Per RFC 6901 the `~1` replacement must run before `~0`.\nfunction decodeJSONPointerSegment(segment) {\n return segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\nfunction resolveRef(ref, ctx) {\n if (!ref.startsWith(\"#\")) {\n throw new Error(\"External $ref is not supported, only local refs (#/...) are allowed\");\n }\n const path = ref.slice(1).split(\"/\").filter(Boolean);\n // Handle root reference \"#\"\n if (path.length === 0) {\n return ctx.rootSchema;\n }\n const defsKey = ctx.version === \"draft-2020-12\" ? \"$defs\" : \"definitions\";\n if (path[0] === defsKey) {\n const key = path[1] === undefined ? undefined : decodeJSONPointerSegment(path[1]);\n if (!key || !ctx.defs[key]) {\n throw new Error(`Reference not found: ${ref}`);\n }\n return ctx.defs[key];\n }\n throw new Error(`Reference not found: ${ref}`);\n}\n/**\n * Enforces the keywords that constrain an object's own keys \u2014 `propertyNames`,\n * `minProperties`, `maxProperties` \u2014 before `objectSchema` runs. The guard has\n * to see the raw input: an object parse drops `__proto__` and can add keys from\n * a property `default`, so its output is not the set of names the instance\n * actually carried.\n */\nfunction checkObjectGuards(objectSchema, guards) {\n // An identity transform, not z.any(), so `toJSONSchema` reports the object on both the input and the output side of the pipe.\n const guard = z\n .transform((value) => value)\n .check((payload) => {\n const value = payload.value;\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n return;\n const keys = Object.getOwnPropertyNames(value);\n if (guards.minProperties !== undefined && keys.length < guards.minProperties) {\n payload.issues.push({\n origin: \"object\",\n code: \"too_small\",\n minimum: guards.minProperties,\n inclusive: true,\n message: `Too small: expected object to have >=${guards.minProperties} properties`,\n input: value,\n inst: objectSchema,\n continue: true,\n });\n }\n if (guards.maxProperties !== undefined && keys.length > guards.maxProperties) {\n payload.issues.push({\n origin: \"object\",\n code: \"too_big\",\n maximum: guards.maxProperties,\n inclusive: true,\n message: `Too big: expected object to have <=${guards.maxProperties} properties`,\n input: value,\n inst: objectSchema,\n continue: true,\n });\n }\n if (guards.keySchema) {\n for (const key of keys) {\n const result = guards.keySchema.safeParse(key);\n if (result.success)\n continue;\n payload.issues.push({\n code: \"invalid_key\",\n origin: \"record\",\n issues: result.error.issues,\n input: key,\n path: [key],\n continue: true,\n });\n }\n }\n });\n return guard.pipe(objectSchema);\n}\n/**\n * An injective string for JSON data: two values share a key exactly when `uniqueItems` calls them\n * equal, so duplicate detection is a Map lookup rather than a pairwise walk. Strings and keys are\n * length-prefixed so no value can spell another one. `null` means \"never equal to anything\" \u2014 a\n * cycle or a NaN, neither of which JSON can express.\n */\nfunction canonicalKey(value, seen) {\n if (value === null)\n return \"z\";\n const type = typeof value;\n if (type !== \"object\") {\n if (type === \"number\" && Number.isNaN(value))\n return null;\n const raw = String(value);\n return `${type[0]}${raw.length}:${raw}`;\n }\n if (seen.has(value))\n return null;\n seen.add(value);\n try {\n if (Array.isArray(value)) {\n const parts = [];\n for (const item of value) {\n const key = canonicalKey(item, seen);\n if (key === null)\n return null;\n parts.push(key);\n }\n return `a${parts.length}:[${parts.join(\",\")}]`;\n }\n const keys = Object.keys(value).sort();\n const parts = [];\n for (const k of keys) {\n const key = canonicalKey(value[k], seen);\n if (key === null)\n return null;\n parts.push(`${k.length}:${k}=${key}`);\n }\n return `o${parts.length}:{${parts.join(\",\")}}`;\n }\n finally {\n seen.delete(value);\n }\n}\n// keywords whose value is a schema or an array of them\nconst SCHEMA_KEYWORDS = /*@__PURE__*/ new Set([\n \"items\",\n \"prefixItems\",\n \"additionalItems\",\n \"additionalProperties\",\n \"contains\",\n \"propertyNames\",\n \"not\",\n \"if\",\n \"then\",\n \"else\",\n \"allOf\",\n \"anyOf\",\n \"oneOf\",\n \"unevaluatedItems\",\n \"unevaluatedProperties\",\n \"contentSchema\",\n]);\n// keywords whose value maps names to schemas. draft-7 `dependencies` also allows an array of property names, which holds no schema to walk\nconst SCHEMA_MAP_KEYWORDS = /*@__PURE__*/ new Set([\n \"properties\",\n \"patternProperties\",\n \"dependentSchemas\",\n \"dependencies\",\n \"$defs\",\n \"definitions\",\n]);\n/**\n * True when a subschema holds a `$ref` anywhere a schema can appear. Only those positions are\n * walked: `$ref` under `default` or an `x-` annotation is instance data with an ordinary key, and\n * reading it as a reference would drop a constraint that resolves perfectly well.\n */\nfunction containsRef(value) {\n if (typeof value !== \"object\" || value === null)\n return false;\n if (Array.isArray(value))\n return value.some(containsRef);\n if (typeof value.$ref === \"string\")\n return true;\n return Object.entries(value).some(([key, sub]) => {\n if (SCHEMA_KEYWORDS.has(key))\n return containsRef(sub);\n if (!SCHEMA_MAP_KEYWORDS.has(key) || typeof sub !== \"object\" || sub === null)\n return false;\n return Object.values(sub).some(containsRef);\n });\n}\nfunction plural(n) {\n return n === 1 ? \"element\" : \"elements\";\n}\n/**\n * Enforces `uniqueItems` and the `contains` family before `arraySchema` runs, for the same reason\n * `checkObjectGuards` runs pre-pipe: an item parse can apply a nested `default`, so the parsed\n * array is not the instance the keywords are defined over. A guard issue aborts the pipe, so\n * `minItems`/`maxItems` are not also reported on the same parse \u2014 instance correctness is worth\n * more than co-reporting two issues.\n */\nfunction checkArrayGuards(arraySchema, guards) {\n // An identity transform, not z.any(), so `toJSONSchema` reports the array on both the input and the output side of the pipe.\n const guard = z\n .transform((value) => value)\n .check((payload) => {\n const items = payload.value;\n if (!Array.isArray(items))\n return;\n if (guards.uniqueItems === true) {\n const firstSeen = new Map();\n for (let i = 0; i < items.length; i++) {\n const key = canonicalKey(items[i], new Set());\n if (key === null)\n continue;\n const first = firstSeen.get(key);\n if (first === undefined) {\n firstSeen.set(key, i);\n continue;\n }\n payload.issues.push({\n code: \"custom\",\n message: `Array items must be unique: element at index ${i} duplicates the one at index ${first}`,\n input: items,\n path: [i],\n continue: true,\n });\n }\n }\n if (guards.containsSchema) {\n const minContains = guards.minContains ?? 1;\n // one past the ceiling already proves the failure, and nothing above it changes the verdict\n const ceiling = guards.maxContains !== undefined ? guards.maxContains + 1 : Number.POSITIVE_INFINITY;\n let matches = 0;\n for (const item of items) {\n if (guards.containsSchema.safeParse(item).success && ++matches >= ceiling)\n break;\n }\n if (matches < minContains) {\n // the scan ran to the end, so this count is exact\n payload.issues.push({\n code: \"custom\",\n message: `Array must contain at least ${minContains} matching ${plural(minContains)}; found ${matches}`,\n input: items,\n continue: true,\n });\n }\n if (guards.maxContains !== undefined && matches > guards.maxContains) {\n payload.issues.push({\n code: \"custom\",\n message: `Array must contain at most ${guards.maxContains} matching ${plural(guards.maxContains)}`,\n input: items,\n continue: true,\n });\n }\n }\n });\n return guard.pipe(arraySchema);\n}\nfunction getTupleRest(restSchema, ctx) {\n if (restSchema === false) {\n return undefined;\n }\n if (restSchema === undefined || restSchema === true) {\n return z.any();\n }\n return convertSchema(restSchema, ctx);\n}\n// the RFC 3339 full-time keyword, narrower than `z.iso.time()`; local because sharing it via `timeSource` pins that builder into every bundle (+139 B gzipped on a mini `z.boolean()`)\nconst fullTime = /^(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$/;\nfunction convertBaseSchema(schema, ctx) {\n // Handle unsupported features\n if (schema.not !== undefined) {\n // Special case: { not: {} } represents never\n if (typeof schema.not === \"object\" && Object.keys(schema.not).length === 0) {\n return z.never();\n }\n throw new Error(\"not is not supported in Zod (except { not: {} } for never)\");\n }\n if (schema.unevaluatedItems !== undefined) {\n throw new Error(\"unevaluatedItems is not supported\");\n }\n if (schema.unevaluatedProperties !== undefined) {\n throw new Error(\"unevaluatedProperties is not supported\");\n }\n if (schema.if !== undefined || schema.then !== undefined || schema.else !== undefined) {\n throw new Error(\"Conditional schemas (if/then/else) are not supported\");\n }\n if (schema.dependentSchemas !== undefined || schema.dependentRequired !== undefined) {\n throw new Error(\"dependentSchemas and dependentRequired are not supported\");\n }\n // Handle $ref\n if (schema.$ref) {\n const refPath = schema.$ref;\n if (ctx.refs.has(refPath)) {\n return ctx.refs.get(refPath);\n }\n if (ctx.processing.has(refPath)) {\n // Circular reference - use lazy\n return z.lazy(() => {\n if (!ctx.refs.has(refPath)) {\n throw new Error(`Circular reference not resolved: ${refPath}`);\n }\n return ctx.refs.get(refPath);\n });\n }\n ctx.processing.add(refPath);\n const resolved = resolveRef(refPath, ctx);\n const zodSchema = convertSchema(resolved, ctx);\n ctx.refs.set(refPath, zodSchema);\n ctx.processing.delete(refPath);\n return zodSchema;\n }\n // Handle enum\n if (schema.enum !== undefined) {\n const enumValues = schema.enum;\n // Special case: OpenAPI 3.0 null representation { type: \"string\", nullable: true, enum: [null] }\n if (ctx.version === \"openapi-3.0\" &&\n schema.nullable === true &&\n enumValues.length === 1 &&\n enumValues[0] === null) {\n return z.null();\n }\n if (enumValues.length === 0) {\n return z.never();\n }\n if (enumValues.length === 1) {\n return z.literal(enumValues[0]);\n }\n // Check if all values are strings\n if (enumValues.every((v) => typeof v === \"string\")) {\n return z.enum(enumValues);\n }\n // Mixed types - use union of literals\n const literalSchemas = enumValues.map((v) => z.literal(v));\n if (literalSchemas.length < 2) {\n return literalSchemas[0];\n }\n return z.union([literalSchemas[0], literalSchemas[1], ...literalSchemas.slice(2)]);\n }\n // Handle const\n if (schema.const !== undefined) {\n return z.literal(schema.const);\n }\n // Handle type\n const type = schema.type;\n if (Array.isArray(type)) {\n // Expand type array into anyOf union\n const typeSchemas = type.map((t) => {\n const typeSchema = { ...schema, type: t };\n return convertBaseSchema(typeSchema, ctx);\n });\n if (typeSchemas.length === 0) {\n return z.never();\n }\n if (typeSchemas.length === 1) {\n return typeSchemas[0];\n }\n return z.union(typeSchemas);\n }\n if (!type) {\n // No type specified - empty schema (any)\n return z.any();\n }\n let zodSchema;\n switch (type) {\n case \"string\": {\n let stringSchema = z.string();\n // Apply format using .check() with Zod format functions\n if (schema.format) {\n const format = schema.format;\n // Map common formats to Zod check functions\n if (format === \"email\") {\n stringSchema = stringSchema.check(z.email());\n }\n else if (format === \"uri\" || format === \"uri-reference\") {\n stringSchema = stringSchema.check(z.url());\n }\n else if (format === \"uuid\" || format === \"guid\") {\n stringSchema = stringSchema.check(z.uuid());\n }\n else if (format === \"date-time\") {\n stringSchema = stringSchema.check(z.iso.datetime({ offset: true }));\n }\n else if (format === \"date\") {\n stringSchema = stringSchema.check(z.iso.date());\n }\n else if (format === \"time\") {\n stringSchema = stringSchema.check(z.regex(fullTime));\n }\n else if (format === \"duration\") {\n stringSchema = stringSchema.check(z.iso.duration());\n }\n else if (format === \"hostname\") {\n stringSchema = stringSchema.check(z.hostname());\n }\n else if (format === \"ipv4\") {\n stringSchema = stringSchema.check(z.ipv4());\n }\n else if (format === \"ipv6\") {\n stringSchema = stringSchema.check(z.ipv6());\n }\n else if (format === \"mac\") {\n stringSchema = stringSchema.check(z.mac());\n }\n else if (format === \"cidr\") {\n stringSchema = stringSchema.check(z.cidrv4());\n }\n else if (format === \"cidr-v6\") {\n stringSchema = stringSchema.check(z.cidrv6());\n }\n else if (format === \"base64\") {\n stringSchema = stringSchema.check(z.base64());\n }\n else if (format === \"base64url\") {\n stringSchema = stringSchema.check(z.base64url());\n }\n else if (format === \"e164\") {\n stringSchema = stringSchema.check(z.e164());\n }\n else if (format === \"credit_card\") {\n stringSchema = stringSchema.check(z.creditCard());\n }\n else if (format === \"iban\") {\n stringSchema = stringSchema.check(z.iban());\n }\n else if (format === \"jwt\") {\n stringSchema = stringSchema.check(z.jwt());\n }\n else if (format === \"emoji\") {\n stringSchema = stringSchema.check(z.emoji());\n }\n else if (format === \"nanoid\") {\n stringSchema = stringSchema.check(z.nanoid());\n }\n else if (format === \"cuid\") {\n stringSchema = stringSchema.check(z.cuid());\n }\n else if (format === \"cuid2\") {\n stringSchema = stringSchema.check(z.cuid2());\n }\n else if (format === \"ulid\") {\n stringSchema = stringSchema.check(z.ulid());\n }\n else if (format === \"xid\") {\n stringSchema = stringSchema.check(z.xid());\n }\n else if (format === \"ksuid\") {\n stringSchema = stringSchema.check(z.ksuid());\n }\n // Note: json-string format is not currently supported by Zod\n // Custom formats are ignored - keep as plain string\n }\n // Apply constraints\n if (typeof schema.minLength === \"number\") {\n stringSchema = stringSchema.min(schema.minLength);\n }\n if (typeof schema.maxLength === \"number\") {\n stringSchema = stringSchema.max(schema.maxLength);\n }\n if (schema.pattern) {\n // JSON Schema patterns are not implicitly anchored (match anywhere in string)\n stringSchema = stringSchema.regex(new RegExp(schema.pattern));\n }\n zodSchema = stringSchema;\n break;\n }\n case \"number\":\n case \"integer\": {\n let numberSchema = type === \"integer\" ? z.number().int() : z.number();\n // Apply constraints\n // In draft-04, `exclusiveMinimum: true` makes the sibling `minimum` exclusive rather than an independent bound, so the inclusive `.min()` is skipped; emitting it too would be dominated by the exclusive check and report a second, weaker issue.\n if (typeof schema.minimum === \"number\" && schema.exclusiveMinimum !== true) {\n numberSchema = numberSchema.min(schema.minimum);\n }\n if (typeof schema.maximum === \"number\" && schema.exclusiveMaximum !== true) {\n numberSchema = numberSchema.max(schema.maximum);\n }\n if (typeof schema.exclusiveMinimum === \"number\") {\n numberSchema = numberSchema.gt(schema.exclusiveMinimum);\n }\n else if (schema.exclusiveMinimum === true && typeof schema.minimum === \"number\") {\n numberSchema = numberSchema.gt(schema.minimum);\n }\n if (typeof schema.exclusiveMaximum === \"number\") {\n numberSchema = numberSchema.lt(schema.exclusiveMaximum);\n }\n else if (schema.exclusiveMaximum === true && typeof schema.maximum === \"number\") {\n numberSchema = numberSchema.lt(schema.maximum);\n }\n if (typeof schema.multipleOf === \"number\") {\n numberSchema = numberSchema.multipleOf(schema.multipleOf);\n }\n zodSchema = numberSchema;\n break;\n }\n case \"boolean\": {\n zodSchema = z.boolean();\n break;\n }\n case \"null\": {\n zodSchema = z.null();\n break;\n }\n case \"object\": {\n const shape = {};\n const properties = schema.properties || {};\n const requiredSet = new Set(schema.required || []);\n const additionalSchema = typeof schema.additionalProperties === \"object\"\n ? convertSchema(schema.additionalProperties, ctx)\n : undefined;\n // Convert properties - mark optional ones\n for (const [key, propSchema] of Object.entries(properties)) {\n const propZodSchema = convertSchema(propSchema, ctx);\n // If not in required array, make it optional. assignProp so a __proto__ key becomes an own property instead of hitting the inherited setter\n assignProp(shape, key, requiredSet.has(key) ? propZodSchema : propZodSchema.optional());\n }\n // Handle patternProperties\n if (schema.patternProperties) {\n // patternProperties: keys matching pattern must satisfy corresponding schema. Use loose records so non-matching keys pass through\n const patternProps = schema.patternProperties;\n const patternKeys = Object.keys(patternProps);\n const looseRecords = [];\n for (const pattern of patternKeys) {\n const patternValue = convertSchema(patternProps[pattern], ctx);\n const keySchema = z.string().regex(new RegExp(pattern));\n looseRecords.push(z.looseRecord(keySchema, patternValue));\n }\n // Build intersection: object schema + all pattern property records\n const schemasToIntersect = [];\n if (Object.keys(shape).length > 0) {\n // Use passthrough so patternProperties can validate additional keys\n schemasToIntersect.push(z.object(shape).passthrough());\n }\n schemasToIntersect.push(...looseRecords);\n if (schemasToIntersect.length === 0) {\n zodSchema = z.object({}).passthrough();\n }\n else if (schemasToIntersect.length === 1) {\n zodSchema = schemasToIntersect[0];\n }\n else {\n // Chain intersections: (A & B) & C & D ...\n let result = z.intersection(schemasToIntersect[0], schemasToIntersect[1]);\n for (let i = 2; i < schemasToIntersect.length; i++) {\n result = z.intersection(result, schemasToIntersect[i]);\n }\n zodSchema = result;\n }\n // When additionalProperties is false, reject keys that are neither defined in properties nor matched by any patternProperty.\n if (schema.additionalProperties === false) {\n const propertyKeys = Object.keys(shape);\n const patterns = patternKeys.map((p) => new RegExp(p));\n const basePatternSchema = zodSchema;\n zodSchema = zodSchema.check((payload) => {\n if (!isPlainObject(payload.value))\n return;\n const unrecognized = [];\n for (const key of Object.keys(payload.value)) {\n if (propertyKeys.includes(key))\n continue;\n if (patterns.some((regex) => regex.test(key)))\n continue;\n unrecognized.push(key);\n }\n if (unrecognized.length) {\n payload.issues.push({\n code: \"unrecognized_keys\",\n keys: unrecognized,\n input: payload.value,\n inst: basePatternSchema,\n });\n }\n });\n }\n }\n else {\n // Handle additionalProperties. In JSON Schema, additionalProperties defaults to true (allow any extra properties). In Zod, objects strip unknown keys by default, so we need to handle this explicitly\n const objectSchema = z.object(shape);\n if (schema.additionalProperties === false) {\n // Strict mode - no extra properties allowed\n zodSchema = objectSchema.strict();\n }\n else if (additionalSchema) {\n // Extra properties must match the specified schema\n zodSchema = objectSchema.catchall(additionalSchema);\n }\n else {\n // additionalProperties is true or undefined - allow any extra properties (passthrough)\n zodSchema = objectSchema.passthrough();\n }\n }\n // propertyNames constrains key *names* only, and says nothing about which keys are required or how their values validate. Layering it on top of the result keeps properties/patternProperties/additionalProperties composing underneath. `true` allows every name, so it needs no guard.\n const hasKeyGuard = schema.propertyNames !== undefined && schema.propertyNames !== true;\n const minProperties = typeof schema.minProperties === \"number\" ? schema.minProperties : undefined;\n const maxProperties = typeof schema.maxProperties === \"number\" ? schema.maxProperties : undefined;\n if (hasKeyGuard || minProperties !== undefined || maxProperties !== undefined) {\n let keySchema;\n if (hasKeyGuard) {\n // Keys are always strings, so a propertyNames subschema that omits `type` still constrains them \u2014 without this it would convert to z.any().\n const keyJSONSchema = typeof schema.propertyNames === \"object\" && schema.propertyNames.type === undefined\n ? { type: \"string\", ...schema.propertyNames }\n : schema.propertyNames;\n keySchema = convertSchema(keyJSONSchema, ctx);\n }\n zodSchema = checkObjectGuards(zodSchema, { keySchema, minProperties, maxProperties });\n }\n break;\n }\n case \"array\": {\n // Check if this is a tuple (prefixItems or items as array)\n const prefixItems = schema.prefixItems;\n const items = schema.items;\n if (prefixItems && Array.isArray(prefixItems)) {\n // Tuple with prefixItems (draft-2020-12)\n const minItems = typeof schema.minItems === \"number\" ? schema.minItems : 0;\n const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));\n const positionalItems = applyMinItems(tupleItems, minItems);\n const rest = !Array.isArray(items) ? getTupleRest(items, ctx) : undefined;\n const tupleSchema = z.tuple(positionalItems);\n zodSchema = rest ? tupleSchema.rest(rest) : tupleSchema;\n // Apply minItems/maxItems constraints to tuples\n if (typeof schema.minItems === \"number\") {\n zodSchema = zodSchema.check(z.minLength(schema.minItems));\n }\n if (typeof schema.maxItems === \"number\") {\n zodSchema = zodSchema.check(z.maxLength(schema.maxItems));\n }\n }\n else if (Array.isArray(items)) {\n // Tuple with items array (draft-7)\n const minItems = typeof schema.minItems === \"number\" ? schema.minItems : 0;\n const tupleItems = items.map((item) => convertSchema(item, ctx));\n const positionalItems = applyMinItems(tupleItems, minItems);\n const rest = getTupleRest(schema.additionalItems, ctx);\n const tupleSchema = z.tuple(positionalItems);\n zodSchema = rest ? tupleSchema.rest(rest) : tupleSchema;\n // Apply minItems/maxItems constraints to tuples\n if (typeof schema.minItems === \"number\") {\n zodSchema = zodSchema.check(z.minLength(schema.minItems));\n }\n if (typeof schema.maxItems === \"number\") {\n zodSchema = zodSchema.check(z.maxLength(schema.maxItems));\n }\n }\n else if (items !== undefined) {\n // Regular array\n const element = convertSchema(items, ctx);\n let arraySchema = z.array(element);\n // Apply constraints\n if (typeof schema.minItems === \"number\") {\n arraySchema = arraySchema.min(schema.minItems);\n }\n if (typeof schema.maxItems === \"number\") {\n arraySchema = arraySchema.max(schema.maxItems);\n }\n zodSchema = arraySchema;\n }\n else {\n // No items specified - array of any\n zodSchema = z.array(z.any());\n }\n // minContains/maxContains only constrain anything when `contains` itself is present\n if (schema.uniqueItems === true || schema.contains !== undefined) {\n zodSchema = checkArrayGuards(zodSchema, {\n uniqueItems: schema.uniqueItems === true,\n containsSchema: schema.contains !== undefined ? convertSchema(schema.contains, ctx) : undefined,\n minContains: typeof schema.minContains === \"number\" ? schema.minContains : undefined,\n maxContains: typeof schema.maxContains === \"number\" ? schema.maxContains : undefined,\n });\n }\n break;\n }\n default:\n throw new Error(`Unsupported type: ${type}`);\n }\n return zodSchema;\n}\nfunction convertSchema(schema, ctx) {\n if (typeof schema === \"boolean\") {\n return schema ? z.any() : z.never();\n }\n // Convert base schema first (ignoring composition keywords)\n let baseSchema = convertBaseSchema(schema, ctx);\n const hasExplicitType = schema.type || schema.enum !== undefined || schema.const !== undefined;\n // Process composition keywords LAST (they can appear together)\n // Handle anyOf - wrap base schema with union\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n const options = schema.anyOf.map((s) => convertSchema(s, ctx));\n const anyOfUnion = z.union(options);\n baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion;\n }\n // Handle oneOf - exclusive union (exactly one must match)\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n const options = schema.oneOf.map((s) => convertSchema(s, ctx));\n const oneOfUnion = z.xor(options);\n baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion;\n }\n // Handle allOf - wrap base schema with intersection\n if (schema.allOf && Array.isArray(schema.allOf)) {\n if (schema.allOf.length === 0) {\n baseSchema = hasExplicitType ? baseSchema : z.any();\n }\n else {\n let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0], ctx);\n const startIdx = hasExplicitType ? 0 : 1;\n for (let i = startIdx; i < schema.allOf.length; i++) {\n result = z.intersection(result, convertSchema(schema.allOf[i], ctx));\n }\n baseSchema = result;\n }\n }\n // Handle nullable (OpenAPI 3.0)\n if (schema.nullable === true && ctx.version === \"openapi-3.0\") {\n baseSchema = z.nullable(baseSchema);\n }\n // Handle readOnly\n if (schema.readOnly === true) {\n baseSchema = z.readonly(baseSchema);\n }\n // Apply `default` so it wraps the fully-composed schema. This ensures `parse(undefined) -> default` works regardless of which branch of `convertBaseSchema` produced the inner schema (enum/const/not/typed/etc.).\n if (schema.default !== undefined) {\n baseSchema = baseSchema.default(schema.default);\n }\n // Collect non-description annotation metadata into the user-supplied registry. Description is handled separately below via `.describe()` to preserve the contract that `schema.description` reads from globalRegistry.\n const extraMeta = {};\n const coreMetadataKeys = [\"$id\", \"id\", \"$comment\", \"$anchor\", \"$vocabulary\", \"$dynamicRef\", \"$dynamicAnchor\"];\n for (const key of coreMetadataKeys) {\n if (key in schema) {\n extraMeta[key] = schema[key];\n }\n }\n const contentMetadataKeys = [\"contentEncoding\", \"contentMediaType\", \"contentSchema\"];\n for (const key of contentMetadataKeys) {\n if (key in schema) {\n extraMeta[key] = schema[key];\n }\n }\n // `propertyNames` and `contains` are enforced by a guard, which `toJSONSchema` cannot infer, so the original keyword is carried as metadata to keep the round-trip lossless. Only where it was actually applied: on any other type it is inert, and on a `$ref` the metadata would land on the target every reference shares. A carried subschema is copied verbatim while the root `$defs` stay behind, so one holding a `$ref` is dropped rather than emitted as a dangling reference.\n if (schema.type === \"object\" && schema.$ref === undefined) {\n if (schema.propertyNames !== undefined && !containsRef(schema.propertyNames)) {\n extraMeta.propertyNames = schema.propertyNames;\n }\n for (const key of [\"minProperties\", \"maxProperties\"]) {\n if (schema[key] !== undefined)\n extraMeta[key] = schema[key];\n }\n }\n if (schema.type === \"array\" && schema.$ref === undefined) {\n if (schema.contains !== undefined && !containsRef(schema.contains)) {\n extraMeta.contains = schema.contains;\n }\n for (const key of [\"uniqueItems\", \"minContains\", \"maxContains\"]) {\n if (schema[key] !== undefined)\n extraMeta[key] = schema[key];\n }\n }\n for (const key of Object.keys(schema)) {\n if (!RECOGNIZED_KEYS.has(key)) {\n assignProp(extraMeta, key, schema[key]);\n }\n }\n if (Object.keys(extraMeta).length > 0) {\n ctx.registry.add(baseSchema, extraMeta);\n }\n // Apply description last. `.describe()` clones the schema and sets `_zod.parent` on the clone, so registry lookups on the returned reference still resolve `extraMeta` via parent inheritance.\n if (schema.description) {\n baseSchema = baseSchema.describe(schema.description);\n }\n return baseSchema;\n}\n/**\n * Converts a JSON Schema to a Zod schema. This function should be considered semi-experimental. It's behavior is liable to change. */\nexport function fromJSONSchema(schema, params) {\n // Handle boolean schemas\n if (typeof schema === \"boolean\") {\n return schema ? z.any() : z.never();\n }\n // Normalize input via a JSON round-trip. This guarantees the converter walks a plain, finite, JSON-valid object graph: cyclic inputs fail here, getter/Proxy-based properties are materialized into static values, and class instances collapse to plain objects.\n let normalized;\n try {\n normalized = JSON.parse(JSON.stringify(schema));\n }\n catch {\n throw new Error(\"fromJSONSchema input is not valid JSON (possibly cyclic); use $defs/$ref for recursive schemas\");\n }\n const version = detectVersion(normalized, params?.defaultTarget);\n const defs = (normalized.$defs || normalized.definitions || {});\n const ctx = {\n version,\n defs,\n refs: new Map(),\n processing: new Set(),\n rootSchema: normalized,\n registry: params?.registry ?? globalRegistry,\n };\n return convertSchema(normalized, ctx);\n}\n", "// Traversal pattern adapted from Jaen's v3 `mapOnSchema` (Apache-2.0): https://gist.github.com/jaens/7e15ae1984bb338c86eb5e452dee3010\nimport * as schemas from \"./schemas.js\";\nimport { clone } from \"./util.js\";\nconst RESOLVING = Symbol(\"z.visit/resolving\");\nexport function visit(schema, fnOrHandlers) {\n const fn = typeof fnOrHandlers === \"function\"\n ? fnOrHandlers\n : (node, rewritten) => {\n // A union of handlers isn't callable with one argument; handler `K` only ever sees kind `K`.\n const h = fnOrHandlers[node._zod.def.type];\n return h ? h(node, rewritten) : node;\n };\n const cache = new Map();\n function run(s) {\n const cached = cache.get(s);\n if (cached === RESOLVING) {\n // Non-lazy cycle. Defer to parse time, when the cache holds the finished node.\n return new schemas.$ZodLazy({\n type: \"lazy\",\n getter: () => cache.get(s),\n });\n }\n if (cached !== undefined)\n return cached;\n cache.set(s, RESOLVING);\n const inner = mapInner(s);\n const mapped = fn(inner, inner !== s);\n cache.set(s, mapped);\n return mapped;\n }\n function mapInner(s) {\n const def = s._zod.def;\n const kind = def.type;\n switch (kind) {\n case \"object\": {\n const oldShape = def.shape;\n const keys = Object.keys(oldShape);\n let changed = false;\n const newShape = {};\n for (const k of keys) {\n const mapped = run(oldShape[k]);\n if (mapped !== oldShape[k])\n changed = true;\n newShape[k] = mapped;\n }\n let newCatchall = def.catchall;\n if (def.catchall) {\n newCatchall = run(def.catchall);\n if (newCatchall !== def.catchall)\n changed = true;\n }\n return changed ? clone(s, { ...def, shape: newShape, catchall: newCatchall }) : s;\n }\n case \"array\": {\n const mapped = run(def.element);\n return mapped === def.element ? s : clone(s, { ...def, element: mapped });\n }\n case \"tuple\": {\n const oldItems = def.items;\n let changed = false;\n const newItems = [];\n for (const item of oldItems) {\n const mapped = run(item);\n if (mapped !== item)\n changed = true;\n newItems.push(mapped);\n }\n let newRest = def.rest;\n if (def.rest) {\n newRest = run(def.rest);\n if (newRest !== def.rest)\n changed = true;\n }\n return changed ? clone(s, { ...def, items: newItems, rest: newRest }) : s;\n }\n case \"record\":\n case \"map\": {\n const newKey = run(def.keyType);\n const newVal = run(def.valueType);\n return newKey === def.keyType && newVal === def.valueType\n ? s\n : clone(s, { ...def, keyType: newKey, valueType: newVal });\n }\n case \"set\": {\n const newVal = run(def.valueType);\n return newVal === def.valueType ? s : clone(s, { ...def, valueType: newVal });\n }\n case \"union\": {\n const oldOptions = def.options;\n let changed = false;\n const newOptions = [];\n for (const opt of oldOptions) {\n const mapped = run(opt);\n if (mapped !== opt)\n changed = true;\n newOptions.push(mapped);\n }\n return changed ? clone(s, { ...def, options: newOptions }) : s;\n }\n case \"intersection\": {\n const newLeft = run(def.left);\n const newRight = run(def.right);\n return newLeft === def.left && newRight === def.right\n ? s\n : clone(s, { ...def, left: newLeft, right: newRight });\n }\n case \"optional\":\n case \"nullable\":\n case \"default\":\n case \"prefault\":\n case \"catch\":\n case \"readonly\":\n case \"nonoptional\":\n case \"promise\":\n case \"success\": {\n const newInner = run(def.innerType);\n return newInner === def.innerType ? s : clone(s, { ...def, innerType: newInner });\n }\n case \"pipe\": {\n const newIn = run(def.in);\n const newOut = run(def.out);\n return newIn === def.in && newOut === def.out ? s : clone(s, { ...def, in: newIn, out: newOut });\n }\n case \"function\": {\n const newInput = run(def.input);\n const newOutput = run(def.output);\n return newInput === def.input && newOutput === def.output\n ? s\n : clone(s, { ...def, input: newInput, output: newOutput });\n }\n case \"lazy\": {\n // Invoking the getter here would trip the cycle check, so lazy nodes always re-clone.\n const original = def.getter;\n // Drop the memo, or it shadows the new getter forever.\n const { _cachedInner, ...rest } = def;\n return clone(s, { ...rest, getter: () => run(original()) });\n }\n // A leaf by choice: `parts` are regex fragments, not data positions.\n case \"template_literal\":\n // Leaves.\n case \"string\":\n case \"number\":\n case \"int\":\n case \"boolean\":\n case \"bigint\":\n case \"symbol\":\n case \"undefined\":\n case \"null\":\n case \"void\":\n case \"never\":\n case \"any\":\n case \"unknown\":\n case \"date\":\n case \"nan\":\n case \"enum\":\n case \"literal\":\n case \"file\":\n case \"transform\":\n case \"custom\":\n return s;\n default: {\n // A new built-in kind becomes a compile error here; unknown user kinds fall through.\n kind;\n return s;\n }\n }\n }\n return run(schema);\n}\n", "import { visit } from \"../core/visit.js\";\nimport * as schemas from \"./schemas.js\";\n/** Returns a copy of the schema with every nested object's properties made optional. */\nexport function deepPartial(schema) {\n return visit(schema, {\n object: (s) => s.partial(),\n // Every partialed option now admits `undefined`, which the constructor rejects as a duplicate.\n union: (s) => {\n const def = s._zod.def;\n return def.discriminator === undefined ? s : schemas.union(def.options);\n },\n });\n}\n", "import { clone, mergeDefs } from \"../core/util.js\";\nimport { visit } from \"../core/visit.js\";\nimport * as schemas from \"./schemas.js\";\n/** Appends a pipe's own checks to the side that replaces it, mirroring how `.check()` clones. */\nfunction withChecks(side, checks) {\n if (!checks?.length)\n return side;\n const def = side._zod.def;\n return clone(side, mergeDefs(def, { checks: [...(def.checks ?? []), ...checks] }), { parent: true });\n}\n/** The out side, carrying the pipe's own checks: those run against the decoded value, which is what `out` produces. */\nfunction outSide(def) {\n return withChecks(def.out, def.checks);\n}\n/** The in side. `z.preprocess` pipes a transform into a schema, and a bare transform validates nothing, so the schema it feeds is the real input side \u2014 the resolution `toJSONSchema` already makes for this case. */\nfunction inSide(def) {\n return def.in._zod.traits.has(\"$ZodTransform\") ? outSide(def) : def.in;\n}\n/** Returns a copy of the schema with every pipe replaced by its input side. A codec's checks are dropped: they constrain the decoded value the input side never produces. */\nexport function input(schema) {\n return visit(schema, {\n pipe: (s) => inSide(s._zod.def),\n // A default value belongs to the output side, so a rewritten inner type leaves it stranded. `.default()` widens the declared input type with `undefined`, and `optional` is what carries that across.\n default: (s, rewritten) => (rewritten ? schemas.optional(s._zod.def.innerType) : s),\n // A catch value is output-side too, but `.catch()` leaves the declared input type alone, so the inner schema stands on its own.\n catch: (s, rewritten) => (rewritten ? s._zod.def.innerType : s),\n });\n}\n/** Returns a copy of the schema with every pipe replaced by its output side, carrying over the pipe's own checks. */\nexport function output(schema) {\n return visit(schema, {\n pipe: (s) => outSide(s._zod.def),\n // A prefault value is fed through the schema, which makes it input-side, so a rewritten inner type leaves it stranded.\n prefault: (s, rewritten) => (rewritten ? s._zod.def.innerType : s),\n });\n}\n", "import * as core from \"../core/index.js\";\nimport * as schemas from \"./schemas.js\";\nexport function string(params) {\n return core._coercedString(schemas.ZodString, params);\n}\nexport function number(params) {\n return core._coercedNumber(schemas.ZodNumber, params);\n}\nexport function boolean(params) {\n return core._coercedBoolean(schemas.ZodBoolean, params);\n}\nexport function bigint(params) {\n return core._coercedBigint(schemas.ZodBigInt, params);\n}\nexport function date(params) {\n return core._coercedDate(schemas.ZodDate, params);\n}\n", "export * as core from \"../core/index.js\";\nexport * from \"./schemas.js\";\nexport * from \"./checks.js\";\nexport * from \"./errors.js\";\nexport * from \"./parse.js\";\nexport * from \"./compat.js\";\nexport { globalRegistry, registry, config, memoizer, $output, $input, $brand, clone, regexes, treeifyError, prettifyError, formatError, flattenError, TimePrecision, util, NEVER, INVALID, toZod, compile, withParser, ZodCompileAsyncError, ZodCompileUnsupportedError, getDiscriminatedOption, } from \"../core/index.js\";\nexport { toJSONSchema } from \"../core/json-schema-processors.js\";\nexport { fromJSONSchema } from \"./from-json-schema.js\";\nexport { deepPartial } from \"./deep-partial.js\";\n// Types and values both, from one module \u2014 re-exporting the types from core would collide.\nexport { input, output } from \"./in-out.js\";\nexport * as locales from \"../locales/index.js\";\n// iso must be exported from top-level https://github.com/colinhacks/zod/issues/4491\nexport { ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration } from \"./iso.js\";\nexport * as iso from \"./iso.js\";\nexport * as coerce from \"./coerce.js\";\n", "import * as z from \"./v4/classic/external.js\";\nexport * from \"./v4/classic/external.js\";\n// Aliasing the binding, instead of `export default z`, keeps the default export a\n// re-export of `z` rather than a fresh namespace value. Rollup and Webpack can then\n// shake `import z from \"zod\"` as they already shake `import { z } from \"zod\"` \u2014 without\n// this they pull in every locale. See #6050.\nexport { z, z as default };\n", "import { z } from \"zod\";\n\nconst TranscriptScrollTargetSourceSchema = z.enum([\n \"overview_citation\",\n \"bench_opinion_reference\",\n \"clerk_citation\",\n \"boolean_search_result\",\n]);\n\n// A character range (line-local, end-exclusive) covered by an ElasticSearch\n// `` highlight within this target's line. Lets the structured reader draw\n// inline search marks from the exact ES match (phrase / proximity / wildcard /\n// stem) instead of re-tokenizing the query client-side.\nexport const TranscriptMatchRangeSchema = z.object({\n start: z.number().int().nonnegative(),\n end: z.number().int().nonnegative(),\n});\nexport type TranscriptMatchRange = z.infer;\n\nexport const TranscriptScrollTargetPointSchema = z.object({\n page: z.number().int().nonnegative(),\n line_number: z.number().int().nonnegative(),\n char_offset: z.number().int().nonnegative().optional(),\n turn_index: z.number().int().nonnegative().optional(),\n line_index: z.number().int().nonnegative().optional(),\n absolute_line_index: z.number().int().nonnegative().optional(),\n anchor_id: z.string().optional(),\n});\n\nexport const TranscriptScrollTargetSchema = z.object({\n excerpt: z.string().optional(),\n source: TranscriptScrollTargetSourceSchema,\n offset_space: z.enum([\"anchor\", \"document\"]).optional(),\n start: TranscriptScrollTargetPointSchema.optional().nullable(),\n end: TranscriptScrollTargetPointSchema.optional().nullable(),\n content_version: z.string().optional(),\n content_fingerprint: z.string().optional(),\n anchor_schema_version: z.string().optional(),\n match_strategy: z.string().optional(),\n match_confidence: z.number().optional(),\n match_ranges: z.array(TranscriptMatchRangeSchema).optional(),\n});\n\nexport const NullableTranscriptScrollTargetSchema = TranscriptScrollTargetSchema.nullable();\nexport const TranscriptScrollTargetArraySchema = z.array(TranscriptScrollTargetSchema.nullable());\n\nexport type TranscriptScrollTarget = z.infer;\nexport type NullableTranscriptScrollTarget = TranscriptScrollTarget | null;\n", "import { z } from \"zod\";\nimport { NullableTranscriptScrollTargetSchema } from \"./transcriptScrollTargets.types\";\n\n// Search params enums - schemas\nexport const TranscriptsAPIIndexURLSearchParamsQueryTypeSchema = z.enum([\"keyword-boolean\"]);\nexport const TranscriptsAPIIndexURLSearchParamsSortFieldsSchema = z.enum([\"date_of_hearing\", \"relevance\"]); // shared with bench opinions\nexport const TranscriptsAPIIndexURLSearchParamsSortDirectionsSchema = z.enum([\"asc\", \"desc\"]); // shared with bench opinions\n\n// Search params enums - types\nexport type TranscriptsAPIIndexURLSearchParamsQueryType = z.infer<\n typeof TranscriptsAPIIndexURLSearchParamsQueryTypeSchema\n>;\nexport type TranscriptsAPIIndexURLSearchParamsSortFields = z.infer<\n typeof TranscriptsAPIIndexURLSearchParamsSortFieldsSchema\n>;\nexport type TranscriptsAPIIndexURLSearchParamsSortDirections = z.infer<\n typeof TranscriptsAPIIndexURLSearchParamsSortDirectionsSchema\n>;\n\n// Common sub-schemas\nconst CourtCaseSchema = z.object({\n id: z.number(),\n name: z.string(),\n number: z.string(),\n});\n\nconst JudgeSchema = z.object({\n name: z.string(),\n});\n\nconst CourtSchema = z.object({\n id: z.number(),\n name: z.string(),\n});\n\nconst TranscriptAnchorSchema = z.record(z.string(), z.unknown());\n\nexport const TranscriptCitationMetadataSchema = z.object({\n document_type: z.enum([\"hearing\", \"trial\"]),\n document_label: z.enum([\"Hr'g Tr.\", \"Trial Tr.\"]),\n case_name: z.string().min(1),\n docket_label: z.enum([\"No.\", \"Adv. No.\"]),\n docket_number: z.string().min(1),\n court_abbreviation: z.string().min(1),\n date_label: z.string().min(1),\n});\n\nconst CitationSchema = z.object({\n index: z.number(),\n transcript_citations: z.array(z.string()),\n transcript_locations: z.array(NullableTranscriptScrollTargetSchema).optional(),\n});\n\nconst ContentAnchorSchema = z.object({\n anchor_id: z.string(),\n offset: z.number().int().nonnegative(),\n text_offset: z.number().int().nonnegative().optional(),\n start_absolute_line_index: z.number().int().nonnegative().optional(),\n start_page: z.number().int().nonnegative().optional(),\n start_line_number: z.number().int().nonnegative().optional(),\n});\n\nconst TranscriptOverviewSchema = z\n .object({\n content: z.string(),\n citations: z.array(CitationSchema),\n })\n .nullable()\n .optional();\n\n// URL Search Params schema\nexport const TranscriptsAPIIndexURLSearchParamsSchema = z.object({\n queryType: TranscriptsAPIIndexURLSearchParamsQueryTypeSchema.nullable().optional(),\n queryText: z.string().nullable().optional(),\n judgeIds: z.array(z.string()).nullable().optional(),\n additionalQuery: z.string().nullable().optional(),\n hearingDateFrom: z.string().nullable().optional(),\n hearingDateTo: z.string().nullable().optional(),\n caseId: z.string().nullable().optional(),\n caseNumber: z.string().nullable().optional(),\n caseName: z.string().nullable().optional(),\n motionType: z.string().nullable().optional(),\n sortField: TranscriptsAPIIndexURLSearchParamsSortFieldsSchema.nullable().optional(),\n sortDirection: TranscriptsAPIIndexURLSearchParamsSortDirectionsSchema.nullable().optional(),\n page: z.string().nullable().optional(),\n disableAutoCorrections: z.string().nullable().optional(),\n disableQueryImprovements: z.string().nullable().optional(),\n originalQuery: z.string().nullable().optional(),\n creditSearchExecutionId: z.string().nullable().optional(),\n});\n\n/*\n * Overview of the transcript without the actual content\n * Used by query results page to list the transcripts results\n */\nexport const TranscriptsAPIReadableContentPreviewSchema = z.object({\n id: z.number(),\n case_name_highlights: z.array(z.string()),\n content_highlights: z.array(z.string()),\n highlight_targets: z.array(NullableTranscriptScrollTargetSchema).optional(),\n motion_type_highlights: z.array(z.string()),\n motion_types: z.array(z.string()),\n court_case: CourtCaseSchema,\n court: CourtSchema,\n date_of_hearing: z.string().nullable(), // TODO: we can use zod transform to convert to date automatically\n judge: JudgeSchema,\n transcript_overview: TranscriptOverviewSchema,\n});\n\n// Index results schema\nexport const TranscriptsAPIIndexResponseSchema = z.object({\n results: z.array(TranscriptsAPIReadableContentPreviewSchema),\n total_count: z.number(),\n total_pages: z.number(),\n credit_usage_id: z.string().optional(),\n client_matter_code: z.string().optional(),\n});\n\n// Show results schema\nexport const TranscriptsAPITranscriptContentsSchema = z.object({\n id: z.number(),\n court_case: CourtCaseSchema,\n judge: JudgeSchema,\n court: CourtSchema.optional(),\n date_of_hearing: z.string().nullable(), // TODO: we can use zod transform to convert to date automatically\n content: z.string(),\n content_source: z.enum([\"legacy\", \"enriched\"]).optional(),\n // Keep reader payload parsing tolerant of older or malformed anchor rows.\n // Citation eligibility is validated separately by\n // buildTranscriptCitationSelectionIndex; an unusable citation anchor must\n // hide Cite rather than make the entire transcript unreadable.\n line_anchors: z.array(TranscriptAnchorSchema).optional(),\n paragraph_anchors: z.array(TranscriptAnchorSchema).optional(),\n citation: z.string(),\n source_document_available: z.boolean().optional(),\n citation_metadata: TranscriptCitationMetadataSchema.optional(),\n content_fingerprint: z.string().nullable().optional(),\n anchor_schema_version: z.string().nullable().optional(),\n content_anchors: z.array(ContentAnchorSchema.passthrough()).optional(),\n enriched_content: z\n .object({\n turns: z.array(z.unknown()).optional(),\n examinations: z.array(z.unknown()).optional(),\n })\n .passthrough()\n .optional(),\n});\n\nexport const TranscriptsAPIShowResponseSchema = z.object({\n transcript: TranscriptsAPITranscriptContentsSchema,\n results: z.array(TranscriptsAPIReadableContentPreviewSchema).optional(), // search within results\n});\n\n// Inferred types\nexport type TranscriptsAPIIndexURLSearchParams = z.infer;\n\nexport type TranscriptsAPIShowQueryParams = {\n queryType?: string;\n queryText?: string;\n targetAnchorIds?: string;\n};\nexport type TranscriptsAPIReadableContentPreview = z.infer;\nexport type TranscriptsAPIIndexResponse = z.infer;\nexport type TranscriptsAPIShowResponse = z.infer;\nexport type TranscriptsAPITranscriptContents = z.infer;\nexport type TranscriptCitationMetadata = z.infer;\nexport type Citation = z.infer;\n", "import { createQueryKeys } from \"@lukemorales/query-key-factory\";\nimport { fetchHelper } from \"../../utils/fetchHelpers\";\nimport { QueryError } from \".\";\nimport {\n TranscriptsAPIIndexURLSearchParams,\n TranscriptsAPIIndexResponse,\n TranscriptsAPIShowQueryParams,\n TranscriptsAPIShowResponse,\n TranscriptsAPIIndexResponseSchema,\n TranscriptsAPIShowResponseSchema,\n TranscriptsAPIIndexURLSearchParamsSchema,\n} from \"./transcripts.types\";\nimport { featureEnabled } from \"../../utils/featureFlags\";\nimport { getStoredActiveMatterCode } from \"../../contexts/ClientMatterContext\";\nimport { isCreditAccount } from \"../../utils/creditBilling\";\n\nexport const transcriptsQueries = createQueryKeys(\"transcripts\", {\n /*\n api/transcripts?... or api/transcripts/incognito_index\n searchParams are the URL params or POST body\n */\n index: (searchParams: TranscriptsAPIIndexURLSearchParams) => ({\n queryKey: [searchParams],\n queryFn: async (): Promise => {\n try {\n TranscriptsAPIIndexURLSearchParamsSchema.parse(searchParams);\n } catch (error) {\n throw new QueryError(`Invalid search params: ${error}`, 400);\n }\n\n let response: Response;\n\n if (isCreditAccount() && searchParams.creditSearchExecutionId) {\n const { creditSearchExecutionId, disableAutoCorrections, disableQueryImprovements, originalQuery, ...body } =\n searchParams;\n const matterCode = getStoredActiveMatterCode();\n response = await fetchHelper(\"/api/credit-transcript-searches\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Credit-Usage-Id\": creditSearchExecutionId,\n ...(matterCode ? { \"X-Client-Matter-Code\": matterCode } : {}),\n },\n body,\n });\n } else if (featureEnabled(\"incognito_queries\")) {\n const url = new URL(\"/api/transcripts/incognito_index\", window.location.origin);\n response = await fetchHelper(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: searchParams,\n });\n } else {\n const url = new URL(\"/api/transcripts\", window.location.origin);\n let paramKey: keyof TranscriptsAPIIndexURLSearchParams;\n for (paramKey in searchParams) {\n const paramVal = searchParams[paramKey];\n if (!paramVal) {\n continue;\n }\n url.searchParams.append(paramKey, paramVal.toString());\n }\n response = await fetchHelper(url.toString());\n }\n\n if (!response.ok) {\n const body = await response.json();\n throw new QueryError(body.error, response.status, body.code);\n }\n const data = await response.json();\n\n // Validate response against schema\n try {\n TranscriptsAPIIndexResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response structure from server: ${error}`);\n }\n return data as TranscriptsAPIIndexResponse;\n },\n }),\n\n /*\n api/transcripts/:id?... or api/transcripts/incognito_show\n */\n show: (id: string, queryParams?: TranscriptsAPIShowQueryParams) => ({\n queryKey: [id, queryParams],\n queryFn: async (): Promise => {\n if (!id) {\n throw new Error(\"Missing or empty id when fetching /api/transcripts/:id\");\n }\n\n let response: Response;\n\n if (featureEnabled(\"incognito_queries\")) {\n const url = new URL(\"/api/transcripts/incognito_show\", window.location.origin);\n const requestBody = { id, ...queryParams };\n response = await fetchHelper(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: requestBody,\n });\n } else {\n const url = new URL(`/api/transcripts/${id}`, window.location.origin);\n if (queryParams) {\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value) {\n url.searchParams.append(key, value);\n }\n });\n }\n response = await fetchHelper(url.toString());\n }\n\n if (!response.ok) {\n throw new QueryError(\"Error fetching api/transcripts/:id\", response.status);\n }\n const data = await response.json();\n\n // Validate response against schema\n try {\n TranscriptsAPIShowResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response structure from server: ${error}`);\n }\n return data as TranscriptsAPIShowResponse;\n },\n }),\n});\n", "// Type definitions for query improvements\n\nimport { Expand, Hammer, Shrink, type LucideIcon } from \"lucide-react\";\n\nexport type QueryImprovementStage = \"suggested\" | \"broaden\" | \"narrow\";\n\nexport interface ImprovedQuery {\n new_query: string | null;\n rule_codes: string[];\n title: string;\n diff_hint?: string;\n explanations: string[];\n confidence: number;\n}\n\nexport interface QueryImprovementPayload {\n version: string;\n source: {\n query: string;\n };\n improved_query: ImprovedQuery;\n}\n\nexport const QUERY_IMPROVEMENT_STATUSES = [\n \"not_active\",\n \"reviewing\",\n \"loading_suggestions\",\n \"view_suggestions\",\n \"done_no_suggestions\",\n \"done_error\",\n] as const;\n\nexport type QueryImprovementStatus = (typeof QUERY_IMPROVEMENT_STATUSES)[number];\n\nexport const QUERY_IMPROVEMENT_RUN_STATUSES = [\n \"reviewing\",\n \"loading_suggestions\",\n \"view_suggestions\",\n \"done_no_suggestions\",\n \"done_error\",\n] as const;\n\nexport const QUERY_IMPROVEMENT_STAGE_STATUSES = [\n \"running\",\n \"error\",\n \"done_with_suggestion\",\n \"done_no_suggestion\",\n] as const;\n\nexport type QueryImprovementStageStatus = (typeof QUERY_IMPROVEMENT_STAGE_STATUSES)[number];\n\nexport const getStageStatuses = (stages?: {\n suggested?: { status?: QueryImprovementStageStatus };\n broaden?: { status?: QueryImprovementStageStatus };\n narrow?: { status?: QueryImprovementStageStatus };\n}) => [stages?.suggested?.status, stages?.broaden?.status, stages?.narrow?.status];\n\n// Stage type to display name mapping\nexport const STAGE_DISPLAY_NAMES: Record = {\n suggested: \"Enhance your query\",\n broaden: \"Broaden your search\",\n narrow: \"Narrow your results\",\n};\n\n// Stage type to tooltip description mapping\nexport const STAGE_TOOLTIPS: Record = {\n suggested: \"Boolean best practices applied to improve your results.\",\n broaden: \"Broadening rules applied to avoid excluding relevant results.\",\n narrow: \"Narrowing rules applied to reduce overly broad results.\",\n};\n\n// Lucide icon used in each stage's chip header (card title and chip-only rows\n// during the loading / no-suggestion states).\nexport const STAGE_ICONS: Record = {\n suggested: Hammer,\n broaden: Expand,\n narrow: Shrink,\n};\n\n// Per-stage progress label shown while the AI is still generating that stage.\n// Paired with an animated ellipsis in the chip body so the user can see which\n// stage is currently working.\nexport const STAGE_RUNNING_LABELS: Record = {\n suggested: \"Enhancing your query\",\n broaden: \"Broadening your search\",\n narrow: \"Narrowing your results\",\n};\n\n// Per-stage success-state label shown when the AI confirms no further\n// improvement of that kind is needed. Rendered as a green BIQChip in place\n// of a full suggestion card.\nexport const STAGE_NO_SUGGESTION_LABELS: Record = {\n suggested: \"No further enhancement is recommended\",\n broaden: \"No further broadening is recommended\",\n narrow: \"No further narrowing is recommended\",\n};\n", "import { z } from \"zod\";\nimport { QUERY_IMPROVEMENT_RUN_STATUSES, QUERY_IMPROVEMENT_STAGE_STATUSES } from \"@/components/types/queryImprovement\";\n\nexport const QueryImprovementCreateResponseSchema = z.object({\n run_id: z.string(),\n});\n\nexport type QueryImprovementCreateResponse = z.infer;\n\nexport interface QueryImprovementCreateParams {\n query: string;\n}\n\nexport interface QueryImprovementPollParams {\n judgeIds?: string;\n hearingDateFrom?: string;\n hearingDateTo?: string;\n caseId?: string;\n caseNumber?: string;\n caseName?: string;\n motionType?: string;\n additionalQuery?: string;\n}\n\nexport const QueryImprovementStageResponseSchema = z.object({\n status: z.enum(QUERY_IMPROVEMENT_STAGE_STATUSES),\n payload: z.record(z.string(), z.any()).optional(),\n error_messages: z.array(z.object({ message: z.string(), at: z.string() })).optional(),\n});\n\nexport const QueryImprovementPollResponseSchema = z.object({\n status: z.string(),\n data: z.object({\n run_id: z.string(),\n run_status: z.enum(QUERY_IMPROVEMENT_RUN_STATUSES),\n stages: z.object({\n suggested: QueryImprovementStageResponseSchema,\n broaden: QueryImprovementStageResponseSchema,\n narrow: QueryImprovementStageResponseSchema,\n }),\n transcript_counts: z\n .object({\n base: z.number().nullable().optional(),\n suggested: z.number().nullable().optional(),\n broaden: z.number().nullable().optional(),\n narrow: z.number().nullable().optional(),\n })\n .optional(),\n }),\n});\n\nexport type QueryImprovementPollResponse = z.infer;\nexport type QueryImprovementStageStatus = z.infer[\"status\"];\n", "import { createQueryKeys } from \"@lukemorales/query-key-factory\";\nimport { fetchHelper } from \"@/utils/fetchHelpers\";\nimport { QueryError } from \".\";\nimport {\n QueryImprovementCreateResponse,\n QueryImprovementCreateResponseSchema,\n QueryImprovementCreateParams,\n QueryImprovementPollResponse,\n QueryImprovementPollResponseSchema,\n QueryImprovementPollParams,\n} from \"./queryImprovement.types\";\n\nconst QUERY_IMPROVEMENT_API_BASE_URL = \"/api/queries/improvements\";\n\nexport const queryImprovementQueries = createQueryKeys(\"queryImprovement\", {\n create: (params: QueryImprovementCreateParams) => ({\n queryKey: [params],\n queryFn: async (): Promise => {\n const url = `${QUERY_IMPROVEMENT_API_BASE_URL}/create`;\n\n const response: Response = await fetchHelper(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: params,\n });\n\n if (!response.ok) {\n throw new QueryError(\"Error creating query improvement run\", response.status);\n }\n\n const data = await response.json();\n\n try {\n QueryImprovementCreateResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response structure from server: ${error}`);\n }\n\n return data as QueryImprovementCreateResponse;\n },\n }),\n poll: (runId: string, params?: QueryImprovementPollParams) => ({\n queryKey: [runId, params],\n queryFn: async (): Promise => {\n const url = new URL(`${QUERY_IMPROVEMENT_API_BASE_URL}/poll/${runId}`, window.location.origin);\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value) {\n url.searchParams.append(key, value);\n }\n });\n }\n const response: Response = await fetchHelper(url.toString());\n\n if (!response.ok) {\n throw new QueryError(\"Error polling query improvement run\", response.status);\n }\n\n const data = await response.json();\n\n try {\n QueryImprovementPollResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response structure from server: ${error}`);\n }\n\n return data as QueryImprovementPollResponse;\n },\n }),\n});\n", "import { z } from \"zod\";\nimport { TranscriptsAPIReadableContentPreviewSchema } from \"./transcripts.types\";\nimport { NullableTranscriptScrollTargetSchema } from \"./transcriptScrollTargets.types\";\nimport {\n TranscriptsAPIIndexURLSearchParamsSortFieldsSchema as BenchOpinionsAPIIndexURLSearchParamsSortFieldsSchema,\n TranscriptsAPIIndexURLSearchParamsSortDirectionsSchema as BenchOpinionsAPIIndexURLSearchParamsSortDirectionsSchema,\n} from \"./transcripts.types\";\n\n// Enum schema\nexport const BenchOpinionsSectionNamesSchema = z.enum([\"background\", \"issues\", \"analysis\", \"disposition\"]);\nexport type BenchOpinionsSectionNames = z.infer;\n\n// URL Search Params schema\nexport const BenchOpinionsAPIIndexURLSearchParamsSchema = z.object({\n queryText: z.string().nullable().optional(),\n judgeIds: z.array(z.string()).nullable().optional(),\n additionalQuery: z.string().nullable().optional(),\n hearingDateFrom: z.string().nullable().optional(),\n hearingDateTo: z.string().nullable().optional(),\n caseId: z.string().nullable().optional(),\n caseNumber: z.string().nullable().optional(),\n caseName: z.string().nullable().optional(),\n motionType: z.string().nullable().optional(),\n sortField: BenchOpinionsAPIIndexURLSearchParamsSortFieldsSchema.nullable().optional(),\n sortDirection: BenchOpinionsAPIIndexURLSearchParamsSortDirectionsSchema.nullable().optional(),\n page: z.string().nullable().optional(),\n});\n\n// Snippets and Citations schemas\nexport const BenchOpinionsSnippetSchema = z.object({\n snippet: z.string(),\n verified: z.boolean(),\n location: NullableTranscriptScrollTargetSchema.optional(),\n});\n\nexport const BenchOpinionsCitationsSchema = z.record(z.string(), z.array(BenchOpinionsSnippetSchema));\n\n// Content schemas\nconst AnalysisItemSchema = z.object({\n issue: z.string(),\n rules: z.string(),\n application: z.string(),\n conclusion: z.string(),\n});\n\nconst BackgroundContentSchema = z.object({\n citations: BenchOpinionsCitationsSchema,\n content: z.string(),\n raw_content: z.string(),\n cited_raw_content: z.string(),\n citable_raw_content: z.string(),\n});\n\nconst IssuesContentSchema = z.object({\n citations: BenchOpinionsCitationsSchema,\n content: z.array(z.string()),\n raw_content: z.string(),\n cited_raw_content: z.string(),\n citable_raw_content: z.string(),\n});\n\nconst AnalysisContentSchema = z.object({\n citations: BenchOpinionsCitationsSchema,\n content: z.array(AnalysisItemSchema),\n raw_content: z.string(),\n cited_raw_content: z.string(),\n structured_content: z.array(AnalysisItemSchema),\n citable_raw_content: z.string(),\n});\n\nconst DispositionContentSchema = z.object({\n citations: BenchOpinionsCitationsSchema.optional(),\n content: z.string(),\n raw_content: z.string(),\n cited_raw_content: z.string(),\n citable_raw_content: z.string(),\n});\n\nexport const BenchOpinionsRawJSONSchema = z.object({\n background: BackgroundContentSchema,\n issues: IssuesContentSchema,\n analysis: AnalysisContentSchema,\n disposition: DispositionContentSchema,\n});\n\n// API Response schemas\nexport const BenchOpinionsAPIIndexResponseSchema = z.object({\n results: z.array(TranscriptsAPIReadableContentPreviewSchema),\n total_count: z.number(),\n total_pages: z.number(),\n});\n\nexport const BenchOpinionsAPIShowResponseSchema = z.object({\n id: z.number().nullable(),\n content: z.string().nullable(),\n raw_json: BenchOpinionsRawJSONSchema.nullable(),\n results: z.array(TranscriptsAPIReadableContentPreviewSchema).optional(),\n});\n\n// Inferred types\nexport type BenchOpinionsAPIIndexURLSearchParams = z.infer;\nexport type BenchOpinionsSnippet = z.infer;\nexport type BenchOpinionsCitations = z.infer;\nexport type BenchOpinionsRawJSON = z.infer;\nexport type BenchOpinionsAPIIndexResponse = z.infer;\nexport type BenchOpinionsAPIShowResponse = z.infer;\n", "import { createQueryKeys } from \"@lukemorales/query-key-factory\";\nimport { fetchHelper } from \"../../utils/fetchHelpers\";\nimport { QueryError } from \".\";\nimport {\n BenchOpinionsAPIIndexURLSearchParams,\n BenchOpinionsAPIIndexResponse,\n BenchOpinionsAPIShowResponse,\n BenchOpinionsAPIIndexResponseSchema,\n BenchOpinionsAPIShowResponseSchema,\n BenchOpinionsAPIIndexURLSearchParamsSchema,\n} from \"./benchOpinions.types\";\n\nexport const benchOpinionsQueries = createQueryKeys(\"benchOpinions\", {\n index: (searchParams: BenchOpinionsAPIIndexURLSearchParams) => ({\n queryKey: [searchParams],\n queryFn: async (): Promise => {\n try {\n BenchOpinionsAPIIndexURLSearchParamsSchema.parse(searchParams);\n } catch (error) {\n throw new QueryError(`Invalid search params: ${error}`, 400);\n }\n\n const url = new URL(\"/api/bench-opinions\", window.location.origin);\n let paramKey: keyof BenchOpinionsAPIIndexURLSearchParams;\n for (paramKey in searchParams) {\n const paramVal = searchParams[paramKey];\n if (!paramVal) {\n continue;\n }\n url.searchParams.append(paramKey, paramVal.toString());\n }\n const response: Response = await fetchHelper(url.toString());\n if (!response.ok) {\n throw new QueryError(\"Error fetching api/bench-opinions\", response.status);\n }\n const data = await response.json();\n\n // Validate response against schema\n try {\n BenchOpinionsAPIIndexResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response structure from server: ${error}`);\n }\n return data as BenchOpinionsAPIIndexResponse;\n },\n }),\n\n show: (transcriptId: string, queryParams?: { queryType?: string; queryText?: string }) => ({\n queryKey: [transcriptId, queryParams],\n queryFn: async (): Promise => {\n if (!transcriptId) {\n throw new Error(\"Missing or empty id when fetching /api/bench-opinions/:id\");\n }\n const url = new URL(`/api/transcripts/${transcriptId}/bench-opinion`, window.location.origin);\n if (queryParams) {\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value) {\n url.searchParams.append(key, value);\n }\n });\n }\n const response: Response = await fetchHelper(url.toString());\n if (!response.ok) {\n throw new QueryError(\"Error fetching api/bench-opinions/:id\", response.status);\n }\n const data = await response.json();\n\n // Validate response against schema\n try {\n BenchOpinionsAPIShowResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response structure from server: ${error}`);\n }\n return data as BenchOpinionsAPIShowResponse;\n },\n }),\n});\n", "import { z } from \"zod\";\n\n// might divert from the Judge schema defined in the transcripts API\nexport const JudgesAPICourtSchema = z.object({\n id: z.number(),\n name: z.string(),\n});\n\n// diverts from the Judge schema defined in the transcripts API\nexport const JudgesAPIJudgeSchema = z.object({\n id: z.number(),\n name: z.string(),\n display_label: z.string().nullable(),\n display_label_helper_text: z.string().nullable(),\n court_id: z.number(),\n created_at: z.string(),\n updated_at: z.string(),\n court: JudgesAPICourtSchema,\n});\n\nexport const JudgeCheckboxStateSchema = z.record(\n z.number(),\n z.object({\n id: z.number(),\n name: z.string(),\n judges: z.record(\n z.number(),\n z.object({\n id: z.number(),\n name: z.string(),\n selected: z.boolean(),\n }),\n ),\n }),\n);\n\nexport const JudgesAPIResponseSchema = z.object({\n judges: z.array(JudgesAPIJudgeSchema),\n});\n\nexport type JudgeCheckboxState = z.infer;\nexport type JudgesAPIJudge = z.infer;\nexport type JudgesAPICourt = z.infer;\nexport type JudgesAPIResponse = z.infer;\n", "import { createQueryKeys } from \"@lukemorales/query-key-factory\";\nimport { JudgesAPIJudge, JudgesAPIResponse, JudgesAPIResponseSchema } from \"./judges.types\";\nimport { fetchHelper } from \"../../utils/fetchHelpers\";\n\nconst judgesQueries = createQueryKeys(\"judges\", {\n list: () => ({\n queryKey: [\"list\"],\n queryFn: async (): Promise => {\n const response = await fetchHelper(\"/api/judges\");\n if (!response.ok) {\n throw new Error(\"Error fetching judges\");\n }\n const rawJSON = await response.json();\n try {\n JudgesAPIResponseSchema.parse(rawJSON);\n } catch (error) {\n console.error(`Unexpected JSON response structure from server: ${error}`);\n }\n const judgesResponse = rawJSON as JudgesAPIResponse;\n return judgesResponse.judges ? [...judgesResponse.judges] : [];\n },\n }),\n});\n\nexport default judgesQueries;\n", "import { z } from \"zod\";\nimport { NullableTranscriptScrollTargetSchema } from \"./transcriptScrollTargets.types\";\nimport { TranscriptCitationMetadataSchema } from \"./transcripts.types\";\n\n// \u2500\u2500 Folderable Types \u2500\u2500\n\nexport const FolderableTypeSchema = z.enum([\"Transcript\", \"AgentPrototypeSession\"]);\nexport type FolderableType = z.infer;\n\n// \u2500\u2500 Pagination \u2500\u2500\n\nexport const PaginationMetaSchema = z.object({\n current_page: z.number(),\n total_pages: z.number(),\n total_count: z.number(),\n});\nexport type PaginationMeta = z.infer;\n\n// \u2500\u2500 Folders \u2500\u2500\n\nexport const FolderKindSchema = z.enum([\"custom\", \"starred\"]);\nexport type FolderKind = z.infer;\n\nexport const FolderSchema = z.object({\n id: z.number(),\n name: z.string(),\n description: z.string().nullable(),\n kind: FolderKindSchema,\n system: z.boolean(),\n item_count: z.number(),\n annotation_count: z.number(),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type Folder = z.infer;\n\nexport const FoldersResponseSchema = z.array(FolderSchema);\n\n// \u2500\u2500 Folder Items \u2500\u2500\n\nconst FolderItemCitationSchema = z.object({\n index: z.number(),\n transcript_citations: z.array(z.string()),\n transcript_locations: z.array(NullableTranscriptScrollTargetSchema).optional(),\n});\n\nconst FolderItemTranscriptOverviewSchema = z\n .object({\n content: z.string(),\n citations: z.array(FolderItemCitationSchema),\n })\n .nullable()\n .optional();\n\nexport const FolderItemSchema = z.object({\n id: z.number(),\n folderable_type: FolderableTypeSchema,\n folderable_id: z.number(),\n added_at: z.string(),\n // Present when folderable_type === \"Transcript\":\n judge_name: z.string().nullable().optional(),\n case_name: z.string().nullable().optional(),\n case_number: z.string().nullable().optional(),\n date_of_hearing: z.string().nullable().optional(),\n transcript_overview: FolderItemTranscriptOverviewSchema,\n // Present when folderable_type === \"AgentPrototypeSession\":\n token: z.string().nullable().optional(),\n title: z.string().nullable().optional(),\n summary: z.string().nullable().optional(),\n});\nexport type FolderItem = z.infer;\n\nexport const FolderDetailResponseSchema = FolderSchema.extend({\n items: z.array(FolderItemSchema),\n meta: PaginationMetaSchema,\n});\nexport type FolderDetailResponse = z.infer;\n\nexport const FolderItemsResponseSchema = z.object({\n items: z.array(FolderItemSchema),\n meta: PaginationMetaSchema,\n});\nexport type FolderItemsResponse = z.infer;\n\n// \u2500\u2500 Highlights & Annotations \u2500\u2500\n\nexport const HighlightAnnotationSchema = z.object({\n id: z.number(),\n body: z.string(),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type HighlightAnnotation = z.infer;\n\nexport const HighlightCitationSchema = z.object({\n pinpoint: z.string().min(1),\n metadata: TranscriptCitationMetadataSchema,\n citation_text: z.string().trim().min(1).max(2_000).optional(),\n});\nexport type HighlightCitation = z.infer;\n\nexport const HighlightSchema = z.object({\n id: z.number(),\n highlightable_type: FolderableTypeSchema,\n highlightable_id: z.number(),\n sub_element_type: z.string().nullable(),\n sub_element_id: z.number().nullable(),\n start_offset: z.number().nullable(),\n end_offset: z.number().nullable(),\n highlighted_text: z.string().nullable(),\n citation: HighlightCitationSchema.nullable().optional(),\n whole_entity: z.boolean(),\n annotations: z.array(HighlightAnnotationSchema),\n created_at: z.string(),\n});\nexport type Highlight = z.infer;\n\nexport const HighlightsResponseSchema = z.array(HighlightSchema);\n\nconst HighlightableSummarySchema = z.object({\n title: z.string().nullable().optional(),\n date: z.string().nullable().optional(),\n judge: z.string().nullable().optional(),\n // Present when highlightable_type === \"AgentPrototypeSession\" \u2014 used to build\n // /agent/:token URLs when opening a session-sourced note from the Notes page.\n token: z.string().nullable().optional(),\n});\n\nexport const HighlightWithSummarySchema = HighlightSchema.extend({\n highlightable_summary: HighlightableSummarySchema,\n});\nexport type HighlightWithSummary = z.infer;\n\nexport const PaginatedHighlightsResponseSchema = z.object({\n highlights: z.array(HighlightWithSummarySchema),\n meta: PaginationMetaSchema,\n});\nexport type PaginatedHighlightsResponse = z.infer;\n\n// \u2500\u2500 Batch Metadata \u2500\u2500\n\nexport const ReadableMetadataEntrySchema = z.object({\n starred: z.boolean(),\n starred_folder_item_id: z.number().nullable(),\n starred_at: z.string().nullable(),\n folder_count: z.number(),\n folder_ids: z.array(z.number()),\n folder_item_ids: z.record(z.string(), z.number()),\n annotation_count: z.number(),\n highlight_count: z.number(),\n});\nexport type ReadableMetadataEntry = z.infer;\n\nexport const ReadableMetadataResponseSchema = z.record(z.string(), ReadableMetadataEntrySchema);\nexport type ReadableMetadataResponse = z.infer;\n", "import { createQueryKeys } from \"@lukemorales/query-key-factory\";\nimport { fetchHelper } from \"../../utils/fetchHelpers\";\nimport { QueryError } from \".\";\nimport {\n FoldersResponseSchema,\n FolderDetailResponseSchema,\n HighlightsResponseSchema,\n PaginatedHighlightsResponseSchema,\n ReadableMetadataResponseSchema,\n type Folder,\n type FolderDetailResponse,\n type FolderItem,\n type Highlight,\n type HighlightCitation,\n type HighlightAnnotation,\n type PaginatedHighlightsResponse,\n type ReadableMetadataResponse,\n type FolderableType,\n} from \"./folders.types\";\n\nexport const foldersQueries = createQueryKeys(\"folders\", {\n // GET /api/folders \u2014 all folders for current user (includes starred)\n list: () => ({\n queryKey: [\"list\"],\n queryFn: async (): Promise => {\n const response = await fetchHelper(\"/api/folders\");\n if (!response.ok) {\n throw new QueryError(\"Error fetching folders\", response.status);\n }\n const data = await response.json();\n try {\n FoldersResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response structure from GET /api/folders: ${error}`);\n }\n return data as Folder[];\n },\n }),\n\n // GET /api/folders/:id?page= \u2014 single folder with paginated items\n detail: (id: number, page = 1) => ({\n queryKey: [id, page],\n queryFn: async (): Promise => {\n const url = new URL(`/api/folders/${id}`, window.location.origin);\n if (page > 1) {\n url.searchParams.append(\"page\", page.toString());\n }\n const response = await fetchHelper(url.toString());\n if (!response.ok) {\n throw new QueryError(\"Error fetching folder detail\", response.status);\n }\n const data = await response.json();\n try {\n FolderDetailResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response structure from GET /api/folders/${id}: ${error}`);\n }\n return data as FolderDetailResponse;\n },\n }),\n\n // GET /api/transcripts/:id/highlights \u2014 all highlights for a transcript (not paginated)\n transcriptHighlights: (transcriptId: number) => ({\n queryKey: [\"transcriptHighlights\", transcriptId],\n queryFn: async (): Promise => {\n const response = await fetchHelper(`/api/transcripts/${transcriptId}/highlights`);\n if (!response.ok) {\n throw new QueryError(\"Error fetching transcript highlights\", response.status);\n }\n const data = await response.json();\n try {\n HighlightsResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response from GET /api/transcripts/${transcriptId}/highlights: ${error}`);\n }\n return data as Highlight[];\n },\n }),\n\n // GET /api/agent-prototype/sessions/:token/highlights \u2014 all highlights for a session (not paginated)\n sessionHighlights: (token: string) => ({\n queryKey: [\"sessionHighlights\", token],\n queryFn: async (): Promise => {\n const response = await fetchHelper(`/api/agent-prototype/sessions/${encodeURIComponent(token)}/highlights`);\n if (!response.ok) {\n throw new QueryError(\"Error fetching session highlights\", response.status);\n }\n const data = await response.json();\n try {\n HighlightsResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response from GET /api/agent-prototype/sessions/${token}/highlights: ${error}`);\n }\n return data as Highlight[];\n },\n }),\n\n // GET /api/highlights?page=&folder_id= \u2014 global highlights, including citation-only entries (paginated)\n globalHighlights: (page = 1, folderId?: number) => ({\n queryKey: [\"globalHighlights\", page, folderId],\n queryFn: async (): Promise => {\n const url = new URL(\"/api/highlights\", window.location.origin);\n if (page > 1) {\n url.searchParams.append(\"page\", page.toString());\n }\n if (folderId) {\n url.searchParams.append(\"folder_id\", folderId.toString());\n }\n const response = await fetchHelper(url.toString());\n if (!response.ok) {\n throw new QueryError(\"Error fetching highlights\", response.status);\n }\n const data = await response.json();\n try {\n PaginatedHighlightsResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response from GET /api/highlights: ${error}`);\n }\n return data as PaginatedHighlightsResponse;\n },\n }),\n\n // GET /api/readables/metadata?type=&ids[]= \u2014 batch metadata for list views\n readableMetadata: (type: FolderableType, ids: number[]) => ({\n queryKey: [type, ids],\n queryFn: async (): Promise => {\n const url = new URL(\"/api/readables/metadata\", window.location.origin);\n url.searchParams.append(\"type\", type);\n ids.forEach((id) => url.searchParams.append(\"ids[]\", id.toString()));\n const response = await fetchHelper(url.toString());\n if (!response.ok) {\n throw new QueryError(\"Error fetching readable metadata\", response.status);\n }\n const data = await response.json();\n try {\n ReadableMetadataResponseSchema.parse(data);\n } catch (error) {\n console.error(`Unexpected JSON response from GET /api/readables/metadata: ${error}`);\n }\n return data as ReadableMetadataResponse;\n },\n }),\n});\n\n// \u2500\u2500 Mutation helpers (used by hooks in api/folders.ts) \u2500\u2500\n\nexport async function createFolder(params: { name: string; description?: string }): Promise {\n const response = await fetchHelper(\"/api/folders\", {\n method: \"POST\",\n body: { folder: params },\n });\n const data = await response.json();\n if (!response.ok) {\n throw new QueryError(data.error || \"Error creating folder\", response.status);\n }\n return data;\n}\n\nexport async function updateFolder(\n id: number,\n params: { name?: string; description?: string | null },\n): Promise {\n const response = await fetchHelper(`/api/folders/${id}`, {\n method: \"PATCH\",\n body: { folder: params },\n });\n const data = await response.json();\n if (!response.ok) {\n throw new QueryError(data.error || \"Error updating folder\", response.status);\n }\n return data;\n}\n\nexport async function deleteFolder(id: number): Promise {\n const response = await fetchHelper(`/api/folders/${id}`, { method: \"DELETE\" });\n if (!response.ok) {\n const data = await response.json();\n throw new QueryError(data.errors?.[0] || data.error || \"Error deleting folder\", response.status);\n }\n}\n\nexport async function addFolderItem(\n folderId: number,\n params: { folderable_type: FolderableType; folderable_id: number },\n): Promise {\n const response = await fetchHelper(`/api/folders/${folderId}/items`, {\n method: \"POST\",\n body: { folder_item: params },\n });\n if (!response.ok) {\n throw new QueryError(\"Error adding item to folder\", response.status);\n }\n return response.json();\n}\n\nexport async function removeFolderItem(itemId: number): Promise {\n const response = await fetchHelper(`/api/items/${itemId}`, { method: \"DELETE\" });\n if (!response.ok) {\n throw new QueryError(\"Error removing item from folder\", response.status);\n }\n}\n\nexport async function createHighlight(params: {\n highlightable_type: FolderableType;\n highlightable_id: number;\n start_offset?: number;\n end_offset?: number;\n highlighted_text?: string;\n sub_element_type?: string;\n sub_element_id?: number;\n annotation_body?: string;\n citation?: HighlightCitation;\n}): Promise {\n const { annotation_body, ...highlightParams } = params;\n const response = await fetchHelper(\"/api/highlights\", {\n method: \"POST\",\n body: { highlight: highlightParams, annotation_body },\n });\n const data = await response.json();\n if (!response.ok) {\n throw new QueryError(data.error || \"Error creating highlight\", response.status);\n }\n return data;\n}\n\nexport interface UpdateHighlightParams {\n citation?: HighlightCitation | null;\n annotation_body?: string;\n}\n\nexport async function updateHighlight(id: number, params: UpdateHighlightParams): Promise {\n const { annotation_body, ...highlight } = params;\n const response = await fetchHelper(`/api/highlights/${id}`, {\n method: \"PATCH\",\n body: {\n highlight,\n ...(annotation_body === undefined ? {} : { annotation_body }),\n },\n });\n const data = await response.json();\n if (!response.ok) {\n throw new QueryError(data.error || \"Error updating highlight\", response.status);\n }\n return data;\n}\n\nexport async function deleteHighlight(id: number): Promise {\n const response = await fetchHelper(`/api/highlights/${id}`, { method: \"DELETE\" });\n if (!response.ok) {\n throw new QueryError(\"Error deleting highlight\", response.status);\n }\n}\n\nexport async function createAnnotation(highlightId: number, body: string): Promise {\n const response = await fetchHelper(`/api/highlights/${highlightId}/annotations`, {\n method: \"POST\",\n body: { body },\n });\n const data = await response.json();\n if (!response.ok) {\n throw new QueryError(data.error || \"Error creating annotation\", response.status);\n }\n return data;\n}\n\nexport async function updateAnnotation(\n highlightId: number,\n annotationId: number,\n body: string,\n): Promise {\n const response = await fetchHelper(`/api/highlights/${highlightId}/annotations/${annotationId}`, {\n method: \"PATCH\",\n body: { body },\n });\n const data = await response.json();\n if (!response.ok) {\n throw new QueryError(data.error || \"Error updating annotation\", response.status);\n }\n return data;\n}\n\nexport async function deleteAnnotation(highlightId: number, annotationId: number): Promise {\n const response = await fetchHelper(`/api/highlights/${highlightId}/annotations/${annotationId}`, {\n method: \"DELETE\",\n });\n if (!response.ok) {\n throw new QueryError(\"Error deleting annotation\", response.status);\n }\n}\n", "import { mergeQueryKeys } from \"@lukemorales/query-key-factory\";\nimport { transcriptsQueries } from \"./transcripts\";\nimport { queryImprovementQueries } from \"./queryImprovement\";\nimport { benchOpinionsQueries } from \"./benchOpinions\";\nimport judgesQueries from \"./judges\";\nimport { foldersQueries } from \"./folders\";\n\n// access query keys + functions from this global store\nexport const queries = mergeQueryKeys(\n transcriptsQueries,\n queryImprovementQueries,\n benchOpinionsQueries,\n judgesQueries,\n foldersQueries,\n);\n\n// error which includes HTTP status code\nexport class QueryError extends Error {\n code?: number;\n apiCode?: string;\n constructor(message: string, code?: number, apiCode?: string, options?: ErrorOptions) {\n super(message, options);\n this.code = code;\n this.apiCode = apiCode;\n }\n}\n\n// list of query types for transcript routes\nexport type TranscriptQueryResultType = \"transcript\" | \"bench-opinion\";\n", "import { TranscriptsAPIIndexResponse } from \"./transcripts.types\";\nimport { CaseHistoryAPIResponse, CaseHistoryAPIEntryData } from \"./caseHistory.types\";\n\nexport const transformTranscriptsToCaseHistory = (\n data: TranscriptsAPIIndexResponse,\n page: number,\n): CaseHistoryAPIResponse => {\n // convert the raw response into EntryData\n const caseHistory: CaseHistoryAPIEntryData[] = [];\n if (\"results\" in data) {\n for (const result of data.results) {\n const motions = result.motion_types.map((motion: string) => ({\n name: motion,\n }));\n caseHistory.push({\n // on staging some transcripts do not have judge or date of hearing\n // set eastern timezone to avoid off by 1 dating\n date: \"date_of_hearing\" in result ? `${result.date_of_hearing}T00:00:00` : undefined,\n judge: \"judge\" in result ? result.judge.name : \"\",\n caseId: result.court_case.id,\n transcriptId: result.id,\n motions: motions,\n transcriptOverview: stripCitations(result.transcript_overview?.content),\n });\n }\n }\n\n const finalCaseHistoryResponse: CaseHistoryAPIResponse = {\n results: caseHistory,\n totalCount: data.total_count || 0,\n totalPages: Math.ceil((data.total_count || 0) / 10),\n currentPage: page,\n };\n\n return finalCaseHistoryResponse;\n};\n\n/**\n * Strips citations from the transcript overview, if present.\n *\n * This method strips citations from the transcript overview and thus makes it\n * appropriate for use in the case history tab. We do not support navigating to\n * specific passages in a transcript from the case history tab, so showing the\n * citation markers in the overview would only confuse users. If the overview is\n * undefined, this method returns undefined.\n */\nfunction stripCitations(content: string | undefined): string | undefined {\n return content?.replaceAll(/\\[\\d+\\]/g, \"\");\n}\n\nexport default transformTranscriptsToCaseHistory;\n", "/**\n * Sample transcript overviews for local design iteration.\n *\n * NEVER imported in production code paths. Used only by `dev/injectOverviews`\n * and gated by `process.env.NODE_ENV !== \"production\"` + a localStorage flag.\n *\n * Each sample exercises a different citation-styling edge case:\n * - 0 citations\n * - 1 citation\n * - consecutive citations [1][2] / [1][2][3]\n * - distributed citations across many sentences\n * - short overview vs long overview\n *\n * Cards on the results page receive samples by index (transcript[i] \u2192\n * SAMPLE_OVERVIEWS[i % length]) so the layout shows multiple variants\n * side-by-side.\n */\n\nimport type { Citation } from \"../api/queries/transcripts.types\";\n\nexport interface SampleOverview {\n content: string;\n citations: Citation[];\n}\n\nexport const SAMPLE_OVERVIEWS: SampleOverview[] = [\n // 0 \u2014 Settlement approval, 4 distributed citations\n {\n content:\n \"The court conducted a confirmation hearing on the debtor's amended Chapter 11 plan, which restructured roughly $220 million in secured debt and provided a 12% recovery to general unsecured creditors. [1] The U.S. Trustee objected on feasibility grounds, arguing the revenue projections were unrealistically optimistic in light of recent macroeconomic conditions. [2] After hearing extensive testimony from the debtor's CFO concerning long-term contractual customer commitments, the court overruled the feasibility objection. [3] The plan was confirmed without modifications, with the effective date set for 14 days after entry of the confirmation order. [4]\",\n citations: [\n {\n index: 1,\n transcript_citations: [\n \"Tr. 4:18\u20135:9 \u2014 Debtor's counsel summarized the proposed treatment for each class of creditors and the projected recovery percentages.\",\n ],\n },\n {\n index: 2,\n transcript_citations: [\n \"Tr. 18:3\u201319:22 \u2014 The U.S. Trustee detailed three specific assumptions in the debtor's projections that it characterized as not borne out by recent industry data.\",\n ],\n },\n {\n index: 3,\n transcript_citations: [\n \"Tr. 33:14\u201335:6 \u2014 The CFO testified to four customer contracts, each five years or longer in duration, that anchor the revenue projections.\",\n \"Tr. 36:11\u201337:2 \u2014 On cross, the CFO acknowledged that two of those contracts contain early-termination clauses but explained the historical exercise rate has been near zero.\",\n ],\n },\n {\n index: 4,\n transcript_citations: [\n \"Tr. 51:8\u201352:19 \u2014 The court entered findings on each of the Section 1129(a) requirements and announced confirmation from the bench.\",\n ],\n },\n ],\n },\n\n // 1 \u2014 Stay relief, 2 consecutive citations\n {\n content:\n \"The secured lender moved for relief from the automatic stay to proceed with foreclosure on the debtor's commercial real estate. The court granted the motion in part, allowing the foreclosure to proceed while staying any deficiency claims pending resolution of the estate's counterclaims against the lender. [1][2]\",\n citations: [\n {\n index: 1,\n transcript_citations: [\n \"Tr. 12:4\u201313:1 \u2014 The court found the debtor lacked equity in the property and that the property was not necessary for an effective reorganization.\",\n ],\n },\n {\n index: 2,\n transcript_citations: [\n \"Tr. 14:7\u201315:18 \u2014 The court explained that staying deficiency claims preserved the estate's affirmative claims against the lender for review on a more complete record.\",\n ],\n },\n ],\n },\n\n // 2 \u2014 Motion to dismiss, single citation at end\n {\n content:\n \"The court heard argument on the trustee's motion to dismiss the Chapter 7 case under Section 707(b) for substantial abuse. After examining the debtor's schedules and the means test calculation, the court found the totality of circumstances did not warrant dismissal and denied the motion from the bench. [1]\",\n citations: [\n {\n index: 1,\n transcript_citations: [\n \"Tr. 22:19\u201324:11 \u2014 The court walked through each of the totality factors and concluded that the debtor's medical-expense documentation outweighed the trustee's substantial-abuse arguments.\",\n ],\n },\n ],\n },\n\n // 3 \u2014 Discovery dispute, 3 consecutive + 1 isolated\n {\n content:\n \"The court addressed a series of discovery disputes between the trustee and a former officer of the debtor regarding production of personal financial records, communications with related entities, and certain board minutes. [1][2][3] The former officer asserted Fifth Amendment privilege over a portion of the materials, while the trustee argued the privilege had been waived through prior testimony in a related state-court proceeding. The court ordered in camera review of the disputed documents and reserved ruling on the underlying production dispute pending that review. [4]\",\n citations: [\n {\n index: 1,\n transcript_citations: [\n \"Tr. 6:2\u20137:14 \u2014 The trustee's counsel listed the categories of documents subject to the motion to compel.\",\n ],\n },\n {\n index: 2,\n transcript_citations: [\n \"Tr. 8:5\u20139:21 \u2014 Counsel for the former officer summarized the privileges asserted and the basis for each.\",\n ],\n },\n {\n index: 3,\n transcript_citations: [\n \"Tr. 10:8\u201311:19 \u2014 The trustee responded that any privilege over financial records had been waived in a prior proceeding before the state court.\",\n ],\n },\n {\n index: 4,\n transcript_citations: [\n \"Tr. 28:3\u201329:17 \u2014 The court directed the parties to submit the disputed documents for in camera review within 14 days and reserved ruling on the underlying motion.\",\n ],\n },\n ],\n },\n\n // 4 \u2014 Cash collateral stipulation, short, 2 isolated citations\n {\n content:\n \"The court approved the debtor's stipulation with the senior secured lender for the continued use of cash collateral through the next interim hearing. [1] Adequate protection takes the form of replacement liens on post-petition receivables and monthly interest payments at the non-default contract rate. [2]\",\n citations: [\n {\n index: 1,\n transcript_citations: [\n \"Tr. 3:11\u20134:8 \u2014 The debtor's counsel walked through the budget supporting the cash-collateral request.\",\n ],\n },\n {\n index: 2,\n transcript_citations: [\n \"Tr. 5:14\u20136:3 \u2014 The court noted that the adequate-protection package was substantially similar to the one approved on first-day relief.\",\n ],\n },\n ],\n },\n\n // 5 \u2014 Settlement approval, no citations\n {\n content:\n \"The debtor presented a global settlement that resolves claims with three creditor groups simultaneously: the unsecured creditors' committee, the indenture trustee, and a class of preferred equity holders. The proposed settlement provides cash distributions totaling $45 million across the three groups and includes the issuance of new common stock equal to 35% of the reorganized company. The court took the matter under advisement pending the deadline for filing objections, which closes in 21 days.\",\n citations: [],\n },\n\n // 6 \u2014 Adversary scheduling conference, no citations, brief\n {\n content:\n \"The court convened a scheduling conference in the adversary proceeding. Counsel for both sides confirmed Rule 26 disclosures were complete, and the parties agreed on a trial-ready date approximately seven months out. The court entered a scheduling order from the bench setting deadlines for fact discovery, expert reports, and dispositive motions.\",\n citations: [],\n },\n\n // 7 \u2014 Long overview, 5 citations distributed across complex narrative\n {\n content:\n \"The court conducted an evidentiary hearing on competing motions concerning the disposition of the debtor's intellectual-property portfolio. [1] The proposed stalking-horse bidder argued that its bid maximized value through a combination of cash, a credit bid component, and the assumption of certain executory contracts. [2] An objecting bidder challenged the bid-protection provisions as chilling, particularly the size of the break-up fee and the scope of the matching rights. [3] The unsecured creditors' committee took an intermediate position, supporting the sale process generally but objecting to the inclusion of certain unencumbered assets within the stalking-horse package. [4] After receiving testimony from the debtor's investment banker on the marketing process and the universe of potential bidders, the court approved the bid procedures with several modifications: a reduced break-up fee, narrower matching rights, and the carve-out of two unencumbered patents from the stalking-horse package. [5]\",\n citations: [\n {\n index: 1,\n transcript_citations: [\n \"Tr. 4:12\u20136:8 \u2014 Debtor's counsel framed the relief sought and the procedural posture of the competing motions.\",\n ],\n },\n {\n index: 2,\n transcript_citations: [\n \"Tr. 16:7\u201318:21 \u2014 Counsel for the stalking-horse bidder detailed the structure of the proposed bid, including the credit-bid mechanics.\",\n \"Tr. 20:3\u201321:14 \u2014 On cross by the objecting bidder, counsel acknowledged that the credit bid component represented roughly 40% of the headline value.\",\n ],\n },\n {\n index: 3,\n transcript_citations: [\n \"Tr. 27:18\u201329:9 \u2014 The objecting bidder argued the 4% break-up fee was outside market and would deter higher bids.\",\n ],\n },\n {\n index: 4,\n transcript_citations: [\n \"Tr. 38:5\u201340:11 \u2014 Committee counsel walked through the unencumbered-asset analysis prepared by the committee's financial advisor.\",\n ],\n },\n {\n index: 5,\n transcript_citations: [\n \"Tr. 64:14\u201367:22 \u2014 The court announced its modifications to the proposed order from the bench, citing the testimony of the investment banker as to the depth of the bidder universe.\",\n \"Tr. 68:3\u201369:2 \u2014 The court directed the parties to submit a revised order reflecting the modifications within three business days.\",\n ],\n },\n ],\n },\n];\n", "/**\n * Dev-only transformer that injects sample transcript overviews into search\n * results that don't have one. Used purely for designing the citation styling\n * locally without needing the enrichment-service round-trip.\n *\n * Two layers of defense to prevent this from ever firing in production:\n * 1. `process.env.NODE_ENV !== \"production\"` \u2014 esbuild inlines this at build\n * time, so the prod bundle dead-code-eliminates the entire branch.\n * 2. `localStorage.devInjectOverviews === \"1\"` \u2014 opt-in even in dev.\n *\n * Usage in the dev browser console:\n * localStorage.devInjectOverviews = \"1\"; // turn on, then reload\n * delete localStorage.devInjectOverviews; // turn off, then reload\n *\n * Real overviews returned by the API are never overwritten \u2014 only nulls get\n * filled in. Toggle off and reload to see the real (often empty) state.\n */\n\nimport { SAMPLE_OVERVIEWS } from \"./sampleOverviews\";\nimport type { TranscriptsAPIReadableContentPreview } from \"../api/queries/transcripts.types\";\n\nconst STORAGE_KEY = \"devInjectOverviews\";\n\nconst isInjectionEnabled = (): boolean => {\n if (process.env.NODE_ENV === \"production\") return false;\n if (typeof window === \"undefined\") return false;\n try {\n return window.localStorage.getItem(STORAGE_KEY) === \"1\";\n } catch {\n return false;\n }\n};\n\nexport function maybeInjectOverviews(\n results: TranscriptsAPIReadableContentPreview[],\n): TranscriptsAPIReadableContentPreview[] {\n if (!isInjectionEnabled()) return results;\n return results.map((result, index) => {\n if (result.transcript_overview) return result;\n const sample = SAMPLE_OVERVIEWS[index % SAMPLE_OVERVIEWS.length];\n return { ...result, transcript_overview: sample };\n });\n}\n", "// exposes React query definitions in queries/transcripts.ts and queries/benchOpinions.ts via hooks\n\nimport { fetchHelper } from \"../utils/fetchHelpers\";\nimport { TranscriptsAPIIndexURLSearchParams, TranscriptsAPIShowQueryParams } from \"./queries/transcripts.types\";\nimport { keepPreviousData, skipToken, useQuery } from \"@tanstack/react-query\";\nimport { queries, QueryError } from \"./queries\";\nimport { useGlobalAlert } from \"../contexts/GlobalAlertContext\";\nimport { BenchOpinionsAPIIndexURLSearchParams } from \"./queries/benchOpinions.types\";\nimport { useEffect, useRef } from \"react\";\nimport { CaseHistoryTabSortByOptions } from \"../components/molecules/case_history_tab/CaseHistoryTab\";\nimport { featureEnabled } from \"../utils/featureFlags\";\nimport transformTranscriptsToCaseHistory from \"./queries/caseHistory\";\nimport { maybeInjectOverviews } from \"../dev/injectOverviews\";\nimport type { SourceDocumentAccess } from \"../components/Reader/pdf\";\n\nconst isSourceDocumentAccess = (value: unknown): value is SourceDocumentAccess => {\n if (!value || typeof value !== \"object\") return false;\n const access = value as Record;\n return (\n (access.url === \"/api/source_documents\" || access.url === \"/api/incognito_source_documents\") &&\n typeof access.accessToken === \"string\" &&\n access.accessToken.length > 0 &&\n typeof access.expiresAt === \"string\" &&\n !Number.isNaN(Date.parse(access.expiresAt)) &&\n typeof access.byteLength === \"number\" &&\n Number.isSafeInteger(access.byteLength) &&\n access.byteLength > 0\n );\n};\n\nexport const createSourceDocumentAccess = async (\n transcriptId: number,\n options: { signal?: AbortSignal; incognito?: boolean } = {},\n): Promise => {\n const incognito = options.incognito ?? featureEnabled(\"incognito_queries\");\n const response = await fetchHelper(\n incognito ? \"/api/transcripts/incognito_source_document\" : \"/api/transcripts/source_document\",\n {\n method: \"POST\",\n body: { id: transcriptId },\n signal: options.signal,\n },\n );\n if (!response.ok) throw new Error(`Official source access failed (${response.status})`);\n const access: unknown = await response.json();\n if (!isSourceDocumentAccess(access)) throw new Error(\"Official source access response was invalid\");\n return access;\n};\n\nexport const retryIfServerError = (failureCount: number, error: QueryError): boolean => {\n console.log(error, failureCount);\n if (failureCount > 3) {\n return false;\n }\n if (error.code) {\n if (error.code >= 500) {\n return true;\n }\n }\n return false;\n};\n\n// declarative api/transcripts?...\nexport const useQueryTranscriptsAPIIndex = (searchParams: TranscriptsAPIIndexURLSearchParams, enabled = true) => {\n return useQuery({\n queryKey: queries.transcripts.index(searchParams).queryKey,\n queryFn: queries.transcripts.index(searchParams).queryFn,\n placeholderData: keepPreviousData,\n enabled: enabled, // if enabled, React Query will auto fetch on window refocus (tab change) if data is stale. Default to false to prevent this\n retry: retryIfServerError,\n staleTime: Infinity, // so React Query will never try to refetch on its own, it will only refetch if query keys change\n // Dev-only: inject sample transcript overviews when localStorage.devInjectOverviews === \"1\".\n // No-op in production (NODE_ENV-gated). See app/javascript/dev/injectOverviews.ts.\n select: (data) => ({ ...data, results: maybeInjectOverviews(data.results) }),\n });\n};\n\n// declarative api/transcripts/:id?...\nexport const useQueryTranscriptsAPIShow = (id: string | null, queryParams?: TranscriptsAPIShowQueryParams) => {\n const query = queries.transcripts.show(id || \"\", queryParams);\n const previousTranscriptIdRef = useRef(id);\n\n const result = useQuery({\n queryKey: query.queryKey,\n queryFn: id !== null ? query.queryFn : skipToken, // disable querying if the id is not given\n placeholderData: (previousData) => {\n return previousTranscriptIdRef.current === id ? previousData : undefined;\n },\n enabled: id !== null,\n retry: retryIfServerError,\n staleTime: Infinity,\n });\n\n useEffect(() => {\n previousTranscriptIdRef.current = id;\n }, [id]);\n\n return result;\n};\n\n// api/bench-opinions?...\nexport const useQueryBenchOpinionsAPIIndex = (searchParams: BenchOpinionsAPIIndexURLSearchParams, enabled = true) => {\n return useQuery({\n queryKey: queries.benchOpinions.index(searchParams).queryKey,\n queryFn: enabled ? queries.benchOpinions.index(searchParams).queryFn : skipToken,\n placeholderData: keepPreviousData,\n enabled: enabled && !featureEnabled(\"disable_generative_ai\") && !featureEnabled(\"incognito_queries\"),\n retry: retryIfServerError,\n staleTime: Infinity,\n });\n};\n\n// api/transcripts/:id/bench-opinion\nexport const useQueryBenchOpinionsAPIShow = (transcriptId: string | null) => {\n return useQuery({\n queryKey: queries.benchOpinions.show(transcriptId || \"\").queryKey,\n queryFn: transcriptId !== null ? queries.benchOpinions.show(transcriptId).queryFn : skipToken,\n // It's not only disabled because incognito_queries accounts don't (at the moment) have AI\n // features enabled, but also because the transcript id in the URI would leak if we had this\n // enabled.\n enabled: !featureEnabled(\"incognito_queries\") && transcriptId !== null,\n retry: retryIfServerError,\n staleTime: Infinity,\n });\n};\n\n// api/transcripts?queryText=&caseId=\n// case history\nexport const useCaseHistory = (courtCaseId: string | undefined, page: number, sortBy: CaseHistoryTabSortByOptions) => {\n const sortField = \"date_of_hearing\";\n const sortDirection = sortBy === \"newest-to-oldest\" ? \"desc\" : \"asc\";\n\n const searchParams: TranscriptsAPIIndexURLSearchParams = {\n queryText: \"\",\n caseId: courtCaseId || \"\",\n page: page.toString(),\n sortField: sortField,\n sortDirection: sortDirection,\n };\n\n return useQuery({\n ...queries.transcripts.index(searchParams),\n staleTime: Infinity,\n placeholderData: keepPreviousData,\n retry: retryIfServerError,\n select: (data) => transformTranscriptsToCaseHistory(data, page),\n enabled: !!courtCaseId,\n });\n};\n\n// api/transcripts/:id/download and api/transcripts/incognito_download\n// Imperative, only fetch when download button explicitly clicked\n// TODO: https://app.asana.com/0/1205268994786591/1209099885496947/f\nexport const useFetchTranscriptPDF = () => {\n const { setAlertWithOptions } = useGlobalAlert();\n return async (id: string): Promise => {\n try {\n let rawResponse;\n if (featureEnabled(\"incognito_queries\")) {\n const url = new URL(\"/api/transcripts/incognito_download\", window.location.origin);\n rawResponse = await fetchHelper(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/pdf\", // Override default Accept header for PDF download\n },\n body: {\n id: id,\n },\n });\n } else {\n const url = new URL(`/api/transcripts/${id}/download`, window.location.origin);\n rawResponse = await fetchHelper(url.toString(), {\n headers: {\n Accept: \"application/pdf\", // Override default Accept header for PDF download\n },\n });\n }\n\n if (!rawResponse.ok) {\n throw new Error(\"Error downloading transcript PDF\");\n }\n return await rawResponse.blob();\n } catch (error) {\n setAlertWithOptions(\"Error downloading transcript PDF\");\n throw error;\n }\n };\n};\n\n// class ClientError extends Error {}\n\nexport const useSearchWithinDocument = (\n transcriptId: string | null,\n searchDocument: \"transcript\" | \"bench-opinion\" | null,\n searchQuery: string,\n isSearchQueryInWestlawBooleanSyntax = true,\n enabled = false,\n) => {\n const { setAlertWithOptions } = useGlobalAlert();\n\n const queryType = isSearchQueryInWestlawBooleanSyntax ? \"search_within\" : \"scroll_within\";\n const queryParams = searchQuery ? { queryType, queryText: searchQuery } : undefined;\n\n const transcriptQuery = useQuery({\n ...queries.transcripts.show(transcriptId || \"\", queryParams),\n enabled: enabled && searchDocument === \"transcript\" && !!transcriptId && !!searchQuery,\n retry: retryIfServerError,\n staleTime: 0, // always refetch for search within\n });\n\n const benchOpinionQuery = useQuery({\n ...queries.benchOpinions.show(transcriptId || \"\", queryParams),\n enabled: enabled && searchDocument === \"bench-opinion\" && !!transcriptId && !!searchQuery,\n retry: retryIfServerError,\n staleTime: 0, // always refetch for search within\n });\n\n const activeQuery = searchDocument === \"transcript\" ? transcriptQuery : benchOpinionQuery;\n\n // Handle errors with global alert\n useEffect(() => {\n if (activeQuery.error) {\n let message;\n const error = activeQuery.error as QueryError;\n\n if (error.code === 400) {\n message = `There is an issue with the request: ${error.message}`;\n }\n\n const fallback = \"An error occurred while performing a search within this transcript.\";\n setAlertWithOptions(message || fallback);\n }\n }, [activeQuery.error, setAlertWithOptions]);\n\n return {\n data: activeQuery.data,\n contentHighlights: activeQuery.data?.results?.[0]?.content_highlights ?? [],\n highlightTargets: activeQuery.data?.results?.[0]?.highlight_targets ?? [],\n isFetching: activeQuery.isFetching,\n error: activeQuery.error,\n isSuccess: activeQuery.isSuccess,\n };\n};\n", "// Exposes React Query hooks for folders, highlights, and annotations.\n// Query definitions live in queries/folders.ts; this file wraps them as hooks.\n\nimport { useMemo } from \"react\";\nimport { useQuery, useMutation, useQueryClient, keepPreviousData, type QueryClient } from \"@tanstack/react-query\";\nimport { queries } from \"./queries\";\nimport { featureEnabled } from \"../utils/featureFlags\";\nimport {\n createFolder,\n updateFolder,\n deleteFolder,\n addFolderItem,\n removeFolderItem,\n createHighlight,\n updateHighlight,\n deleteHighlight,\n createAnnotation,\n updateAnnotation,\n deleteAnnotation,\n} from \"./queries/folders\";\nimport type { UpdateHighlightParams } from \"./queries/folders\";\nimport type { FolderableType } from \"./queries/folders.types\";\nimport { retryIfServerError } from \"./documents\";\n\n// \u2500\u2500 Invalidation Helpers \u2500\u2500\n\nfunction invalidateAllHighlightQueries(queryClient: QueryClient) {\n queryClient.invalidateQueries({ queryKey: [\"folders\", \"transcriptHighlights\"] });\n queryClient.invalidateQueries({ queryKey: [\"folders\", \"sessionHighlights\"] });\n queryClient.invalidateQueries({ queryKey: [\"folders\", \"globalHighlights\"] });\n // Folder-detail row badges and list-view counts read from readableMetadata,\n // so they need to refresh whenever the underlying highlight/annotation set\n // changes. Without this, annotation add/edit/delete leaves stale counts on\n // any folder page that stays mounted.\n queryClient.invalidateQueries({ queryKey: queries.folders.readableMetadata._def });\n}\n\nfunction invalidateReadableMetadata(queryClient: QueryClient, type: FolderableType) {\n queryClient.invalidateQueries({ queryKey: [...queries.folders.readableMetadata._def, type] });\n}\n\n// Invalidate every cached page of this folder's detail. The factory's query key includes\n// a `page` parameter, so queries.folders.detail(id).queryKey defaults to page 1 and would\n// miss any non-page-1 caches. The _def prefix + id covers all pages.\nfunction invalidateFolderDetail(queryClient: QueryClient, folderId: number) {\n queryClient.invalidateQueries({ queryKey: [...queries.folders.detail._def, folderId] });\n}\n\n// \u2500\u2500 Folder Queries \u2500\u2500\n\n/** All folders for the current user (includes the auto-created starred folder). */\nexport const useFolders = (enabled = true, options: { refetchOnMount?: boolean | \"always\" } = {}) => {\n const flagEnabled = featureEnabled(\"folders_and_annotations\");\n return useQuery({\n ...queries.folders.list(),\n enabled: enabled && flagEnabled,\n retry: retryIfServerError,\n staleTime: Infinity,\n refetchOnMount: options.refetchOnMount,\n });\n};\n\n/** Single folder with paginated items. */\nexport const useFolder = (id: number | null, page = 1) => {\n const flagEnabled = featureEnabled(\"folders_and_annotations\");\n return useQuery({\n // id ?? 0 is a placeholder key \u2014 enabled: false prevents the fetch when id is null\n ...queries.folders.detail(id ?? 0, page),\n enabled: id !== null && flagEnabled,\n retry: retryIfServerError,\n staleTime: Infinity,\n placeholderData: keepPreviousData,\n });\n};\n\n// \u2500\u2500 Highlight Queries \u2500\u2500\n\n/** All highlights for a transcript (with and without annotations, not paginated). */\nexport const useTranscriptHighlights = (transcriptId: number | null) => {\n const flagEnabled = featureEnabled(\"folders_and_annotations\") || featureEnabled(\"copy_text_with_citation\");\n return useQuery({\n // transcriptId ?? 0 is a placeholder key \u2014 enabled: false prevents the fetch when null\n ...queries.folders.transcriptHighlights(transcriptId ?? 0),\n enabled: transcriptId !== null && flagEnabled,\n retry: retryIfServerError,\n staleTime: Infinity,\n });\n};\n\n/** All highlights for an agent session (with and without annotations, not paginated). */\nexport const useSessionHighlights = (token: string | null) => {\n const flagEnabled = featureEnabled(\"folders_and_annotations\");\n return useQuery({\n ...queries.folders.sessionHighlights(token ?? \"\"),\n enabled: token !== null && flagEnabled,\n retry: retryIfServerError,\n staleTime: Infinity,\n });\n};\n\n/** Global highlights \u2014 notes, bare highlights, and citation-only entries, paginated. Optional folder filter. */\nexport const useGlobalHighlights = (page = 1, folderId?: number) => {\n const flagEnabled = featureEnabled(\"folders_and_annotations\");\n return useQuery({\n ...queries.folders.globalHighlights(page, folderId),\n enabled: flagEnabled,\n retry: retryIfServerError,\n staleTime: Infinity,\n placeholderData: keepPreviousData,\n });\n};\n\n/** Batch metadata (starred, folder_count, folder_ids, annotation_count) for a list of items. */\nexport const useReadableMetadata = (type: FolderableType, ids: number[]) => {\n const flagEnabled = featureEnabled(\"folders_and_annotations\");\n // Memoize so a stable ids input from the caller produces a stable sorted array \u2014 avoids\n // re-sorting and re-keying the query on every render. ids is intentionally the dep: if\n // the caller passes a fresh array literal each render, this memo will bust, which is\n // the caller's bug to fix (see StarToggle.tsx for the matching memo).\n // TODO: Backend caps readableMetadata at 100 IDs (ReadablesController::MAX_BATCH_SIZE).\n // If list views ever exceed 100 items, chunk IDs here or bump the backend limit.\n const sortedIds = useMemo(() => [...ids].sort((a, b) => a - b), [ids]);\n return useQuery({\n ...queries.folders.readableMetadata(type, sortedIds),\n enabled: sortedIds.length > 0 && flagEnabled,\n retry: retryIfServerError,\n staleTime: Infinity,\n // Keep previous metadata visible while a new ids-keyed query resolves.\n placeholderData: keepPreviousData,\n });\n};\n\n/** Returns the auto-created starred folder and its ID. */\nexport const useStarredFolder = () => {\n const { data: folders, ...rest } = useFolders();\n const starredFolder = folders?.find((f) => f.kind === \"starred\");\n return { starredFolder, starredFolderId: starredFolder?.id ?? null, ...rest };\n};\n\n// \u2500\u2500 Folder Mutations \u2500\u2500\n\nexport const useCreateFolder = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: createFolder,\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: queries.folders.list().queryKey });\n },\n });\n};\n\nexport const useUpdateFolder = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, ...params }: { id: number; name?: string; description?: string | null }) =>\n updateFolder(id, params),\n onSuccess: (_data, variables) => {\n queryClient.invalidateQueries({ queryKey: queries.folders.list().queryKey });\n invalidateFolderDetail(queryClient, variables.id);\n },\n });\n};\n\nexport const useDeleteFolder = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: deleteFolder,\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: queries.folders.list().queryKey });\n },\n });\n};\n\n// \u2500\u2500 Folder Item Mutations \u2500\u2500\n\nexport const useAddFolderItem = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n folderId,\n folderableType,\n folderableId,\n }: {\n folderId: number;\n folderableType: FolderableType;\n folderableId: number;\n }) => addFolderItem(folderId, { folderable_type: folderableType, folderable_id: folderableId }),\n onSuccess: (_data, variables) => {\n queryClient.invalidateQueries({ queryKey: queries.folders.list().queryKey });\n invalidateFolderDetail(queryClient, variables.folderId);\n invalidateReadableMetadata(queryClient, variables.folderableType);\n },\n });\n};\n\nexport const useRemoveFolderItem = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ itemId }: { itemId: number; folderId?: number; folderableType?: FolderableType }) =>\n removeFolderItem(itemId),\n onSuccess: (_data, variables) => {\n queryClient.invalidateQueries({ queryKey: queries.folders.list().queryKey });\n // When folderId/folderableType are provided, invalidate the targeted scope.\n // When they aren't (e.g. folder-chip X on the reader toolbar), fall back to\n // wiping the whole namespace prefix so we don't leave stale `folder_ids`\n // behind in any consumer's metadata cache.\n if (variables.folderId) {\n invalidateFolderDetail(queryClient, variables.folderId);\n } else {\n queryClient.invalidateQueries({ queryKey: queries.folders.detail._def });\n }\n if (variables.folderableType) {\n invalidateReadableMetadata(queryClient, variables.folderableType);\n } else {\n queryClient.invalidateQueries({ queryKey: queries.folders.readableMetadata._def });\n }\n },\n });\n};\n\n// \u2500\u2500 Highlight Mutations \u2500\u2500\n\nexport const useCreateHighlight = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: createHighlight,\n onError: (error) => console.error(\"Failed to create highlight:\", error),\n onSuccess: (_data, variables) => {\n if (variables.highlightable_type === \"Transcript\") {\n queryClient.invalidateQueries({\n queryKey: queries.folders.transcriptHighlights(variables.highlightable_id).queryKey,\n });\n }\n // Session highlights are keyed by token, but we only have the ID here \u2014 invalidate all session highlight queries\n if (variables.highlightable_type === \"AgentPrototypeSession\") {\n queryClient.invalidateQueries({ queryKey: [\"folders\", \"sessionHighlights\"] });\n }\n invalidateReadableMetadata(queryClient, variables.highlightable_type);\n queryClient.invalidateQueries({ queryKey: [\"folders\", \"globalHighlights\"] });\n },\n });\n};\n\nexport const useUpdateHighlight = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ highlightId, ...params }: { highlightId: number } & UpdateHighlightParams) =>\n updateHighlight(highlightId, params),\n onError: (error) => console.error(\"Failed to update highlight:\", error),\n onSuccess: () => {\n invalidateAllHighlightQueries(queryClient);\n },\n });\n};\n\nexport const useDeleteHighlight = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n highlightId,\n }: {\n highlightId: number;\n highlightableType?: FolderableType;\n highlightableId?: number;\n }) => deleteHighlight(highlightId),\n onError: (error) => console.error(\"Failed to delete highlight:\", error),\n onSuccess: (_data, variables) => {\n if (variables.highlightableType === \"Transcript\" && variables.highlightableId) {\n queryClient.invalidateQueries({\n queryKey: queries.folders.transcriptHighlights(variables.highlightableId).queryKey,\n });\n }\n if (variables.highlightableType === \"AgentPrototypeSession\") {\n queryClient.invalidateQueries({ queryKey: [\"folders\", \"sessionHighlights\"] });\n }\n if (variables.highlightableType) {\n invalidateReadableMetadata(queryClient, variables.highlightableType);\n }\n queryClient.invalidateQueries({ queryKey: [\"folders\", \"globalHighlights\"] });\n },\n });\n};\n\n// \u2500\u2500 Annotation Mutations \u2500\u2500\n\nexport const useCreateAnnotation = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ highlightId, body }: { highlightId: number; body: string }) => createAnnotation(highlightId, body),\n onError: (error) => console.error(\"Failed to create annotation:\", error),\n onSuccess: () => {\n invalidateAllHighlightQueries(queryClient);\n },\n });\n};\n\nexport const useUpdateAnnotation = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ highlightId, annotationId, body }: { highlightId: number; annotationId: number; body: string }) =>\n updateAnnotation(highlightId, annotationId, body),\n onError: (error) => console.error(\"Failed to update annotation:\", error),\n onSuccess: () => {\n invalidateAllHighlightQueries(queryClient);\n },\n });\n};\n\nexport const useDeleteAnnotation = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ highlightId, annotationId }: { highlightId: number; annotationId: number }) =>\n deleteAnnotation(highlightId, annotationId),\n onError: (error) => console.error(\"Failed to delete annotation:\", error),\n onSuccess: () => {\n invalidateAllHighlightQueries(queryClient);\n },\n });\n};\n", "import { useCallback, useMemo, useState } from \"react\";\nimport { useFolders, useReadableMetadata, useRemoveFolderItem } from \"../api/folders\";\nimport type { FolderableType, Folder } from \"../api/queries/folders.types\";\nimport { featureEnabled } from \"../utils/featureFlags\";\nimport { recordUserEvent } from \"../api/userEvents\";\n\nconst EMPTY_FOLDER_IDS: number[] = [];\nconst EMPTY_FOLDER_ITEM_IDS: Record = {};\n\nexport interface FolderChipData {\n id: number;\n name: string;\n itemId: number;\n}\n\nexport interface UseSaveToFolderArgs {\n folderableType: FolderableType;\n folderableId: number;\n sourceType: \"transcript\" | \"clerk_session\";\n enabled?: boolean;\n}\n\nexport interface UseSaveToFolderReturn {\n anchorEl: HTMLElement | null;\n openPopover: (eventOrElement: React.MouseEvent | HTMLElement) => void;\n closePopover: () => void;\n /** Folders this item currently belongs to (for FolderChipRow). */\n itemFolders: FolderChipData[];\n /** Folder IDs this item currently belongs to (for SaveToFolderPopover initial state). */\n currentFolderIds: number[];\n /** All custom folders for the popover list. */\n customFolders: Folder[];\n /** Map of folder_id \u2192 folder_item_id for the popover's unchecking logic. */\n folderItemIds: Record;\n /** Remove item from a folder by folder ID (resolves folder_item_id internally). */\n removeFromFolder: (folderId: number) => void;\n isLoading: boolean;\n refetchMemberships: () => Promise;\n}\n\n/**\n * Shared hook for the \"Save to Folder\" feature. Encapsulates all data-fetching,\n * state, and mutation logic used by both TranscriptReader and AgentPrototypeLayout.\n */\nexport const useSaveToFolder = ({\n folderableType,\n folderableId,\n sourceType,\n enabled = true,\n}: UseSaveToFolderArgs): UseSaveToFolderReturn => {\n const flagEnabled = featureEnabled(\"folders_and_annotations\");\n const isEnabled = enabled && flagEnabled;\n\n const [anchorEl, setAnchorEl] = useState(null);\n\n const { data: folders, isLoading: foldersLoading, refetch: refetchFolders } = useFolders(isEnabled);\n const metadataIds = useMemo(() => (isEnabled ? [folderableId] : []), [isEnabled, folderableId]);\n const {\n data: metadata,\n isLoading: metadataLoading,\n refetch: refetchMetadata,\n } = useReadableMetadata(folderableType, metadataIds);\n\n // `useMutation` returns a new result object on every render, while its\n // `mutate` function is stable. Capture the function directly so\n // `removeFromFolder` also stays stable. TranscriptReader includes this\n // callback in the external FolderChipRow slot it registers with\n // ReaderLayout; changing it every render would recreate the slot, update the\n // parent layout, and rerender the reader in a loop once the first chip\n // appears after Save.\n const { mutate: removeItem } = useRemoveFolderItem();\n\n const entry = metadata?.[String(folderableId)];\n const currentFolderIds = entry?.folder_ids ?? EMPTY_FOLDER_IDS;\n const folderItemIds = entry?.folder_item_ids ?? EMPTY_FOLDER_ITEM_IDS;\n\n const customFolders = useMemo(() => (folders ?? []).filter((f) => f.kind === \"custom\"), [folders]);\n\n const itemFolders: FolderChipData[] = useMemo(() => {\n if (!folders || !currentFolderIds.length) return [];\n return currentFolderIds\n .map((folderId) => {\n const folder = folders.find((f) => f.id === folderId);\n if (!folder) return null;\n const itemId = folderItemIds[String(folderId)] ?? 0;\n return { id: folder.id, name: folder.name, itemId };\n })\n .filter((f): f is FolderChipData => f !== null);\n }, [folders, currentFolderIds, folderItemIds]);\n\n const openPopover = useCallback(\n (eventOrElement: React.MouseEvent | HTMLElement) => {\n if (eventOrElement instanceof HTMLElement) {\n setAnchorEl(eventOrElement);\n } else {\n setAnchorEl(eventOrElement.currentTarget);\n }\n if (isEnabled) void refetchFolders();\n void recordUserEvent({\n event_name: \"save_to_folder_opened\",\n event_properties: { existing_folder_count: customFolders.length, source_type: sourceType },\n });\n },\n [customFolders.length, isEnabled, refetchFolders, sourceType],\n );\n\n const closePopover = useCallback(() => {\n setAnchorEl(null);\n }, []);\n\n const removeFromFolder = useCallback(\n (folderId: number) => {\n const itemId = folderItemIds[String(folderId)];\n if (!itemId) return;\n removeItem(\n { itemId, folderId, folderableType },\n { onError: () => console.error(\"Failed to remove from folder\") },\n );\n },\n [removeItem, folderableType, folderItemIds],\n );\n\n return {\n anchorEl,\n openPopover,\n closePopover,\n itemFolders,\n currentFolderIds,\n customFolders,\n folderItemIds,\n removeFromFolder,\n isLoading: foldersLoading || metadataLoading,\n refetchMemberships: async () => Promise.all([refetchFolders(), refetchMetadata()]),\n };\n};\n", "import type { SxProps, Theme } from \"@mui/material/styles\";\n\n/**\n * Strips a MUI Autocomplete/MenuItem option row's `aria-selected` background\n * fill while keeping the hover / keyboard-highlight (`.Mui-focused`) affordance.\n *\n * For checkbox-list dropdowns the checkbox already signals selection, so the row\n * fill is redundant. Applied per-callsite (not as a global theme override) so\n * regular selects keep their selection highlight. `&&` doubles specificity to\n * win over MUI's option rules.\n */\nexport const noSelectedRowFillSx: SxProps = {\n \"&&[aria-selected='true']\": { backgroundColor: \"transparent\" },\n \"&&[aria-selected='true'].Mui-focused\": { backgroundColor: \"action.hover\" },\n};\n", "import {MutableRefObject, Ref} from 'react'\n\ntype OptionalRef = Ref | undefined\n\nexport default function composeRefs(...refs: [OptionalRef, OptionalRef, ...Array>]): Ref {\n if (refs.length === 2) { // micro-optimize the hot path\n return composeTwoRefs(refs[0], refs[1]) || null\n }\n\n const composedRef = refs.slice(1).reduce(\n (semiCombinedRef: OptionalRef, refToInclude: OptionalRef) => composeTwoRefs(semiCombinedRef, refToInclude),\n refs[0],\n )\n return composedRef || null\n}\n\ntype NonNullRef = NonNullable>\nconst composedRefCache = new WeakMap, WeakMap, NonNullRef>>()\n\nfunction composeTwoRefs(ref1: OptionalRef, ref2: OptionalRef): OptionalRef {\n if (ref1 && ref2) {\n const ref1Cache = composedRefCache.get(ref1) || new WeakMap, NonNullRef>()\n composedRefCache.set(ref1, ref1Cache)\n\n const composedRef = ref1Cache.get(ref2) || ((instance: T): void => {\n updateRef(ref1, instance)\n updateRef(ref2, instance)\n })\n ref1Cache.set(ref2, composedRef)\n\n return composedRef as NonNullRef\n }\n\n if (!ref1) {\n return ref2\n } else {\n return ref1\n }\n}\n\nfunction updateRef(ref: NonNullRef, instance: null | T): void {\n if (typeof ref === 'function') {\n ref(instance)\n } else {\n (ref as MutableRefObject).current = instance\n }\n}\n", "import React, { useEffect, useRef, useState } from \"react\";\nimport { TextField, TextFieldProps, Box } from \"@mui/material\";\nimport { grey } from \"@mui/material/colors\";\nimport composeRefs from \"@seznam/compose-react-refs\";\n\ninterface GhostTextFieldProps extends Omit {\n ghostText: string;\n ghostTextColor?: string;\n}\n\nconst GhostTextField: React.FC = ({\n ghostText,\n ghostTextColor = grey[600],\n sx = {},\n id,\n placeholder,\n autoFocus,\n inputProps,\n inputRef: inputRefProp,\n ...props\n}) => {\n const [isOverflowing, setIsOverflowing] = useState(false);\n const inputRef = useRef(null);\n\n useEffect(() => {\n if (inputRef?.current) {\n setIsOverflowing(inputRef.current.scrollWidth > inputRef.current.clientWidth);\n }\n }, [inputRef?.current?.scrollWidth, inputRef?.current?.clientWidth]);\n\n return (\n \n \n \n \n );\n};\n\nexport default GhostTextField;\n", "import React, { useState, useEffect, useRef } from \"react\";\nimport { X } from \"lucide-react\";\nimport { Dialog, Stack, Typography } from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { BIQInputField } from \"@/components/atoms/BIQInputField\";\nimport { useCreateFolder } from \"../../api/folders\";\nimport type { Folder } from \"../../api/queries/folders.types\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { MODAL_WIDTH } from \"../../utils/constants\";\n\nexport interface CreateFolderModalProps {\n open: boolean;\n onClose: () => void;\n onCreated?: (folder: Folder) => void;\n /**\n * Called when the mutation fails with a transport-class error (network / 5xx).\n * The parent is expected to close the dialog and surface a persistent error\n * banner at the top of the page. When `onError` is omitted, transport\n * failures still close the dialog silently to match the Folders List Page\n * two-lane error pattern; the existing SaveToFolderPopover consumer is not\n * affected because it passes neither `onError` nor a banner surface.\n */\n onError?: (message: string) => void;\n /**\n * Surface that triggered this modal open. Used as the `opened_from` /\n * `created_from` dimension on the `folder_create_modal_opened` and\n * `folder_created` analytics events.\n */\n opened_from: \"folders_page\" | \"save_to_folder_popover\";\n}\n\n/**\n * Modal for creating a new folder with a name (required) and description (optional).\n * Follows the Dialog + Stack pattern used by RequestJudgeModal.\n * Reused by both SaveToFolderPopover and the Folders List Page (PR6).\n */\nexport const CreateFolderModal: React.FC = ({\n open,\n onClose,\n onCreated,\n onError,\n opened_from,\n}) => {\n const [name, setName] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [nameError, setNameError] = useState(false);\n\n const descriptionRef = useRef(null);\n const createFolder = useCreateFolder();\n // Tracks whether the current open-session ended in a successful create.\n // Used to suppress the `folder_create_cancelled` event on the close rising\n // edge, so a successful create doesn't spuriously also log a cancel.\n const createdRef = useRef(false);\n // Tracks whether the current open-session ended because the create\n // mutation errored. A transport failure closes the dialog but is not a\n // user-initiated cancel, so we suppress the cancel event in that case.\n const erroredRef = useRef(false);\n // Latest typed name \u2014 read synchronously from the close-edge effect, which\n // would otherwise close over a stale value.\n const nameRef = useRef(\"\");\n useEffect(() => {\n nameRef.current = name;\n }, [name]);\n // Tracks the previous `open` value so we can detect rising / falling edges\n // without re-firing analytics on unrelated re-renders.\n const prevOpenRef = useRef(false);\n\n useEffect(() => {\n const wasOpen = prevOpenRef.current;\n prevOpenRef.current = open;\n\n if (open && !wasOpen) {\n // Rising edge \u2014 reset form and fire the modal-opened event.\n setName(\"\");\n setDescription(\"\");\n setNameError(false);\n createdRef.current = false;\n erroredRef.current = false;\n nameRef.current = \"\";\n void recordUserEvent({\n event_name: \"folder_create_modal_opened\",\n event_properties: { opened_from },\n });\n } else if (!open && wasOpen) {\n // Falling edge \u2014 emit folder_create_cancelled unless the close was\n // caused by a successful create or a transport-class mutation error.\n if (!createdRef.current && !erroredRef.current) {\n void recordUserEvent({\n event_name: \"folder_create_cancelled\",\n event_properties: { had_typed_name: nameRef.current.trim().length > 0 },\n });\n }\n }\n }, [open, opened_from]);\n\n const handleCreate = () => {\n const trimmedName = name.trim();\n if (!trimmedName) {\n setNameError(true);\n return;\n }\n\n createFolder.mutate(\n { name: trimmedName, description: description.trim() || undefined },\n {\n onSuccess: (data) => {\n createdRef.current = true;\n void recordUserEvent({\n event_name: \"folder_created\",\n event_properties: {\n has_description: description.trim().length > 0,\n name_length_chars: trimmedName.length,\n created_from: opened_from,\n },\n });\n onCreated?.(data as Folder);\n onClose();\n },\n onError: (error) => {\n // Transport lane per the PR6 two-lane error pattern: close the dialog\n // and let the parent surface a persistent error banner. Form state is\n // lost \\u2014 the user retries by reopening the dialog.\n erroredRef.current = true;\n onClose();\n onError?.(error instanceof Error ? error.message : \"Couldn't create folder. Please try again.\");\n },\n },\n );\n };\n\n // When the create mutation is in flight, block the backdrop-click and\n // Escape-key dismiss paths as well as the X button. Without this guard, a\n // user could dismiss the dialog while the request is in flight and then\n // get an error banner after they have already moved on. Matches the pattern\n // in EditFolderModal and DeleteFolderDialog.\n const handleDialogClose = () => {\n if (createFolder.isPending) return;\n onClose();\n };\n\n return (\n ({ borderRadius: `${theme.tokens.radii.smallRadius}px`, width: MODAL_WIDTH }) }}\n >\n \n \n Create Folder\n \n \n\n \n {\n setName(e.target.value);\n if (nameError) setNameError(false);\n }}\n error={nameError}\n helper={nameError ? \"Folder name is required\" : undefined}\n fullWidth\n autoFocus\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n descriptionRef.current?.focus();\n }\n }}\n />\n\n setDescription(e.target.value)}\n inputRef={descriptionRef}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n (e.target as HTMLElement).blur();\n handleCreate();\n }\n }}\n multiline\n fullWidth\n />\n \n\n \n \n Cancel\n \n \n Create\n \n \n \n \n );\n};\n\nexport default CreateFolderModal;\n", "import { FolderPlus } from \"lucide-react\";\n\nexport const ADD_TO_FOLDERS_LABEL = \"Add to folders\";\nexport const ADD_TO_FOLDERS_PLACEHOLDER = \"Add to...\";\nexport const ADD_TO_FOLDERS_ICON = FolderPlus;\n", "import React, { useState, useEffect, useMemo, useCallback } from \"react\";\nimport {\n Popover,\n Box,\n Checkbox,\n Typography,\n Autocomplete,\n MenuItem,\n ListItemIcon,\n ListItemText,\n MenuList,\n type AutocompleteRenderOptionState,\n type PopoverOrigin,\n} from \"@mui/material\";\nimport { Plus } from \"lucide-react\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQChip } from \"@/components/atoms/BIQChip\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { noSelectedRowFillSx } from \"@/components/theme/mixins/noSelectedRowFillSx\";\nimport GhostTextField from \"../atoms/GhostTextField\";\nimport { useAddFolderItem, useRemoveFolderItem } from \"../../api/folders\";\nimport type { FolderableType, Folder } from \"../../api/queries/folders.types\";\nimport { CreateFolderModal } from \"./CreateFolderModal\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { useOptionalGlobalAlert } from \"@/contexts/GlobalAlertContext\";\nimport { ADD_TO_FOLDERS_PLACEHOLDER } from \"./addToFoldersAction\";\n\nconst FOLDER_CHANGE_TOAST_DURATION_MS = 7000;\nconst MAX_NAMED_FOLDER_TOAST_LENGTH = 48;\n\nexport const folderMembershipChangeMessage = (addedFolders: Folder[], removedFolders: Folder[]): string | null => {\n const addedCount = addedFolders.length;\n const removedCount = removedFolders.length;\n\n if (addedCount === 0 && removedCount === 0) return null;\n\n const namedFolders = [\n ...(addedCount === 1 && removedCount <= 1 ? addedFolders : []),\n ...(removedCount === 1 && addedCount <= 1 ? removedFolders : []),\n ];\n if (namedFolders.some((folder) => folder.name.length > MAX_NAMED_FOLDER_TOAST_LENGTH)) {\n return \"Folders updated.\";\n }\n\n if (addedCount > 0 && removedCount > 0) {\n if (addedCount === 1 && removedCount === 1) {\n return `Added to ${addedFolders[0].name}, removed from ${removedFolders[0].name}.`;\n }\n const addedDescription = addedCount === 1 ? \"1\" : `${addedCount} folders`;\n const removedDescription = removedCount === 1 ? \"1\" : `${removedCount} folders`;\n return `Added to ${addedDescription}, removed from ${removedDescription}.`;\n }\n\n if (addedCount === 1) return `Added to ${addedFolders[0].name}.`;\n if (addedCount > 1) return `Added to ${addedCount} folders.`;\n if (removedCount === 1) return `Removed from ${removedFolders[0].name}.`;\n return `Removed from ${removedCount} folders.`;\n};\n\nexport interface SaveToFolderPopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null;\n onClose: () => void;\n folderableType: FolderableType;\n folderableId: number;\n sourceType: \"transcript\" | \"clerk_session\";\n currentFolderIds: number[];\n /** Map of folder_id \u2192 folder_item_id, for removing items from unchecked folders. */\n folderItemIds: Record;\n /** Custom folders (kind === \"custom\"), provided by useSaveToFolder hook. */\n customFolders: Folder[];\n commitLabel?: string;\n placeholder?: string;\n anchorOrigin?: PopoverOrigin;\n transformOrigin?: PopoverOrigin;\n onReconcile?: () => Promise | void;\n}\n\nconst formatDate = (dateString: string) => {\n const date = new Date(dateString);\n return date.toLocaleDateString(\"en-US\", { year: \"numeric\", month: \"short\", day: \"numeric\" });\n};\n\n// Render the Autocomplete dropdown inline inside the Popover (no portal/Popper).\nconst InlinePopper = ({ children, disablePortal: _disablePortal, anchorEl: _anchorEl, open: _open, ...props }: any) => (\n \n {children}\n \n);\nconst InlinePaper = ({ children, ...props }: any) => {children};\n\n/**\n * Popover listing all custom folders with checkboxes. Uses MUI Autocomplete\n * for the search + checkbox list (same foundation as JudgeAutocomplete).\n * System folders (Starred) are excluded. Changes are deferred until Save.\n */\nexport const SaveToFolderPopover: React.FC = ({\n open,\n anchorEl,\n onClose,\n folderableType,\n folderableId,\n sourceType,\n currentFolderIds,\n folderItemIds,\n customFolders,\n commitLabel = \"Save\",\n placeholder = ADD_TO_FOLDERS_PLACEHOLDER,\n anchorOrigin = { vertical: \"bottom\", horizontal: \"right\" },\n transformOrigin = { vertical: \"top\", horizontal: \"right\" },\n onReconcile,\n}) => {\n const theme = useTheme();\n const addItem = useAddFolderItem();\n const removeItem = useRemoveFolderItem();\n const globalAlert = useOptionalGlobalAlert();\n\n const [localSelectedFolders, setLocalSelectedFolders] = useState([]);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [createModalOpen, setCreateModalOpen] = useState(false);\n const [committing, setCommitting] = useState(false);\n const [commitError, setCommitError] = useState(null);\n\n // Tracks whether handleSave has already fired in this open session; used to\n // suppress save_to_folder_cancelled on the subsequent onClose invocation.\n const committedRef = React.useRef(false);\n const retrySaveRef = React.useRef<() => void>(() => {});\n const selectionEditedRef = React.useRef(false);\n\n // Initialize selected state when the popover opens. Dynamic callers such as\n // History and Recents begin loading memberships when their row menu opens,\n // so authoritative data can arrive after the popover is already visible.\n // Keep absorbing that data until the user makes their first local edit; from\n // that point onward their pending selection is the source of truth.\n const prevOpenRef = React.useRef(false);\n useEffect(() => {\n if (open && !prevOpenRef.current) {\n setSearchQuery(\"\");\n setCommitError(null);\n committedRef.current = false;\n selectionEditedRef.current = false;\n }\n if (open && !selectionEditedRef.current) {\n const selected = customFolders.filter((f) => currentFolderIds.includes(f.id));\n setLocalSelectedFolders((current) => {\n const currentIds = current.map((folder) => folder.id);\n const selectedIds = selected.map((folder) => folder.id);\n return currentIds.length === selectedIds.length && currentIds.every((id, index) => id === selectedIds[index])\n ? current\n : selected;\n });\n }\n prevOpenRef.current = open;\n }, [open, currentFolderIds, customFolders]);\n\n const ghostText = useMemo(() => {\n if (!searchQuery || customFolders.length === 0) return \"\";\n const query = searchQuery.toLowerCase();\n const firstMatch = customFolders.find((f) => f.name.toLowerCase().startsWith(query));\n if (firstMatch) {\n return searchQuery + firstMatch.name.slice(searchQuery.length);\n }\n return \"\";\n }, [searchQuery, customFolders]);\n\n const localSelectedIds = useMemo(() => new Set(localSelectedFolders.map((f) => f.id)), [localSelectedFolders]);\n const folderOptions = useMemo(\n () => [\n ...customFolders,\n ...localSelectedFolders.filter((selected) => !customFolders.some((folder) => folder.id === selected.id)),\n ],\n [customFolders, localSelectedFolders],\n );\n\n const handleSave = async () => {\n if (committing) return;\n const previousIds = new Set(currentFolderIds);\n const newlyChecked = Array.from(localSelectedIds).filter((id) => !previousIds.has(id));\n const newlyUnchecked = Array.from(previousIds).filter((id) => !localSelectedIds.has(id));\n\n // Clicking Save always records a commit \u2014 including the zero-change case\n // (added=0, removed=0) \u2014 so the commit rate reflects real Save intent and\n // is not inflated or deflated by the no-op path. The ref still suppresses\n // the follow-on cancel that fires as the popover closes.\n committedRef.current = true;\n setCommitError(null);\n void recordUserEvent({\n event_name: \"save_to_folder_committed\",\n event_properties: {\n folders_added_count: newlyChecked.length,\n folders_removed_count: newlyUnchecked.length,\n source_type: sourceType,\n },\n });\n\n if (newlyChecked.length === 0 && newlyUnchecked.length === 0) {\n onClose();\n return;\n }\n\n setCommitting(true);\n\n const additions = newlyChecked.map((folderId) => addItem.mutateAsync({ folderId, folderableType, folderableId }));\n const removals = newlyUnchecked.map((folderId) => {\n const itemId = folderItemIds[String(folderId)];\n if (!itemId) return Promise.reject(new Error(`Missing folder item for folder ${folderId}`));\n return removeItem.mutateAsync({ itemId, folderId, folderableType });\n });\n const [additionResults, removalResults] = await Promise.all([\n Promise.allSettled(additions),\n Promise.allSettled(removals),\n ]);\n if ([...additionResults, ...removalResults].some((result) => result.status === \"rejected\")) {\n const message = \"Couldn't update folders.\";\n committedRef.current = false;\n await onReconcile?.();\n setCommitError(message);\n globalAlert?.setAlertWithOptions(message, \"error\", FOLDER_CHANGE_TOAST_DURATION_MS, null, {\n label: \"Retry\",\n onClick: () => retrySaveRef.current(),\n });\n setCommitting(false);\n return;\n }\n\n const addedFolders = newlyChecked.flatMap((folderId) => {\n const folder = folderOptions.find((candidate) => candidate.id === folderId);\n return folder ? [folder] : [];\n });\n const removedFolders = newlyUnchecked.flatMap((folderId) => {\n const folder = folderOptions.find((candidate) => candidate.id === folderId);\n return folder ? [folder] : [];\n });\n const message =\n addedFolders.length === newlyChecked.length && removedFolders.length === newlyUnchecked.length\n ? folderMembershipChangeMessage(addedFolders, removedFolders)\n : \"Folders updated.\";\n\n const undoOperations: Array<() => Promise> = [\n ...additionResults.map((result, index) => {\n if (result.status !== \"fulfilled\") throw new Error(\"Successful save returned a rejected addition\");\n const itemId = result.value.id;\n const folderId = newlyChecked[index];\n return () => removeItem.mutateAsync({ itemId, folderId, folderableType });\n }),\n ...newlyUnchecked.map((folderId) => () => addItem.mutateAsync({ folderId, folderableType, folderableId })),\n ];\n\n const undoChanges = async (operations: Array<() => Promise>): Promise => {\n const results = await Promise.allSettled(operations.map((operation) => operation()));\n const failedOperations = operations.filter((_operation, index) => results[index].status === \"rejected\");\n await onReconcile?.();\n if (failedOperations.length > 0) {\n globalAlert?.setAlertWithOptions(\"Couldn't update folders.\", \"error\", FOLDER_CHANGE_TOAST_DURATION_MS, null, {\n label: \"Retry\",\n onClick: () => undoChanges(failedOperations),\n });\n }\n };\n\n if (message) {\n globalAlert?.setAlertWithOptions(message, \"success\", FOLDER_CHANGE_TOAST_DURATION_MS, null, {\n label: \"Undo\",\n onClick: () => undoChanges(undoOperations),\n });\n }\n\n setCommitting(false);\n onClose();\n };\n\n retrySaveRef.current = () => void handleSave();\n\n const handleCancel = () => {\n if (committing) return;\n if (!committedRef.current) {\n const previousIds = new Set(currentFolderIds);\n const hadPendingChanges =\n Array.from(localSelectedIds).some((id) => !previousIds.has(id)) ||\n Array.from(previousIds).some((id) => !localSelectedIds.has(id));\n void recordUserEvent({\n event_name: \"save_to_folder_cancelled\",\n event_properties: { had_pending_changes: hadPendingChanges, source_type: sourceType },\n });\n }\n onClose();\n };\n\n const handleFolderCreated = (folder: Folder) => {\n // The popover stays open behind the create modal so the user's pending\n // checkbox changes survive the New Folder flow. Pre-check the new folder\n // in local selection; it gets committed alongside the rest when the user\n // clicks Save. If the popover happens to be closed (legacy callers), fall\n // back to committing immediately.\n if (open) {\n selectionEditedRef.current = true;\n setLocalSelectedFolders((prev) => (prev.some((f) => f.id === folder.id) ? prev : [...prev, folder]));\n } else {\n addItem.mutate(\n { folderId: folder.id, folderableType, folderableId },\n { onError: (error) => console.error(\"Failed to add item to new folder:\", error) },\n );\n }\n };\n\n const renderFolderOption = useCallback(\n (props: React.HTMLAttributes, option: Folder, { selected }: AutocompleteRenderOptionState) => (\n \n \n \n \n \n \n ),\n [],\n );\n\n const filterOptions = useCallback(\n (options: Folder[]) => {\n if (!searchQuery.trim()) return options;\n const query = searchQuery.toLowerCase();\n return options.filter((f) => f.name.toLowerCase().includes(query));\n },\n [searchQuery],\n );\n\n return (\n <>\n \n {customFolders.length === 0 ? (\n /* Empty state */\n \n \n \n No folders yet\n \n \n \n Create a folder to organize transcripts by client or matter.\n \n \n \n ) : (\n /* Autocomplete: search input + checkbox list */\n {\n selectionEditedRef.current = true;\n setLocalSelectedFolders(newValue);\n }}\n inputValue={searchQuery}\n onInputChange={(_event, newValue, reason) => {\n if (reason !== \"reset\") setSearchQuery(newValue);\n }}\n filterOptions={filterOptions}\n getOptionLabel={(option) => option.name}\n isOptionEqualToValue={(option, value) => option.id === value.id}\n renderOption={renderFolderOption}\n renderTags={(value, getTagProps) =>\n value.map((option, index) => )\n }\n ListboxComponent={MenuList}\n ListboxProps={{ sx: { maxHeight: 300, overflowY: \"auto\", py: 0 } } as any}\n PopperComponent={InlinePopper}\n PaperComponent={InlinePaper}\n disablePortal\n renderInput={(params) => (\n \n \n \n )}\n noOptionsText={\n \n No folders match your search.\n \n }\n sx={{\n \"& .MuiAutocomplete-endAdornment\": { display: \"none\" },\n }}\n />\n )}\n\n {commitError && (\n \n {commitError}\n \n )}\n\n {/* Footer: New Folder + Cancel + Save */}\n \n \n {\n // Keep the popover open underneath; the modal renders on top.\n // Preserves any pending checkbox changes through the create flow.\n setCreateModalOpen(true);\n }}\n disabled={committing}\n sx={{\n color: open && customFolders.length === 0 ? \"primary.main\" : \"inherit\",\n }}\n >\n New folder\n \n \n \n \n Cancel\n \n void handleSave()} disabled={committing}>\n {commitLabel}\n \n \n \n \n\n setCreateModalOpen(false)}\n onCreated={handleFolderCreated}\n opened_from=\"save_to_folder_popover\"\n />\n \n );\n};\n\nexport default SaveToFolderPopover;\n", "\"use client\";\nimport { createContext } from 'react';\n\nconst LayoutGroupContext = createContext({});\n\nexport { LayoutGroupContext };\n//# sourceMappingURL=LayoutGroupContext.mjs.map\n", "\"use client\"\n\nimport { useRef } from \"react\"\n\ntype Init = () => T\n\n/**\n * Creates a constant value over the lifecycle of a component.\n *\n * Even if `useMemo` is provided an empty array as its final argument, it doesn't offer\n * a guarantee that it won't re-run for performance reasons later on. By using `useConstant`\n * you can ensure that initialisers don't execute twice or more.\n */\nexport function useConstant(init: Init) {\n const ref = useRef(null)\n\n if (ref.current === null) {\n ref.current = init()\n }\n\n return ref.current\n}\n", "export const isBrowser = typeof window !== \"undefined\"\n", "\"use client\"\n\nimport { useEffect, useLayoutEffect } from \"react\"\nimport { isBrowser } from \"./is-browser\"\n\nexport const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect\n", "\"use client\"\n\nimport { createContext } from \"react\"\nimport type { PresenceContextProps } from \"motion-dom\"\n\nexport type { PresenceContextProps }\n\n/**\n * @public\n */\nexport const PresenceContext =\n /* @__PURE__ */ createContext(null)\n", "export function addUniqueItem(arr: T[], item: T) {\n if (arr.indexOf(item) === -1) arr.push(item)\n}\n\nexport function removeItem(arr: T[], item: T) {\n const index = arr.indexOf(item)\n if (index > -1) arr.splice(index, 1)\n}\n\n// Adapted from array-move\nexport function moveItem([...arr]: T[], fromIndex: number, toIndex: number) {\n const startIndex = fromIndex < 0 ? arr.length + fromIndex : fromIndex\n\n if (startIndex >= 0 && startIndex < arr.length) {\n const endIndex = toIndex < 0 ? arr.length + toIndex : toIndex\n\n const [item] = arr.splice(fromIndex, 1)\n arr.splice(endIndex, 0, item)\n }\n\n return arr\n}\n", "export const clamp = (min: number, max: number, v: number) => {\n if (v > max) return max\n if (v < min) return min\n return v\n}\n", "import { formatErrorMessage } from \"./format-error-message\"\n\nexport type DevMessage = (\n check: boolean,\n message: string,\n errorCode?: string\n) => void\n\nlet warning: DevMessage = () => {}\nlet invariant: DevMessage = () => {}\n\nif (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n) {\n warning = (check, message, errorCode) => {\n if (!check && typeof console !== \"undefined\") {\n console.warn(formatErrorMessage(message, errorCode))\n }\n }\n\n invariant = (check, message, errorCode) => {\n if (!check) {\n throw new Error(formatErrorMessage(message, errorCode))\n }\n }\n}\n\nexport { invariant, warning }\n", "export const MotionGlobalConfig: {\n skipAnimations?: boolean\n instantAnimations?: boolean\n useManualTiming?: boolean\n WillChange?: any\n mix?: (a: T, b: T) => (p: number) => T\n} = {}\n", "/**\n * Check if value is a numerical string, ie a string that is purely a number eg \"100\" or \"-100.1\"\n */\nexport const isNumericalString = (v: string) => /^-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)$/u.test(v)\n", "export function isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null\n}\n", "/**\n * Check if the value is a zero value string like \"0px\" or \"0%\"\n */\nexport const isZeroValueString = (v: string) => /^0[^.\\s]+$/u.test(v)\n", "/*#__NO_SIDE_EFFECTS__*/\nexport function memo(callback: () => T) {\n let result: T | undefined\n\n return () => {\n if (result === undefined) result = callback()\n return result\n }\n}\n", "/*#__NO_SIDE_EFFECTS__*/\nexport const noop = (any: T): T => any\n", "/**\n * Pipe\n * Compose other transformers to run linearily\n * pipe(min(20), max(40))\n * @param {...functions} transformers\n * @return {function}\n */\nconst combineFunctions = (a: Function, b: Function) => (v: any) => b(a(v))\nexport const pipe = (...transformers: Function[]) =>\n transformers.reduce(combineFunctions)\n", "/*\n Progress within given range\n\n Given a lower limit and an upper limit, we return the progress\n (expressed as a number 0-1) represented by the given value, and\n limit that progress to within 0-1.\n\n @param [number]: Lower limit\n @param [number]: Upper limit\n @param [number]: Value to find progress within given range\n @return [number]: Progress of value within range as expressed 0-1\n*/\n/*#__NO_SIDE_EFFECTS__*/\nexport const progress = (from: number, to: number, value: number) => {\n const toFromDifference = to - from\n\n return toFromDifference === 0 ? 1 : (value - from) / toFromDifference\n}\n", "import { addUniqueItem, removeItem } from \"./array\"\n\ntype GenericHandler = (...args: any) => void\n\nexport class SubscriptionManager {\n private subscriptions: Handler[] = []\n\n add(handler: Handler): VoidFunction {\n addUniqueItem(this.subscriptions, handler)\n return () => removeItem(this.subscriptions, handler)\n }\n\n notify(\n a?: Parameters[0],\n b?: Parameters[1],\n c?: Parameters[2]\n ) {\n const numSubscriptions = this.subscriptions.length\n\n if (!numSubscriptions) return\n\n if (numSubscriptions === 1) {\n /**\n * If there's only a single handler we can just call it without invoking a loop.\n */\n this.subscriptions[0](a, b, c)\n } else {\n for (let i = 0; i < numSubscriptions; i++) {\n /**\n * Check whether the handler exists before firing as it's possible\n * the subscriptions were modified during this loop running.\n */\n const handler = this.subscriptions[i]\n handler && handler(a, b, c)\n }\n }\n }\n\n getSize() {\n return this.subscriptions.length\n }\n\n clear() {\n this.subscriptions.length = 0\n }\n}\n", "/**\n * Converts seconds to milliseconds\n *\n * @param seconds - Time in seconds.\n * @return milliseconds - Converted time in milliseconds.\n */\n\n/*#__NO_SIDE_EFFECTS__*/\nexport const secondsToMilliseconds = (seconds: number) => seconds * 1000\n\n/*#__NO_SIDE_EFFECTS__*/\nexport const millisecondsToSeconds = (milliseconds: number) =>\n milliseconds / 1000\n", "/*\n Convert velocity into velocity per second\n\n @param [number]: Unit per frame\n @param [number]: Frame duration in ms\n*/\nexport function velocityPerSecond(velocity: number, frameDuration: number) {\n return frameDuration ? velocity * (1000 / frameDuration) : 0\n}\n", "/*\n Bezier function generator\n This has been modified from Gaëtan Renaudeau's BezierEasing\n https://github.com/gre/bezier-easing/blob/master/src/index.js\n https://github.com/gre/bezier-easing/blob/master/LICENSE\n \n I've removed the newtonRaphsonIterate algo because in benchmarking it\n wasn't noticeably faster than binarySubdivision, indeed removing it\n usually improved times, depending on the curve.\n I also removed the lookup table, as for the added bundle size and loop we're\n only cutting ~4 or so subdivision iterations. I bumped the max iterations up\n to 12 to compensate and this still tended to be faster for no perceivable\n loss in accuracy.\n Usage\n const easeOut = cubicBezier(.17,.67,.83,.67);\n const x = easeOut(0.5); // returns 0.627...\n*/\n\nimport { noop } from \"../noop\"\n\n// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.\nconst calcBezier = (t: number, a1: number, a2: number) =>\n (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *\n t\n\nconst subdivisionPrecision = 0.0000001\nconst subdivisionMaxIterations = 12\n\nfunction binarySubdivide(\n x: number,\n lowerBound: number,\n upperBound: number,\n mX1: number,\n mX2: number\n) {\n let currentX: number\n let currentT: number\n let i: number = 0\n\n do {\n currentT = lowerBound + (upperBound - lowerBound) / 2.0\n currentX = calcBezier(currentT, mX1, mX2) - x\n if (currentX > 0.0) {\n upperBound = currentT\n } else {\n lowerBound = currentT\n }\n } while (\n Math.abs(currentX) > subdivisionPrecision &&\n ++i < subdivisionMaxIterations\n )\n\n return currentT\n}\n\nexport function cubicBezier(\n mX1: number,\n mY1: number,\n mX2: number,\n mY2: number\n) {\n // If this is a linear gradient, return linear easing\n if (mX1 === mY1 && mX2 === mY2) return noop\n\n const getTForX = (aX: number) => binarySubdivide(aX, 0, 1, mX1, mX2)\n\n // If animation is at start/end, return t without easing\n return (t: number) =>\n t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2)\n}\n", "// Accepts an easing function and returns a new one that outputs mirrored values for\n\nimport { EasingModifier } from \"../types\"\n\n// the second half of the animation. Turns easeIn into easeInOut.\nexport const mirrorEasing: EasingModifier = (easing) => (p) =>\n p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2\n", "// Accepts an easing function and returns a new one that outputs reversed values.\n\nimport { EasingModifier } from \"../types\"\n\n// Turns easeIn into easeOut.\nexport const reverseEasing: EasingModifier = (easing) => (p) =>\n 1 - easing(1 - p)\n", "import { cubicBezier } from \"./cubic-bezier\"\nimport { mirrorEasing } from \"./modifiers/mirror\"\nimport { reverseEasing } from \"./modifiers/reverse\"\n\nexport const backOut = /*@__PURE__*/ cubicBezier(0.33, 1.53, 0.69, 0.99)\nexport const backIn = /*@__PURE__*/ reverseEasing(backOut)\nexport const backInOut = /*@__PURE__*/ mirrorEasing(backIn)\n", "import { backIn } from \"./back\"\n\nexport const anticipate = (p: number) =>\n p >= 1\n ? 1\n : (p *= 2) < 1\n ? 0.5 * backIn(p)\n : 0.5 * (2 - Math.pow(2, -10 * (p - 1)))\n", "import { mirrorEasing } from \"./modifiers/mirror\"\nimport { reverseEasing } from \"./modifiers/reverse\"\nimport { EasingFunction } from \"./types\"\n\nexport const circIn: EasingFunction = (p) => 1 - Math.sin(Math.acos(p))\nexport const circOut = reverseEasing(circIn)\nexport const circInOut = mirrorEasing(circIn)\n", "import { cubicBezier } from \"./cubic-bezier\"\n\nexport const easeIn = /*@__PURE__*/ cubicBezier(0.42, 0, 1, 1)\nexport const easeOut = /*@__PURE__*/ cubicBezier(0, 0, 0.58, 1)\nexport const easeInOut = /*@__PURE__*/ cubicBezier(0.42, 0, 0.58, 1)\n", "import { Easing } from \"../types\"\n\nexport const isEasingArray = (ease: any): ease is Easing[] => {\n return Array.isArray(ease) && typeof ease[0] !== \"number\"\n}\n", "import { BezierDefinition, Easing } from \"../types\"\n\nexport const isBezierDefinition = (\n easing: Easing | Easing[]\n): easing is BezierDefinition =>\n Array.isArray(easing) && typeof easing[0] === \"number\"\n", "import { invariant } from \"../../errors\"\nimport { noop } from \"../../noop\"\nimport { anticipate } from \"../anticipate\"\nimport { backIn, backInOut, backOut } from \"../back\"\nimport { circIn, circInOut, circOut } from \"../circ\"\nimport { cubicBezier } from \"../cubic-bezier\"\nimport { easeIn, easeInOut, easeOut } from \"../ease\"\nimport { Easing, EasingFunction } from \"../types\"\nimport { isBezierDefinition } from \"./is-bezier-definition\"\n\nconst easingLookup = {\n linear: noop,\n easeIn,\n easeInOut,\n easeOut,\n circIn,\n circInOut,\n circOut,\n backIn,\n backInOut,\n backOut,\n anticipate,\n}\n\nconst isValidEasing = (easing: Easing): easing is keyof typeof easingLookup => {\n return typeof easing === \"string\"\n}\n\nexport const easingDefinitionToFunction = (\n definition: Easing\n): EasingFunction => {\n if (isBezierDefinition(definition)) {\n // If cubic bezier definition, create bezier curve\n invariant(\n definition.length === 4,\n `Cubic bezier arrays must contain four numerical values.`,\n \"cubic-bezier-length\"\n )\n\n const [x1, y1, x2, y2] = definition\n return cubicBezier(x1, y1, x2, y2)\n } else if (isValidEasing(definition)) {\n // Else lookup from table\n invariant(\n easingLookup[definition] !== undefined,\n `Invalid easing type '${definition}'`,\n \"invalid-easing-type\"\n )\n return easingLookup[definition]\n }\n\n return definition\n}\n", "export { addUniqueItem, moveItem, removeItem } from './array.mjs';\nexport { clamp } from './clamp.mjs';\nexport { invariant, warning } from './errors.mjs';\nexport { MotionGlobalConfig } from './global-config.mjs';\nexport { isNumericalString } from './is-numerical-string.mjs';\nexport { isObject } from './is-object.mjs';\nexport { isZeroValueString } from './is-zero-value-string.mjs';\nexport { memo } from './memo.mjs';\nexport { noop } from './noop.mjs';\nexport { pipe } from './pipe.mjs';\nexport { progress } from './progress.mjs';\nexport { SubscriptionManager } from './subscription-manager.mjs';\nexport { millisecondsToSeconds, secondsToMilliseconds } from './time-conversion.mjs';\nexport { velocityPerSecond } from './velocity-per-second.mjs';\nexport { hasWarned, warnOnce } from './warn-once.mjs';\nexport { wrap } from './wrap.mjs';\nexport { anticipate } from './easing/anticipate.mjs';\nexport { backIn, backInOut, backOut } from './easing/back.mjs';\nexport { circIn, circInOut, circOut } from './easing/circ.mjs';\nexport { cubicBezier } from './easing/cubic-bezier.mjs';\nexport { easeIn, easeInOut, easeOut } from './easing/ease.mjs';\nexport { mirrorEasing } from './easing/modifiers/mirror.mjs';\nexport { reverseEasing } from './easing/modifiers/reverse.mjs';\nexport { steps } from './easing/steps.mjs';\nexport { getEasingForSegment } from './easing/utils/get-easing-for-segment.mjs';\nexport { isBezierDefinition } from './easing/utils/is-bezier-definition.mjs';\nexport { isEasingArray } from './easing/utils/is-easing-array.mjs';\nexport { easingDefinitionToFunction } from './easing/utils/map.mjs';\n//# sourceMappingURL=index.mjs.map\n", "import { StepId } from \"./types\"\n\nexport const stepsOrder: StepId[] = [\n \"setup\", // Compute\n \"read\", // Read\n \"resolveKeyframes\", // Write/Read/Write/Read\n \"preUpdate\", // Compute\n \"update\", // Compute\n \"preRender\", // Compute\n \"render\", // Write\n \"postRender\", // Compute\n] as const\n\nexport type StepNames = (typeof stepsOrder)[number]\n", "import type { StatsRecording } from \"./types\"\n\nexport type InactiveStatsBuffer = {\n value: null\n addProjectionMetrics: null\n}\n\nexport type ActiveStatsBuffer = {\n value: StatsRecording\n addProjectionMetrics: (metrics: {\n nodes: number\n calculatedTargetDeltas: number\n calculatedProjections: number\n }) => void\n}\n\nexport const statsBuffer: InactiveStatsBuffer | ActiveStatsBuffer = {\n value: null,\n addProjectionMetrics: null,\n}\n", "import { statsBuffer } from \"../stats/buffer\"\nimport { StepNames } from \"./order\"\nimport { FrameData, Process, Step } from \"./types\"\n\nexport function createRenderStep(\n runNextFrame: () => void,\n stepName?: StepNames\n): Step {\n /**\n * We create and reuse two queues, one to queue jobs for the current frame\n * and one for the next. We reuse to avoid triggering GC after x frames.\n */\n let thisFrame = new Set()\n let nextFrame = new Set()\n\n /**\n * Track whether we're currently processing jobs in this step. This way\n * we can decide whether to schedule new jobs for this frame or next.\n */\n let isProcessing = false\n\n let flushNextFrame = false\n\n /**\n * A set of processes which were marked keepAlive when scheduled.\n */\n const toKeepAlive = new WeakSet()\n\n let latestFrameData: FrameData = {\n delta: 0.0,\n timestamp: 0.0,\n isProcessing: false,\n }\n\n let numCalls = 0\n\n function triggerCallback(callback: Process) {\n if (toKeepAlive.has(callback)) {\n step.schedule(callback)\n runNextFrame()\n }\n\n numCalls++\n callback(latestFrameData)\n }\n\n const step: Step = {\n /**\n * Schedule a process to run on the next frame.\n */\n schedule: (callback, keepAlive = false, immediate = false) => {\n const addToCurrentFrame = immediate && isProcessing\n const queue = addToCurrentFrame ? thisFrame : nextFrame\n\n if (keepAlive) toKeepAlive.add(callback)\n\n queue.add(callback)\n\n return callback\n },\n\n /**\n * Cancel the provided callback from running on the next frame.\n */\n cancel: (callback) => {\n nextFrame.delete(callback)\n toKeepAlive.delete(callback)\n },\n\n /**\n * Execute all schedule callbacks.\n */\n process: (frameData) => {\n latestFrameData = frameData\n\n /**\n * If we're already processing we've probably been triggered by a flushSync\n * inside an existing process. Instead of executing, mark flushNextFrame\n * as true and ensure we flush the following frame at the end of this one.\n */\n if (isProcessing) {\n flushNextFrame = true\n return\n }\n\n isProcessing = true\n\n // Swap this frame and the next to avoid GC\n const prevFrame = thisFrame\n thisFrame = nextFrame\n nextFrame = prevFrame\n\n // Execute this frame\n thisFrame.forEach(triggerCallback)\n\n /**\n * If we're recording stats then\n */\n if (stepName && statsBuffer.value) {\n statsBuffer.value.frameloop[stepName].push(numCalls)\n }\n numCalls = 0\n\n // Clear the frame so no callbacks remain. This is to avoid\n // memory leaks should this render step not run for a while.\n thisFrame.clear()\n\n isProcessing = false\n\n if (flushNextFrame) {\n flushNextFrame = false\n step.process(frameData)\n }\n },\n }\n\n return step\n}\n", "import { MotionGlobalConfig } from \"motion-utils\"\nimport { stepsOrder } from \"./order\"\nimport { createRenderStep } from \"./render-step\"\nimport { Batcher, FrameData, Process, Steps } from \"./types\"\n\nconst maxElapsed = 40\n\nexport function createRenderBatcher(\n scheduleNextBatch: (callback: Function) => void,\n allowKeepAlive: boolean\n) {\n let runNextFrame = false\n let useDefaultElapsed = true\n\n const state: FrameData = {\n delta: 0.0,\n timestamp: 0.0,\n isProcessing: false,\n }\n\n const flagRunNextFrame = () => (runNextFrame = true)\n\n const steps = stepsOrder.reduce((acc, key) => {\n acc[key] = createRenderStep(\n flagRunNextFrame,\n allowKeepAlive ? key : undefined\n )\n return acc\n }, {} as Steps)\n\n const {\n setup,\n read,\n resolveKeyframes,\n preUpdate,\n update,\n preRender,\n render,\n postRender,\n } = steps\n\n const processBatch = () => {\n const useManualTiming = MotionGlobalConfig.useManualTiming\n const timestamp = useManualTiming\n ? state.timestamp\n : performance.now()\n runNextFrame = false\n\n if (!useManualTiming) {\n state.delta = useDefaultElapsed\n ? 1000 / 60\n : Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1)\n }\n\n state.timestamp = timestamp\n state.isProcessing = true\n\n // Unrolled render loop for better per-frame performance\n setup.process(state)\n read.process(state)\n resolveKeyframes.process(state)\n preUpdate.process(state)\n update.process(state)\n preRender.process(state)\n render.process(state)\n postRender.process(state)\n\n state.isProcessing = false\n\n if (runNextFrame && allowKeepAlive) {\n useDefaultElapsed = false\n scheduleNextBatch(processBatch)\n }\n }\n\n const wake = () => {\n runNextFrame = true\n useDefaultElapsed = true\n\n if (!state.isProcessing) {\n scheduleNextBatch(processBatch)\n }\n }\n\n const schedule = stepsOrder.reduce((acc, key) => {\n const step = steps[key]\n acc[key] = (process: Process, keepAlive = false, immediate = false) => {\n if (!runNextFrame) wake()\n\n return step.schedule(process, keepAlive, immediate)\n }\n return acc\n }, {} as Batcher)\n\n const cancel = (process: Process) => {\n for (let i = 0; i < stepsOrder.length; i++) {\n steps[stepsOrder[i]].cancel(process)\n }\n }\n\n return { schedule, cancel, state, steps }\n}\n", "import { noop } from \"motion-utils\"\nimport { createRenderBatcher } from \"./batcher\"\n\nexport const {\n schedule: frame,\n cancel: cancelFrame,\n state: frameData,\n steps: frameSteps,\n} = /* @__PURE__ */ createRenderBatcher(\n typeof requestAnimationFrame !== \"undefined\" ? requestAnimationFrame : noop,\n true\n)\n", "import { MotionGlobalConfig } from \"motion-utils\"\nimport { frameData } from \"./frame\"\n\nlet now: number | undefined\n\nfunction clearTime() {\n now = undefined\n}\n\n/**\n * An eventloop-synchronous alternative to performance.now().\n *\n * Ensures that time measurements remain consistent within a synchronous context.\n * Usually calling performance.now() twice within the same synchronous context\n * will return different values which isn't useful for animations when we're usually\n * trying to sync animations to the same frame.\n */\nexport const time = {\n now: (): number => {\n if (now === undefined) {\n time.set(\n frameData.isProcessing || MotionGlobalConfig.useManualTiming\n ? frameData.timestamp\n : performance.now()\n )\n }\n\n return now!\n },\n set: (newTime: number) => {\n now = newTime\n queueMicrotask(clearTime)\n },\n}\n", "export const activeAnimations = {\n layout: 0,\n mainThread: 0,\n waapi: 0,\n}\n", "import { AnyResolvedKeyframe } from \"../types\"\n\nexport type CSSVariableName = `--${string}`\n\nexport type CSSVariableToken = `var(${CSSVariableName})`\n\nconst checkStringStartsWith =\n (token: string) =>\n (key?: AnyResolvedKeyframe | null): key is T =>\n typeof key === \"string\" && key.startsWith(token)\n\nexport const isCSSVariableName =\n /*@__PURE__*/ checkStringStartsWith(\"--\")\n\nconst startsAsVariableToken =\n /*@__PURE__*/ checkStringStartsWith(\"var(--\")\nexport const isCSSVariableToken = (\n value?: string\n): value is CSSVariableToken => {\n const startsWithToken = startsAsVariableToken(value)\n\n if (!startsWithToken) return false\n\n // Ensure any comments are stripped from the value as this can harm performance of the regex.\n return singleCssVariableRegex.test(value.split(\"/*\")[0].trim())\n}\n\nconst singleCssVariableRegex =\n /var\\(--(?:[\\w-]+\\s*|[\\w-]+\\s*,(?:\\s*[^)(\\s]|\\s*\\((?:[^)(]|\\([^)(]*\\))*\\))+\\s*)\\)$/iu\n\n/**\n * Check if a value contains a CSS variable anywhere (e.g. inside calc()).\n * Unlike isCSSVariableToken which checks if the value IS a var() token,\n * this checks if the value CONTAINS var() somewhere in the string.\n */\nexport function containsCSSVariable(\n value?: AnyResolvedKeyframe | null\n): boolean {\n if (typeof value !== \"string\") return false\n // Strip comments to avoid false positives\n return value.split(\"/*\")[0].includes(\"var(--\")\n}\n", "import { clamp } from \"motion-utils\"\n\nexport const number = {\n test: (v: number) => typeof v === \"number\",\n parse: parseFloat,\n transform: (v: number) => v,\n}\n\nexport const alpha = {\n ...number,\n transform: (v: number) => clamp(0, 1, v),\n}\n\nexport const scale = {\n ...number,\n default: 1,\n}\n", "// If this number is a decimal, make it just five decimal places\n// to avoid exponents\nexport const sanitize = (v: number) => Math.round(v * 100000) / 100000\n", "export const floatRegex = /-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)/gu\n", "export function isNullish(v: any): v is null | undefined {\n return v == null\n}\n", "export const singleColorRegex =\n /^(?:#[\\da-f]{3,8}|(?:rgb|hsl)a?\\((?:-?[\\d.]+%?[,\\s]+){2}-?[\\d.]+%?\\s*(?:[,/]\\s*)?(?:\\b\\d+(?:\\.\\d+)?|\\.\\d+)?%?\\))$/iu\n", "import { Color, HSLA, RGBA } from \"../types\"\nimport { floatRegex } from \"../utils/float-regex\"\nimport { isNullish } from \"../utils/is-nullish\"\nimport { singleColorRegex } from \"../utils/single-color-regex\"\n\n/**\n * Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,\n * but false if a number or multiple colors\n */\nexport const isColorString = (type: string, testProp?: string) => (v: any) => {\n return Boolean(\n (typeof v === \"string\" &&\n singleColorRegex.test(v) &&\n v.startsWith(type)) ||\n (testProp &&\n !isNullish(v) &&\n Object.prototype.hasOwnProperty.call(v, testProp))\n )\n}\n\nexport const splitColor =\n (aName: string, bName: string, cName: string) =>\n (v: string | Color): V => {\n if (typeof v !== \"string\") return v as any\n\n const [a, b, c, alpha] = v.match(floatRegex) as any\n\n return {\n [aName]: parseFloat(a),\n [bName]: parseFloat(b),\n [cName]: parseFloat(c),\n alpha: alpha !== undefined ? parseFloat(alpha) : 1,\n } as V\n }\n", "import { clamp } from \"motion-utils\"\nimport { alpha as alphaType, number } from \"../numbers\"\nimport { RGBA } from \"../types\"\nimport { sanitize } from \"../utils/sanitize\"\nimport { isColorString, splitColor } from \"./utils\"\n\nconst clampRgbUnit = (v: number) => clamp(0, 255, v)\nexport const rgbUnit = {\n ...number,\n transform: (v: number) => Math.round(clampRgbUnit(v)),\n}\n\nexport const rgba = {\n test: /*@__PURE__*/ isColorString(\"rgb\", \"red\"),\n parse: /*@__PURE__*/ splitColor(\"red\", \"green\", \"blue\"),\n transform: ({ red, green, blue, alpha = 1 }: RGBA) =>\n \"rgba(\" +\n rgbUnit.transform(red) +\n \", \" +\n rgbUnit.transform(green) +\n \", \" +\n rgbUnit.transform(blue) +\n \", \" +\n sanitize(alphaType.transform(alpha)) +\n \")\",\n}\n", "import { RGBA } from \"../types\"\nimport { rgba } from \"./rgba\"\nimport { isColorString } from \"./utils\"\n\nfunction parseHex(v: string): RGBA {\n let r = \"\"\n let g = \"\"\n let b = \"\"\n let a = \"\"\n\n // If we have 6 characters, ie #FF0000\n if (v.length > 5) {\n r = v.substring(1, 3)\n g = v.substring(3, 5)\n b = v.substring(5, 7)\n a = v.substring(7, 9)\n\n // Or we have 3 characters, ie #F00\n } else {\n r = v.substring(1, 2)\n g = v.substring(2, 3)\n b = v.substring(3, 4)\n a = v.substring(4, 5)\n r += r\n g += g\n b += b\n a += a\n }\n\n return {\n red: parseInt(r, 16),\n green: parseInt(g, 16),\n blue: parseInt(b, 16),\n alpha: a ? parseInt(a, 16) / 255 : 1,\n }\n}\n\nexport const hex = {\n test: /*@__PURE__*/ isColorString(\"#\"),\n parse: parseHex,\n transform: rgba.transform,\n}\n", "import { AnyResolvedKeyframe } from \"../../../animation/types\"\n\n/*#__NO_SIDE_EFFECTS__*/\nconst createUnitType = (unit: string) => ({\n test: (v: AnyResolvedKeyframe) =>\n typeof v === \"string\" && v.endsWith(unit) && v.split(\" \").length === 1,\n parse: parseFloat,\n transform: (v: number | string) => `${v}${unit}`,\n})\n\nexport const degrees = /*@__PURE__*/ createUnitType(\"deg\")\nexport const percent = /*@__PURE__*/ createUnitType(\"%\")\nexport const px = /*@__PURE__*/ createUnitType(\"px\")\nexport const vh = /*@__PURE__*/ createUnitType(\"vh\")\nexport const vw = /*@__PURE__*/ createUnitType(\"vw\")\n\nexport const progressPercentage = /*@__PURE__*/ (() => ({\n ...percent,\n parse: (v: string) => percent.parse(v) / 100,\n transform: (v: number) => percent.transform(v * 100),\n}))()\n", "import { alpha as alphaType } from \"../numbers\"\nimport { percent } from \"../numbers/units\"\nimport { HSLA } from \"../types\"\nimport { sanitize } from \"../utils/sanitize\"\nimport { isColorString, splitColor } from \"./utils\"\n\nexport const hsla = {\n test: /*@__PURE__*/ isColorString(\"hsl\", \"hue\"),\n parse: /*@__PURE__*/ splitColor(\"hue\", \"saturation\", \"lightness\"),\n transform: ({ hue, saturation, lightness, alpha = 1 }: HSLA) => {\n return (\n \"hsla(\" +\n Math.round(hue) +\n \", \" +\n percent.transform(sanitize(saturation)) +\n \", \" +\n percent.transform(sanitize(lightness)) +\n \", \" +\n sanitize(alphaType.transform(alpha)) +\n \")\"\n )\n },\n}\n", "import { HSLA, RGBA } from \"../types\"\nimport { hex } from \"./hex\"\nimport { hsla } from \"./hsla\"\nimport { rgba } from \"./rgba\"\n\nexport const color = {\n test: (v: any) => rgba.test(v) || hex.test(v) || hsla.test(v),\n parse: (v: any): RGBA | HSLA => {\n if (rgba.test(v)) {\n return rgba.parse(v)\n } else if (hsla.test(v)) {\n return hsla.parse(v)\n } else {\n return hex.parse(v)\n }\n },\n transform: (v: HSLA | RGBA | string) => {\n return typeof v === \"string\"\n ? v\n : v.hasOwnProperty(\"red\")\n ? rgba.transform(v as RGBA)\n : hsla.transform(v as HSLA)\n },\n getAnimatableNone: (v: string) => {\n const parsed = color.parse(v)\n parsed.alpha = 0\n return color.transform(parsed)\n },\n}\n", "export const colorRegex =\n /(?:#[\\da-f]{3,8}|(?:rgb|hsl)a?\\((?:-?[\\d.]+%?[,\\s]+){2}-?[\\d.]+%?\\s*(?:[,/]\\s*)?(?:\\b\\d+(?:\\.\\d+)?|\\.\\d+)?%?\\))/giu\n", "import { AnyResolvedKeyframe } from \"../../../animation/types\"\nimport { CSSVariableToken } from \"../../../animation/utils/is-css-variable\"\nimport { color } from \"../color\"\nimport { Color } from \"../types\"\nimport { colorRegex } from \"../utils/color-regex\"\nimport { floatRegex } from \"../utils/float-regex\"\nimport { sanitize } from \"../utils/sanitize\"\n\nfunction test(v: any) {\n return (\n isNaN(v) &&\n typeof v === \"string\" &&\n (v.match(floatRegex)?.length || 0) +\n (v.match(colorRegex)?.length || 0) >\n 0\n )\n}\n\nconst NUMBER_TOKEN = \"number\"\nconst COLOR_TOKEN = \"color\"\nconst VAR_TOKEN = \"var\"\nconst VAR_FUNCTION_TOKEN = \"var(\"\nconst SPLIT_TOKEN = \"${}\"\n\nexport type ComplexValues = Array<\n CSSVariableToken | AnyResolvedKeyframe | Color\n>\n\nexport interface ValueIndexes {\n color: number[]\n number: number[]\n var: number[]\n}\n\nexport interface ComplexValueInfo {\n values: ComplexValues\n split: string[]\n indexes: ValueIndexes\n types: Array\n}\n\n// this regex consists of the `singleCssVariableRegex|rgbHSLValueRegex|digitRegex`\nconst complexRegex =\n /var\\s*\\(\\s*--(?:[\\w-]+\\s*|[\\w-]+\\s*,(?:\\s*[^)(\\s]|\\s*\\((?:[^)(]|\\([^)(]*\\))*\\))+\\s*)\\)|#[\\da-f]{3,8}|(?:rgb|hsl)a?\\((?:-?[\\d.]+%?[,\\s]+){2}-?[\\d.]+%?\\s*(?:[,/]\\s*)?(?:\\b\\d+(?:\\.\\d+)?|\\.\\d+)?%?\\)|-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)/giu\n\nexport function analyseComplexValue(\n value: AnyResolvedKeyframe\n): ComplexValueInfo {\n const originalValue = value.toString()\n\n const values: ComplexValues = []\n const indexes: ValueIndexes = {\n color: [],\n number: [],\n var: [],\n }\n const types: Array = []\n\n let i = 0\n const tokenised = originalValue.replace(complexRegex, (parsedValue) => {\n if (color.test(parsedValue)) {\n indexes.color.push(i)\n types.push(COLOR_TOKEN)\n values.push(color.parse(parsedValue))\n } else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {\n indexes.var.push(i)\n types.push(VAR_TOKEN)\n values.push(parsedValue)\n } else {\n indexes.number.push(i)\n types.push(NUMBER_TOKEN)\n values.push(parseFloat(parsedValue))\n }\n ++i\n return SPLIT_TOKEN\n })\n const split = tokenised.split(SPLIT_TOKEN)\n\n return { values, split, indexes, types }\n}\n\nfunction parseComplexValue(v: AnyResolvedKeyframe) {\n return analyseComplexValue(v).values\n}\n\nfunction buildTransformer({ split, types }: ComplexValueInfo) {\n const numSections = split.length\n return (v: Array) => {\n let output = \"\"\n for (let i = 0; i < numSections; i++) {\n output += split[i]\n if (v[i] !== undefined) {\n const type = types[i]\n if (type === NUMBER_TOKEN) {\n output += sanitize(v[i] as number)\n } else if (type === COLOR_TOKEN) {\n output += color.transform(v[i] as Color)\n } else {\n output += v[i]\n }\n }\n }\n\n return output\n }\n}\n\nfunction createTransformer(source: AnyResolvedKeyframe) {\n return buildTransformer(analyseComplexValue(source))\n}\n\nconst convertNumbersToZero = (v: number | string) =>\n typeof v === \"number\" ? 0 : color.test(v) ? color.getAnimatableNone(v) : v\n\n/**\n * Convert a parsed value to its zero equivalent, but preserve numbers\n * that act as divisors in CSS calc() expressions.\n *\n * analyseComplexValue extracts numbers from CSS strings and puts the\n * surrounding text into a `split` template array. For example:\n * \"calc(var(--gap) / 5)\" → values: [var(--gap), 5]\n * split: [\"calc(\", \" / \", \")\"]\n *\n * When building a zero-equivalent for animation, naively zeroing all\n * numbers turns the divisor into 0 → \"calc(var(--gap) / 0)\" → NaN.\n * We detect this by checking whether the text preceding a number\n * (split[i]) ends with \"/\" — the CSS calc division operator.\n */\nconst convertToZero = (\n value: ComplexValues[number],\n splitBefore: string\n): ComplexValues[number] => {\n if (typeof value === \"number\") {\n return splitBefore?.trim().endsWith(\"/\") ? value : 0\n }\n return convertNumbersToZero(value as string)\n}\n\nfunction getAnimatableNone(v: AnyResolvedKeyframe) {\n const info = analyseComplexValue(v)\n const transformer = buildTransformer(info)\n return transformer(\n info.values.map((value, i) => convertToZero(value, info.split[i]))\n )\n}\n\nexport const complex = {\n test,\n parse: parseComplexValue,\n createTransformer,\n getAnimatableNone,\n}\n", "import { HSLA, RGBA } from \"../types\"\n\n// Adapted from https://gist.github.com/mjackson/5311256\nfunction hueToRgb(p: number, q: number, t: number) {\n if (t < 0) t += 1\n if (t > 1) t -= 1\n if (t < 1 / 6) return p + (q - p) * 6 * t\n if (t < 1 / 2) return q\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n return p\n}\n\nexport function hslaToRgba({ hue, saturation, lightness, alpha }: HSLA): RGBA {\n hue /= 360\n saturation /= 100\n lightness /= 100\n\n let red = 0\n let green = 0\n let blue = 0\n\n if (!saturation) {\n red = green = blue = lightness\n } else {\n const q =\n lightness < 0.5\n ? lightness * (1 + saturation)\n : lightness + saturation - lightness * saturation\n const p = 2 * lightness - q\n\n red = hueToRgb(p, q, hue + 1 / 3)\n green = hueToRgb(p, q, hue)\n blue = hueToRgb(p, q, hue - 1 / 3)\n }\n\n return {\n red: Math.round(red * 255),\n green: Math.round(green * 255),\n blue: Math.round(blue * 255),\n alpha,\n }\n}\n", "export function mixImmediate(a: T, b: T) {\n return (p: number) => (p > 0 ? b : a)\n}\n", "/*\n Value in range from progress\n\n Given a lower limit and an upper limit, we return the value within\n that range as expressed by progress (usually a number from 0 to 1)\n\n So progress = 0.5 would change\n\n from -------- to\n\n to\n\n from ---- to\n\n E.g. from = 10, to = 20, progress = 0.5 => 15\n\n @param [number]: Lower limit of range\n @param [number]: Upper limit of range\n @param [number]: The progress between lower and upper limits expressed 0-1\n @return [number]: Value as calculated from progress within range (not limited within range)\n*/\nexport const mixNumber = (from: number, to: number, progress: number) => {\n return from + (to - from) * progress\n}\n", "import { warning } from \"motion-utils\"\nimport { hex } from \"../../value/types/color/hex\"\nimport { hsla } from \"../../value/types/color/hsla\"\nimport { hslaToRgba } from \"../../value/types/color/hsla-to-rgba\"\nimport { rgba } from \"../../value/types/color/rgba\"\nimport { Color, HSLA, RGBA } from \"../../value/types/types\"\nimport { mixImmediate } from \"./immediate\"\nimport { mixNumber } from \"./number\"\n\n// Linear color space blending\n// Explained https://www.youtube.com/watch?v=LKnqECcg6Gw\n// Demonstrated http://codepen.io/osublake/pen/xGVVaN\nexport const mixLinearColor = (from: number, to: number, v: number) => {\n const fromExpo = from * from\n const expo = v * (to * to - fromExpo) + fromExpo\n return expo < 0 ? 0 : Math.sqrt(expo)\n}\n\nconst colorTypes = [hex, rgba, hsla]\nconst getColorType = (v: Color | string) =>\n colorTypes.find((type) => type.test(v))\n\nfunction asRGBA(color: Color | string) {\n const type = getColorType(color)\n\n warning(\n Boolean(type),\n `'${color}' is not an animatable color. Use the equivalent color code instead.`,\n \"color-not-animatable\"\n )\n\n if (!Boolean(type)) return false\n\n let model = type!.parse(color)\n\n if (type === hsla) {\n // TODO Remove this cast - needed since Motion's stricter typing\n model = hslaToRgba(model as HSLA)\n }\n\n return model as RGBA\n}\n\nexport const mixColor = (from: Color | string, to: Color | string) => {\n const fromRGBA = asRGBA(from)\n const toRGBA = asRGBA(to)\n\n if (!fromRGBA || !toRGBA) {\n return mixImmediate(from, to)\n }\n\n const blended = { ...fromRGBA }\n\n return (v: number) => {\n blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v)\n blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v)\n blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v)\n blended.alpha = mixNumber(fromRGBA.alpha, toRGBA.alpha, v)\n return rgba.transform!(blended)\n }\n}\n", "export const invisibleValues = new Set([\"none\", \"hidden\"])\n\n/**\n * Returns a function that, when provided a progress value between 0 and 1,\n * will return the \"none\" or \"hidden\" string only when the progress is that of\n * the origin or target.\n */\nexport function mixVisibility(origin: string, target: string) {\n if (invisibleValues.has(origin)) {\n return (p: number) => (p <= 0 ? origin : target)\n } else {\n return (p: number) => (p >= 1 ? target : origin)\n }\n}\n", "import { pipe, warning } from \"motion-utils\"\nimport { AnyResolvedKeyframe } from \"../../animation/types\"\nimport { isCSSVariableToken } from \"../../animation/utils/is-css-variable\"\nimport { color } from \"../../value/types/color\"\nimport {\n analyseComplexValue,\n complex,\n ComplexValueInfo,\n ComplexValues,\n} from \"../../value/types/complex\"\nimport { HSLA, RGBA } from \"../../value/types/types\"\nimport { mixColor } from \"./color\"\nimport { mixImmediate } from \"./immediate\"\nimport { mixNumber as mixNumberImmediate } from \"./number\"\nimport { invisibleValues, mixVisibility } from \"./visibility\"\n\ntype MixableArray = Array\ninterface MixableObject {\n [key: string]: AnyResolvedKeyframe | RGBA | HSLA\n}\n\nfunction mixNumber(a: number, b: number) {\n return (p: number) => mixNumberImmediate(a, b, p)\n}\n\nexport function getMixer(a: T) {\n if (typeof a === \"number\") {\n return mixNumber\n } else if (typeof a === \"string\") {\n return isCSSVariableToken(a)\n ? mixImmediate\n : color.test(a)\n ? mixColor\n : mixComplex\n } else if (Array.isArray(a)) {\n return mixArray\n } else if (typeof a === \"object\") {\n return color.test(a) ? mixColor : mixObject\n }\n\n return mixImmediate\n}\n\nexport function mixArray(a: MixableArray, b: MixableArray) {\n const output = [...a]\n const numValues = output.length\n\n const blendValue = a.map((v, i) => getMixer(v)(v as any, b[i] as any))\n\n return (p: number) => {\n for (let i = 0; i < numValues; i++) {\n output[i] = blendValue[i](p) as any\n }\n return output\n }\n}\n\nexport function mixObject(a: MixableObject, b: MixableObject) {\n const output = { ...a, ...b }\n const blendValue: { [key: string]: (v: number) => any } = {}\n\n for (const key in output) {\n if (a[key] !== undefined && b[key] !== undefined) {\n blendValue[key] = getMixer(a[key])(\n a[key] as any,\n b[key] as any\n ) as any\n }\n }\n\n return (v: number) => {\n for (const key in blendValue) {\n output[key] = blendValue[key](v)\n }\n return output\n }\n}\n\nfunction matchOrder(\n origin: ComplexValueInfo,\n target: ComplexValueInfo\n): ComplexValues {\n const orderedOrigin: ComplexValues = []\n\n const pointers = { color: 0, var: 0, number: 0 }\n\n for (let i = 0; i < target.values.length; i++) {\n const type = target.types[i]\n const originIndex = origin.indexes[type][pointers[type]]\n const originValue = origin.values[originIndex] ?? 0\n\n orderedOrigin[i] = originValue\n\n pointers[type]++\n }\n\n return orderedOrigin\n}\n\nexport const mixComplex = (\n origin: AnyResolvedKeyframe,\n target: AnyResolvedKeyframe\n) => {\n const template = complex.createTransformer(target)\n const originStats = analyseComplexValue(origin)\n const targetStats = analyseComplexValue(target)\n const canInterpolate =\n originStats.indexes.var.length === targetStats.indexes.var.length &&\n originStats.indexes.color.length === targetStats.indexes.color.length &&\n originStats.indexes.number.length >= targetStats.indexes.number.length\n\n if (canInterpolate) {\n if (\n (invisibleValues.has(origin as string) &&\n !targetStats.values.length) ||\n (invisibleValues.has(target as string) &&\n !originStats.values.length)\n ) {\n return mixVisibility(origin as string, target as string)\n }\n\n return pipe(\n mixArray(matchOrder(originStats, targetStats), targetStats.values),\n template\n )\n } else {\n warning(\n true,\n `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`,\n \"complex-values-different\"\n )\n\n return mixImmediate(origin, target)\n }\n}\n", "import { getMixer } from \"./complex\"\nimport { mixNumber as mixNumberImmediate } from \"./number\"\nimport { Mixer } from \"./types\"\n\nexport function mix(from: T, to: T): Mixer\nexport function mix(from: number, to: number, p: number): number\nexport function mix(from: T, to: T, p?: T): Mixer | number {\n if (\n typeof from === \"number\" &&\n typeof to === \"number\" &&\n typeof p === \"number\"\n ) {\n return mixNumberImmediate(from, to, p)\n }\n\n const mixer = getMixer(from)\n return mixer(from as any, to as any) as Mixer\n}\n", "import { cancelFrame, frame, frameData } from \"../../frameloop\"\nimport { time } from \"../../frameloop/sync-time\"\nimport { FrameData } from \"../../frameloop/types\"\nimport { Driver } from \"./types\"\n\nexport const frameloopDriver: Driver = (update) => {\n const passTimestamp = ({ timestamp }: FrameData) => update(timestamp)\n\n return {\n start: (keepAlive = true) => frame.update(passTimestamp, keepAlive),\n stop: () => cancelFrame(passTimestamp),\n /**\n * If we're processing this frame we can use the\n * framelocked timestamp to keep things in sync.\n */\n now: () => (frameData.isProcessing ? frameData.timestamp : time.now()),\n }\n}\n", "import { EasingFunction } from \"motion-utils\"\n\nexport const generateLinearEasing = (\n easing: EasingFunction,\n duration: number, // as milliseconds\n resolution: number = 10 // as milliseconds\n): string => {\n let points = \"\"\n const numPoints = Math.max(Math.round(duration / resolution), 2)\n\n for (let i = 0; i < numPoints; i++) {\n points += Math.round(easing(i / (numPoints - 1)) * 10000) / 10000 + \", \"\n }\n\n return `linear(${points.substring(0, points.length - 2)})`\n}\n", "import { KeyframeGenerator } from \"../../types\"\n\n/**\n * Implement a practical max duration for keyframe generation\n * to prevent infinite loops\n */\nexport const maxGeneratorDuration = 20_000\nexport function calcGeneratorDuration(\n generator: KeyframeGenerator\n): number {\n let duration = 0\n const timeStep = 50\n let state = generator.next(duration)\n while (!state.done && duration < maxGeneratorDuration) {\n duration += timeStep\n state = generator.next(duration)\n }\n\n return duration >= maxGeneratorDuration ? Infinity : duration\n}\n", "import { millisecondsToSeconds } from \"motion-utils\"\nimport { GeneratorFactory, Transition } from \"../../types\"\nimport { calcGeneratorDuration, maxGeneratorDuration } from \"./calc-duration\"\n\n/**\n * Create a progress => progress easing function from a generator.\n */\nexport function createGeneratorEasing(\n options: Transition,\n scale = 100,\n createGenerator: GeneratorFactory\n) {\n const generator = createGenerator({ ...options, keyframes: [0, scale] })\n const duration = Math.min(\n calcGeneratorDuration(generator),\n maxGeneratorDuration\n )\n\n return {\n type: \"keyframes\",\n ease: (progress: number) => {\n return generator.next(duration * progress).value / scale\n },\n duration: millisecondsToSeconds(duration),\n }\n}\n", "import {\n clamp,\n millisecondsToSeconds,\n secondsToMilliseconds,\n warning,\n} from \"motion-utils\"\nimport {\n AnimationState,\n KeyframeGenerator,\n SpringOptions,\n Transition,\n ValueAnimationOptions,\n} from \"../types\"\nimport { generateLinearEasing } from \"../waapi/utils/linear\"\nimport {\n calcGeneratorDuration,\n maxGeneratorDuration,\n} from \"./utils/calc-duration\"\nimport { createGeneratorEasing } from \"./utils/create-generator-easing\"\n\nconst springDefaults = {\n // Default spring physics\n stiffness: 100,\n damping: 10,\n mass: 1.0,\n velocity: 0.0,\n\n // Default duration/bounce-based options\n duration: 800, // in ms\n bounce: 0.3,\n visualDuration: 0.3, // in seconds\n\n // Rest thresholds\n restSpeed: {\n granular: 0.01,\n default: 2,\n },\n restDelta: {\n granular: 0.005,\n default: 0.5,\n },\n\n // Limits\n minDuration: 0.01, // in seconds\n maxDuration: 10.0, // in seconds\n minDamping: 0.05,\n maxDamping: 1,\n}\n\nfunction calcAngularFreq(undampedFreq: number, dampingRatio: number) {\n return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio)\n}\n\nconst rootIterations = 12\nfunction approximateRoot(\n envelope: (num: number) => number,\n derivative: (num: number) => number,\n initialGuess: number\n): number {\n let result = initialGuess\n for (let i = 1; i < rootIterations; i++) {\n result = result - envelope(result) / derivative(result)\n }\n return result\n}\n\n/**\n * This is ported from the Framer implementation of duration-based spring resolution.\n */\nconst safeMin = 0.001\n\nfunction findSpring({\n duration = springDefaults.duration,\n bounce = springDefaults.bounce,\n velocity = springDefaults.velocity,\n mass = springDefaults.mass,\n}: SpringOptions) {\n let envelope: (num: number) => number\n let derivative: (num: number) => number\n\n warning(\n duration <= secondsToMilliseconds(springDefaults.maxDuration),\n \"Spring duration must be 10 seconds or less\",\n \"spring-duration-limit\"\n )\n\n let dampingRatio = 1 - bounce\n\n /**\n * Restrict dampingRatio and duration to within acceptable ranges.\n */\n dampingRatio = clamp(\n springDefaults.minDamping,\n springDefaults.maxDamping,\n dampingRatio\n )\n duration = clamp(\n springDefaults.minDuration,\n springDefaults.maxDuration,\n millisecondsToSeconds(duration)\n )\n\n if (dampingRatio < 1) {\n /**\n * Underdamped spring\n */\n envelope = (undampedFreq) => {\n const exponentialDecay = undampedFreq * dampingRatio\n const delta = exponentialDecay * duration\n const a = exponentialDecay - velocity\n const b = calcAngularFreq(undampedFreq, dampingRatio)\n const c = Math.exp(-delta)\n return safeMin - (a / b) * c\n }\n\n derivative = (undampedFreq) => {\n const exponentialDecay = undampedFreq * dampingRatio\n const delta = exponentialDecay * duration\n const d = delta * velocity + velocity\n const e =\n Math.pow(dampingRatio, 2) * Math.pow(undampedFreq, 2) * duration\n const f = Math.exp(-delta)\n const g = calcAngularFreq(Math.pow(undampedFreq, 2), dampingRatio)\n const factor = -envelope(undampedFreq) + safeMin > 0 ? -1 : 1\n return (factor * ((d - e) * f)) / g\n }\n } else {\n /**\n * Critically-damped spring\n */\n envelope = (undampedFreq) => {\n const a = Math.exp(-undampedFreq * duration)\n const b = (undampedFreq - velocity) * duration + 1\n return -safeMin + a * b\n }\n\n derivative = (undampedFreq) => {\n const a = Math.exp(-undampedFreq * duration)\n const b = (velocity - undampedFreq) * (duration * duration)\n return a * b\n }\n }\n\n const initialGuess = 5 / duration\n const undampedFreq = approximateRoot(envelope, derivative, initialGuess)\n\n duration = secondsToMilliseconds(duration)\n if (isNaN(undampedFreq)) {\n return {\n stiffness: springDefaults.stiffness,\n damping: springDefaults.damping,\n duration,\n }\n } else {\n const stiffness = Math.pow(undampedFreq, 2) * mass\n return {\n stiffness,\n damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),\n duration,\n }\n }\n}\n\nconst durationKeys = [\"duration\", \"bounce\"]\nconst physicsKeys = [\"stiffness\", \"damping\", \"mass\"]\n\nfunction isSpringType(options: SpringOptions, keys: string[]) {\n return keys.some((key) => (options as any)[key] !== undefined)\n}\n\nfunction getSpringOptions(options: SpringOptions) {\n let springOptions = {\n velocity: springDefaults.velocity,\n stiffness: springDefaults.stiffness,\n damping: springDefaults.damping,\n mass: springDefaults.mass,\n isResolvedFromDuration: false,\n ...options,\n }\n // stiffness/damping/mass overrides duration/bounce\n if (\n !isSpringType(options, physicsKeys) &&\n isSpringType(options, durationKeys)\n ) {\n // Time-defined springs should ignore inherited velocity.\n // Velocity from interrupted animations can cause findSpring()\n // to compute wildly different spring parameters, leading to\n // massive oscillation on small-range animations.\n springOptions.velocity = 0\n\n if (options.visualDuration) {\n const visualDuration = options.visualDuration\n const root = (2 * Math.PI) / (visualDuration * 1.2)\n const stiffness = root * root\n const damping =\n 2 *\n clamp(0.05, 1, 1 - (options.bounce || 0)) *\n Math.sqrt(stiffness)\n\n springOptions = {\n ...springOptions,\n mass: springDefaults.mass,\n stiffness,\n damping,\n }\n } else {\n const derived = findSpring({ ...options, velocity: 0 })\n\n springOptions = {\n ...springOptions,\n ...derived,\n mass: springDefaults.mass,\n }\n springOptions.isResolvedFromDuration = true\n }\n }\n\n return springOptions\n}\n\nfunction spring(\n optionsOrVisualDuration:\n | ValueAnimationOptions\n | number = springDefaults.visualDuration,\n bounce = springDefaults.bounce\n): KeyframeGenerator {\n const options =\n typeof optionsOrVisualDuration !== \"object\"\n ? ({\n visualDuration: optionsOrVisualDuration,\n keyframes: [0, 1],\n bounce,\n } as ValueAnimationOptions)\n : optionsOrVisualDuration\n\n let { restSpeed, restDelta } = options\n\n const origin = options.keyframes[0]\n const target = options.keyframes[options.keyframes.length - 1]\n\n /**\n * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator\n * to reduce GC during animation.\n */\n const state: AnimationState = { done: false, value: origin }\n\n const {\n stiffness,\n damping,\n mass,\n duration,\n velocity,\n isResolvedFromDuration,\n } = getSpringOptions({\n ...options,\n velocity: -millisecondsToSeconds(options.velocity || 0),\n })\n\n const initialVelocity = velocity || 0.0\n const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass))\n\n const initialDelta = target - origin\n const undampedAngularFreq = millisecondsToSeconds(\n Math.sqrt(stiffness / mass)\n )\n\n /**\n * If we're working on a granular scale, use smaller defaults for determining\n * when the spring is finished.\n *\n * These defaults have been selected emprically based on what strikes a good\n * ratio between feeling good and finishing as soon as changes are imperceptible.\n */\n const isGranularScale = Math.abs(initialDelta) < 5\n restSpeed ||= isGranularScale\n ? springDefaults.restSpeed.granular\n : springDefaults.restSpeed.default\n restDelta ||= isGranularScale\n ? springDefaults.restDelta.granular\n : springDefaults.restDelta.default\n\n let resolveSpring: (v: number) => number\n let resolveVelocity: (t: number) => number\n\n // Underdamped coefficients, hoisted for use in the inlined next() hot path\n let angularFreq: number\n let A: number\n let sinCoeff: number\n let cosCoeff: number\n\n if (dampingRatio < 1) {\n angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio)\n\n A =\n (initialVelocity +\n dampingRatio * undampedAngularFreq * initialDelta) /\n angularFreq\n\n // Underdamped spring\n resolveSpring = (t: number) => {\n const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t)\n\n return (\n target -\n envelope *\n (A * Math.sin(angularFreq * t) +\n initialDelta * Math.cos(angularFreq * t))\n )\n }\n\n // Analytical derivative of underdamped spring (px/ms)\n sinCoeff =\n dampingRatio * undampedAngularFreq * A + initialDelta * angularFreq\n cosCoeff =\n dampingRatio * undampedAngularFreq * initialDelta - A * angularFreq\n resolveVelocity = (t: number) => {\n const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t)\n return envelope *\n (sinCoeff * Math.sin(angularFreq * t) +\n cosCoeff * Math.cos(angularFreq * t))\n }\n } else if (dampingRatio === 1) {\n // Critically damped spring\n resolveSpring = (t: number) =>\n target -\n Math.exp(-undampedAngularFreq * t) *\n (initialDelta +\n (initialVelocity + undampedAngularFreq * initialDelta) * t)\n\n // Analytical derivative of critically damped spring (px/ms)\n const C = initialVelocity + undampedAngularFreq * initialDelta\n resolveVelocity = (t: number) =>\n Math.exp(-undampedAngularFreq * t) *\n (undampedAngularFreq * C * t - initialVelocity)\n } else {\n // Overdamped spring\n const dampedAngularFreq =\n undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1)\n\n resolveSpring = (t: number) => {\n const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t)\n\n // When performing sinh or cosh values can hit Infinity so we cap them here\n const freqForT = Math.min(dampedAngularFreq * t, 300)\n\n return (\n target -\n (envelope *\n ((initialVelocity +\n dampingRatio * undampedAngularFreq * initialDelta) *\n Math.sinh(freqForT) +\n dampedAngularFreq *\n initialDelta *\n Math.cosh(freqForT))) /\n dampedAngularFreq\n )\n }\n\n // Analytical derivative of overdamped spring (px/ms)\n const P =\n (initialVelocity +\n dampingRatio * undampedAngularFreq * initialDelta) /\n dampedAngularFreq\n const sinhCoeff =\n dampingRatio * undampedAngularFreq * P - initialDelta * dampedAngularFreq\n const coshCoeff =\n dampingRatio * undampedAngularFreq * initialDelta - P * dampedAngularFreq\n resolveVelocity = (t: number) => {\n const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t)\n const freqForT = Math.min(dampedAngularFreq * t, 300)\n return envelope *\n (sinhCoeff * Math.sinh(freqForT) +\n coshCoeff * Math.cosh(freqForT))\n }\n }\n\n const generator = {\n calculatedDuration: isResolvedFromDuration ? duration || null : null,\n velocity: (t: number) => secondsToMilliseconds(resolveVelocity(t)),\n next: (t: number) => {\n /**\n * For underdamped physics springs we need both position and\n * velocity each tick. Compute shared trig values once to avoid\n * duplicate Math.exp/sin/cos calls on the hot path.\n */\n if (!isResolvedFromDuration && dampingRatio < 1) {\n const envelope = Math.exp(\n -dampingRatio * undampedAngularFreq * t\n )\n const sin = Math.sin(angularFreq * t)\n const cos = Math.cos(angularFreq * t)\n\n const current =\n target -\n envelope *\n (A * sin + initialDelta * cos)\n const currentVelocity = secondsToMilliseconds(\n envelope *\n (sinCoeff * sin + cosCoeff * cos)\n )\n\n state.done =\n Math.abs(currentVelocity) <= restSpeed! &&\n Math.abs(target - current) <= restDelta!\n state.value = state.done ? target : current\n\n return state\n }\n\n const current = resolveSpring(t)\n\n if (!isResolvedFromDuration) {\n const currentVelocity = secondsToMilliseconds(\n resolveVelocity(t)\n )\n state.done =\n Math.abs(currentVelocity) <= restSpeed! &&\n Math.abs(target - current) <= restDelta!\n } else {\n state.done = t >= duration!\n }\n\n state.value = state.done ? target : current\n\n return state\n },\n toString: () => {\n const calculatedDuration = Math.min(\n calcGeneratorDuration(generator),\n maxGeneratorDuration\n )\n\n const easing = generateLinearEasing(\n (progress: number) =>\n generator.next(calculatedDuration * progress).value,\n calculatedDuration,\n 30\n )\n\n return calculatedDuration + \"ms \" + easing\n },\n toTransition: () => {},\n }\n\n return generator\n}\n\nspring.applyToOptions = (options: Transition) => {\n const generatorOptions = createGeneratorEasing(options as any, 100, spring)\n\n options.ease = generatorOptions.ease\n options.duration = secondsToMilliseconds(generatorOptions.duration)\n options.type = \"keyframes\"\n return options\n}\n\nexport { spring }\n", "import { velocityPerSecond } from \"motion-utils\"\n\nconst velocitySampleDuration = 5 // ms\n\nexport function getGeneratorVelocity(\n resolveValue: (v: number) => number,\n t: number,\n current: number\n) {\n const prevT = Math.max(t - velocitySampleDuration, 0)\n return velocityPerSecond(current - resolveValue(prevT), t - prevT)\n}\n", "import {\n AnimationState,\n KeyframeGenerator,\n ValueAnimationOptions,\n} from \"../types\"\nimport { spring as createSpring } from \"./spring\"\nimport { getGeneratorVelocity } from \"./utils/velocity\"\n\nexport function inertia({\n keyframes,\n velocity = 0.0,\n power = 0.8,\n timeConstant = 325,\n bounceDamping = 10,\n bounceStiffness = 500,\n modifyTarget,\n min,\n max,\n restDelta = 0.5,\n restSpeed,\n}: ValueAnimationOptions): KeyframeGenerator {\n const origin = keyframes[0]\n\n const state: AnimationState = {\n done: false,\n value: origin,\n }\n\n const isOutOfBounds = (v: number) =>\n (min !== undefined && v < min) || (max !== undefined && v > max)\n\n const nearestBoundary = (v: number) => {\n if (min === undefined) return max\n if (max === undefined) return min\n\n return Math.abs(min - v) < Math.abs(max - v) ? min : max\n }\n\n let amplitude = power * velocity\n const ideal = origin + amplitude\n const target = modifyTarget === undefined ? ideal : modifyTarget(ideal)\n\n /**\n * If the target has changed we need to re-calculate the amplitude, otherwise\n * the animation will start from the wrong position.\n */\n if (target !== ideal) amplitude = target - origin\n\n const calcDelta = (t: number) => -amplitude * Math.exp(-t / timeConstant)\n\n const calcLatest = (t: number) => target + calcDelta(t)\n\n const applyFriction = (t: number) => {\n const delta = calcDelta(t)\n const latest = calcLatest(t)\n state.done = Math.abs(delta) <= restDelta\n state.value = state.done ? target : latest\n }\n\n /**\n * Ideally this would resolve for t in a stateless way, we could\n * do that by always precalculating the animation but as we know\n * this will be done anyway we can assume that spring will\n * be discovered during that.\n */\n let timeReachedBoundary: number | undefined\n let spring: KeyframeGenerator | undefined\n\n const checkCatchBoundary = (t: number) => {\n if (!isOutOfBounds(state.value)) return\n\n timeReachedBoundary = t\n\n spring = createSpring({\n keyframes: [state.value, nearestBoundary(state.value)!],\n velocity: getGeneratorVelocity(calcLatest, t, state.value), // TODO: This should be passing * 1000\n damping: bounceDamping,\n stiffness: bounceStiffness,\n restDelta,\n restSpeed,\n })\n }\n\n checkCatchBoundary(0)\n\n return {\n calculatedDuration: null,\n next: (t: number) => {\n /**\n * We need to resolve the friction to figure out if we need a\n * spring but we don't want to do this twice per frame. So here\n * we flag if we updated for this frame and later if we did\n * we can skip doing it again.\n */\n let hasUpdatedFrame = false\n if (!spring && timeReachedBoundary === undefined) {\n hasUpdatedFrame = true\n applyFriction(t)\n checkCatchBoundary(t)\n }\n\n /**\n * If we have a spring and the provided t is beyond the moment the friction\n * animation crossed the min/max boundary, use the spring.\n */\n if (timeReachedBoundary !== undefined && t >= timeReachedBoundary) {\n return spring!.next(t - timeReachedBoundary)\n } else {\n !hasUpdatedFrame && applyFriction(t)\n return state\n }\n },\n }\n}\n", "import {\n clamp,\n EasingFunction,\n invariant,\n MotionGlobalConfig,\n noop,\n pipe,\n progress,\n} from \"motion-utils\"\nimport { mix } from \"./mix\"\nimport { Mixer, MixerFactory } from \"./mix/types\"\n\nexport interface InterpolateOptions {\n clamp?: boolean\n ease?: EasingFunction | EasingFunction[]\n mixer?: MixerFactory\n}\n\nfunction createMixers(\n output: T[],\n ease?: EasingFunction | EasingFunction[],\n customMixer?: MixerFactory\n) {\n const mixers: Array> = []\n const mixerFactory: MixerFactory =\n customMixer || MotionGlobalConfig.mix || mix\n const numMixers = output.length - 1\n\n for (let i = 0; i < numMixers; i++) {\n let mixer = mixerFactory(output[i], output[i + 1])\n\n if (ease) {\n const easingFunction = Array.isArray(ease) ? ease[i] || noop : ease\n mixer = pipe(easingFunction, mixer) as Mixer\n }\n\n mixers.push(mixer)\n }\n\n return mixers\n}\n\n/**\n * Create a function that maps from a numerical input array to a generic output array.\n *\n * Accepts:\n * - Numbers\n * - Colors (hex, hsl, hsla, rgb, rgba)\n * - Complex (combinations of one or more numbers or strings)\n *\n * ```jsx\n * const mixColor = interpolate([0, 1], ['#fff', '#000'])\n *\n * mixColor(0.5) // 'rgba(128, 128, 128, 1)'\n * ```\n *\n * TODO Revisit this approach once we've moved to data models for values,\n * probably not needed to pregenerate mixer functions.\n *\n * @public\n */\nexport function interpolate(\n input: number[],\n output: T[],\n { clamp: isClamp = true, ease, mixer }: InterpolateOptions = {}\n): (v: number) => T {\n const inputLength = input.length\n\n invariant(\n inputLength === output.length,\n \"Both input and output ranges must be the same length\",\n \"range-length\"\n )\n\n /**\n * If we're only provided a single input, we can just make a function\n * that returns the output.\n */\n if (inputLength === 1) return () => output[0]\n if (inputLength === 2 && output[0] === output[1]) return () => output[1]\n\n const isZeroDeltaRange = input[0] === input[1]\n\n // If input runs highest -> lowest, reverse both arrays\n if (input[0] > input[inputLength - 1]) {\n input = [...input].reverse()\n output = [...output].reverse()\n }\n\n const mixers = createMixers(output, ease, mixer)\n const numMixers = mixers.length\n\n const interpolator = (v: number): T => {\n if (isZeroDeltaRange && v < input[0]) return output[0]\n\n let i = 0\n\n if (numMixers > 1) {\n for (; i < input.length - 2; i++) {\n if (v < input[i + 1]) break\n }\n }\n\n const progressInRange = progress(input[i], input[i + 1], v)\n\n return mixers[i](progressInRange)\n }\n\n return isClamp\n ? (v: number) =>\n interpolator(clamp(input[0], input[inputLength - 1], v))\n : interpolator\n}\n", "import { progress } from \"motion-utils\"\nimport { mixNumber } from \"../../../utils/mix/number\"\n\nexport function fillOffset(offset: number[], remaining: number): void {\n const min = offset[offset.length - 1]\n for (let i = 1; i <= remaining; i++) {\n const offsetProgress = progress(0, remaining, i)\n offset.push(mixNumber(min, 1, offsetProgress))\n }\n}\n", "import { fillOffset } from \"./fill\"\n\nexport function defaultOffset(arr: any[]): number[] {\n const offset = [0]\n fillOffset(offset, arr.length - 1)\n return offset\n}\n", "export function convertOffsetToTimes(offset: number[], duration: number) {\n return offset.map((o) => o * duration)\n}\n", "import {\n easeInOut,\n easingDefinitionToFunction,\n EasingFunction,\n isEasingArray,\n} from \"motion-utils\"\nimport { interpolate } from \"../../utils/interpolate\"\nimport { defaultOffset } from \"../keyframes/offsets/default\"\nimport { convertOffsetToTimes } from \"../keyframes/offsets/time\"\nimport {\n AnimationState,\n AnyResolvedKeyframe,\n KeyframeGenerator,\n ValueAnimationOptions,\n} from \"../types\"\n\nexport function defaultEasing(\n values: any[],\n easing?: EasingFunction\n): EasingFunction[] {\n return values.map(() => easing || easeInOut).splice(0, values.length - 1)\n}\n\nexport function keyframes({\n duration = 300,\n keyframes: keyframeValues,\n times,\n ease = \"easeInOut\",\n}: ValueAnimationOptions): KeyframeGenerator {\n /**\n * Easing functions can be externally defined as strings. Here we convert them\n * into actual functions.\n */\n const easingFunctions = isEasingArray(ease)\n ? ease.map(easingDefinitionToFunction)\n : easingDefinitionToFunction(ease)\n\n /**\n * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator\n * to reduce GC during animation.\n */\n const state: AnimationState = {\n done: false,\n value: keyframeValues[0],\n }\n\n /**\n * Create a times array based on the provided 0-1 offsets\n */\n const absoluteTimes = convertOffsetToTimes(\n // Only use the provided offsets if they're the correct length\n // TODO Maybe we should warn here if there's a length mismatch\n times && times.length === keyframeValues.length\n ? times\n : defaultOffset(keyframeValues),\n duration\n )\n\n const mapTimeToKeyframe = interpolate(absoluteTimes, keyframeValues, {\n ease: Array.isArray(easingFunctions)\n ? easingFunctions\n : defaultEasing(keyframeValues, easingFunctions),\n })\n\n return {\n calculatedDuration: duration,\n next: (t: number) => {\n state.value = mapTimeToKeyframe(t)\n state.done = t >= duration\n return state\n },\n }\n}\n", "import { AnimationPlaybackOptions } from \"../types\"\n\nconst isNotNull = (value: unknown) => value !== null\n\nexport function getFinalKeyframe(\n keyframes: T[],\n { repeat, repeatType = \"loop\" }: AnimationPlaybackOptions,\n finalKeyframe?: T,\n speed: number = 1\n): T {\n const resolvedKeyframes = keyframes.filter(isNotNull)\n const useFirstKeyframe =\n speed < 0 || (repeat && repeatType !== \"loop\" && repeat % 2 === 1)\n const index = useFirstKeyframe ? 0 : resolvedKeyframes.length - 1\n\n return !index || finalKeyframe === undefined\n ? resolvedKeyframes[index]\n : finalKeyframe\n}\n", "import { inertia } from \"../generators/inertia\"\nimport { keyframes } from \"../generators/keyframes\"\nimport { spring } from \"../generators/spring\"\nimport { GeneratorFactory, ValueAnimationTransition } from \"../types\"\n\nconst transitionTypeMap: { [key: string]: GeneratorFactory } = {\n decay: inertia,\n inertia,\n tween: keyframes,\n keyframes: keyframes,\n spring,\n}\n\nexport function replaceTransitionType(transition: ValueAnimationTransition) {\n if (typeof transition.type === \"string\") {\n transition.type = transitionTypeMap[transition.type]\n }\n}\n", "export class WithPromise {\n protected _finished: Promise\n\n resolve: VoidFunction\n\n constructor() {\n this.updateFinished()\n }\n\n get finished() {\n return this._finished\n }\n\n protected updateFinished() {\n this._finished = new Promise((resolve) => {\n this.resolve = resolve\n })\n }\n\n protected notifyFinished() {\n this.resolve()\n }\n\n /**\n * Allows the animation to be awaited.\n *\n * @deprecated Use `finished` instead.\n */\n then(onResolve: VoidFunction, onReject?: VoidFunction) {\n return this.finished.then(onResolve, onReject)\n }\n}\n", "import {\n clamp,\n invariant,\n millisecondsToSeconds,\n pipe,\n secondsToMilliseconds,\n} from \"motion-utils\"\nimport { time } from \"../frameloop/sync-time\"\nimport { activeAnimations } from \"../stats/animation-count\"\nimport { mix } from \"../utils/mix\"\nimport { Mixer } from \"../utils/mix/types\"\nimport { frameloopDriver } from \"./drivers/frame\"\nimport { DriverControls } from \"./drivers/types\"\nimport { inertia } from \"./generators/inertia\"\nimport { keyframes as keyframesGenerator } from \"./generators/keyframes\"\nimport { calcGeneratorDuration } from \"./generators/utils/calc-duration\"\nimport { getGeneratorVelocity } from \"./generators/utils/velocity\"\nimport { getFinalKeyframe } from \"./keyframes/get-final\"\nimport {\n AnimationPlaybackControlsWithThen,\n AnimationState,\n GeneratorFactory,\n KeyframeGenerator,\n TimelineWithFallback,\n ValueAnimationOptions,\n} from \"./types\"\nimport { replaceTransitionType } from \"./utils/replace-transition-type\"\nimport { WithPromise } from \"./utils/WithPromise\"\n\nconst percentToProgress = (percent: number) => percent / 100\n\nexport class JSAnimation\n extends WithPromise\n implements AnimationPlaybackControlsWithThen\n{\n state: AnimationPlayState = \"idle\"\n\n startTime: number | null = null\n\n /**\n * The driver that's controlling the animation loop. Normally this is a requestAnimationFrame loop\n * but in tests we can pass in a synchronous loop.\n */\n private driver?: DriverControls\n\n private isStopped = false\n\n private generator: KeyframeGenerator\n\n private calculatedDuration: number\n\n private resolvedDuration: number\n\n private totalDuration: number\n\n private options: ValueAnimationOptions\n\n /**\n * The current time of the animation.\n */\n private currentTime: number = 0\n\n /**\n * The time at which the animation was paused.\n */\n private holdTime: number | null = null\n\n /**\n * Playback speed as a factor. 0 would be stopped, -1 reverse and 2 double speed.\n */\n private playbackSpeed = 1\n\n /*\n * If our generator doesn't support mixing numbers, we need to replace keyframes with\n * [0, 100] and then make a function that maps that to the actual keyframes.\n *\n * 100 is chosen instead of 1 as it works nicer with spring animations.\n */\n private mixKeyframes: Mixer | undefined\n\n private mirroredGenerator: KeyframeGenerator | undefined\n\n /**\n * Reusable state object for the delay phase to avoid\n * allocating a new object every frame.\n */\n private delayState: AnimationState = {\n done: false,\n value: undefined as unknown as T,\n }\n\n constructor(options: ValueAnimationOptions) {\n super()\n activeAnimations.mainThread++\n\n this.options = options\n this.initAnimation()\n this.play()\n\n if (options.autoplay === false) this.pause()\n }\n\n initAnimation() {\n const { options } = this\n\n replaceTransitionType(options)\n\n const {\n type = keyframesGenerator,\n repeat = 0,\n repeatDelay = 0,\n repeatType,\n velocity = 0,\n } = options\n let { keyframes } = options\n\n const generatorFactory =\n (type as GeneratorFactory) || keyframesGenerator\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n generatorFactory !== keyframesGenerator\n ) {\n invariant(\n keyframes.length <= 2,\n `Only two keyframes currently supported with spring and inertia animations. Trying to animate ${keyframes}`,\n \"spring-two-frames\"\n )\n }\n\n if (\n generatorFactory !== keyframesGenerator &&\n typeof keyframes[0] !== \"number\"\n ) {\n this.mixKeyframes = pipe(\n percentToProgress,\n mix(keyframes[0], keyframes[1])\n ) as (t: number) => T\n\n keyframes = [0 as T, 100 as T]\n }\n\n const generator = generatorFactory({ ...options, keyframes })\n\n /**\n * If we have a mirror repeat type we need to create a second generator that outputs the\n * mirrored (not reversed) animation and later ping pong between the two generators.\n */\n if (repeatType === \"mirror\") {\n this.mirroredGenerator = generatorFactory({\n ...options,\n keyframes: [...keyframes].reverse(),\n velocity: -velocity,\n })\n }\n\n /**\n * If duration is undefined and we have repeat options,\n * we need to calculate a duration from the generator.\n *\n * We set it to the generator itself to cache the duration.\n * Any timeline resolver will need to have already precalculated\n * the duration by this step.\n */\n if (generator.calculatedDuration === null) {\n generator.calculatedDuration = calcGeneratorDuration(generator)\n }\n\n const { calculatedDuration } = generator\n this.calculatedDuration = calculatedDuration\n this.resolvedDuration = calculatedDuration + repeatDelay\n this.totalDuration = this.resolvedDuration * (repeat + 1) - repeatDelay\n this.generator = generator\n }\n\n updateTime(timestamp: number) {\n const animationTime =\n Math.round(timestamp - this.startTime!) * this.playbackSpeed\n\n // Update currentTime\n if (this.holdTime !== null) {\n this.currentTime = this.holdTime\n } else {\n // Rounding the time because floating point arithmetic is not always accurate, e.g. 3000.367 - 1000.367 =\n // 2000.0000000000002. This is a problem when we are comparing the currentTime with the duration, for\n // example.\n this.currentTime = animationTime\n }\n }\n\n tick(timestamp: number, sample = false) {\n const {\n generator,\n totalDuration,\n mixKeyframes,\n mirroredGenerator,\n resolvedDuration,\n calculatedDuration,\n } = this\n\n if (this.startTime === null) return generator.next(0)\n\n const {\n delay = 0,\n keyframes,\n repeat,\n repeatType,\n repeatDelay,\n type,\n onUpdate,\n finalKeyframe,\n } = this.options\n\n /**\n * requestAnimationFrame timestamps can come through as lower than\n * the startTime as set by performance.now(). Here we prevent this,\n * though in the future it could be possible to make setting startTime\n * a pending operation that gets resolved here.\n */\n if (this.speed > 0) {\n this.startTime = Math.min(this.startTime, timestamp)\n } else if (this.speed < 0) {\n this.startTime = Math.min(\n timestamp - totalDuration / this.speed,\n this.startTime\n )\n }\n\n if (sample) {\n this.currentTime = timestamp\n } else {\n this.updateTime(timestamp)\n }\n\n // Rebase on delay\n const timeWithoutDelay =\n this.currentTime - delay * (this.playbackSpeed >= 0 ? 1 : -1)\n const isInDelayPhase =\n this.playbackSpeed >= 0\n ? timeWithoutDelay < 0\n : timeWithoutDelay > totalDuration\n this.currentTime = Math.max(timeWithoutDelay, 0)\n\n // If this animation has finished, set the current time to the total duration.\n if (this.state === \"finished\" && this.holdTime === null) {\n this.currentTime = totalDuration\n }\n\n let elapsed = this.currentTime\n let frameGenerator = generator\n\n if (repeat) {\n /**\n * Get the current progress (0-1) of the animation. If t is >\n * than duration we'll get values like 2.5 (midway through the\n * third iteration)\n */\n const progress =\n Math.min(this.currentTime, totalDuration) / resolvedDuration\n\n /**\n * Get the current iteration (0 indexed). For instance the floor of\n * 2.5 is 2.\n */\n let currentIteration = Math.floor(progress)\n\n /**\n * Get the current progress of the iteration by taking the remainder\n * so 2.5 is 0.5 through iteration 2\n */\n let iterationProgress = progress % 1.0\n\n /**\n * If iteration progress is 1 we count that as the end\n * of the previous iteration.\n */\n if (!iterationProgress && progress >= 1) {\n iterationProgress = 1\n }\n\n iterationProgress === 1 && currentIteration--\n\n currentIteration = Math.min(currentIteration, repeat + 1)\n\n /**\n * Reverse progress if we're not running in \"normal\" direction\n */\n\n const isOddIteration = Boolean(currentIteration % 2)\n if (isOddIteration) {\n if (repeatType === \"reverse\") {\n iterationProgress = 1 - iterationProgress\n if (repeatDelay) {\n iterationProgress -= repeatDelay / resolvedDuration\n }\n } else if (repeatType === \"mirror\") {\n frameGenerator = mirroredGenerator!\n }\n }\n\n elapsed = clamp(0, 1, iterationProgress) * resolvedDuration\n }\n\n /**\n * If we're in negative time, set state as the initial keyframe.\n * This prevents delay: x, duration: 0 animations from finishing\n * instantly.\n */\n let state: AnimationState\n if (isInDelayPhase) {\n this.delayState.value = keyframes[0]\n state = this.delayState\n } else {\n state = frameGenerator.next(elapsed)\n }\n\n if (mixKeyframes && !isInDelayPhase) {\n state.value = mixKeyframes(state.value as number)\n }\n\n let { done } = state\n\n if (!isInDelayPhase && calculatedDuration !== null) {\n done =\n this.playbackSpeed >= 0\n ? this.currentTime >= totalDuration\n : this.currentTime <= 0\n }\n\n const isAnimationFinished =\n this.holdTime === null &&\n (this.state === \"finished\" || (this.state === \"running\" && done))\n\n // TODO: The exception for inertia could be cleaner here\n if (isAnimationFinished && type !== inertia) {\n state.value = getFinalKeyframe(\n keyframes,\n this.options,\n finalKeyframe,\n this.speed\n )\n }\n\n if (onUpdate) {\n onUpdate(state.value)\n }\n\n if (isAnimationFinished) {\n this.finish()\n }\n\n return state\n }\n\n /**\n * Allows the returned animation to be awaited or promise-chained. Currently\n * resolves when the animation finishes at all but in a future update could/should\n * reject if its cancels.\n */\n then(resolve: VoidFunction, reject?: VoidFunction) {\n return this.finished.then(resolve, reject)\n }\n\n get duration() {\n return millisecondsToSeconds(this.calculatedDuration)\n }\n\n get iterationDuration() {\n const { delay = 0 } = this.options || {}\n return this.duration + millisecondsToSeconds(delay)\n }\n\n get time() {\n return millisecondsToSeconds(this.currentTime)\n }\n\n set time(newTime: number) {\n newTime = secondsToMilliseconds(newTime)\n this.currentTime = newTime\n\n if (\n this.startTime === null ||\n this.holdTime !== null ||\n this.playbackSpeed === 0\n ) {\n this.holdTime = newTime\n } else if (this.driver) {\n this.startTime = this.driver.now() - newTime / this.playbackSpeed\n }\n\n if (this.driver) {\n this.driver.start(false)\n } else {\n this.startTime = 0\n this.state = \"paused\"\n this.holdTime = newTime\n this.tick(newTime)\n }\n }\n\n /**\n * Returns the generator's velocity at the current time in units/second.\n * Uses the analytical derivative when available (springs), avoiding\n * the MotionValue's frame-dependent velocity estimation.\n */\n getGeneratorVelocity(): number {\n const t = this.currentTime\n if (t <= 0) return this.options.velocity || 0\n\n if (this.generator.velocity) {\n return this.generator.velocity(t)\n }\n\n // Fallback: finite difference\n const current = this.generator.next(t).value as number\n return getGeneratorVelocity(\n (s) => this.generator.next(s).value as number,\n t,\n current\n )\n }\n\n get speed() {\n return this.playbackSpeed\n }\n\n set speed(newSpeed: number) {\n const hasChanged = this.playbackSpeed !== newSpeed\n\n if (hasChanged && this.driver) {\n this.updateTime(time.now())\n }\n\n this.playbackSpeed = newSpeed\n\n if (hasChanged && this.driver) {\n this.time = millisecondsToSeconds(this.currentTime)\n }\n }\n\n play() {\n if (this.isStopped) return\n\n const { driver = frameloopDriver, startTime } = this.options\n\n if (!this.driver) {\n this.driver = driver((timestamp) => this.tick(timestamp))\n }\n\n this.options.onPlay?.()\n\n const now = this.driver.now()\n\n if (this.state === \"finished\") {\n this.updateFinished()\n this.startTime = now\n } else if (this.holdTime !== null) {\n this.startTime = now - this.holdTime\n } else if (!this.startTime) {\n this.startTime = startTime ?? now\n }\n\n if (this.state === \"finished\" && this.speed < 0) {\n this.startTime += this.calculatedDuration\n }\n\n this.holdTime = null\n\n /**\n * Set playState to running only after we've used it in\n * the previous logic.\n */\n this.state = \"running\"\n\n this.driver.start()\n }\n\n pause() {\n this.state = \"paused\"\n this.updateTime(time.now())\n this.holdTime = this.currentTime\n }\n\n /**\n * This method is bound to the instance to fix a pattern where\n * animation.stop is returned as a reference from a useEffect.\n */\n stop = () => {\n const { motionValue } = this.options\n if (motionValue && motionValue.updatedAt !== time.now()) {\n this.tick(time.now())\n }\n\n this.isStopped = true\n if (this.state === \"idle\") return\n this.teardown()\n this.options.onStop?.()\n }\n\n complete() {\n if (this.state !== \"running\") {\n this.play()\n }\n\n this.state = \"finished\"\n this.holdTime = null\n }\n\n finish() {\n this.notifyFinished()\n this.teardown()\n this.state = \"finished\"\n\n this.options.onComplete?.()\n }\n\n cancel() {\n this.holdTime = null\n this.startTime = 0\n this.tick(0)\n this.teardown()\n this.options.onCancel?.()\n }\n\n private teardown() {\n this.state = \"idle\"\n this.stopDriver()\n this.startTime = this.holdTime = null\n activeAnimations.mainThread--\n }\n\n private stopDriver() {\n if (!this.driver) return\n this.driver.stop()\n this.driver = undefined\n }\n\n sample(sampleTime: number): AnimationState {\n this.startTime = 0\n return this.tick(sampleTime, true)\n }\n\n attachTimeline(timeline: TimelineWithFallback): VoidFunction {\n if (this.options.allowFlatten) {\n this.options.type = \"keyframes\"\n this.options.ease = \"linear\"\n this.initAnimation()\n }\n\n this.driver?.stop()\n return timeline.observe(this)\n }\n}\n\n// Legacy function support\nexport function animateValue(\n options: ValueAnimationOptions\n) {\n return new JSAnimation(options)\n}\n", "import { UnresolvedValueKeyframe, ValueKeyframe } from \"../../types\"\n\nexport function fillWildcards(\n keyframes: ValueKeyframe[] | UnresolvedValueKeyframe[]\n) {\n for (let i = 1; i < keyframes.length; i++) {\n keyframes[i] ??= keyframes[i - 1]\n }\n}\n", "import { transformPropOrder } from \"../utils/keys-transform\"\n\nconst radToDeg = (rad: number) => (rad * 180) / Math.PI\n\ntype MatrixParser = (values: number[]) => number\n\ntype MatrixParsers = Record<\n (typeof transformPropOrder)[number],\n number | MatrixParser\n>\n\nconst rotate = (v: number[]) => {\n const angle = radToDeg(Math.atan2(v[1], v[0]))\n return rebaseAngle(angle)\n}\n\nconst matrix2dParsers: MatrixParsers = {\n x: 4,\n y: 5,\n translateX: 4,\n translateY: 5,\n scaleX: 0,\n scaleY: 3,\n scale: (v) => (Math.abs(v[0]) + Math.abs(v[3])) / 2,\n rotate,\n rotateZ: rotate,\n skewX: (v) => radToDeg(Math.atan(v[1])),\n skewY: (v) => radToDeg(Math.atan(v[2])),\n skew: (v) => (Math.abs(v[1]) + Math.abs(v[2])) / 2,\n} as const\n\nconst rebaseAngle = (angle: number) => {\n angle = angle % 360\n if (angle < 0) angle += 360\n return angle\n}\n\nconst rotateZ = rotate\n\nconst scaleX = (v: number[]) => Math.sqrt(v[0] * v[0] + v[1] * v[1])\nconst scaleY = (v: number[]) => Math.sqrt(v[4] * v[4] + v[5] * v[5])\n\nconst matrix3dParsers: MatrixParsers = {\n x: 12,\n y: 13,\n z: 14,\n translateX: 12,\n translateY: 13,\n translateZ: 14,\n scaleX,\n scaleY,\n scale: (v) => (scaleX(v) + scaleY(v)) / 2,\n rotateX: (v) => rebaseAngle(radToDeg(Math.atan2(v[6], v[5]))),\n rotateY: (v) => rebaseAngle(radToDeg(Math.atan2(-v[2], v[0]))),\n rotateZ,\n rotate: rotateZ,\n skewX: (v) => radToDeg(Math.atan(v[4])),\n skewY: (v) => radToDeg(Math.atan(v[1])),\n skew: (v) => (Math.abs(v[1]) + Math.abs(v[4])) / 2,\n} as const\n\nexport function defaultTransformValue(name: string): number {\n return name.includes(\"scale\") ? 1 : 0\n}\n\nexport function parseValueFromTransform(\n transform: string | undefined,\n name: string\n): number {\n if (!transform || transform === \"none\") {\n return defaultTransformValue(name)\n }\n\n const matrix3dMatch = transform.match(/^matrix3d\\(([-\\d.e\\s,]+)\\)$/u)\n\n let parsers: MatrixParsers\n let match: RegExpMatchArray | null\n\n if (matrix3dMatch) {\n parsers = matrix3dParsers\n match = matrix3dMatch\n } else {\n const matrix2dMatch = transform.match(/^matrix\\(([-\\d.e\\s,]+)\\)$/u)\n\n parsers = matrix2dParsers\n match = matrix2dMatch\n }\n\n if (!match) {\n return defaultTransformValue(name)\n }\n\n const valueParser = parsers[name]\n const values = match[1].split(\",\").map(convertTransformToNumber)\n\n return typeof valueParser === \"function\"\n ? valueParser(values)\n : values[valueParser]\n}\n\nexport const readTransformValue = (instance: HTMLElement, name: string) => {\n const { transform = \"none\" } = getComputedStyle(instance)\n return parseValueFromTransform(transform, name)\n}\n\nfunction convertTransformToNumber(value: string): number {\n return parseFloat(value.trim())\n}\n", "/**\n * Generate a list of every possible transform key.\n */\nexport const transformPropOrder = [\n \"transformPerspective\",\n \"x\",\n \"y\",\n \"z\",\n \"translateX\",\n \"translateY\",\n \"translateZ\",\n \"scale\",\n \"scaleX\",\n \"scaleY\",\n \"rotate\",\n \"rotateX\",\n \"rotateY\",\n \"rotateZ\",\n \"skew\",\n \"skewX\",\n \"skewY\",\n]\n\n/**\n * A quick lookup for transform props.\n */\nexport const transformProps = /*@__PURE__*/ (() =>\n new Set(transformPropOrder))()\n", "import type { Box } from \"motion-utils\"\nimport { parseValueFromTransform } from \"../../../render/dom/parse-transform\"\nimport { transformPropOrder } from \"../../../render/utils/keys-transform\"\nimport { MotionValue } from \"../../../value\"\nimport { number } from \"../../../value/types/numbers\"\nimport { px } from \"../../../value/types/numbers/units\"\nimport { ValueType } from \"../../../value/types/types\"\nimport { AnyResolvedKeyframe } from \"../../types\"\nimport { WithRender } from \"../types\"\n\nexport const isNumOrPxType = (v?: ValueType): v is ValueType =>\n v === number || v === px\n\ntype GetActualMeasurementInPixels = (\n bbox: Box,\n computedStyle: Partial\n) => number\n\nconst transformKeys = new Set([\"x\", \"y\", \"z\"])\nconst nonTranslationalTransformKeys = transformPropOrder.filter(\n (key) => !transformKeys.has(key)\n)\n\ntype RemovedTransforms = [string, AnyResolvedKeyframe][]\nexport function removeNonTranslationalTransform(visualElement: WithRender) {\n const removedTransforms: RemovedTransforms = []\n\n nonTranslationalTransformKeys.forEach((key) => {\n const value: MotionValue | undefined =\n visualElement.getValue(key)\n if (value !== undefined) {\n removedTransforms.push([key, value.get()])\n value.set(key.startsWith(\"scale\") ? 1 : 0)\n }\n })\n\n return removedTransforms\n}\n\nexport const positionalValues: { [key: string]: GetActualMeasurementInPixels } =\n {\n // Dimensions\n width: (\n { x },\n { paddingLeft = \"0\", paddingRight = \"0\", boxSizing }\n ) => {\n const width = x.max - x.min\n return boxSizing === \"border-box\"\n ? width\n : width - parseFloat(paddingLeft) - parseFloat(paddingRight)\n },\n height: (\n { y },\n { paddingTop = \"0\", paddingBottom = \"0\", boxSizing }\n ) => {\n const height = y.max - y.min\n return boxSizing === \"border-box\"\n ? height\n : height - parseFloat(paddingTop) - parseFloat(paddingBottom)\n },\n\n top: (_bbox, { top }) => parseFloat(top as string),\n left: (_bbox, { left }) => parseFloat(left as string),\n bottom: ({ y }, { top }) => parseFloat(top as string) + (y.max - y.min),\n right: ({ x }, { left }) =>\n parseFloat(left as string) + (x.max - x.min),\n\n // Transform\n x: (_bbox, { transform }) => parseValueFromTransform(transform, \"x\"),\n y: (_bbox, { transform }) => parseValueFromTransform(transform, \"y\"),\n }\n\n// Alias translate longform names\npositionalValues.translateX = positionalValues.x\npositionalValues.translateY = positionalValues.y\n", "import { frame } from \"../../frameloop\"\nimport { MotionValue } from \"../../value\"\nimport { AnyResolvedKeyframe } from \"../types\"\nimport { WithRender } from \"./types\"\nimport { fillWildcards } from \"./utils/fill-wildcards\"\nimport { removeNonTranslationalTransform } from \"./utils/unit-conversion\"\n\nexport type UnresolvedKeyframes = Array\n\nexport type ResolvedKeyframes = Array\n\nconst toResolve = new Set()\nlet isScheduled = false\nlet anyNeedsMeasurement = false\nlet isForced = false\n\nfunction measureAllKeyframes() {\n if (anyNeedsMeasurement) {\n const resolversToMeasure = Array.from(toResolve).filter(\n (resolver: KeyframeResolver) => resolver.needsMeasurement\n )\n const elementsToMeasure = new Set(\n resolversToMeasure.map((resolver) => resolver.element)\n )\n const transformsToRestore = new Map<\n WithRender,\n [string, AnyResolvedKeyframe][]\n >()\n\n /**\n * Write pass\n * If we're measuring elements we want to remove bounding box-changing transforms.\n */\n elementsToMeasure.forEach((element: WithRender) => {\n const removedTransforms = removeNonTranslationalTransform(\n element as any\n )\n\n if (!removedTransforms.length) return\n\n transformsToRestore.set(element, removedTransforms)\n\n element.render()\n })\n\n // Read\n resolversToMeasure.forEach((resolver) => resolver.measureInitialState())\n\n // Write\n elementsToMeasure.forEach((element: WithRender) => {\n element.render()\n\n const restore = transformsToRestore.get(element)\n if (restore) {\n restore.forEach(([key, value]) => {\n element.getValue(key)?.set(value)\n })\n }\n })\n\n // Read\n resolversToMeasure.forEach((resolver) => resolver.measureEndState())\n\n // Write\n resolversToMeasure.forEach((resolver) => {\n if (resolver.suspendedScrollY !== undefined) {\n window.scrollTo(0, resolver.suspendedScrollY)\n }\n })\n }\n\n anyNeedsMeasurement = false\n isScheduled = false\n\n toResolve.forEach((resolver) => resolver.complete(isForced))\n toResolve.clear()\n}\n\nfunction readAllKeyframes() {\n toResolve.forEach((resolver) => {\n resolver.readKeyframes()\n\n if (resolver.needsMeasurement) {\n anyNeedsMeasurement = true\n }\n })\n}\n\nexport function flushKeyframeResolvers() {\n isForced = true\n readAllKeyframes()\n measureAllKeyframes()\n isForced = false\n}\n\nexport type OnKeyframesResolved = (\n resolvedKeyframes: ResolvedKeyframes,\n finalKeyframe: T,\n forced: boolean\n) => void\n\nexport class KeyframeResolver {\n name?: string\n element?: WithRender\n finalKeyframe?: T\n suspendedScrollY?: number\n\n protected unresolvedKeyframes: UnresolvedKeyframes\n\n private motionValue?: MotionValue\n private onComplete: OnKeyframesResolved\n\n state: \"pending\" | \"scheduled\" | \"complete\" = \"pending\"\n\n /**\n * Track whether this resolver is async. If it is, it'll be added to the\n * resolver queue and flushed in the next frame. Resolvers that aren't going\n * to trigger read/write thrashing don't need to be async.\n */\n private isAsync = false\n\n /**\n * Track whether this resolver needs to perform a measurement\n * to resolve its keyframes.\n */\n needsMeasurement = false\n\n constructor(\n unresolvedKeyframes: UnresolvedKeyframes,\n onComplete: OnKeyframesResolved,\n name?: string,\n motionValue?: MotionValue,\n element?: WithRender,\n isAsync = false\n ) {\n this.unresolvedKeyframes = [...unresolvedKeyframes]\n this.onComplete = onComplete\n this.name = name\n this.motionValue = motionValue\n this.element = element\n this.isAsync = isAsync\n }\n\n scheduleResolve() {\n this.state = \"scheduled\"\n\n if (this.isAsync) {\n toResolve.add(this)\n\n if (!isScheduled) {\n isScheduled = true\n frame.read(readAllKeyframes)\n frame.resolveKeyframes(measureAllKeyframes)\n }\n } else {\n this.readKeyframes()\n this.complete()\n }\n }\n\n readKeyframes() {\n const { unresolvedKeyframes, name, element, motionValue } = this\n\n // If initial keyframe is null we need to read it from the DOM\n if (unresolvedKeyframes[0] === null) {\n const currentValue = motionValue?.get()\n\n // TODO: This doesn't work if the final keyframe is a wildcard\n const finalKeyframe =\n unresolvedKeyframes[unresolvedKeyframes.length - 1]\n\n if (currentValue !== undefined) {\n unresolvedKeyframes[0] = currentValue\n } else if (element && name) {\n const valueAsRead = element.readValue(name, finalKeyframe)\n\n if (valueAsRead !== undefined && valueAsRead !== null) {\n unresolvedKeyframes[0] = valueAsRead\n }\n }\n\n if (unresolvedKeyframes[0] === undefined) {\n unresolvedKeyframes[0] = finalKeyframe\n }\n\n if (motionValue && currentValue === undefined) {\n motionValue.set(unresolvedKeyframes[0] as T)\n }\n }\n\n fillWildcards(unresolvedKeyframes)\n }\n\n setFinalKeyframe() {}\n measureInitialState() {}\n renderEndStyles() {}\n measureEndState() {}\n\n complete(isForcedComplete = false) {\n this.state = \"complete\"\n\n this.onComplete(\n this.unresolvedKeyframes as ResolvedKeyframes,\n this.finalKeyframe as T,\n isForcedComplete\n )\n\n toResolve.delete(this)\n }\n\n cancel() {\n if (this.state === \"scheduled\") {\n toResolve.delete(this)\n this.state = \"pending\"\n }\n }\n\n resume() {\n if (this.state === \"pending\") this.scheduleResolve()\n }\n}\n", "export const isCSSVar = (name: string) => name.startsWith(\"--\")\n", "import { AnyResolvedKeyframe } from \"../../animation/types\"\nimport { isCSSVar } from \"./is-css-var\"\n\nexport function setStyle(\n element: HTMLElement | SVGElement,\n name: string,\n value: AnyResolvedKeyframe\n) {\n isCSSVar(name)\n ? element.style.setProperty(name, value as string)\n : (element.style[name as any] = value as string)\n}\n", "/**\n * Add the ability for test suites to manually set support flags\n * to better test more environments.\n */\nexport const supportsFlags: Record = {}\n", "import { memo } from \"motion-utils\"\nimport { supportsFlags } from \"./flags\"\n\nexport function memoSupports(\n callback: () => T,\n supportsFlag: keyof typeof supportsFlags\n) {\n const memoized = memo(callback)\n return () => supportsFlags[supportsFlag] ?? memoized()\n}\n", "import { ProgressTimeline } from \"../..\"\nimport { memoSupports } from \"./memo\"\n\ndeclare global {\n interface Window {\n ScrollTimeline: ScrollTimeline\n ViewTimeline: ViewTimeline\n }\n}\n\ndeclare class ScrollTimeline implements ProgressTimeline {\n constructor(options: ScrollOptions)\n\n currentTime: null | { value: number }\n\n cancel?: VoidFunction\n}\n\ndeclare class ViewTimeline implements ProgressTimeline {\n constructor(options: { subject: Element; axis?: string })\n\n currentTime: null | { value: number }\n\n cancel?: VoidFunction\n}\n\nexport const supportsScrollTimeline = /* @__PURE__ */ memoSupports(\n () => window.ScrollTimeline !== undefined,\n \"scrollTimeline\"\n)\n\nexport const supportsViewTimeline = /* @__PURE__ */ memoSupports(\n () => window.ViewTimeline !== undefined,\n \"viewTimeline\"\n)\n", "import { memoSupports } from \"./memo\"\n\nexport const supportsLinearEasing = /*@__PURE__*/ memoSupports(() => {\n try {\n document\n .createElement(\"div\")\n .animate({ opacity: 0 }, { easing: \"linear(0, 1)\" })\n } catch (e) {\n return false\n }\n return true\n}, \"linearEasing\")\n", "import { BezierDefinition } from \"motion-utils\"\n\nexport const cubicBezierAsString = ([a, b, c, d]: BezierDefinition) =>\n `cubic-bezier(${a}, ${b}, ${c}, ${d})`\n", "import { cubicBezierAsString } from \"./cubic-bezier\"\n\nexport const supportedWaapiEasing = {\n linear: \"linear\",\n ease: \"ease\",\n easeIn: \"ease-in\",\n easeOut: \"ease-out\",\n easeInOut: \"ease-in-out\",\n circIn: /*@__PURE__*/ cubicBezierAsString([0, 0.65, 0.55, 1]),\n circOut: /*@__PURE__*/ cubicBezierAsString([0.55, 0, 1, 0.45]),\n backIn: /*@__PURE__*/ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),\n backOut: /*@__PURE__*/ cubicBezierAsString([0.33, 1.53, 0.69, 0.99]),\n}\n", "import { Easing, isBezierDefinition } from \"motion-utils\"\nimport { supportsLinearEasing } from \"../../../utils/supports/linear-easing\"\nimport { generateLinearEasing } from \"../utils/linear\"\nimport { cubicBezierAsString } from \"./cubic-bezier\"\nimport { supportedWaapiEasing } from \"./supported\"\n\nexport function mapEasingToNativeEasing(\n easing: Easing | Easing[] | undefined,\n duration: number\n): undefined | string | string[] {\n if (!easing) {\n return undefined\n } else if (typeof easing === \"function\") {\n return supportsLinearEasing()\n ? generateLinearEasing(easing, duration)\n : \"ease-out\"\n } else if (isBezierDefinition(easing)) {\n return cubicBezierAsString(easing)\n } else if (Array.isArray(easing)) {\n return easing.map(\n (segmentEasing) =>\n (mapEasingToNativeEasing(segmentEasing, duration) as string) ||\n supportedWaapiEasing.easeOut\n )\n } else {\n return supportedWaapiEasing[easing as keyof typeof supportedWaapiEasing]\n }\n}\n", "import { activeAnimations } from \"../../stats/animation-count\"\nimport { statsBuffer } from \"../../stats/buffer\"\nimport { ValueKeyframesDefinition, ValueTransition } from \"../types\"\nimport { mapEasingToNativeEasing } from \"./easing/map-easing\"\n\nexport function startWaapiAnimation(\n element: Element,\n valueName: string,\n keyframes: ValueKeyframesDefinition,\n {\n delay = 0,\n duration = 300,\n repeat = 0,\n repeatType = \"loop\",\n ease = \"easeOut\",\n times,\n }: ValueTransition = {},\n pseudoElement: string | undefined = undefined\n) {\n const keyframeOptions: PropertyIndexedKeyframes = {\n [valueName]: keyframes as string[],\n }\n if (times) keyframeOptions.offset = times\n\n const easing = mapEasingToNativeEasing(ease, duration)\n\n /**\n * If this is an easing array, apply to keyframes, not animation as a whole\n */\n if (Array.isArray(easing)) keyframeOptions.easing = easing\n\n if (statsBuffer.value) {\n activeAnimations.waapi++\n }\n\n const options: KeyframeAnimationOptions = {\n delay,\n duration,\n easing: !Array.isArray(easing) ? easing : \"linear\",\n fill: \"both\",\n iterations: repeat + 1,\n direction: repeatType === \"reverse\" ? \"alternate\" : \"normal\",\n }\n\n if (pseudoElement) options.pseudoElement = pseudoElement\n\n const animation = element.animate(keyframeOptions, options)\n\n if (statsBuffer.value) {\n animation.finished.finally(() => {\n activeAnimations.waapi--\n })\n }\n\n return animation\n}\n", "import { AnimationGeneratorType, GeneratorFactory } from \"../../types\"\n\nexport function isGenerator(\n type?: AnimationGeneratorType\n): type is GeneratorFactory {\n return typeof type === \"function\" && \"applyToOptions\" in type\n}\n", "import { ValueTransition } from \"../../../animation/types\"\nimport { supportsLinearEasing } from \"../../../utils/supports/linear-easing\"\nimport { isGenerator } from \"../../generators/utils/is-generator\"\n\nexport function applyGeneratorOptions({\n type,\n ...options\n}: ValueTransition): ValueTransition {\n if (isGenerator(type) && supportsLinearEasing()) {\n return type.applyToOptions!(options)\n } else {\n options.duration ??= 300\n options.ease ??= \"easeOut\"\n }\n\n return options\n}\n", "import {\n invariant,\n millisecondsToSeconds,\n noop,\n secondsToMilliseconds,\n} from \"motion-utils\"\nimport { setStyle } from \"../render/dom/style-set\"\nimport { supportsScrollTimeline } from \"../utils/supports/scroll-timeline\"\nimport { getFinalKeyframe } from \"./keyframes/get-final\"\nimport {\n AnimationPlaybackControlsWithThen,\n AnyResolvedKeyframe,\n DOMValueAnimationOptions,\n TimelineWithFallback,\n} from \"./types\"\nimport { WithPromise } from \"./utils/WithPromise\"\nimport { startWaapiAnimation } from \"./waapi/start-waapi-animation\"\nimport { applyGeneratorOptions } from \"./waapi/utils/apply-generator\"\n\nexport interface NativeAnimationOptions\n extends DOMValueAnimationOptions {\n pseudoElement?: string\n startTime?: number\n}\n\n/**\n * NativeAnimation implements AnimationPlaybackControls for the browser's Web Animations API.\n */\nexport class NativeAnimation\n extends WithPromise\n implements AnimationPlaybackControlsWithThen\n{\n /**\n * The interfaced Web Animation API animation\n */\n protected animation: Animation\n\n protected finishedTime: number | null = null\n\n protected options: NativeAnimationOptions\n\n private allowFlatten: boolean\n\n private isStopped = false\n\n private isPseudoElement: boolean\n\n /**\n * Tracks a manually-set start time that takes precedence over WAAPI's\n * dynamic startTime. This is cleared when play() or time setter is called,\n * allowing WAAPI to take over timing.\n */\n protected manualStartTime: number | null = null\n\n constructor(options?: NativeAnimationOptions) {\n super()\n\n if (!options) return\n\n const {\n element,\n name,\n keyframes,\n pseudoElement,\n allowFlatten = false,\n finalKeyframe,\n onComplete,\n } = options as any\n\n this.isPseudoElement = Boolean(pseudoElement)\n\n this.allowFlatten = allowFlatten\n this.options = options\n\n invariant(\n typeof options.type !== \"string\",\n `Mini animate() doesn't support \"type\" as a string.`,\n \"mini-spring\"\n )\n\n const transition = applyGeneratorOptions(options)\n\n this.animation = startWaapiAnimation(\n element,\n name,\n keyframes,\n transition,\n pseudoElement\n )\n\n if (transition.autoplay === false) {\n this.animation.pause()\n }\n\n this.animation.onfinish = () => {\n this.finishedTime = this.time\n\n if (!pseudoElement) {\n const keyframe = getFinalKeyframe(\n keyframes as any,\n this.options as any,\n finalKeyframe,\n this.speed\n )\n if (this.updateMotionValue) {\n this.updateMotionValue(keyframe)\n }\n\n /**\n * If we can, we want to commit the final style as set by the user,\n * rather than the computed keyframe value supplied by the animation.\n * We always do this, even when a motion value is present, to prevent\n * a visual flash in Firefox where the WAAPI animation's fill is removed\n * during cancel() before the scheduled render can apply the correct value.\n */\n setStyle(element, name, keyframe)\n\n this.animation.cancel()\n }\n\n onComplete?.()\n this.notifyFinished()\n }\n }\n\n updateMotionValue?(value?: T): void\n\n play() {\n if (this.isStopped) return\n\n this.manualStartTime = null\n this.animation.play()\n\n if (this.state === \"finished\") {\n this.updateFinished()\n }\n }\n\n pause() {\n this.animation.pause()\n }\n\n complete() {\n this.animation.finish?.()\n }\n\n cancel() {\n try {\n this.animation.cancel()\n } catch (e) {}\n }\n\n stop() {\n if (this.isStopped) return\n this.isStopped = true\n const { state } = this\n\n if (state === \"idle\" || state === \"finished\") {\n return\n }\n\n if (this.updateMotionValue) {\n this.updateMotionValue()\n } else {\n this.commitStyles()\n }\n\n if (!this.isPseudoElement) this.cancel()\n }\n\n /**\n * WAAPI doesn't natively have any interruption capabilities.\n *\n * In this method, we commit styles back to the DOM before cancelling\n * the animation.\n *\n * This is designed to be overridden by NativeAnimationExtended, which\n * will create a renderless JS animation and sample it twice to calculate\n * its current value, \"previous\" value, and therefore allow\n * Motion to also correctly calculate velocity for any subsequent animation\n * while deferring the commit until the next animation frame.\n */\n protected commitStyles() {\n const element = this.options?.element\n if (!this.isPseudoElement && element?.isConnected) {\n this.animation.commitStyles?.()\n }\n }\n\n get duration() {\n const duration =\n this.animation.effect?.getComputedTiming?.().duration || 0\n\n return millisecondsToSeconds(Number(duration))\n }\n\n get iterationDuration() {\n const { delay = 0 } = this.options || {}\n return this.duration + millisecondsToSeconds(delay)\n }\n\n get time() {\n return millisecondsToSeconds(Number(this.animation.currentTime) || 0)\n }\n\n set time(newTime: number) {\n const wasFinished = this.finishedTime !== null\n this.manualStartTime = null\n this.finishedTime = null\n this.animation.currentTime = secondsToMilliseconds(newTime)\n\n if (wasFinished) {\n this.animation.pause()\n }\n }\n\n /**\n * The playback speed of the animation.\n * 1 = normal speed, 2 = double speed, 0.5 = half speed.\n */\n get speed() {\n return this.animation.playbackRate\n }\n\n set speed(newSpeed: number) {\n // Allow backwards playback after finishing\n if (newSpeed < 0) this.finishedTime = null\n\n this.animation.playbackRate = newSpeed\n }\n\n get state() {\n return this.finishedTime !== null\n ? \"finished\"\n : this.animation.playState\n }\n\n get startTime() {\n return this.manualStartTime ?? Number(this.animation.startTime)\n }\n\n set startTime(newStartTime: number) {\n this.manualStartTime = this.animation.startTime = newStartTime\n }\n\n /**\n * Attaches a timeline to the animation, for instance the `ScrollTimeline`.\n */\n attachTimeline({\n timeline,\n rangeStart,\n rangeEnd,\n observe,\n }: TimelineWithFallback): VoidFunction {\n if (this.allowFlatten) {\n this.animation.effect?.updateTiming({ easing: \"linear\" })\n }\n\n this.animation.onfinish = null\n\n if (timeline && supportsScrollTimeline()) {\n this.animation.timeline = timeline as any\n\n if (rangeStart) (this.animation as any).rangeStart = rangeStart\n if (rangeEnd) (this.animation as any).rangeEnd = rangeEnd\n\n return noop\n } else {\n return observe(this)\n }\n }\n}\n", "import { anticipate, backInOut, circInOut } from \"motion-utils\"\nimport { ValueAnimationTransition } from \"../../types\"\n\nconst unsupportedEasingFunctions = {\n anticipate,\n backInOut,\n circInOut,\n}\n\nfunction isUnsupportedEase(\n key: string\n): key is keyof typeof unsupportedEasingFunctions {\n return key in unsupportedEasingFunctions\n}\n\nexport function replaceStringEasing(transition: ValueAnimationTransition) {\n if (\n typeof transition.ease === \"string\" &&\n isUnsupportedEase(transition.ease)\n ) {\n transition.ease = unsupportedEasingFunctions[transition.ease]\n }\n}\n", "import { clamp } from \"motion-utils\"\nimport { time } from \"../frameloop/sync-time\"\nimport { setStyle } from \"../render/dom/style-set\"\nimport { JSAnimation } from \"./JSAnimation\"\nimport { NativeAnimation, NativeAnimationOptions } from \"./NativeAnimation\"\nimport { AnyResolvedKeyframe, ValueAnimationOptions } from \"./types\"\nimport { replaceTransitionType } from \"./utils/replace-transition-type\"\nimport { replaceStringEasing } from \"./waapi/utils/unsupported-easing\"\n\nexport type NativeAnimationOptionsExtended =\n NativeAnimationOptions & ValueAnimationOptions & NativeAnimationOptions\n\n/**\n * 10ms is chosen here as it strikes a balance between smooth\n * results (more than one keyframe per frame at 60fps) and\n * keyframe quantity.\n */\nconst sampleDelta = 10 //ms\n\nexport class NativeAnimationExtended<\n T extends AnyResolvedKeyframe\n> extends NativeAnimation {\n options: NativeAnimationOptionsExtended\n\n constructor(options: NativeAnimationOptionsExtended) {\n /**\n * The base NativeAnimation function only supports a subset\n * of Motion easings, and WAAPI also only supports some\n * easing functions via string/cubic-bezier definitions.\n *\n * This function replaces those unsupported easing functions\n * with a JS easing function. This will later get compiled\n * to a linear() easing function.\n */\n replaceStringEasing(options)\n\n /**\n * Ensure we replace the transition type with a generator function\n * before passing to WAAPI.\n *\n * TODO: Does this have a better home? It could be shared with\n * JSAnimation.\n */\n replaceTransitionType(options)\n\n super(options)\n\n /**\n * Only set startTime when the animation should autoplay.\n * Setting startTime on a paused WAAPI animation unpauses it\n * (per the WAAPI spec), which breaks autoplay: false.\n */\n if (options.startTime !== undefined && options.autoplay !== false) {\n this.startTime = options.startTime\n }\n\n this.options = options\n }\n\n /**\n * WAAPI doesn't natively have any interruption capabilities.\n *\n * Rather than read committed styles back out of the DOM, we can\n * create a renderless JS animation and sample it twice to calculate\n * its current value, \"previous\" value, and therefore allow\n * Motion to calculate velocity for any subsequent animation.\n */\n updateMotionValue(value?: T) {\n const { motionValue, onUpdate, onComplete, element, ...options } =\n this.options\n\n if (!motionValue) return\n\n if (value !== undefined) {\n motionValue.set(value)\n return\n }\n\n const sampleAnimation = new JSAnimation({\n ...options,\n autoplay: false,\n })\n\n /**\n * Use wall-clock elapsed time for sampling.\n * Under CPU load, WAAPI's currentTime may not reflect actual\n * elapsed time, causing incorrect sampling and visual jumps.\n */\n const sampleTime = Math.max(sampleDelta, time.now() - this.startTime)\n const delta = clamp(0, sampleDelta, sampleTime - sampleDelta)\n const current = sampleAnimation.sample(sampleTime).value\n\n /**\n * Write the estimated value to inline style so it persists\n * after cancel(), covering the async gap before the next\n * animation starts.\n */\n const { name } = this.options\n if (element && name) setStyle(element, name, current)\n\n motionValue.setWithVelocity(\n sampleAnimation.sample(Math.max(0, sampleTime - delta)).value,\n current,\n delta\n )\n\n sampleAnimation.stop()\n }\n}\n", "import { complex } from \"../../value/types/complex\"\nimport { ValueKeyframesDefinition } from \"../types\"\n\n/**\n * Check if a value is animatable. Examples:\n *\n * ✅: 100, \"100px\", \"#fff\"\n * ❌: \"block\", \"url(2.jpg)\"\n * @param value\n *\n * @internal\n */\nexport const isAnimatable = (\n value: ValueKeyframesDefinition,\n name?: string\n) => {\n // If the list of keys that might be non-animatable grows, replace with Set\n if (name === \"zIndex\") return false\n\n // If it's a number or a keyframes array, we can animate it. We might at some point\n // need to do a deep isAnimatable check of keyframes, or let Popmotion handle this,\n // but for now lets leave it like this for performance reasons\n if (typeof value === \"number\" || Array.isArray(value)) return true\n\n if (\n typeof value === \"string\" && // It's animatable if we have a string\n (complex.test(value) || value === \"0\") && // And it contains numbers and/or colors\n !value.startsWith(\"url(\") // Unless it starts with \"url(\"\n ) {\n return true\n }\n\n return false\n}\n", "import { warning } from \"motion-utils\"\nimport { isGenerator } from \"../generators/utils/is-generator\"\nimport { ResolvedKeyframes } from \"../keyframes/KeyframesResolver\"\nimport { AnimationGeneratorType } from \"../types\"\nimport { isAnimatable } from \"./is-animatable\"\n\nfunction hasKeyframesChanged(keyframes: ResolvedKeyframes) {\n const current = keyframes[0]\n if (keyframes.length === 1) return true\n for (let i = 0; i < keyframes.length; i++) {\n if (keyframes[i] !== current) return true\n }\n}\n\nexport function canAnimate(\n keyframes: ResolvedKeyframes,\n name?: string,\n type?: AnimationGeneratorType,\n velocity?: number\n) {\n /**\n * Check if we're able to animate between the start and end keyframes,\n * and throw a warning if we're attempting to animate between one that's\n * animatable and another that isn't.\n */\n const originKeyframe = keyframes[0]\n if (originKeyframe === null) {\n return false\n }\n\n /**\n * These aren't traditionally animatable but we do support them.\n * In future we could look into making this more generic or replacing\n * this function with mix() === mixImmediate\n */\n if (name === \"display\" || name === \"visibility\") return true\n\n const targetKeyframe = keyframes[keyframes.length - 1]\n const isOriginAnimatable = isAnimatable(originKeyframe, name)\n const isTargetAnimatable = isAnimatable(targetKeyframe, name)\n\n warning(\n isOriginAnimatable === isTargetAnimatable,\n `You are trying to animate ${name} from \"${originKeyframe}\" to \"${targetKeyframe}\". \"${\n isOriginAnimatable ? targetKeyframe : originKeyframe\n }\" is not an animatable value.`,\n \"value-not-animatable\"\n )\n\n // Always skip if any of these are true\n if (!isOriginAnimatable || !isTargetAnimatable) {\n return false\n }\n\n return (\n hasKeyframesChanged(keyframes) ||\n ((type === \"spring\" || isGenerator(type)) && velocity)\n )\n}\n", "import { ValueAnimationOptions } from \"../types\"\n\nexport function makeAnimationInstant(\n options: Partial<{\n duration: ValueAnimationOptions[\"duration\"]\n type: ValueAnimationOptions[\"type\"]\n }>\n): void {\n options.duration = 0\n options.type = \"keyframes\"\n}\n", "/**\n * A list of values that can be hardware-accelerated.\n */\nexport const acceleratedValues = new Set([\n \"opacity\",\n \"clipPath\",\n \"filter\",\n \"transform\",\n // TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved\n // or until we implement support for linear() easing.\n // \"background-color\"\n])\n", "const browserColorFunctions =\n /^(?:oklch|oklab|lab|lch|color|color-mix|light-dark)\\(/\n\nexport function hasBrowserOnlyColors(keyframes: any[]): boolean {\n for (let i = 0; i < keyframes.length; i++) {\n if (\n typeof keyframes[i] === \"string\" &&\n browserColorFunctions.test(keyframes[i])\n ) {\n return true\n }\n }\n return false\n}\n", "import { memo } from \"motion-utils\"\nimport {\n AnyResolvedKeyframe,\n ValueAnimationOptionsWithRenderContext,\n} from \"../../types\"\nimport { acceleratedValues } from \"../utils/accelerated-values\"\nimport { hasBrowserOnlyColors } from \"../utils/is-browser-color\"\n\nconst colorProperties = new Set([\n \"color\",\n \"backgroundColor\",\n \"outlineColor\",\n \"fill\",\n \"stroke\",\n \"borderColor\",\n \"borderTopColor\",\n \"borderRightColor\",\n \"borderBottomColor\",\n \"borderLeftColor\",\n])\n\nconst supportsWaapi = /*@__PURE__*/ memo(() =>\n Object.hasOwnProperty.call(Element.prototype, \"animate\")\n)\n\nexport function supportsBrowserAnimation(\n options: ValueAnimationOptionsWithRenderContext\n) {\n const {\n motionValue,\n name,\n repeatDelay,\n repeatType,\n damping,\n type,\n keyframes,\n } = options\n\n const subject = motionValue?.owner?.current\n\n /**\n * We use this check instead of isHTMLElement() because we explicitly\n * **don't** want elements in different timing contexts (i.e. popups)\n * to be accelerated, as it's not possible to sync these animations\n * properly with those driven from the main window frameloop.\n */\n if (!(subject instanceof HTMLElement)) {\n return false\n }\n\n const { onUpdate, transformTemplate } = motionValue!.owner!.getProps()\n\n return (\n supportsWaapi() &&\n name &&\n /**\n * Force WAAPI for color properties with browser-only color formats\n * (oklch, oklab, lab, lch, etc.) that the JS animation path can't parse.\n */\n (acceleratedValues.has(name) ||\n (colorProperties.has(name) &&\n hasBrowserOnlyColors(keyframes))) &&\n (name !== \"transform\" || !transformTemplate) &&\n /**\n * If we're outputting values to onUpdate then we can't use WAAPI as there's\n * no way to read the value from WAAPI every frame.\n */\n !onUpdate &&\n !repeatDelay &&\n repeatType !== \"mirror\" &&\n damping !== 0 &&\n type !== \"inertia\"\n )\n}\n", "import { MotionGlobalConfig, noop } from \"motion-utils\"\nimport { time } from \"../frameloop/sync-time\"\nimport { JSAnimation } from \"./JSAnimation\"\nimport { getFinalKeyframe } from \"./keyframes/get-final\"\nimport {\n KeyframeResolver as DefaultKeyframeResolver,\n flushKeyframeResolvers,\n ResolvedKeyframes,\n} from \"./keyframes/KeyframesResolver\"\nimport { NativeAnimationExtended } from \"./NativeAnimationExtended\"\nimport {\n AnimationPlaybackControls,\n AnyResolvedKeyframe,\n TimelineWithFallback,\n ValueAnimationOptions,\n} from \"./types\"\nimport { canAnimate } from \"./utils/can-animate\"\nimport { makeAnimationInstant } from \"./utils/make-animation-instant\"\nimport { WithPromise } from \"./utils/WithPromise\"\nimport { supportsBrowserAnimation } from \"./waapi/supports/waapi\"\n\n/**\n * Maximum time allowed between an animation being created and it being\n * resolved for us to use the latter as the start time.\n *\n * This is to ensure that while we prefer to \"start\" an animation as soon\n * as it's triggered, we also want to avoid a visual jump if there's a big delay\n * between these two moments.\n */\nconst MAX_RESOLVE_DELAY = 40\n\ntype OptionsWithoutKeyframes = Omit<\n ValueAnimationOptions,\n \"keyframes\"\n>\n\nexport class AsyncMotionValueAnimation\n extends WithPromise\n implements AnimationPlaybackControls\n{\n private createdAt: number\n\n private resolvedAt: number | undefined\n\n private _animation: AnimationPlaybackControls | undefined\n\n private pendingTimeline: TimelineWithFallback | undefined\n\n private keyframeResolver: DefaultKeyframeResolver | undefined\n\n private stopTimeline: VoidFunction | undefined\n\n constructor({\n autoplay = true,\n delay = 0,\n type = \"keyframes\",\n repeat = 0,\n repeatDelay = 0,\n repeatType = \"loop\",\n keyframes,\n name,\n motionValue,\n element,\n ...options\n }: ValueAnimationOptions) {\n super()\n\n this.createdAt = time.now()\n\n const optionsWithDefaults: OptionsWithoutKeyframes = {\n autoplay,\n delay,\n type,\n repeat,\n repeatDelay,\n repeatType,\n name,\n motionValue,\n element,\n ...options,\n }\n\n const KeyframeResolver =\n element?.KeyframeResolver || DefaultKeyframeResolver\n\n this.keyframeResolver = new KeyframeResolver(\n keyframes,\n (\n resolvedKeyframes: ResolvedKeyframes,\n finalKeyframe: T,\n forced: boolean\n ) =>\n this.onKeyframesResolved(\n resolvedKeyframes,\n finalKeyframe,\n optionsWithDefaults,\n !forced\n ),\n name,\n motionValue,\n element\n )\n this.keyframeResolver?.scheduleResolve()\n }\n\n onKeyframesResolved(\n keyframes: ResolvedKeyframes,\n finalKeyframe: T,\n options: OptionsWithoutKeyframes,\n sync: boolean\n ) {\n this.keyframeResolver = undefined\n\n const { name, type, velocity, delay, isHandoff, onUpdate } = options\n this.resolvedAt = time.now()\n\n /**\n * If we can't animate this value with the resolved keyframes\n * then we should complete it immediately.\n */\n let canAnimateValue = true\n if (!canAnimate(keyframes, name, type, velocity)) {\n canAnimateValue = false\n\n if (MotionGlobalConfig.instantAnimations || !delay) {\n onUpdate?.(getFinalKeyframe(keyframes, options, finalKeyframe))\n }\n\n keyframes[0] = keyframes[keyframes.length - 1]\n\n makeAnimationInstant(options)\n options.repeat = 0\n }\n\n /**\n * Resolve startTime for the animation.\n *\n * This method uses the createdAt and resolvedAt to calculate the\n * animation startTime. *Ideally*, we would use the createdAt time as t=0\n * as the following frame would then be the first frame of the animation in\n * progress, which would feel snappier.\n *\n * However, if there's a delay (main thread work) between the creation of\n * the animation and the first committed frame, we prefer to use resolvedAt\n * to avoid a sudden jump into the animation.\n */\n const startTime = sync\n ? !this.resolvedAt\n ? this.createdAt\n : this.resolvedAt - this.createdAt > MAX_RESOLVE_DELAY\n ? this.resolvedAt\n : this.createdAt\n : undefined\n\n const resolvedOptions = {\n startTime,\n finalKeyframe,\n ...options,\n keyframes,\n }\n\n /**\n * Animate via WAAPI if possible. If this is a handoff animation, the optimised animation will be running via\n * WAAPI. Therefore, this animation must be JS to ensure it runs \"under\" the\n * optimised animation.\n *\n * Also skip WAAPI when keyframes aren't animatable, as the resolved\n * values may not be valid CSS and would trigger browser warnings.\n */\n const useWaapi =\n canAnimateValue &&\n !isHandoff &&\n supportsBrowserAnimation(resolvedOptions)\n const element = resolvedOptions.motionValue?.owner?.current\n\n let animation: AnimationPlaybackControls\n if (useWaapi) {\n try {\n animation = new NativeAnimationExtended({\n ...resolvedOptions,\n element,\n } as any)\n } catch {\n animation = new JSAnimation(resolvedOptions)\n }\n } else {\n animation = new JSAnimation(resolvedOptions)\n }\n\n animation.finished.then(() => {\n this.notifyFinished()\n }).catch(noop)\n\n if (this.pendingTimeline) {\n this.stopTimeline = animation.attachTimeline(this.pendingTimeline)\n this.pendingTimeline = undefined\n }\n\n this._animation = animation\n }\n\n get finished() {\n if (!this._animation) {\n return this._finished\n } else {\n return this.animation.finished\n }\n }\n\n then(onResolve: VoidFunction, _onReject?: VoidFunction) {\n return this.finished.finally(onResolve).then(() => {})\n }\n\n get animation(): AnimationPlaybackControls {\n if (!this._animation) {\n this.keyframeResolver?.resume()\n flushKeyframeResolvers()\n }\n\n return this._animation!\n }\n\n get duration() {\n return this.animation.duration\n }\n\n get iterationDuration() {\n return this.animation.iterationDuration\n }\n\n get time() {\n return this.animation.time\n }\n\n set time(newTime: number) {\n this.animation.time = newTime\n }\n\n get speed() {\n return this.animation.speed\n }\n\n get state() {\n return this.animation.state\n }\n\n set speed(newSpeed: number) {\n this.animation.speed = newSpeed\n }\n\n get startTime() {\n return this.animation.startTime\n }\n\n attachTimeline(timeline: TimelineWithFallback) {\n if (this._animation) {\n this.stopTimeline = this.animation.attachTimeline(timeline)\n } else {\n this.pendingTimeline = timeline\n }\n\n return () => this.stop()\n }\n\n play() {\n this.animation.play()\n }\n\n pause() {\n this.animation.pause()\n }\n\n complete() {\n this.animation.complete()\n }\n\n cancel() {\n if (this._animation) {\n this.animation.cancel()\n }\n\n this.keyframeResolver?.cancel()\n }\n\n /**\n * Bound to support return animation.stop pattern\n */\n stop = () => {\n if (this._animation) {\n this._animation.stop()\n this.stopTimeline?.()\n }\n\n this.keyframeResolver?.cancel()\n }\n}\n", "import type { DynamicOption } from \"../types\"\nimport type { VisualElement } from \"../../render/VisualElement\"\n\nexport function calcChildStagger(\n children: Set,\n child: VisualElement,\n delayChildren?: number | DynamicOption,\n staggerChildren: number = 0,\n staggerDirection: number = 1\n): number {\n const index = Array.from(children)\n .sort((a, b) => a.sortNodePosition(b))\n .indexOf(child)\n const numChildren = children.size\n const maxStaggerDuration = (numChildren - 1) * staggerChildren\n const delayIsFunction = typeof delayChildren === \"function\"\n\n return delayIsFunction\n ? delayChildren(index, numChildren)\n : staggerDirection === 1\n ? index * staggerChildren\n : maxStaggerDuration - index * staggerChildren\n}\n", "import { invariant, isNumericalString } from \"motion-utils\"\nimport { AnyResolvedKeyframe } from \"../types\"\nimport { CSSVariableToken, isCSSVariableToken } from \"./is-css-variable\"\n\n/**\n * Parse Framer's special CSS variable format into a CSS token and a fallback.\n *\n * ```\n * `var(--foo, #fff)` => [`--foo`, '#fff']\n * ```\n *\n * @param current\n */\n\nconst splitCSSVariableRegex =\n // eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words\n /^var\\(--(?:([\\w-]+)|([\\w-]+), ?([a-zA-Z\\d ()%#.,-]+))\\)/u\nexport function parseCSSVariable(current: string) {\n const match = splitCSSVariableRegex.exec(current)\n if (!match) return [,]\n\n const [, token1, token2, fallback] = match\n return [`--${token1 ?? token2}`, fallback]\n}\n\nconst maxDepth = 4\nexport function getVariableValue(\n current: CSSVariableToken,\n element: Element,\n depth = 1\n): AnyResolvedKeyframe | undefined {\n invariant(\n depth <= maxDepth,\n `Max CSS variable fallback depth detected in property \"${current}\". This may indicate a circular fallback dependency.`,\n \"max-css-var-depth\"\n )\n\n const [token, fallback] = parseCSSVariable(current)\n\n // No CSS variable detected\n if (!token) return\n\n // Attempt to read this CSS variable off the element\n const resolved = window.getComputedStyle(element).getPropertyValue(token)\n\n if (resolved) {\n const trimmed = resolved.trim()\n return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed\n }\n\n return isCSSVariableToken(fallback)\n ? getVariableValue(fallback, element, depth + 1)\n : fallback\n}\n", "import { transformProps } from \"../../render/utils/keys-transform\"\nimport type { ValueAnimationOptions } from \"../types\"\n\nconst underDampedSpring: Partial = {\n type: \"spring\",\n stiffness: 500,\n damping: 25,\n restSpeed: 10,\n}\n\nconst criticallyDampedSpring = (\n target: unknown\n): Partial => ({\n type: \"spring\",\n stiffness: 550,\n damping: target === 0 ? 2 * Math.sqrt(550) : 30,\n restSpeed: 10,\n})\n\nconst keyframesTransition: Partial = {\n type: \"keyframes\",\n duration: 0.8,\n}\n\n/**\n * Default easing curve is a slightly shallower version of\n * the default browser easing curve.\n */\nconst ease: Partial = {\n type: \"keyframes\",\n ease: [0.25, 0.1, 0.35, 1],\n duration: 0.3,\n}\n\nexport const getDefaultTransition = (\n valueKey: string,\n { keyframes }: ValueAnimationOptions\n): Partial => {\n if (keyframes.length > 2) {\n return keyframesTransition\n } else if (transformProps.has(valueKey)) {\n return valueKey.startsWith(\"scale\")\n ? criticallyDampedSpring(keyframes[1])\n : underDampedSpring\n }\n\n return ease\n}\n", "/**\n * If `transition` has `inherit: true`, shallow-merge it with\n * `parentTransition` (child keys win) and strip the `inherit` key.\n * Otherwise return `transition` unchanged.\n */\nexport function resolveTransition(\n transition: any,\n parentTransition?: any\n) {\n if (transition?.inherit && parentTransition) {\n const { inherit: _, ...rest } = transition\n return { ...parentTransition, ...rest }\n }\n\n return transition\n}\n", "import { resolveTransition } from \"./resolve-transition\"\n\nexport function getValueTransition(transition: any, key: string) {\n const valueTransition =\n transition?.[key as keyof typeof transition] ??\n transition?.[\"default\"] ??\n transition\n\n if (valueTransition !== transition) {\n return resolveTransition(valueTransition, transition)\n }\n\n return valueTransition\n}\n", "import type { AnyResolvedKeyframe } from \"../types\"\nimport type { Transition } from \"../types\"\n\nconst orchestrationKeys = new Set([\n \"when\",\n \"delay\",\n \"delayChildren\",\n \"staggerChildren\",\n \"staggerDirection\",\n \"repeat\",\n \"repeatType\",\n \"repeatDelay\",\n \"from\",\n \"elapsed\",\n])\n\n/**\n * Decide whether a transition is defined on a given Transition.\n * This filters out orchestration options and returns true\n * if any options are left.\n */\nexport function isTransitionDefined(\n transition: Transition & { elapsed?: number; from?: AnyResolvedKeyframe }\n) {\n for (const key in transition) {\n if (!orchestrationKeys.has(key)) return true\n }\n return false\n}\n", "import { MotionGlobalConfig, secondsToMilliseconds } from \"motion-utils\"\nimport { AsyncMotionValueAnimation } from \"../AsyncMotionValueAnimation\"\nimport { JSAnimation } from \"../JSAnimation\"\nimport type {\n AnyResolvedKeyframe,\n ValueAnimationOptions,\n ValueTransition,\n} from \"../types\"\nimport type { UnresolvedKeyframes } from \"../keyframes/KeyframesResolver\"\nimport { getValueTransition } from \"../utils/get-value-transition\"\nimport { makeAnimationInstant } from \"../utils/make-animation-instant\"\nimport { getDefaultTransition } from \"../utils/default-transitions\"\nimport { getFinalKeyframe } from \"../keyframes/get-final\"\nimport { isTransitionDefined } from \"../utils/is-transition-defined\"\nimport { frame } from \"../../frameloop\"\nimport type { MotionValue, StartAnimation } from \"../../value\"\nimport type { VisualElement } from \"../../render/VisualElement\"\n\nexport const animateMotionValue =\n (\n name: string,\n value: MotionValue,\n target: V | UnresolvedKeyframes,\n transition: ValueTransition & { elapsed?: number } = {},\n element?: VisualElement,\n isHandoff?: boolean\n ): StartAnimation =>\n (onComplete) => {\n const valueTransition = getValueTransition(transition, name) || {}\n\n /**\n * Most transition values are currently completely overwritten by value-specific\n * transitions. In the future it'd be nicer to blend these transitions. But for now\n * delay actually does inherit from the root transition if not value-specific.\n */\n const delay = valueTransition.delay || transition.delay || 0\n\n /**\n * Elapsed isn't a public transition option but can be passed through from\n * optimized appear effects in milliseconds.\n */\n let { elapsed = 0 } = transition\n elapsed = elapsed - secondsToMilliseconds(delay)\n\n const options: ValueAnimationOptions = {\n keyframes: Array.isArray(target) ? target : [null, target],\n ease: \"easeOut\",\n velocity: value.getVelocity(),\n ...valueTransition,\n delay: -elapsed,\n onUpdate: (v) => {\n value.set(v)\n valueTransition.onUpdate && valueTransition.onUpdate(v)\n },\n onComplete: () => {\n onComplete()\n valueTransition.onComplete && valueTransition.onComplete()\n },\n name,\n motionValue: value,\n element: isHandoff ? undefined : element,\n }\n\n /**\n * If there's no transition defined for this value, we can generate\n * unique transition settings for this value.\n */\n if (!isTransitionDefined(valueTransition)) {\n Object.assign(options, getDefaultTransition(name, options))\n }\n\n /**\n * Both WAAPI and our internal animation functions use durations\n * as defined by milliseconds, while our external API defines them\n * as seconds.\n */\n options.duration &&= secondsToMilliseconds(options.duration)\n options.repeatDelay &&= secondsToMilliseconds(options.repeatDelay)\n\n /**\n * Support deprecated way to set initial value. Prefer keyframe syntax.\n */\n if (options.from !== undefined) {\n options.keyframes[0] = options.from as any\n }\n\n let shouldSkip = false\n\n if (\n (options as any).type === false ||\n (options.duration === 0 && !options.repeatDelay)\n ) {\n makeAnimationInstant(options)\n\n if (options.delay === 0) {\n shouldSkip = true\n }\n }\n\n if (\n MotionGlobalConfig.instantAnimations ||\n MotionGlobalConfig.skipAnimations ||\n element?.shouldSkipAnimations\n ) {\n shouldSkip = true\n makeAnimationInstant(options)\n options.delay = 0\n }\n\n /**\n * If the transition type or easing has been explicitly set by the user\n * then we don't want to allow flattening the animation.\n */\n options.allowFlatten = !valueTransition.type && !valueTransition.ease\n\n /**\n * If we can or must skip creating the animation, and apply only\n * the final keyframe, do so. We also check once keyframes are resolved but\n * this early check prevents the need to create an animation at all.\n */\n if (shouldSkip && !isHandoff && value.get() !== undefined) {\n const finalKeyframe = getFinalKeyframe(\n options.keyframes as V[],\n valueTransition\n )\n\n if (finalKeyframe !== undefined) {\n frame.update(() => {\n options.onUpdate!(finalKeyframe)\n options.onComplete!()\n })\n\n return\n }\n }\n\n return valueTransition.isSync\n ? new JSAnimation(options)\n : new AsyncMotionValueAnimation(options)\n }\n", "import type {\n AnimationDefinition,\n MotionNodeOptions,\n TargetAndTransition,\n TargetResolver,\n} from \"../../node/types\"\nimport type { ResolvedValues } from \"../types\"\n\nfunction getValueState(visualElement?: any): [ResolvedValues, ResolvedValues] {\n const state: [ResolvedValues, ResolvedValues] = [{}, {}]\n\n visualElement?.values.forEach((value: any, key: string) => {\n state[0][key] = value.get()\n state[1][key] = value.getVelocity()\n })\n\n return state\n}\n\nexport function resolveVariantFromProps(\n props: MotionNodeOptions,\n definition: TargetAndTransition | TargetResolver,\n custom?: any,\n visualElement?: any\n): TargetAndTransition\nexport function resolveVariantFromProps(\n props: MotionNodeOptions,\n definition?: AnimationDefinition,\n custom?: any,\n visualElement?: any\n): undefined | TargetAndTransition\nexport function resolveVariantFromProps(\n props: MotionNodeOptions,\n definition?: AnimationDefinition,\n custom?: any,\n visualElement?: any\n) {\n /**\n * If the variant definition is a function, resolve.\n */\n if (typeof definition === \"function\") {\n const [current, velocity] = getValueState(visualElement)\n definition = definition(\n custom !== undefined ? custom : props.custom,\n current,\n velocity\n )\n }\n\n /**\n * If the variant definition is a variant label, or\n * the function returned a variant label, resolve.\n */\n if (typeof definition === \"string\") {\n definition = props.variants && props.variants[definition]\n }\n\n /**\n * At this point we've resolved both functions and variant labels,\n * but the resolved variant label might itself have been a function.\n * If so, resolve. This can only have returned a valid target object.\n */\n if (typeof definition === \"function\") {\n const [current, velocity] = getValueState(visualElement)\n definition = definition(\n custom !== undefined ? custom : props.custom,\n current,\n velocity\n )\n }\n\n return definition\n}\n", "import type {\n AnimationDefinition,\n TargetAndTransition,\n TargetResolver,\n} from \"../../node/types\"\nimport { resolveVariantFromProps } from \"./resolve-variants\"\n\n/**\n * Resolves a variant if it's a variant resolver.\n * Uses `any` type for visualElement to avoid circular dependencies.\n */\nexport function resolveVariant(\n visualElement: any,\n definition?: TargetAndTransition | TargetResolver,\n custom?: any\n): TargetAndTransition\nexport function resolveVariant(\n visualElement: any,\n definition?: AnimationDefinition,\n custom?: any\n): TargetAndTransition | undefined\nexport function resolveVariant(\n visualElement: any,\n definition?: AnimationDefinition,\n custom?: any\n) {\n const props = visualElement.getProps()\n return resolveVariantFromProps(\n props,\n definition,\n custom !== undefined ? custom : props.custom,\n visualElement\n )\n}\n", "import { transformPropOrder } from \"./keys-transform\"\n\nexport const positionalKeys = new Set([\n \"width\",\n \"height\",\n \"top\",\n \"left\",\n \"right\",\n \"bottom\",\n ...transformPropOrder,\n])\n", "import {\n EasingFunction,\n SubscriptionManager,\n velocityPerSecond,\n warnOnce,\n} from \"motion-utils\"\nimport {\n AnimationPlaybackControlsWithThen,\n AnyResolvedKeyframe,\n TransformProperties,\n} from \"../animation/types\"\nimport { frame } from \"../frameloop\"\nimport { time } from \"../frameloop/sync-time\"\n\n/**\n * @public\n */\nexport type Subscriber = (v: T) => void\n\n/**\n * @public\n */\nexport type PassiveEffect = (v: T, safeSetter: (v: T) => void) => void\n\nexport type StartAnimation = (\n complete: () => void\n) => AnimationPlaybackControlsWithThen | undefined\n\nexport interface MotionValueEventCallbacks {\n animationStart: () => void\n animationComplete: () => void\n animationCancel: () => void\n change: (latestValue: V) => void\n destroy: () => void\n}\n\n/**\n * Maximum time between the value of two frames, beyond which we\n * assume the velocity has since been 0.\n */\nconst MAX_VELOCITY_DELTA = 30\n\nconst isFloat = (value: any): value is string => {\n return !isNaN(parseFloat(value))\n}\n\ninterface ResolvedValues {\n [key: string]: AnyResolvedKeyframe\n}\n\nexport interface Owner {\n current: HTMLElement | unknown\n getProps: () => {\n onUpdate?: (latest: ResolvedValues) => void\n transformTemplate?: (\n transform: TransformProperties,\n generatedTransform: string\n ) => string\n }\n}\n\nexport interface AccelerateConfig {\n factory: (animation: AnimationPlaybackControlsWithThen) => VoidFunction\n times: number[]\n keyframes: any[]\n ease?: EasingFunction | EasingFunction[]\n duration: number\n isTransformed?: boolean\n}\n\nexport interface MotionValueOptions {\n owner?: Owner\n}\n\nexport const collectMotionValues: { current: MotionValue[] | undefined } = {\n current: undefined,\n}\n\n/**\n * `MotionValue` is used to track the state and velocity of motion values.\n *\n * @public\n */\nexport class MotionValue {\n /**\n * If a MotionValue has an owner, it was created internally within Motion\n * and therefore has no external listeners. It is therefore safe to animate via WAAPI.\n */\n owner?: Owner\n\n /**\n * The current state of the `MotionValue`.\n */\n private current: V | undefined\n\n /**\n * The previous state of the `MotionValue`.\n */\n private prev: V | undefined\n\n /**\n * The previous state of the `MotionValue` at the end of the previous frame.\n */\n private prevFrameValue: V | undefined\n\n /**\n * The last time the `MotionValue` was updated.\n */\n updatedAt: number\n\n /**\n * The time `prevFrameValue` was updated.\n */\n prevUpdatedAt: number | undefined\n\n /**\n * Add a passive effect to this `MotionValue`.\n *\n * A passive effect intercepts calls to `set`. For instance, `useSpring` adds\n * a passive effect that attaches a `spring` to the latest\n * set value. Hypothetically there could be a `useSmooth` that attaches an input smoothing effect.\n *\n * @internal\n */\n private passiveEffect?: PassiveEffect\n private stopPassiveEffect?: VoidFunction\n\n /**\n * Whether the passive effect is active.\n */\n isEffectActive?: boolean\n\n /**\n * A reference to the currently-controlling animation.\n */\n animation?: AnimationPlaybackControlsWithThen\n\n /**\n * Tracks whether this value can output a velocity. Currently this is only true\n * if the value is numerical, but we might be able to widen the scope here and support\n * other value types.\n *\n * @internal\n */\n private canTrackVelocity: boolean | null = null\n\n /**\n * A list of MotionValues whose values are computed from this one.\n * This is a rough start to a proper signal-like dirtying system.\n */\n private dependents: Set | undefined\n\n /**\n * Tracks whether this value should be removed\n */\n liveStyle?: boolean\n\n /**\n * Scroll timeline acceleration metadata. When set, VisualElement\n * can create a native WAAPI animation attached to a scroll timeline\n * instead of driving updates through JS.\n */\n accelerate?: AccelerateConfig\n\n /**\n * @param init - The initiating value\n * @param config - Optional configuration options\n *\n * - `transformer`: A function to transform incoming values with.\n */\n constructor(init: V, options: MotionValueOptions = {}) {\n this.setCurrent(init)\n this.owner = options.owner\n }\n\n setCurrent(current: V) {\n this.current = current\n this.updatedAt = time.now()\n\n if (this.canTrackVelocity === null && current !== undefined) {\n this.canTrackVelocity = isFloat(this.current)\n }\n }\n\n setPrevFrameValue(prevFrameValue: V | undefined = this.current) {\n this.prevFrameValue = prevFrameValue\n this.prevUpdatedAt = this.updatedAt\n }\n\n /**\n * Adds a function that will be notified when the `MotionValue` is updated.\n *\n * It returns a function that, when called, will cancel the subscription.\n *\n * When calling `onChange` inside a React component, it should be wrapped with the\n * `useEffect` hook. As it returns an unsubscribe function, this should be returned\n * from the `useEffect` function to ensure you don't add duplicate subscribers..\n *\n * ```jsx\n * export const MyComponent = () => {\n * const x = useMotionValue(0)\n * const y = useMotionValue(0)\n * const opacity = useMotionValue(1)\n *\n * useEffect(() => {\n * function updateOpacity() {\n * const maxXY = Math.max(x.get(), y.get())\n * const newOpacity = transform(maxXY, [0, 100], [1, 0])\n * opacity.set(newOpacity)\n * }\n *\n * const unsubscribeX = x.on(\"change\", updateOpacity)\n * const unsubscribeY = y.on(\"change\", updateOpacity)\n *\n * return () => {\n * unsubscribeX()\n * unsubscribeY()\n * }\n * }, [])\n *\n * return \n * }\n * ```\n *\n * @param subscriber - A function that receives the latest value.\n * @returns A function that, when called, will cancel this subscription.\n *\n * @deprecated\n */\n onChange(subscription: Subscriber): () => void {\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n false,\n `value.onChange(callback) is deprecated. Switch to value.on(\"change\", callback).`\n )\n }\n return this.on(\"change\", subscription)\n }\n\n /**\n * An object containing a SubscriptionManager for each active event.\n */\n private events: {\n [key: string]: SubscriptionManager\n } = {}\n\n on>(\n eventName: EventName,\n callback: MotionValueEventCallbacks[EventName]\n ) {\n if (!this.events[eventName]) {\n this.events[eventName] = new SubscriptionManager()\n }\n\n const unsubscribe = this.events[eventName].add(callback)\n\n if (eventName === \"change\") {\n return () => {\n unsubscribe()\n\n /**\n * If we have no more change listeners by the start\n * of the next frame, stop active animations.\n */\n frame.read(() => {\n if (!this.events.change.getSize()) {\n this.stop()\n }\n })\n }\n }\n\n return unsubscribe\n }\n\n clearListeners() {\n for (const eventManagers in this.events) {\n this.events[eventManagers].clear()\n }\n }\n\n /**\n * Attaches a passive effect to the `MotionValue`.\n */\n attach(passiveEffect: PassiveEffect, stopPassiveEffect: VoidFunction) {\n this.passiveEffect = passiveEffect\n this.stopPassiveEffect = stopPassiveEffect\n }\n\n /**\n * Sets the state of the `MotionValue`.\n *\n * @remarks\n *\n * ```jsx\n * const x = useMotionValue(0)\n * x.set(10)\n * ```\n *\n * @param latest - Latest value to set.\n * @param render - Whether to notify render subscribers. Defaults to `true`\n *\n * @public\n */\n set(v: V) {\n if (!this.passiveEffect) {\n this.updateAndNotify(v)\n } else {\n this.passiveEffect(v, this.updateAndNotify)\n }\n }\n\n setWithVelocity(prev: V, current: V, delta: number) {\n this.set(current)\n this.prev = undefined\n this.prevFrameValue = prev\n this.prevUpdatedAt = this.updatedAt - delta\n }\n\n /**\n * Set the state of the `MotionValue`, stopping any active animations,\n * effects, and resets velocity to `0`.\n */\n jump(v: V, endAnimation = true) {\n this.updateAndNotify(v)\n this.prev = v\n this.prevUpdatedAt = this.prevFrameValue = undefined\n endAnimation && this.stop()\n if (this.stopPassiveEffect) this.stopPassiveEffect()\n }\n\n dirty() {\n this.events.change?.notify(this.current)\n }\n\n addDependent(dependent: MotionValue) {\n if (!this.dependents) {\n this.dependents = new Set()\n }\n this.dependents.add(dependent)\n }\n\n removeDependent(dependent: MotionValue) {\n if (this.dependents) {\n this.dependents.delete(dependent)\n }\n }\n\n updateAndNotify = (v: V) => {\n const currentTime = time.now()\n\n /**\n * If we're updating the value during another frame or eventloop\n * than the previous frame, then the we set the previous frame value\n * to current.\n */\n if (this.updatedAt !== currentTime) {\n this.setPrevFrameValue()\n }\n\n this.prev = this.current\n\n this.setCurrent(v)\n\n // Update update subscribers\n if (this.current !== this.prev) {\n this.events.change?.notify(this.current)\n\n if (this.dependents) {\n for (const dependent of this.dependents) {\n dependent.dirty()\n }\n }\n }\n }\n\n /**\n * Returns the latest state of `MotionValue`\n *\n * @returns - The latest state of `MotionValue`\n *\n * @public\n */\n get() {\n if (collectMotionValues.current) {\n collectMotionValues.current.push(this)\n }\n\n return this.current!\n }\n\n /**\n * @public\n */\n getPrevious() {\n return this.prev\n }\n\n /**\n * Returns the latest velocity of `MotionValue`\n *\n * @returns - The latest velocity of `MotionValue`. Returns `0` if the state is non-numerical.\n *\n * @public\n */\n getVelocity() {\n const currentTime = time.now()\n\n if (\n !this.canTrackVelocity ||\n this.prevFrameValue === undefined ||\n currentTime - this.updatedAt > MAX_VELOCITY_DELTA\n ) {\n return 0\n }\n\n const delta = Math.min(\n this.updatedAt - this.prevUpdatedAt!,\n MAX_VELOCITY_DELTA\n )\n\n // Casts because of parseFloat's poor typing\n return velocityPerSecond(\n parseFloat(this.current as any) -\n parseFloat(this.prevFrameValue as any),\n delta\n )\n }\n\n hasAnimated = false\n\n /**\n * Registers a new animation to control this `MotionValue`. Only one\n * animation can drive a `MotionValue` at one time.\n *\n * ```jsx\n * value.start()\n * ```\n *\n * @param animation - A function that starts the provided animation\n */\n start(startAnimation: StartAnimation) {\n this.stop()\n\n return new Promise((resolve) => {\n this.hasAnimated = true\n this.animation = startAnimation(resolve)\n\n if (this.events.animationStart) {\n this.events.animationStart.notify()\n }\n }).then(() => {\n if (this.events.animationComplete) {\n this.events.animationComplete.notify()\n }\n this.clearAnimation()\n })\n }\n\n /**\n * Stop the currently active animation.\n *\n * @public\n */\n stop() {\n if (this.animation) {\n this.animation.stop()\n if (this.events.animationCancel) {\n this.events.animationCancel.notify()\n }\n }\n this.clearAnimation()\n }\n\n /**\n * Returns `true` if this value is currently animating.\n *\n * @public\n */\n isAnimating() {\n return !!this.animation\n }\n\n private clearAnimation() {\n delete this.animation\n }\n\n /**\n * Destroy and clean up subscribers to this `MotionValue`.\n *\n * The `MotionValue` hooks like `useMotionValue` and `useTransform` automatically\n * handle the lifecycle of the returned `MotionValue`, so this method is only necessary if you've manually\n * created a `MotionValue` via the `motionValue` function.\n *\n * @public\n */\n destroy() {\n this.dependents?.clear()\n this.events.destroy?.notify()\n this.clearListeners()\n this.stop()\n\n if (this.stopPassiveEffect) {\n this.stopPassiveEffect()\n }\n }\n}\n\nexport function motionValue(init: V, options?: MotionValueOptions) {\n return new MotionValue(init, options)\n}\n", "import type { UnresolvedValueKeyframe, ValueKeyframesDefinition } from \"../../animation/types\"\n\nexport const isKeyframesTarget = (\n v: ValueKeyframesDefinition\n): v is UnresolvedValueKeyframe[] => {\n return Array.isArray(v)\n}\n", "import { motionValue } from \"../../value\"\nimport { resolveVariant } from \"./resolve-dynamic-variants\"\nimport { isKeyframesTarget } from \"./is-keyframes-target\"\nimport type { AnimationDefinition } from \"../../node/types\"\nimport type {\n AnyResolvedKeyframe,\n UnresolvedValueKeyframe,\n ValueKeyframesDefinition,\n} from \"../../animation/types\"\nimport type { VisualElement } from \"../VisualElement\"\n\n/**\n * Set VisualElement's MotionValue, creating a new MotionValue for it if\n * it doesn't exist.\n */\nfunction setMotionValue(\n visualElement: VisualElement,\n key: string,\n value: AnyResolvedKeyframe\n) {\n if (visualElement.hasValue(key)) {\n visualElement.getValue(key)!.set(value)\n } else {\n visualElement.addValue(key, motionValue(value))\n }\n}\n\nfunction resolveFinalValueInKeyframes(\n v: ValueKeyframesDefinition\n): UnresolvedValueKeyframe {\n // TODO maybe throw if v.length - 1 is placeholder token?\n return isKeyframesTarget(v) ? v[v.length - 1] || 0 : v\n}\n\nexport function setTarget(\n visualElement: VisualElement,\n definition: AnimationDefinition\n) {\n const resolved = resolveVariant(visualElement, definition)\n let { transitionEnd = {}, transition = {}, ...target } = resolved || {}\n\n target = { ...target, ...transitionEnd }\n\n for (const key in target) {\n const value = resolveFinalValueInKeyframes(\n target[key as keyof typeof target] as any\n )\n setMotionValue(visualElement, key, value as AnyResolvedKeyframe)\n }\n}\n", "import type { MotionValue } from \"..\"\n\nexport const isMotionValue = (value: any): value is MotionValue =>\n Boolean(value && value.getVelocity)\n", "import { isMotionValue } from \"../utils/is-motion-value\"\nimport type { WillChange } from \"./types\"\n\nexport function isWillChangeMotionValue(value: any): value is WillChange {\n return Boolean(isMotionValue(value) && (value as WillChange).add)\n}\n", "import { MotionGlobalConfig } from \"motion-utils\"\nimport type { VisualElement } from \"../../render/VisualElement\"\nimport { isWillChangeMotionValue } from \"./is\"\n\nexport function addValueToWillChange(\n visualElement: VisualElement,\n key: string\n) {\n const willChange = visualElement.getValue(\"willChange\")\n\n /**\n * It could be that a user has set willChange to a regular MotionValue,\n * in which case we can't add the value to it.\n */\n if (isWillChangeMotionValue(willChange)) {\n return willChange.add(key)\n } else if (!willChange && MotionGlobalConfig.WillChange) {\n const newWillChange = new MotionGlobalConfig.WillChange(\"auto\")\n\n visualElement.addValue(\"willChange\", newWillChange)\n newWillChange.add(key)\n }\n}\n", "export function camelToDash(str: string): string {\n return str.replace(/([A-Z])/g, (match) => `-${match.toLowerCase()}`)\n}\n", "import { camelToDash } from \"../../render/dom/utils/camel-to-dash\"\n\nexport const optimizedAppearDataId = \"framerAppearId\"\n\nexport const optimizedAppearDataAttribute =\n \"data-\" + camelToDash(optimizedAppearDataId) as \"data-framer-appear-id\"\n", "import { optimizedAppearDataAttribute } from \"./data-id\"\nimport type { WithAppearProps } from \"./types\"\n\nexport function getOptimisedAppearId(\n visualElement: WithAppearProps\n): string | undefined {\n return visualElement.props[optimizedAppearDataAttribute]\n}\n", "import { frame } from \"../../frameloop\"\nimport { getValueTransition } from \"../utils/get-value-transition\"\nimport { resolveTransition } from \"../utils/resolve-transition\"\nimport { positionalKeys } from \"../../render/utils/keys-position\"\nimport { setTarget } from \"../../render/utils/setters\"\nimport { addValueToWillChange } from \"../../value/will-change/add-will-change\"\nimport { getOptimisedAppearId } from \"../optimized-appear/get-appear-id\"\nimport { animateMotionValue } from \"./motion-value\"\nimport type { VisualElementAnimationOptions } from \"./types\"\nimport type { AnimationPlaybackControlsWithThen } from \"../types\"\nimport type { TargetAndTransition } from \"../../node/types\"\nimport type { AnimationTypeState } from \"../../render/utils/animation-state\"\nimport type { VisualElement } from \"../../render/VisualElement\"\n\n/**\n * Decide whether we should block this animation. Previously, we achieved this\n * just by checking whether the key was listed in protectedKeys, but this\n * posed problems if an animation was triggered by afterChildren and protectedKeys\n * had been set to true in the meantime.\n */\nfunction shouldBlockAnimation(\n { protectedKeys, needsAnimating }: AnimationTypeState,\n key: string\n) {\n const shouldBlock =\n protectedKeys.hasOwnProperty(key) && needsAnimating[key] !== true\n\n needsAnimating[key] = false\n return shouldBlock\n}\n\nexport function animateTarget(\n visualElement: VisualElement,\n targetAndTransition: TargetAndTransition,\n { delay = 0, transitionOverride, type }: VisualElementAnimationOptions = {}\n): AnimationPlaybackControlsWithThen[] {\n let {\n transition,\n transitionEnd,\n ...target\n } = targetAndTransition\n\n const defaultTransition = visualElement.getDefaultTransition()\n transition = transition\n ? resolveTransition(transition, defaultTransition)\n : defaultTransition\n\n const reduceMotion = (transition as { reduceMotion?: boolean })?.reduceMotion\n\n if (transitionOverride) transition = transitionOverride\n\n const animations: AnimationPlaybackControlsWithThen[] = []\n\n const animationTypeState =\n type &&\n visualElement.animationState &&\n visualElement.animationState.getState()[type]\n\n for (const key in target) {\n const value = visualElement.getValue(\n key,\n visualElement.latestValues[key] ?? null\n )\n const valueTarget = target[key as keyof typeof target]\n\n if (\n valueTarget === undefined ||\n (animationTypeState &&\n shouldBlockAnimation(animationTypeState, key))\n ) {\n continue\n }\n\n const valueTransition = {\n delay,\n ...getValueTransition(transition || {}, key),\n }\n\n /**\n * If the value is already at the defined target, skip the animation.\n * We still re-assert the value via frame.update to take precedence\n * over any stale transitionEnd callbacks from previous animations.\n */\n const currentValue = value.get()\n if (\n currentValue !== undefined &&\n !value.isAnimating() &&\n !Array.isArray(valueTarget) &&\n valueTarget === currentValue &&\n !valueTransition.velocity\n ) {\n frame.update(() => value.set(valueTarget as any))\n continue\n }\n\n /**\n * If this is the first time a value is being animated, check\n * to see if we're handling off from an existing animation.\n */\n let isHandoff = false\n if (window.MotionHandoffAnimation) {\n const appearId = getOptimisedAppearId(visualElement)\n\n if (appearId) {\n const startTime = window.MotionHandoffAnimation(\n appearId,\n key,\n frame\n )\n\n if (startTime !== null) {\n valueTransition.startTime = startTime\n isHandoff = true\n }\n }\n }\n\n addValueToWillChange(visualElement, key)\n\n const shouldReduceMotion =\n reduceMotion ?? visualElement.shouldReduceMotion\n\n value.start(\n animateMotionValue(\n key,\n value,\n valueTarget,\n shouldReduceMotion && positionalKeys.has(key)\n ? { type: false }\n : valueTransition,\n visualElement,\n isHandoff\n )\n )\n\n const animation = value.animation\n\n if (animation) {\n animations.push(animation)\n }\n }\n\n if (transitionEnd) {\n const applyTransitionEnd = () =>\n frame.update(() => {\n transitionEnd && setTarget(visualElement, transitionEnd)\n })\n\n if (animations.length) {\n Promise.all(animations).then(applyTransitionEnd)\n } else {\n applyTransitionEnd()\n }\n }\n\n return animations\n}\n", "import { resolveVariant } from \"../../render/utils/resolve-dynamic-variants\"\nimport { calcChildStagger } from \"../utils/calc-child-stagger\"\nimport type { VisualElementAnimationOptions } from \"./types\"\nimport { animateTarget } from \"./visual-element-target\"\nimport type { DynamicOption } from \"../types\"\nimport type { VisualElement } from \"../../render/VisualElement\"\n\nexport function animateVariant(\n visualElement: VisualElement,\n variant: string,\n options: VisualElementAnimationOptions = {}\n): Promise {\n const resolved = resolveVariant(\n visualElement,\n variant,\n options.type === \"exit\"\n ? visualElement.presenceContext?.custom\n : undefined\n )\n\n let { transition = visualElement.getDefaultTransition() || {} } =\n resolved || {}\n\n if (options.transitionOverride) {\n transition = options.transitionOverride\n }\n\n /**\n * If we have a variant, create a callback that runs it as an animation.\n * Otherwise, we resolve a Promise immediately for a composable no-op.\n */\n const getAnimation: () => Promise = resolved\n ? () => Promise.all(animateTarget(visualElement, resolved, options))\n : () => Promise.resolve()\n\n /**\n * If we have children, create a callback that runs all their animations.\n * Otherwise, we resolve a Promise immediately for a composable no-op.\n */\n const getChildAnimations =\n visualElement.variantChildren && visualElement.variantChildren.size\n ? (forwardDelay = 0) => {\n const {\n delayChildren = 0,\n staggerChildren,\n staggerDirection,\n } = transition\n\n return animateChildren(\n visualElement,\n variant,\n forwardDelay,\n delayChildren,\n staggerChildren,\n staggerDirection,\n options\n )\n }\n : () => Promise.resolve()\n\n /**\n * If the transition explicitly defines a \"when\" option, we need to resolve either\n * this animation or all children animations before playing the other.\n */\n const { when } = transition\n if (when) {\n const [first, last] =\n when === \"beforeChildren\"\n ? [getAnimation, getChildAnimations]\n : [getChildAnimations, getAnimation]\n\n return first().then(() => last())\n } else {\n return Promise.all([getAnimation(), getChildAnimations(options.delay)])\n }\n}\n\nfunction animateChildren(\n visualElement: VisualElement,\n variant: string,\n delay: number = 0,\n delayChildren: number | DynamicOption = 0,\n staggerChildren = 0,\n staggerDirection = 1,\n options: VisualElementAnimationOptions\n) {\n const animations: Promise[] = []\n\n for (const child of visualElement.variantChildren!) {\n child.notify(\"AnimationStart\", variant)\n animations.push(\n animateVariant(child, variant, {\n ...options,\n delay:\n delay +\n (typeof delayChildren === \"function\" ? 0 : delayChildren) +\n calcChildStagger(\n visualElement.variantChildren!,\n child,\n delayChildren,\n staggerChildren,\n staggerDirection\n ),\n }).then(() => child.notify(\"AnimationComplete\", variant))\n )\n }\n\n return Promise.all(animations)\n}\n", "import { resolveVariant } from \"../../render/utils/resolve-dynamic-variants\"\nimport type { AnimationDefinition } from \"../../node/types\"\nimport type { VisualElement } from \"../../render/VisualElement\"\nimport type { VisualElementAnimationOptions } from \"./types\"\nimport { animateTarget } from \"./visual-element-target\"\nimport { animateVariant } from \"./visual-element-variant\"\n\nexport function animateVisualElement(\n visualElement: VisualElement,\n definition: AnimationDefinition,\n options: VisualElementAnimationOptions = {}\n) {\n visualElement.notify(\"AnimationStart\", definition)\n let animation: Promise\n\n if (Array.isArray(definition)) {\n const animations = definition.map((variant) =>\n animateVariant(visualElement, variant, options)\n )\n animation = Promise.all(animations)\n } else if (typeof definition === \"string\") {\n animation = animateVariant(visualElement, definition, options)\n } else {\n const resolvedDefinition =\n typeof definition === \"function\"\n ? resolveVariant(visualElement, definition, options.custom)\n : definition\n\n animation = Promise.all(\n animateTarget(visualElement, resolvedDefinition, options)\n )\n }\n\n return animation.then(() => {\n visualElement.notify(\"AnimationComplete\", definition)\n })\n}\n", "import { ValueType } from \"./types\"\n\n/**\n * ValueType for \"auto\"\n */\nexport const auto: ValueType = {\n test: (v: any) => v === \"auto\",\n parse: (v) => v,\n}\n", "import { ValueType } from \"./types\"\n\n/**\n * Tests a provided value against a ValueType\n */\nexport const testValueType = (v: any) => (type: ValueType) => type.test(v)\n", "import { auto } from \"./auto\"\nimport { number } from \"./numbers\"\nimport { degrees, percent, px, vh, vw } from \"./numbers/units\"\nimport { testValueType } from \"./test\"\n\n/**\n * A list of value types commonly used for dimensions\n */\nexport const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto]\n\n/**\n * Tests a dimensional value against the list of dimension ValueTypes\n */\nexport const findDimensionValueType = (v: any) =>\n dimensionValueTypes.find(testValueType(v))\n", "import { isZeroValueString } from \"motion-utils\"\nimport { AnyResolvedKeyframe } from \"../../types\"\n\nexport function isNone(value: AnyResolvedKeyframe | null) {\n if (typeof value === \"number\") {\n return value === 0\n } else if (value !== null) {\n return value === \"none\" || value === \"0\" || isZeroValueString(value)\n } else {\n return true\n }\n}\n", "import { complex } from \".\"\nimport { floatRegex } from \"../utils/float-regex\"\n\n/**\n * Properties that should default to 1 or 100%\n */\nconst maxDefaults = new Set([\"brightness\", \"contrast\", \"saturate\", \"opacity\"])\n\nfunction applyDefaultFilter(v: string) {\n const [name, value] = v.slice(0, -1).split(\"(\")\n\n if (name === \"drop-shadow\") return v\n\n const [number] = value.match(floatRegex) || []\n if (!number) return v\n\n const unit = value.replace(number, \"\")\n let defaultValue = maxDefaults.has(name) ? 1 : 0\n if (number !== value) defaultValue *= 100\n\n return name + \"(\" + defaultValue + unit + \")\"\n}\n\nconst functionRegex = /\\b([a-z-]*)\\(.*?\\)/gu\n\nexport const filter = {\n ...complex,\n getAnimatableNone: (v: string) => {\n const functions = v.match(functionRegex)\n return functions ? functions.map(applyDefaultFilter).join(\" \") : v\n },\n}\n", "import { complex } from \".\"\nimport { AnyResolvedKeyframe } from \"../../../animation/types\"\n\nexport const mask = {\n ...complex,\n getAnimatableNone: (v: AnyResolvedKeyframe) => {\n const parsed = complex.parse(v)\n const transformer = complex.createTransformer(v)\n return transformer(\n parsed.map((v) =>\n typeof v === \"number\" ? 0 : typeof v === \"object\" ? { ...v, alpha: 1 } : v\n )\n )\n },\n}\n", "import { number } from \"./numbers\"\n\nexport const int = {\n ...number,\n transform: Math.round,\n}\n", "import { alpha, scale } from \"../numbers\"\nimport { degrees, progressPercentage, px } from \"../numbers/units\"\nimport { ValueTypeMap } from \"./types\"\n\nexport const transformValueTypes: ValueTypeMap = {\n rotate: degrees,\n rotateX: degrees,\n rotateY: degrees,\n rotateZ: degrees,\n scale,\n scaleX: scale,\n scaleY: scale,\n scaleZ: scale,\n skew: degrees,\n skewX: degrees,\n skewY: degrees,\n distance: px,\n translateX: px,\n translateY: px,\n translateZ: px,\n x: px,\n y: px,\n z: px,\n perspective: px,\n transformPerspective: px,\n opacity: alpha,\n originX: progressPercentage,\n originY: progressPercentage,\n originZ: px,\n}\n", "import { int } from \"../int\"\nimport { alpha } from \"../numbers\"\nimport { px } from \"../numbers/units\"\nimport { transformValueTypes } from \"./transform\"\nimport { ValueTypeMap } from \"./types\"\n\nexport const numberValueTypes: ValueTypeMap = {\n // Border props\n borderWidth: px,\n borderTopWidth: px,\n borderRightWidth: px,\n borderBottomWidth: px,\n borderLeftWidth: px,\n borderRadius: px,\n borderTopLeftRadius: px,\n borderTopRightRadius: px,\n borderBottomRightRadius: px,\n borderBottomLeftRadius: px,\n\n // Positioning props\n width: px,\n maxWidth: px,\n height: px,\n maxHeight: px,\n top: px,\n right: px,\n bottom: px,\n left: px,\n inset: px,\n insetBlock: px,\n insetBlockStart: px,\n insetBlockEnd: px,\n insetInline: px,\n insetInlineStart: px,\n insetInlineEnd: px,\n\n // Spacing props\n padding: px,\n paddingTop: px,\n paddingRight: px,\n paddingBottom: px,\n paddingLeft: px,\n paddingBlock: px,\n paddingBlockStart: px,\n paddingBlockEnd: px,\n paddingInline: px,\n paddingInlineStart: px,\n paddingInlineEnd: px,\n margin: px,\n marginTop: px,\n marginRight: px,\n marginBottom: px,\n marginLeft: px,\n marginBlock: px,\n marginBlockStart: px,\n marginBlockEnd: px,\n marginInline: px,\n marginInlineStart: px,\n marginInlineEnd: px,\n\n // Typography\n fontSize: px,\n\n // Misc\n backgroundPositionX: px,\n backgroundPositionY: px,\n\n ...transformValueTypes,\n zIndex: int,\n\n // SVG\n fillOpacity: alpha,\n strokeOpacity: alpha,\n numOctaves: int,\n}\n", "import { color } from \"../color\"\nimport { filter } from \"../complex/filter\"\nimport { mask } from \"../complex/mask\"\nimport { numberValueTypes } from \"./number\"\nimport { ValueTypeMap } from \"./types\"\n\n/**\n * A map of default value types for common values\n */\nexport const defaultValueTypes: ValueTypeMap = {\n ...numberValueTypes,\n\n // Color props\n color,\n backgroundColor: color,\n outlineColor: color,\n fill: color,\n stroke: color,\n\n // Border props\n borderColor: color,\n borderTopColor: color,\n borderRightColor: color,\n borderBottomColor: color,\n borderLeftColor: color,\n filter,\n WebkitFilter: filter,\n mask,\n WebkitMask: mask,\n}\n\n/**\n * Gets the default ValueType for the provided value key\n */\nexport const getDefaultValueType = (key: string) => defaultValueTypes[key]\n", "import { complex } from \"../complex\"\nimport { filter } from \"../complex/filter\"\nimport { mask } from \"../complex/mask\"\nimport { getDefaultValueType } from \"../maps/defaults\"\n\nconst customTypes = /*@__PURE__*/ new Set([filter, mask])\n\nexport function getAnimatableNone(key: string, value: string) {\n let defaultValueType = getDefaultValueType(key)\n if (!customTypes.has(defaultValueType as any)) defaultValueType = complex\n // If value is not recognised as animatable, ie \"none\", create an animatable version origin based on the target\n return defaultValueType.getAnimatableNone\n ? defaultValueType.getAnimatableNone(value)\n : undefined\n}\n", "import { analyseComplexValue } from \"../../../value/types/complex\"\nimport { getAnimatableNone } from \"../../../value/types/utils/animatable-none\"\nimport { AnyResolvedKeyframe } from \"../../types\"\nimport { UnresolvedKeyframes } from \"../KeyframesResolver\"\n\n/**\n * If we encounter keyframes like \"none\" or \"0\" and we also have keyframes like\n * \"#fff\" or \"200px 200px\" we want to find a keyframe to serve as a template for\n * the \"none\" keyframes. In this case \"#fff\" or \"200px 200px\" - then these get turned into\n * zero equivalents, i.e. \"#fff0\" or \"0px 0px\".\n */\nconst invalidTemplates = new Set([\"auto\", \"none\", \"0\"])\n\nexport function makeNoneKeyframesAnimatable(\n unresolvedKeyframes: UnresolvedKeyframes,\n noneKeyframeIndexes: number[],\n name?: string\n) {\n let i = 0\n let animatableTemplate: string | undefined = undefined\n while (i < unresolvedKeyframes.length && !animatableTemplate) {\n const keyframe = unresolvedKeyframes[i]\n if (\n typeof keyframe === \"string\" &&\n !invalidTemplates.has(keyframe) &&\n analyseComplexValue(keyframe).values.length\n ) {\n animatableTemplate = unresolvedKeyframes[i] as string\n }\n i++\n }\n\n if (animatableTemplate && name) {\n for (const noneIndex of noneKeyframeIndexes) {\n unresolvedKeyframes[noneIndex] = getAnimatableNone(\n name,\n animatableTemplate\n )\n }\n }\n}\n", "import { positionalKeys } from \"../../render/utils/keys-position\"\nimport { MotionValue } from \"../../value\"\nimport { findDimensionValueType } from \"../../value/types/dimensions\"\nimport { AnyResolvedKeyframe } from \"../types\"\nimport { getVariableValue } from \"../utils/css-variables-conversion\"\nimport {\n containsCSSVariable,\n isCSSVariableToken,\n} from \"../utils/is-css-variable\"\nimport {\n KeyframeResolver,\n OnKeyframesResolved,\n UnresolvedKeyframes,\n} from \"./KeyframesResolver\"\nimport { WithRender } from \"./types\"\nimport { isNone } from \"./utils/is-none\"\nimport { makeNoneKeyframesAnimatable } from \"./utils/make-none-animatable\"\nimport { isNumOrPxType, positionalValues } from \"./utils/unit-conversion\"\n\nexport class DOMKeyframesResolver<\n T extends AnyResolvedKeyframe\n> extends KeyframeResolver {\n name: string\n element?: WithRender\n\n private removedTransforms?: [string, AnyResolvedKeyframe][]\n private measuredOrigin?: AnyResolvedKeyframe\n\n constructor(\n unresolvedKeyframes: UnresolvedKeyframes,\n onComplete: OnKeyframesResolved,\n name?: string,\n motionValue?: MotionValue,\n element?: WithRender\n ) {\n super(unresolvedKeyframes, onComplete, name, motionValue, element, true)\n }\n\n readKeyframes() {\n const { unresolvedKeyframes, element, name } = this\n\n if (!element || !element.current) return\n\n super.readKeyframes()\n\n /**\n * If any keyframe is a CSS variable, we need to find its value by sampling the element\n */\n for (let i = 0; i < unresolvedKeyframes.length; i++) {\n let keyframe = unresolvedKeyframes[i]\n\n if (typeof keyframe === \"string\") {\n keyframe = keyframe.trim()\n\n if (isCSSVariableToken(keyframe)) {\n const resolved = getVariableValue(keyframe, element.current)\n\n if (resolved !== undefined) {\n unresolvedKeyframes[i] = resolved as T\n }\n\n if (i === unresolvedKeyframes.length - 1) {\n this.finalKeyframe = keyframe as T\n }\n }\n }\n }\n\n /**\n * Resolve \"none\" values. We do this potentially twice - once before and once after measuring keyframes.\n * This could be seen as inefficient but it's a trade-off to avoid measurements in more situations, which\n * have a far bigger performance impact.\n */\n this.resolveNoneKeyframes()\n\n /**\n * Check to see if unit type has changed. If so schedule jobs that will\n * temporarily set styles to the destination keyframes.\n * Skip if we have more than two keyframes or this isn't a positional value.\n * TODO: We can throw if there are multiple keyframes and the value type changes.\n */\n if (!positionalKeys.has(name) || unresolvedKeyframes.length !== 2) {\n return\n }\n\n const [origin, target] = unresolvedKeyframes\n const originType = findDimensionValueType(origin)\n const targetType = findDimensionValueType(target)\n\n /**\n * If one keyframe contains embedded CSS variables (e.g. in calc()) and the other\n * doesn't, we need to measure to convert to pixels. This handles GitHub issue #3410.\n */\n const originHasVar = containsCSSVariable(origin)\n const targetHasVar = containsCSSVariable(target)\n\n if (originHasVar !== targetHasVar && positionalValues[name]) {\n this.needsMeasurement = true\n return\n }\n\n /**\n * Either we don't recognise these value types or we can animate between them.\n */\n if (originType === targetType) return\n\n /**\n * If both values are numbers or pixels, we can animate between them by\n * converting them to numbers.\n */\n if (isNumOrPxType(originType) && isNumOrPxType(targetType)) {\n for (let i = 0; i < unresolvedKeyframes.length; i++) {\n const value = unresolvedKeyframes[i]\n if (typeof value === \"string\") {\n unresolvedKeyframes[i] = parseFloat(value as string)\n }\n }\n } else if (positionalValues[name]) {\n /**\n * Else, the only way to resolve this is by measuring the element.\n */\n this.needsMeasurement = true\n }\n }\n\n resolveNoneKeyframes() {\n const { unresolvedKeyframes, name } = this\n\n const noneKeyframeIndexes: number[] = []\n for (let i = 0; i < unresolvedKeyframes.length; i++) {\n if (\n unresolvedKeyframes[i] === null ||\n isNone(unresolvedKeyframes[i])\n ) {\n noneKeyframeIndexes.push(i)\n }\n }\n\n if (noneKeyframeIndexes.length) {\n makeNoneKeyframesAnimatable(\n unresolvedKeyframes,\n noneKeyframeIndexes,\n name\n )\n }\n }\n\n measureInitialState() {\n const { element, unresolvedKeyframes, name } = this\n\n if (!element || !element.current) return\n\n if (name === \"height\") {\n this.suspendedScrollY = window.pageYOffset\n }\n\n this.measuredOrigin = positionalValues[name](\n element.measureViewportBox(),\n window.getComputedStyle(element.current)\n )\n\n unresolvedKeyframes[0] = this.measuredOrigin\n\n // Set final key frame to measure after next render\n const measureKeyframe =\n unresolvedKeyframes[unresolvedKeyframes.length - 1]\n\n if (measureKeyframe !== undefined) {\n element.getValue(name, measureKeyframe).jump(measureKeyframe, false)\n }\n }\n\n measureEndState() {\n const { element, name, unresolvedKeyframes } = this\n\n if (!element || !element.current) return\n\n const value = element.getValue(name)\n value && value.jump(this.measuredOrigin, false)\n\n const finalKeyframeIndex = unresolvedKeyframes.length - 1\n const finalKeyframe = unresolvedKeyframes[finalKeyframeIndex]\n\n unresolvedKeyframes[finalKeyframeIndex] = positionalValues[name](\n element.measureViewportBox(),\n window.getComputedStyle(element.current)\n ) as any\n\n if (finalKeyframe !== null && this.finalKeyframe === undefined) {\n this.finalKeyframe = finalKeyframe as T\n }\n\n // If we removed transform values, reapply them before the next render\n if (this.removedTransforms?.length) {\n this.removedTransforms.forEach(\n ([unsetTransformName, unsetTransformValue]) => {\n element\n .getValue(unsetTransformName)!\n .set(unsetTransformValue)\n }\n )\n }\n\n this.resolveNoneKeyframes()\n }\n}\n", "export type ElementOrSelector =\n | Element\n | Element[]\n | NodeListOf\n | string\n | null\n | undefined\n\nexport interface WithQuerySelectorAll {\n querySelectorAll: Element[\"querySelectorAll\"]\n}\n\nexport interface AnimationScope {\n readonly current: T\n animations: any[] // TODO: Refactor to types package AnimationPlaybackControls[]\n}\n\nexport interface SelectorCache {\n [key: string]: NodeListOf\n}\n\nexport function resolveElements(\n elementOrSelector: ElementOrSelector,\n scope?: AnimationScope,\n selectorCache?: SelectorCache\n): Element[] {\n if (elementOrSelector == null) {\n return []\n }\n\n if (elementOrSelector instanceof EventTarget) {\n return [elementOrSelector]\n } else if (typeof elementOrSelector === \"string\") {\n let root: WithQuerySelectorAll = document\n\n if (scope) {\n root = scope.current\n }\n\n const elements =\n selectorCache?.[elementOrSelector] ??\n root.querySelectorAll(elementOrSelector)\n\n return elements ? Array.from(elements) : []\n }\n\n return Array.from(elementOrSelector).filter(\n (element): element is Element => element != null\n )\n}\n", "import { ValueType } from \"../types\"\n\n/**\n * Provided a value and a ValueType, returns the value as that value type.\n */\nexport const getValueAsType = (value: any, type?: ValueType) => {\n return type && typeof value === \"number\"\n ? (type as any).transform(value)\n : value\n}\n", "import { isObject } from \"motion-utils\"\n\n/**\n * Checks if an element is an HTML element in a way\n * that works across iframes\n */\nexport function isHTMLElement(element: unknown): element is HTMLElement {\n return (\n isObject(element) &&\n \"offsetHeight\" in element &&\n !(\"ownerSVGElement\" in element)\n )\n}\n", "import { createRenderBatcher } from \"./batcher\"\n\nexport const { schedule: microtask, cancel: cancelMicrotask } =\n /* @__PURE__ */ createRenderBatcher(queueMicrotask, false)\n", "export const isDragging = {\n x: false,\n y: false,\n}\n\nexport function isDragActive() {\n return isDragging.x || isDragging.y\n}\n", "import { isDragging } from \"./is-active\"\n\nexport function setDragLock(axis: boolean | \"x\" | \"y\" | \"lockDirection\") {\n if (axis === \"x\" || axis === \"y\") {\n if (isDragging[axis]) {\n return null\n } else {\n isDragging[axis] = true\n return () => {\n isDragging[axis] = false\n }\n }\n } else {\n if (isDragging.x || isDragging.y) {\n return null\n } else {\n isDragging.x = isDragging.y = true\n return () => {\n isDragging.x = isDragging.y = false\n }\n }\n }\n}\n", "import {\n ElementOrSelector,\n resolveElements,\n} from \"../../utils/resolve-elements\"\nimport { EventOptions } from \"../types\"\n\nexport function setupGesture(\n elementOrSelector: ElementOrSelector,\n options: EventOptions\n): [Element[], AddEventListenerOptions, VoidFunction] {\n const elements = resolveElements(elementOrSelector)\n\n const gestureAbortController = new AbortController()\n\n const eventOptions = {\n passive: true,\n ...options,\n signal: gestureAbortController.signal,\n }\n\n const cancel = () => gestureAbortController.abort()\n\n return [elements, eventOptions, cancel]\n}\n", "import { ElementOrSelector } from \"../utils/resolve-elements\"\nimport { isDragActive } from \"./drag/state/is-active\"\nimport { EventOptions } from \"./types\"\nimport { setupGesture } from \"./utils/setup\"\n\n/**\n * A function to be called when a hover gesture starts.\n *\n * This function can optionally return a function that will be called\n * when the hover gesture ends.\n *\n * @public\n */\nexport type OnHoverStartEvent = (\n element: Element,\n event: PointerEvent\n) => void | OnHoverEndEvent\n\n/**\n * A function to be called when a hover gesture ends.\n *\n * @public\n */\nexport type OnHoverEndEvent = (event: PointerEvent) => void\n\nfunction isValidHover(event: PointerEvent) {\n return !(event.pointerType === \"touch\" || isDragActive())\n}\n\n/**\n * Create a hover gesture. hover() is different to .addEventListener(\"pointerenter\")\n * in that it has an easier syntax, filters out polyfilled touch events, interoperates\n * with drag gestures, and automatically removes the \"pointerennd\" event listener when the hover ends.\n *\n * @public\n */\nexport function hover(\n elementOrSelector: ElementOrSelector,\n onHoverStart: OnHoverStartEvent,\n options: EventOptions = {}\n): VoidFunction {\n const [elements, eventOptions, cancel] = setupGesture(\n elementOrSelector,\n options\n )\n\n elements.forEach((element) => {\n let isPressed = false\n let deferredHoverEnd = false\n let hoverEndCallback: OnHoverEndEvent | undefined\n\n const removePointerLeave = () => {\n element.removeEventListener(\n \"pointerleave\",\n onPointerLeave as EventListener\n )\n }\n\n const endHover = (event: PointerEvent) => {\n if (hoverEndCallback) {\n hoverEndCallback(event)\n hoverEndCallback = undefined\n }\n removePointerLeave()\n }\n\n const onPointerUp = (event: Event) => {\n isPressed = false\n window.removeEventListener(\n \"pointerup\",\n onPointerUp as EventListener\n )\n window.removeEventListener(\n \"pointercancel\",\n onPointerUp as EventListener\n )\n\n if (deferredHoverEnd) {\n deferredHoverEnd = false\n endHover(event as PointerEvent)\n }\n }\n\n const onPointerDown = () => {\n isPressed = true\n window.addEventListener(\n \"pointerup\",\n onPointerUp as EventListener,\n eventOptions\n )\n window.addEventListener(\n \"pointercancel\",\n onPointerUp as EventListener,\n eventOptions\n )\n }\n\n const onPointerLeave = (leaveEvent: PointerEvent) => {\n if (leaveEvent.pointerType === \"touch\") return\n\n if (isPressed) {\n deferredHoverEnd = true\n return\n }\n\n endHover(leaveEvent)\n }\n\n const onPointerEnter = (enterEvent: PointerEvent) => {\n if (!isValidHover(enterEvent)) return\n\n deferredHoverEnd = false\n\n const onHoverEnd = onHoverStart(\n element as Element,\n enterEvent\n )\n\n if (typeof onHoverEnd !== \"function\") return\n\n hoverEndCallback = onHoverEnd\n\n element.addEventListener(\n \"pointerleave\",\n onPointerLeave as EventListener,\n eventOptions\n )\n }\n\n element.addEventListener(\n \"pointerenter\",\n onPointerEnter as EventListener,\n eventOptions\n )\n element.addEventListener(\n \"pointerdown\",\n onPointerDown as EventListener,\n eventOptions\n )\n })\n\n return cancel\n}\n", "/**\n * Recursively traverse up the tree to check whether the provided child node\n * is the parent or a descendant of it.\n *\n * @param parent - Element to find\n * @param child - Element to test against parent\n */\nexport const isNodeOrChild = (\n parent: Element | null,\n child?: Element | null\n): boolean => {\n if (!child) {\n return false\n } else if (parent === child) {\n return true\n } else {\n return isNodeOrChild(parent, child.parentElement)\n }\n}\n", "export const isPrimaryPointer = (event: PointerEvent) => {\n if (event.pointerType === \"mouse\") {\n return typeof event.button !== \"number\" || event.button <= 0\n } else {\n /**\n * isPrimary is true for all mice buttons, whereas every touch point\n * is regarded as its own input. So subsequent concurrent touch points\n * will be false.\n *\n * Specifically match against false here as incomplete versions of\n * PointerEvents in very old browser might have it set as undefined.\n */\n return event.isPrimary !== false\n }\n}\n", "const keyboardAccessibleElements = new Set([\n \"BUTTON\",\n \"INPUT\",\n \"SELECT\",\n \"TEXTAREA\",\n \"A\",\n])\n\n/**\n * Checks if an element is natively keyboard accessible (focusable).\n * Used by the press gesture to determine if we need to add tabIndex.\n */\nexport function isElementKeyboardAccessible(element: Element) {\n return (\n keyboardAccessibleElements.has(element.tagName) ||\n (element as HTMLElement).isContentEditable === true\n )\n}\n\nconst textInputElements = new Set([\"INPUT\", \"SELECT\", \"TEXTAREA\"])\n\n/**\n * Checks if an element has text selection or direct interaction behavior\n * that should block drag gestures from starting.\n *\n * This specifically targets form controls where the user might want to select\n * text or interact with the control (e.g., sliders, dropdowns).\n *\n * Buttons and links are NOT included because they don't have click-and-move\n * actions of their own - they only respond to click events, so dragging\n * should still work when initiated from these elements.\n */\nexport function isElementTextInput(element: Element) {\n return (\n textInputElements.has(element.tagName) ||\n (element as HTMLElement).isContentEditable === true\n )\n}\n", "export const isPressing = new WeakSet()\n", "import { isPressing } from \"./state\"\n\n/**\n * Filter out events that are not \"Enter\" keys.\n */\nfunction filterEvents(callback: (event: KeyboardEvent) => void) {\n return (event: KeyboardEvent) => {\n if (event.key !== \"Enter\") return\n callback(event)\n }\n}\n\nfunction firePointerEvent(target: EventTarget, type: \"down\" | \"up\" | \"cancel\") {\n target.dispatchEvent(\n new PointerEvent(\"pointer\" + type, { isPrimary: true, bubbles: true })\n )\n}\n\nexport const enableKeyboardPress = (\n focusEvent: FocusEvent,\n eventOptions: AddEventListenerOptions\n) => {\n const element = focusEvent.currentTarget as HTMLElement\n if (!element) return\n\n const handleKeydown = filterEvents(() => {\n if (isPressing.has(element)) return\n\n firePointerEvent(element, \"down\")\n\n const handleKeyup = filterEvents(() => {\n firePointerEvent(element, \"up\")\n })\n\n const handleBlur = () => firePointerEvent(element, \"cancel\")\n\n element.addEventListener(\"keyup\", handleKeyup, eventOptions)\n element.addEventListener(\"blur\", handleBlur, eventOptions)\n })\n\n element.addEventListener(\"keydown\", handleKeydown, eventOptions)\n\n /**\n * Add an event listener that fires on blur to remove the keydown events.\n */\n element.addEventListener(\n \"blur\",\n () => element.removeEventListener(\"keydown\", handleKeydown),\n eventOptions\n )\n}\n", "import { isHTMLElement } from \"../../utils/is-html-element\"\nimport { ElementOrSelector } from \"../../utils/resolve-elements\"\nimport { isDragActive } from \"../drag/state/is-active\"\nimport { EventOptions } from \"../types\"\nimport { isNodeOrChild } from \"../utils/is-node-or-child\"\nimport { isPrimaryPointer } from \"../utils/is-primary-pointer\"\nimport { setupGesture } from \"../utils/setup\"\nimport { OnPressStartEvent } from \"./types\"\nimport { isElementKeyboardAccessible } from \"./utils/is-keyboard-accessible\"\nimport { enableKeyboardPress } from \"./utils/keyboard\"\nimport { isPressing } from \"./utils/state\"\n\n/**\n * Filter out events that are not primary pointer events, or are triggering\n * while a Motion gesture is active.\n */\nfunction isValidPressEvent(event: PointerEvent) {\n return isPrimaryPointer(event) && !isDragActive()\n}\n\nconst claimedPointerDownEvents = new WeakSet()\n\nexport interface PointerEventOptions extends EventOptions {\n useGlobalTarget?: boolean\n stopPropagation?: boolean\n}\n\n/**\n * Create a press gesture.\n *\n * Press is different to `\"pointerdown\"`, `\"pointerup\"` in that it\n * automatically filters out secondary pointer events like right\n * click and multitouch.\n *\n * It also adds accessibility support for keyboards, where\n * an element with a press gesture will receive focus and\n * trigger on Enter `\"keydown\"` and `\"keyup\"` events.\n *\n * This is different to a browser's `\"click\"` event, which does\n * respond to keyboards but only for the `\"click\"` itself, rather\n * than the press start and end/cancel. The element also needs\n * to be focusable for this to work, whereas a press gesture will\n * make an element focusable by default.\n *\n * @public\n */\nexport function press(\n targetOrSelector: ElementOrSelector,\n onPressStart: OnPressStartEvent,\n options: PointerEventOptions = {}\n): VoidFunction {\n const [targets, eventOptions, cancelEvents] = setupGesture(\n targetOrSelector,\n options\n )\n\n const startPress = (startEvent: PointerEvent) => {\n const target = startEvent.currentTarget as Element\n\n if (!isValidPressEvent(startEvent)) return\n if (claimedPointerDownEvents.has(startEvent)) return\n\n isPressing.add(target)\n\n if (options.stopPropagation) {\n claimedPointerDownEvents.add(startEvent)\n }\n\n const onPressEnd = onPressStart(target, startEvent)\n\n const onPointerEnd = (endEvent: PointerEvent, success: boolean) => {\n window.removeEventListener(\"pointerup\", onPointerUp)\n window.removeEventListener(\"pointercancel\", onPointerCancel)\n\n if (isPressing.has(target)) {\n isPressing.delete(target)\n }\n\n if (!isValidPressEvent(endEvent)) {\n return\n }\n\n if (typeof onPressEnd === \"function\") {\n onPressEnd(endEvent, { success })\n }\n }\n\n const onPointerUp = (upEvent: PointerEvent) => {\n onPointerEnd(\n upEvent,\n (target as any) === window ||\n (target as any) === document ||\n options.useGlobalTarget ||\n isNodeOrChild(target, upEvent.target as Element)\n )\n }\n\n const onPointerCancel = (cancelEvent: PointerEvent) => {\n onPointerEnd(cancelEvent, false)\n }\n\n window.addEventListener(\"pointerup\", onPointerUp, eventOptions)\n window.addEventListener(\"pointercancel\", onPointerCancel, eventOptions)\n }\n\n targets.forEach((target: EventTarget) => {\n const pointerDownTarget = options.useGlobalTarget ? window : target\n pointerDownTarget.addEventListener(\n \"pointerdown\",\n startPress as EventListener,\n eventOptions\n )\n\n if (isHTMLElement(target)) {\n target.addEventListener(\"focus\", (event) =>\n enableKeyboardPress(event as FocusEvent, eventOptions)\n )\n\n if (\n !isElementKeyboardAccessible(target) &&\n !target.hasAttribute(\"tabindex\")\n ) {\n target.tabIndex = 0\n }\n }\n })\n\n return cancelEvents\n}\n", "import { isObject } from \"motion-utils\"\n\n/**\n * Checks if an element is an SVG element in a way\n * that works across iframes\n */\nexport function isSVGElement(element: unknown): element is SVGElement {\n return isObject(element) && \"ownerSVGElement\" in element\n}\n", "import { isSVGElement } from \"../utils/is-svg-element\"\nimport { ElementOrSelector, resolveElements } from \"../utils/resolve-elements\"\nimport { ResizeHandler } from \"./types\"\n\nconst resizeHandlers = new WeakMap>>()\n\nlet observer: ResizeObserver | undefined\n\nconst getSize =\n (\n borderBoxAxis: \"inline\" | \"block\",\n svgAxis: \"width\" | \"height\",\n htmlAxis: \"offsetWidth\" | \"offsetHeight\"\n ) =>\n (target: Element, borderBoxSize?: ReadonlyArray) => {\n if (borderBoxSize && borderBoxSize[0]) {\n return borderBoxSize[0][\n (borderBoxAxis + \"Size\") as keyof ResizeObserverSize\n ]\n } else if (isSVGElement(target) && \"getBBox\" in target) {\n return (target as SVGGraphicsElement).getBBox()[svgAxis]\n } else {\n return (target as HTMLElement)[htmlAxis]\n }\n }\n\nconst getWidth = /*@__PURE__*/ getSize(\"inline\", \"width\", \"offsetWidth\")\nconst getHeight = /*@__PURE__*/ getSize(\"block\", \"height\", \"offsetHeight\")\n\nfunction notifyTarget({ target, borderBoxSize }: ResizeObserverEntry) {\n resizeHandlers.get(target)?.forEach((handler) => {\n handler(target, {\n get width() {\n return getWidth(target, borderBoxSize)\n },\n get height() {\n return getHeight(target, borderBoxSize)\n },\n })\n })\n}\n\nfunction notifyAll(entries: ResizeObserverEntry[]) {\n entries.forEach(notifyTarget)\n}\n\nfunction createResizeObserver() {\n if (typeof ResizeObserver === \"undefined\") return\n\n observer = new ResizeObserver(notifyAll)\n}\n\nexport function resizeElement(\n target: ElementOrSelector,\n handler: ResizeHandler\n) {\n if (!observer) createResizeObserver()\n\n const elements = resolveElements(target)\n\n elements.forEach((element) => {\n let elementHandlers = resizeHandlers.get(element)\n\n if (!elementHandlers) {\n elementHandlers = new Set()\n resizeHandlers.set(element, elementHandlers)\n }\n\n elementHandlers.add(handler)\n observer?.observe(element)\n })\n\n return () => {\n elements.forEach((element) => {\n const elementHandlers = resizeHandlers.get(element)\n\n elementHandlers?.delete(handler)\n\n if (!elementHandlers?.size) {\n observer?.unobserve(element)\n }\n })\n }\n}\n", "import { WindowResizeHandler } from \"./types\"\n\nconst windowCallbacks = new Set()\n\nlet windowResizeHandler: VoidFunction | undefined\n\nfunction createWindowResizeHandler() {\n windowResizeHandler = () => {\n const info = {\n get width() {\n return window.innerWidth\n },\n get height() {\n return window.innerHeight\n },\n }\n\n windowCallbacks.forEach((callback) => callback(info))\n }\n\n window.addEventListener(\"resize\", windowResizeHandler)\n}\n\nexport function resizeWindow(callback: WindowResizeHandler) {\n windowCallbacks.add(callback)\n\n if (!windowResizeHandler) createWindowResizeHandler()\n\n return () => {\n windowCallbacks.delete(callback)\n\n if (\n !windowCallbacks.size &&\n typeof windowResizeHandler === \"function\"\n ) {\n window.removeEventListener(\"resize\", windowResizeHandler)\n windowResizeHandler = undefined\n }\n }\n}\n", "import { ElementOrSelector } from \"../utils/resolve-elements\"\nimport { resizeElement } from \"./handle-element\"\nimport { resizeWindow } from \"./handle-window\"\nimport { ResizeHandler, WindowResizeHandler } from \"./types\"\n\nexport function resize(onResize: WindowResizeHandler): VoidFunction\nexport function resize(\n target: ElementOrSelector,\n onResize: ResizeHandler\n): VoidFunction\nexport function resize(\n a: WindowResizeHandler | ElementOrSelector,\n b?: ResizeHandler\n) {\n return typeof a === \"function\" ? resizeWindow(a) : resizeElement(a, b!)\n}\n", "import { isSVGElement } from \"./is-svg-element\"\n\n/**\n * Checks if an element is specifically an SVGSVGElement (the root SVG element)\n * in a way that works across iframes\n */\nexport function isSVGSVGElement(element: unknown): element is SVGSVGElement {\n return isSVGElement(element) && element.tagName === \"svg\"\n}\n", "import { color } from \"../color\"\nimport { complex } from \"../complex\"\nimport { dimensionValueTypes } from \"../dimensions\"\nimport { testValueType } from \"../test\"\n\n/**\n * A list of all ValueTypes\n */\nconst valueTypes = [...dimensionValueTypes, color, complex]\n\n/**\n * Tests a value against the list of ValueTypes\n */\nexport const findValueType = (v: any) => valueTypes.find(testValueType(v))\n", "import { Axis, AxisDelta, Box, Delta } from \"motion-utils\"\n\nexport const createAxisDelta = (): AxisDelta => ({\n translate: 0,\n scale: 1,\n origin: 0,\n originPoint: 0,\n})\n\nexport const createDelta = (): Delta => ({\n x: createAxisDelta(),\n y: createAxisDelta(),\n})\n\nexport const createAxis = (): Axis => ({ min: 0, max: 0 })\n\nexport const createBox = (): Box => ({\n x: createAxis(),\n y: createAxis(),\n})\n", "import type { VisualElement } from \"./VisualElement\"\n\nexport const visualElementStore = new WeakMap()\n", "import type { LegacyAnimationControls } from \"../../node/types\"\n\nexport function isAnimationControls(v?: unknown): v is LegacyAnimationControls {\n return (\n v !== null &&\n typeof v === \"object\" &&\n typeof (v as LegacyAnimationControls).start === \"function\"\n )\n}\n", "/**\n * Decides if the supplied variable is variant label\n */\nexport function isVariantLabel(v: unknown): v is string | string[] {\n return typeof v === \"string\" || Array.isArray(v)\n}\n", "import type { AnimationType } from \"../types\"\n\nexport const variantPriorityOrder: AnimationType[] = [\n \"animate\",\n \"whileInView\",\n \"whileFocus\",\n \"whileHover\",\n \"whileTap\",\n \"whileDrag\",\n \"exit\",\n]\n\nexport const variantProps = [\"initial\", ...variantPriorityOrder]\n", "import type { MotionNodeOptions } from \"../../node/types\"\nimport { isAnimationControls } from \"./is-animation-controls\"\nimport { isVariantLabel } from \"./is-variant-label\"\nimport { variantProps } from \"./variant-props\"\n\nexport function isControllingVariants(props: MotionNodeOptions) {\n return (\n isAnimationControls(props.animate) ||\n variantProps.some((name) =>\n isVariantLabel(props[name as keyof typeof props])\n )\n )\n}\n\nexport function isVariantNode(props: MotionNodeOptions) {\n return Boolean(isControllingVariants(props) || props.variants)\n}\n", "import { motionValue } from \"../../value\"\nimport { isMotionValue } from \"../../value/utils/is-motion-value\"\n\ntype MotionStyleLike = Record\n\n/**\n * Updates motion values from props changes.\n * Uses `any` type for element to avoid circular dependencies with VisualElement.\n */\nexport function updateMotionValuesFromProps(\n element: any,\n next: MotionStyleLike,\n prev: MotionStyleLike\n) {\n for (const key in next) {\n const nextValue = next[key]\n const prevValue = prev[key]\n\n if (isMotionValue(nextValue)) {\n /**\n * If this is a motion value found in props or style, we want to add it\n * to our visual element's motion value map.\n */\n element.addValue(key, nextValue)\n } else if (isMotionValue(prevValue)) {\n /**\n * If we're swapping from a motion value to a static value,\n * create a new motion value from that\n */\n element.addValue(key, motionValue(nextValue, { owner: element }))\n } else if (prevValue !== nextValue) {\n /**\n * If this is a flat value that has changed, update the motion value\n * or create one if it doesn't exist. We only want to do this if we're\n * not handling the value with our animation state.\n */\n if (element.hasValue(key)) {\n const existingValue = element.getValue(key)!\n\n if (existingValue.liveStyle === true) {\n existingValue.jump(nextValue)\n } else if (!existingValue.hasAnimated) {\n existingValue.set(nextValue)\n }\n } else {\n const latestValue = element.getStaticValue(key)\n element.addValue(\n key,\n motionValue(\n latestValue !== undefined ? latestValue : nextValue,\n { owner: element }\n )\n )\n }\n }\n }\n\n // Handle removed values\n for (const key in prev) {\n if (next[key] === undefined) element.removeValue(key)\n }\n\n return next\n}\n", "interface ReducedMotionState {\n current: boolean | null\n}\n\n// Does this device prefer reduced motion? Returns `null` server-side.\nexport const prefersReducedMotion: ReducedMotionState = { current: null }\n\nexport const hasReducedMotionListener = { current: false }\n", "import { hasReducedMotionListener, prefersReducedMotion } from \"./state\"\n\nconst isBrowser = typeof window !== \"undefined\"\n\nexport function initPrefersReducedMotion() {\n hasReducedMotionListener.current = true\n if (!isBrowser) return\n\n if (window.matchMedia) {\n const motionMediaQuery = window.matchMedia(\"(prefers-reduced-motion)\")\n\n const setReducedMotionPreferences = () =>\n (prefersReducedMotion.current = motionMediaQuery.matches)\n\n motionMediaQuery.addEventListener(\"change\", setReducedMotionPreferences)\n\n setReducedMotionPreferences()\n } else {\n prefersReducedMotion.current = false\n }\n}\n\nexport { prefersReducedMotion, hasReducedMotionListener }\n", "import {\n Box,\n isNumericalString,\n isZeroValueString,\n secondsToMilliseconds,\n SubscriptionManager,\n warnOnce,\n} from \"motion-utils\"\nimport { KeyframeResolver } from \"../animation/keyframes/KeyframesResolver\"\nimport { NativeAnimation } from \"../animation/NativeAnimation\"\nimport type { AnyResolvedKeyframe } from \"../animation/types\"\nimport { acceleratedValues } from \"../animation/waapi/utils/accelerated-values\"\nimport { cancelFrame, frame } from \"../frameloop\"\nimport { microtask } from \"../frameloop/microtask\"\nimport { time } from \"../frameloop/sync-time\"\nimport type { MotionNodeOptions } from \"../node/types\"\nimport { createBox } from \"../projection/geometry/models\"\nimport { motionValue, MotionValue } from \"../value\"\nimport { complex } from \"../value/types/complex\"\nimport { getAnimatableNone } from \"../value/types/utils/animatable-none\"\nimport { findValueType } from \"../value/types/utils/find\"\nimport { isMotionValue } from \"../value/utils/is-motion-value\"\nimport { Feature } from \"./Feature\"\nimport { visualElementStore } from \"./store\"\nimport {\n FeatureDefinitions,\n MotionConfigContextProps,\n PresenceContextProps,\n ReducedMotionConfig,\n ResolvedValues,\n VisualElementEventCallbacks,\n VisualElementOptions,\n} from \"./types\"\nimport { AnimationState } from \"./utils/animation-state\"\nimport {\n isControllingVariants as checkIsControllingVariants,\n isVariantNode as checkIsVariantNode,\n} from \"./utils/is-controlling-variants\"\nimport { transformProps } from \"./utils/keys-transform\"\nimport { updateMotionValuesFromProps } from \"./utils/motion-values\"\nimport {\n hasReducedMotionListener,\n initPrefersReducedMotion,\n prefersReducedMotion,\n} from \"./utils/reduced-motion\"\nimport { resolveVariantFromProps } from \"./utils/resolve-variants\"\n\nconst propEventHandlers = [\n \"AnimationStart\",\n \"AnimationComplete\",\n \"Update\",\n \"BeforeLayoutMeasure\",\n \"LayoutMeasure\",\n \"LayoutAnimationStart\",\n \"LayoutAnimationComplete\",\n] as const\n\n/**\n * Static feature definitions - can be injected by framework layer\n */\nlet featureDefinitions: Partial = {}\n\n/**\n * Set feature definitions for all VisualElements.\n * This should be called by the framework layer (e.g., framer-motion) during initialization.\n */\nexport function setFeatureDefinitions(\n definitions: Partial\n) {\n featureDefinitions = definitions\n}\n\n/**\n * Get the current feature definitions\n */\nexport function getFeatureDefinitions(): Partial {\n return featureDefinitions\n}\n\n/**\n * Motion style type - a subset of CSS properties that can contain motion values\n */\nexport type MotionStyle = {\n [K: string]: AnyResolvedKeyframe | MotionValue | undefined\n}\n\n/**\n * A VisualElement is an imperative abstraction around UI elements such as\n * HTMLElement, SVGElement, Three.Object3D etc.\n */\nexport abstract class VisualElement<\n Instance = unknown,\n RenderState = unknown,\n Options extends {} = {}\n> {\n /**\n * VisualElements are arranged in trees mirroring that of the React tree.\n * Each type of VisualElement has a unique name, to detect when we're crossing\n * type boundaries within that tree.\n */\n abstract type: string\n\n /**\n * An `Array.sort` compatible function that will compare two Instances and\n * compare their respective positions within the tree.\n */\n abstract sortInstanceNodePosition(a: Instance, b: Instance): number\n\n /**\n * Measure the viewport-relative bounding box of the Instance.\n */\n abstract measureInstanceViewportBox(\n instance: Instance,\n props: MotionNodeOptions & Partial\n ): Box\n\n /**\n * When a value has been removed from all animation props we need to\n * pick a target to animate back to. For instance, for HTMLElements\n * we can look in the style prop.\n */\n abstract getBaseTargetFromProps(\n props: MotionNodeOptions,\n key: string\n ): AnyResolvedKeyframe | undefined | MotionValue\n\n /**\n * When we first animate to a value we need to animate it *from* a value.\n * Often this have been specified via the initial prop but it might be\n * that the value needs to be read from the Instance.\n */\n abstract readValueFromInstance(\n instance: Instance,\n key: string,\n options: Options\n ): AnyResolvedKeyframe | null | undefined\n\n /**\n * When a value has been removed from the VisualElement we use this to remove\n * it from the inherting class' unique render state.\n */\n abstract removeValueFromRenderState(\n key: string,\n renderState: RenderState\n ): void\n\n /**\n * Run before a React or VisualElement render, builds the latest motion\n * values into an Instance-specific format. For example, HTMLVisualElement\n * will use this step to build `style` and `var` values.\n */\n abstract build(\n renderState: RenderState,\n latestValues: ResolvedValues,\n props: MotionNodeOptions\n ): void\n\n /**\n * Apply the built values to the Instance. For example, HTMLElements will have\n * styles applied via `setProperty` and the style attribute, whereas SVGElements\n * will have values applied to attributes.\n */\n abstract renderInstance(\n instance: Instance,\n renderState: RenderState,\n styleProp?: MotionStyle,\n projection?: any\n ): void\n\n /**\n * This method is called when a transform property is bound to a motion value.\n * It's currently used to measure SVG elements when a new transform property is bound.\n */\n onBindTransform?(): void\n\n /**\n * If the component child is provided as a motion value, handle subscriptions\n * with the renderer-specific VisualElement.\n */\n handleChildMotionValue?(): void\n\n /**\n * This method takes React props and returns found MotionValues. For example, HTML\n * MotionValues will be found within the style prop, whereas for Three.js within attribute arrays.\n *\n * This isn't an abstract method as it needs calling in the constructor, but it is\n * intended to be one.\n */\n scrapeMotionValuesFromProps(\n _props: MotionNodeOptions,\n _prevProps: MotionNodeOptions,\n _visualElement: VisualElement\n ): {\n [key: string]: MotionValue | AnyResolvedKeyframe\n } {\n return {}\n }\n\n /**\n * A reference to the current underlying Instance, e.g. a HTMLElement\n * or Three.Mesh etc.\n */\n current: Instance | null = null\n\n /**\n * A reference to the parent VisualElement (if exists).\n */\n parent: VisualElement | undefined\n\n /**\n * A set containing references to this VisualElement's children.\n */\n children = new Set()\n\n /**\n * A set containing the latest children of this VisualElement. This is flushed\n * at the start of every commit. We use it to calculate the stagger delay\n * for newly-added children.\n */\n enteringChildren?: Set\n\n /**\n * The depth of this VisualElement within the overall VisualElement tree.\n */\n depth: number\n\n /**\n * The current render state of this VisualElement. Defined by inherting VisualElements.\n */\n renderState: RenderState\n\n /**\n * An object containing the latest static values for each of this VisualElement's\n * MotionValues.\n */\n latestValues: ResolvedValues\n\n /**\n * Determine what role this visual element should take in the variant tree.\n */\n isVariantNode: boolean = false\n isControllingVariants: boolean = false\n\n /**\n * If this component is part of the variant tree, it should track\n * any children that are also part of the tree. This is essentially\n * a shadow tree to simplify logic around how to stagger over children.\n */\n variantChildren?: Set\n\n /**\n * Decides whether this VisualElement should animate in reduced motion\n * mode.\n *\n * TODO: This is currently set on every individual VisualElement but feels\n * like it could be set globally.\n */\n shouldReduceMotion: boolean | null = null\n\n /**\n * Decides whether animations should be skipped for this VisualElement.\n * Useful for E2E tests and visual regression testing.\n */\n shouldSkipAnimations: boolean = false\n\n /**\n * Normally, if a component is controlled by a parent's variants, it can\n * rely on that ancestor to trigger animations further down the tree.\n * However, if a component is created after its parent is mounted, the parent\n * won't trigger that mount animation so the child needs to.\n *\n * TODO: This might be better replaced with a method isParentMounted\n */\n manuallyAnimateOnMount: boolean\n\n /**\n * This can be set by AnimatePresence to force components that mount\n * at the same time as it to mount as if they have initial={false} set.\n */\n blockInitialAnimation: boolean\n\n /**\n * A reference to this VisualElement's projection node, used in layout animations.\n */\n projection?: any\n\n /**\n * A map of all motion values attached to this visual element. Motion\n * values are source of truth for any given animated value. A motion\n * value might be provided externally by the component via props.\n */\n values = new Map()\n\n /**\n * The AnimationState, this is hydrated by the animation Feature.\n */\n animationState?: AnimationState\n\n KeyframeResolver = KeyframeResolver\n\n /**\n * The options used to create this VisualElement. The Options type is defined\n * by the inheriting VisualElement and is passed straight through to the render functions.\n */\n readonly options: Options\n\n /**\n * A reference to the latest props provided to the VisualElement's host React component.\n */\n props: MotionNodeOptions\n prevProps?: MotionNodeOptions\n\n presenceContext: PresenceContextProps | null\n prevPresenceContext?: PresenceContextProps | null\n\n /**\n * Cleanup functions for active features (hover/tap/exit etc)\n */\n private features: {\n [K in keyof FeatureDefinitions]?: Feature\n } = {}\n\n /**\n * A map of every subscription that binds the provided or generated\n * motion values onChange listeners to this visual element.\n */\n private valueSubscriptions = new Map()\n\n /**\n * A reference to the ReducedMotionConfig passed to the VisualElement's host React component.\n */\n private reducedMotionConfig: ReducedMotionConfig | undefined\n\n /**\n * A reference to the skipAnimations config passed to the VisualElement's host React component.\n */\n private skipAnimationsConfig: boolean | undefined\n\n /**\n * On mount, this will be hydrated with a callback to disconnect\n * this visual element from its parent on unmount.\n */\n private removeFromVariantTree: undefined | VoidFunction\n\n /**\n * A reference to the previously-provided motion values as returned\n * from scrapeMotionValuesFromProps. We use the keys in here to determine\n * if any motion values need to be removed after props are updated.\n */\n private prevMotionValues: MotionStyle = {}\n\n /**\n * When values are removed from all animation props we need to search\n * for a fallback value to animate to. These values are tracked in baseTarget.\n */\n private baseTarget: ResolvedValues\n\n /**\n * Create an object of the values we initially animated from (if initial prop present).\n */\n private initialValues: ResolvedValues\n\n /**\n * Track whether this element has been mounted before, to detect\n * remounts after Suspense unmount/remount cycles.\n */\n private hasBeenMounted = false\n\n /**\n * An object containing a SubscriptionManager for each active event.\n */\n private events: {\n [key: string]: SubscriptionManager\n } = {}\n\n /**\n * An object containing an unsubscribe function for each prop event subscription.\n * For example, every \"Update\" event can have multiple subscribers via\n * VisualElement.on(), but only one of those can be defined via the onUpdate prop.\n */\n private propEventSubscriptions: {\n [key: string]: VoidFunction\n } = {}\n\n constructor(\n {\n parent,\n props,\n presenceContext,\n reducedMotionConfig,\n skipAnimations,\n blockInitialAnimation,\n visualState,\n }: VisualElementOptions,\n options: Options = {} as any\n ) {\n const { latestValues, renderState } = visualState\n this.latestValues = latestValues\n this.baseTarget = { ...latestValues }\n this.initialValues = props.initial ? { ...latestValues } : {}\n this.renderState = renderState\n this.parent = parent\n this.props = props\n this.presenceContext = presenceContext\n this.depth = parent ? parent.depth + 1 : 0\n this.reducedMotionConfig = reducedMotionConfig\n this.skipAnimationsConfig = skipAnimations\n this.options = options\n this.blockInitialAnimation = Boolean(blockInitialAnimation)\n\n this.isControllingVariants = checkIsControllingVariants(props)\n this.isVariantNode = checkIsVariantNode(props)\n if (this.isVariantNode) {\n this.variantChildren = new Set()\n }\n\n this.manuallyAnimateOnMount = Boolean(parent && parent.current)\n\n /**\n * Any motion values that are provided to the element when created\n * aren't yet bound to the element, as this would technically be impure.\n * However, we iterate through the motion values and set them to the\n * initial values for this component.\n *\n * TODO: This is impure and we should look at changing this to run on mount.\n * Doing so will break some tests but this isn't necessarily a breaking change,\n * more a reflection of the test.\n */\n const { willChange, ...initialMotionValues } =\n this.scrapeMotionValuesFromProps(props, {}, this)\n\n for (const key in initialMotionValues) {\n const value = initialMotionValues[key]\n\n if (latestValues[key] !== undefined && isMotionValue(value)) {\n value.set(latestValues[key])\n }\n }\n }\n\n mount(instance: Instance) {\n /**\n * If this element has been mounted before (e.g. after a Suspense\n * unmount/remount), reset motion values to their initial state\n * so animations replay correctly from initial → animate.\n */\n if (this.hasBeenMounted) {\n for (const key in this.initialValues) {\n this.values.get(key)?.jump(this.initialValues[key])\n this.latestValues[key] = this.initialValues[key]\n }\n }\n\n this.current = instance\n\n visualElementStore.set(instance, this)\n\n if (this.projection && !this.projection.instance) {\n this.projection.mount(instance)\n }\n\n if (this.parent && this.isVariantNode && !this.isControllingVariants) {\n this.removeFromVariantTree = this.parent.addVariantChild(this)\n }\n\n this.values.forEach((value, key) => this.bindToMotionValue(key, value))\n\n /**\n * Determine reduced motion preference. Only initialize the matchMedia\n * listener if we actually need the dynamic value (i.e., when config\n * is neither \"never\" nor \"always\").\n */\n if (this.reducedMotionConfig === \"never\") {\n this.shouldReduceMotion = false\n } else if (this.reducedMotionConfig === \"always\") {\n this.shouldReduceMotion = true\n } else {\n if (!hasReducedMotionListener.current) {\n initPrefersReducedMotion()\n }\n this.shouldReduceMotion = prefersReducedMotion.current\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n this.shouldReduceMotion !== true,\n \"You have Reduced Motion enabled on your device. Animations may not appear as expected.\",\n \"reduced-motion-disabled\"\n )\n }\n\n /**\n * Set whether animations should be skipped based on the config.\n */\n this.shouldSkipAnimations = this.skipAnimationsConfig ?? false\n\n this.parent?.addChild(this)\n\n this.update(this.props, this.presenceContext)\n\n this.hasBeenMounted = true\n }\n\n unmount() {\n this.projection && this.projection.unmount()\n cancelFrame(this.notifyUpdate)\n cancelFrame(this.render)\n this.valueSubscriptions.forEach((remove) => remove())\n this.valueSubscriptions.clear()\n this.removeFromVariantTree && this.removeFromVariantTree()\n this.parent?.removeChild(this)\n\n for (const key in this.events) {\n this.events[key].clear()\n }\n\n for (const key in this.features) {\n const feature = this.features[key as keyof typeof this.features]\n if (feature) {\n feature.unmount()\n feature.isMounted = false\n }\n }\n this.current = null\n }\n\n addChild(child: VisualElement) {\n this.children.add(child)\n this.enteringChildren ??= new Set()\n this.enteringChildren.add(child)\n }\n\n removeChild(child: VisualElement) {\n this.children.delete(child)\n this.enteringChildren && this.enteringChildren.delete(child)\n }\n\n private bindToMotionValue(key: string, value: MotionValue) {\n if (this.valueSubscriptions.has(key)) {\n this.valueSubscriptions.get(key)!()\n }\n\n if (\n value.accelerate &&\n acceleratedValues.has(key) &&\n this.current instanceof HTMLElement\n ) {\n const { factory, keyframes, times, ease, duration } =\n value.accelerate\n\n const animation = new NativeAnimation({\n element: this.current,\n name: key,\n keyframes,\n times,\n ease,\n duration: secondsToMilliseconds(duration),\n })\n\n const cleanup = factory(animation)\n\n this.valueSubscriptions.set(key, () => {\n cleanup()\n animation.cancel()\n })\n return\n }\n\n const valueIsTransform = transformProps.has(key)\n\n if (valueIsTransform && this.onBindTransform) {\n this.onBindTransform()\n }\n\n const removeOnChange = value.on(\n \"change\",\n (latestValue: AnyResolvedKeyframe) => {\n this.latestValues[key] = latestValue\n\n this.props.onUpdate && frame.preRender(this.notifyUpdate)\n\n if (valueIsTransform && this.projection) {\n this.projection.isTransformDirty = true\n }\n\n this.scheduleRender()\n }\n )\n\n let removeSyncCheck: VoidFunction | void\n if (\n typeof window !== \"undefined\" &&\n (window as any).MotionCheckAppearSync\n ) {\n removeSyncCheck = (window as any).MotionCheckAppearSync(\n this,\n key,\n value\n )\n }\n\n this.valueSubscriptions.set(key, () => {\n removeOnChange()\n if (removeSyncCheck) removeSyncCheck()\n if (value.owner) value.stop()\n })\n }\n\n sortNodePosition(other: VisualElement) {\n /**\n * If these nodes aren't even of the same type we can't compare their depth.\n */\n if (\n !this.current ||\n !this.sortInstanceNodePosition ||\n this.type !== other.type\n ) {\n return 0\n }\n\n return this.sortInstanceNodePosition(\n this.current as Instance,\n other.current as Instance\n )\n }\n\n updateFeatures() {\n let key: keyof typeof featureDefinitions = \"animation\"\n\n for (key in featureDefinitions) {\n const featureDefinition = featureDefinitions[key]\n\n if (!featureDefinition) continue\n\n const { isEnabled, Feature: FeatureConstructor } = featureDefinition\n\n /**\n * If this feature is enabled but not active, make a new instance.\n */\n if (\n !this.features[key] &&\n FeatureConstructor &&\n isEnabled(this.props)\n ) {\n this.features[key] = new FeatureConstructor(this) as any\n }\n\n /**\n * If we have a feature, mount or update it.\n */\n if (this.features[key]) {\n const feature = this.features[key]!\n if (feature.isMounted) {\n feature.update()\n } else {\n feature.mount()\n feature.isMounted = true\n }\n }\n }\n }\n\n notifyUpdate = () => this.notify(\"Update\", this.latestValues)\n\n triggerBuild() {\n this.build(this.renderState, this.latestValues, this.props)\n }\n\n render = () => {\n if (!this.current) return\n this.triggerBuild()\n this.renderInstance(\n this.current,\n this.renderState,\n (this.props as any).style,\n this.projection\n )\n }\n\n private renderScheduledAt = 0.0\n scheduleRender = () => {\n const now = time.now()\n if (this.renderScheduledAt < now) {\n this.renderScheduledAt = now\n frame.render(this.render, false, true)\n }\n }\n\n /**\n * Measure the current viewport box with or without transforms.\n * Only measures axis-aligned boxes, rotate and skew must be manually\n * removed with a re-render to work.\n */\n measureViewportBox() {\n return this.current\n ? this.measureInstanceViewportBox(this.current, this.props)\n : createBox()\n }\n\n getStaticValue(key: string) {\n return this.latestValues[key]\n }\n\n setStaticValue(key: string, value: AnyResolvedKeyframe) {\n this.latestValues[key] = value\n }\n\n /**\n * Update the provided props. Ensure any newly-added motion values are\n * added to our map, old ones removed, and listeners updated.\n */\n update(\n props: MotionNodeOptions,\n presenceContext: PresenceContextProps | null\n ) {\n if (props.transformTemplate || this.props.transformTemplate) {\n this.scheduleRender()\n }\n\n this.prevProps = this.props\n this.props = props\n\n this.prevPresenceContext = this.presenceContext\n this.presenceContext = presenceContext\n\n /**\n * Update prop event handlers ie onAnimationStart, onAnimationComplete\n */\n for (let i = 0; i < propEventHandlers.length; i++) {\n const key = propEventHandlers[i]\n if (this.propEventSubscriptions[key]) {\n this.propEventSubscriptions[key]()\n delete this.propEventSubscriptions[key]\n }\n\n const listenerName = (\"on\" + key) as keyof typeof props\n const listener = props[listenerName]\n if (listener) {\n this.propEventSubscriptions[key] = this.on(key as any, listener)\n }\n }\n\n this.prevMotionValues = updateMotionValuesFromProps(\n this,\n this.scrapeMotionValuesFromProps(props, this.prevProps || {}, this),\n this.prevMotionValues\n )\n\n if (this.handleChildMotionValue) {\n this.handleChildMotionValue()\n }\n }\n\n getProps() {\n return this.props\n }\n\n /**\n * Returns the variant definition with a given name.\n */\n getVariant(name: string) {\n return this.props.variants ? this.props.variants[name] : undefined\n }\n\n /**\n * Returns the defined default transition on this component.\n */\n getDefaultTransition() {\n return this.props.transition\n }\n\n getTransformPagePoint() {\n return (this.props as any).transformPagePoint\n }\n\n getClosestVariantNode(): VisualElement | undefined {\n return this.isVariantNode\n ? this\n : this.parent\n ? this.parent.getClosestVariantNode()\n : undefined\n }\n\n /**\n * Add a child visual element to our set of children.\n */\n addVariantChild(child: VisualElement) {\n const closestVariantNode = this.getClosestVariantNode()\n if (closestVariantNode) {\n closestVariantNode.variantChildren &&\n closestVariantNode.variantChildren.add(child)\n return () => closestVariantNode.variantChildren!.delete(child)\n }\n }\n\n /**\n * Add a motion value and bind it to this visual element.\n */\n addValue(key: string, value: MotionValue) {\n // Remove existing value if it exists\n const existingValue = this.values.get(key)\n\n if (value !== existingValue) {\n if (existingValue) this.removeValue(key)\n this.bindToMotionValue(key, value)\n this.values.set(key, value)\n this.latestValues[key] = value.get()\n }\n }\n\n /**\n * Remove a motion value and unbind any active subscriptions.\n */\n removeValue(key: string) {\n this.values.delete(key)\n const unsubscribe = this.valueSubscriptions.get(key)\n if (unsubscribe) {\n unsubscribe()\n this.valueSubscriptions.delete(key)\n }\n delete this.latestValues[key]\n this.removeValueFromRenderState(key, this.renderState)\n }\n\n /**\n * Check whether we have a motion value for this key\n */\n hasValue(key: string) {\n return this.values.has(key)\n }\n\n /**\n * Get a motion value for this key. If called with a default\n * value, we'll create one if none exists.\n */\n getValue(key: string): MotionValue | undefined\n getValue(key: string, defaultValue: AnyResolvedKeyframe | null): MotionValue\n getValue(\n key: string,\n defaultValue?: AnyResolvedKeyframe | null\n ): MotionValue | undefined {\n if (this.props.values && this.props.values[key]) {\n return this.props.values[key]\n }\n\n let value = this.values.get(key)\n\n if (value === undefined && defaultValue !== undefined) {\n value = motionValue(\n defaultValue === null ? undefined : defaultValue,\n { owner: this }\n )\n this.addValue(key, value)\n }\n\n return value\n }\n\n /**\n * If we're trying to animate to a previously unencountered value,\n * we need to check for it in our state and as a last resort read it\n * directly from the instance (which might have performance implications).\n */\n readValue(key: string, target?: AnyResolvedKeyframe | null) {\n let value =\n this.latestValues[key] !== undefined || !this.current\n ? this.latestValues[key]\n : this.getBaseTargetFromProps(this.props, key) ??\n this.readValueFromInstance(this.current, key, this.options)\n\n if (value !== undefined && value !== null) {\n if (\n typeof value === \"string\" &&\n (isNumericalString(value) || isZeroValueString(value))\n ) {\n // If this is a number read as a string, ie \"0\" or \"200\", convert it to a number\n value = parseFloat(value)\n } else if (!findValueType(value) && complex.test(target)) {\n value = getAnimatableNone(key, target as string)\n }\n\n this.setBaseTarget(key, isMotionValue(value) ? value.get() : value)\n }\n\n return isMotionValue(value) ? value.get() : value\n }\n\n /**\n * Set the base target to later animate back to. This is currently\n * only hydrated on creation and when we first read a value.\n */\n setBaseTarget(key: string, value: AnyResolvedKeyframe) {\n this.baseTarget[key] = value\n }\n\n /**\n * Find the base target for a value thats been removed from all animation\n * props.\n */\n getBaseTarget(key: string): ResolvedValues[string] | undefined | null {\n const { initial } = this.props\n\n let valueFromInitial: ResolvedValues[string] | undefined | null\n\n if (typeof initial === \"string\" || typeof initial === \"object\") {\n const variant = resolveVariantFromProps(\n this.props,\n initial as any,\n this.presenceContext?.custom\n )\n if (variant) {\n valueFromInitial = variant[\n key as keyof typeof variant\n ] as string\n }\n }\n\n /**\n * If this value still exists in the current initial variant, read that.\n */\n if (initial && valueFromInitial !== undefined) {\n return valueFromInitial\n }\n\n /**\n * Alternatively, if this VisualElement config has defined a getBaseTarget\n * so we can read the value from an alternative source, try that.\n */\n const target = this.getBaseTargetFromProps(this.props, key)\n if (target !== undefined && !isMotionValue(target)) return target\n\n /**\n * If the value was initially defined on initial, but it doesn't any more,\n * return undefined. Otherwise return the value as initially read from the DOM.\n */\n return this.initialValues[key] !== undefined &&\n valueFromInitial === undefined\n ? undefined\n : this.baseTarget[key]\n }\n\n on(\n eventName: EventName,\n callback: VisualElementEventCallbacks[EventName]\n ) {\n if (!this.events[eventName]) {\n this.events[eventName] = new SubscriptionManager()\n }\n\n return this.events[eventName].add(callback)\n }\n\n notify(\n eventName: EventName,\n ...args: any\n ) {\n if (this.events[eventName]) {\n this.events[eventName].notify(...args)\n }\n }\n\n scheduleRenderMicrotask() {\n microtask.render(this.render)\n }\n}\n", "import { isMotionValue } from \"../../value/utils/is-motion-value\"\nimport type { MotionValue } from \"../../value\"\nimport type { AnyResolvedKeyframe } from \"../../animation/types\"\nimport { DOMKeyframesResolver } from \"../../animation/keyframes/DOMKeyframesResolver\"\nimport type { MotionNodeOptions } from \"../../node/types\"\nimport type { DOMVisualElementOptions } from \"./types\"\nimport type { HTMLRenderState } from \"../html/types\"\nimport { VisualElement, MotionStyle } from \"../VisualElement\"\n\nexport abstract class DOMVisualElement<\n Instance extends HTMLElement | SVGElement = HTMLElement,\n State extends HTMLRenderState = HTMLRenderState,\n Options extends DOMVisualElementOptions = DOMVisualElementOptions\n> extends VisualElement {\n sortInstanceNodePosition(a: Instance, b: Instance): number {\n /**\n * compareDocumentPosition returns a bitmask, by using the bitwise &\n * we're returning true if 2 in that bitmask is set to true. 2 is set\n * to true if b preceeds a.\n */\n return a.compareDocumentPosition(b) & 2 ? 1 : -1\n }\n\n getBaseTargetFromProps(\n props: MotionNodeOptions,\n key: string\n ): AnyResolvedKeyframe | MotionValue | undefined {\n const style = (props as MotionNodeOptions & { style?: MotionStyle }).style\n return style ? (style[key] as string) : undefined\n }\n\n removeValueFromRenderState(\n key: string,\n { vars, style }: HTMLRenderState\n ): void {\n delete vars[key]\n delete style[key]\n }\n\n KeyframeResolver = DOMKeyframesResolver\n\n childSubscription?: VoidFunction\n handleChildMotionValue() {\n if (this.childSubscription) {\n this.childSubscription()\n delete this.childSubscription\n }\n\n const { children } = this.props as MotionNodeOptions & { children?: MotionValue | any }\n if (isMotionValue(children)) {\n this.childSubscription = children.on(\"change\", (latest) => {\n if (this.current) {\n this.current.textContent = `${latest}`\n }\n })\n }\n }\n}\n", "import type { VisualElement } from \"./VisualElement\"\n\n/**\n * Feature base class for extending VisualElement functionality.\n * Features are plugins that can be mounted/unmounted to add behavior\n * like gestures, animations, or layout tracking.\n */\nexport abstract class Feature {\n isMounted = false\n\n node: VisualElement\n\n constructor(node: VisualElement) {\n this.node = node\n }\n\n abstract mount(): void\n\n abstract unmount(): void\n\n update(): void {}\n}\n", "import { BoundingBox, Box, TransformPoint } from \"motion-utils\"\n\n/**\n * Bounding boxes tend to be defined as top, left, right, bottom. For various operations\n * it's easier to consider each axis individually. This function returns a bounding box\n * as a map of single-axis min/max values.\n */\nexport function convertBoundingBoxToBox({\n top,\n left,\n right,\n bottom,\n}: BoundingBox): Box {\n return {\n x: { min: left, max: right },\n y: { min: top, max: bottom },\n }\n}\n\nexport function convertBoxToBoundingBox({ x, y }: Box): BoundingBox {\n return { top: y.min, right: x.max, bottom: y.max, left: x.min }\n}\n\n/**\n * Applies a TransformPoint function to a bounding box. TransformPoint is usually a function\n * provided by Framer to allow measured points to be corrected for device scaling. This is used\n * when measuring DOM elements and DOM event points.\n */\nexport function transformBoxPoints(\n point: BoundingBox,\n transformPoint?: TransformPoint\n) {\n if (!transformPoint) return point\n const topLeft = transformPoint({ x: point.left, y: point.top })\n const bottomRight = transformPoint({ x: point.right, y: point.bottom })\n\n return {\n top: topLeft.y,\n left: topLeft.x,\n bottom: bottomRight.y,\n right: bottomRight.x,\n }\n}\n", "import { type AnyResolvedKeyframe } from \"../../animation/types\"\nimport { ResolvedValues } from \"../../render/types\"\n\nfunction isIdentityScale(scale: AnyResolvedKeyframe | undefined) {\n return scale === undefined || scale === 1\n}\n\nexport function hasScale({ scale, scaleX, scaleY }: ResolvedValues) {\n return (\n !isIdentityScale(scale) ||\n !isIdentityScale(scaleX) ||\n !isIdentityScale(scaleY)\n )\n}\n\nexport function hasTransform(values: ResolvedValues) {\n return (\n hasScale(values) ||\n has2DTranslate(values) ||\n values.z ||\n values.rotate ||\n values.rotateX ||\n values.rotateY ||\n values.skewX ||\n values.skewY\n )\n}\n\nexport function has2DTranslate(values: ResolvedValues) {\n return is2DTranslate(values.x) || is2DTranslate(values.y)\n}\n\nfunction is2DTranslate(value: AnyResolvedKeyframe | undefined) {\n return value && value !== \"0%\"\n}\n", "import { Axis, Box, Delta, Point } from \"motion-utils\"\nimport { mixNumber } from \"../../utils/mix/number\"\nimport { ResolvedValues } from \"../../render/types\"\nimport { hasTransform } from \"../utils/has-transform\"\n\n/**\n * Scales a point based on a factor and an originPoint\n */\nexport function scalePoint(point: number, scale: number, originPoint: number) {\n const distanceFromOrigin = point - originPoint\n const scaled = scale * distanceFromOrigin\n return originPoint + scaled\n}\n\n/**\n * Applies a translate/scale delta to a point\n */\nexport function applyPointDelta(\n point: number,\n translate: number,\n scale: number,\n originPoint: number,\n boxScale?: number\n): number {\n if (boxScale !== undefined) {\n point = scalePoint(point, boxScale, originPoint)\n }\n\n return scalePoint(point, scale, originPoint) + translate\n}\n\n/**\n * Applies a translate/scale delta to an axis\n */\nexport function applyAxisDelta(\n axis: Axis,\n translate: number = 0,\n scale: number = 1,\n originPoint: number,\n boxScale?: number\n): void {\n axis.min = applyPointDelta(\n axis.min,\n translate,\n scale,\n originPoint,\n boxScale\n )\n\n axis.max = applyPointDelta(\n axis.max,\n translate,\n scale,\n originPoint,\n boxScale\n )\n}\n\n/**\n * Applies a translate/scale delta to a box\n */\nexport function applyBoxDelta(box: Box, { x, y }: Delta): void {\n applyAxisDelta(box.x, x.translate, x.scale, x.originPoint)\n applyAxisDelta(box.y, y.translate, y.scale, y.originPoint)\n}\n\nconst TREE_SCALE_SNAP_MIN = 0.999999999999\nconst TREE_SCALE_SNAP_MAX = 1.0000000000001\n\n/**\n * Apply a tree of deltas to a box. We do this to calculate the effect of all the transforms\n * in a tree upon our box before then calculating how to project it into our desired viewport-relative box\n *\n * This is the final nested loop within updateLayoutDelta for future refactoring\n */\nexport function applyTreeDeltas(\n box: Box,\n treeScale: Point,\n treePath: any[],\n isSharedTransition: boolean = false\n) {\n const treeLength = treePath.length\n if (!treeLength) return\n\n // Reset the treeScale\n treeScale.x = treeScale.y = 1\n\n let node: any\n let delta: Delta | undefined\n\n for (let i = 0; i < treeLength; i++) {\n node = treePath[i]\n delta = node.projectionDelta\n\n /**\n * TODO: Prefer to remove this, but currently we have motion components with\n * display: contents in Framer.\n */\n const { visualElement } = node.options\n if (\n visualElement &&\n visualElement.props.style &&\n visualElement.props.style.display === \"contents\"\n ) {\n continue\n }\n\n if (\n isSharedTransition &&\n node.options.layoutScroll &&\n node.scroll &&\n node !== node.root\n ) {\n translateAxis(box.x, -node.scroll.offset.x)\n translateAxis(box.y, -node.scroll.offset.y)\n }\n\n if (delta) {\n // Incoporate each ancestor's scale into a cumulative treeScale for this component\n treeScale.x *= delta.x.scale\n treeScale.y *= delta.y.scale\n\n // Apply each ancestor's calculated delta into this component's recorded layout box\n applyBoxDelta(box, delta)\n }\n\n if (isSharedTransition && hasTransform(node.latestValues)) {\n transformBox(box, node.latestValues, node.layout?.layoutBox)\n }\n }\n\n /**\n * Snap tree scale back to 1 if it's within a non-perceivable threshold.\n * This will help reduce useless scales getting rendered.\n */\n if (\n treeScale.x < TREE_SCALE_SNAP_MAX &&\n treeScale.x > TREE_SCALE_SNAP_MIN\n ) {\n treeScale.x = 1.0\n }\n if (\n treeScale.y < TREE_SCALE_SNAP_MAX &&\n treeScale.y > TREE_SCALE_SNAP_MIN\n ) {\n treeScale.y = 1.0\n }\n}\n\nexport function translateAxis(axis: Axis, distance: number) {\n axis.min += distance\n axis.max += distance\n}\n\n/**\n * Apply a transform to an axis from the latest resolved motion values.\n * This function basically acts as a bridge between a flat motion value map\n * and applyAxisDelta\n */\nexport function transformAxis(\n axis: Axis,\n axisTranslate?: number,\n axisScale?: number,\n boxScale?: number,\n axisOrigin: number = 0.5\n): void {\n const originPoint = mixNumber(axis.min, axis.max, axisOrigin)\n\n // Apply the axis delta to the final axis\n applyAxisDelta(axis, axisTranslate, axisScale, originPoint, boxScale)\n}\n\nfunction resolveAxisTranslate(\n value: number | string | undefined,\n axis: Axis\n): number | undefined {\n if (typeof value === \"string\") {\n return (parseFloat(value) / 100) * (axis.max - axis.min)\n }\n return value as number | undefined\n}\n\n/**\n * Apply a transform to a box from the latest resolved motion values.\n */\nexport function transformBox(\n box: Box,\n transform: ResolvedValues,\n sourceBox?: Box\n) {\n const resolveBox = sourceBox ?? box\n transformAxis(\n box.x,\n resolveAxisTranslate(transform.x, resolveBox.x),\n transform.scaleX as number,\n transform.scale as number,\n transform.originX as number\n )\n transformAxis(\n box.y,\n resolveAxisTranslate(transform.y, resolveBox.y),\n transform.scaleY as number,\n transform.scale as number,\n transform.originY as number\n )\n}\n", "import { TransformPoint } from \"motion-utils\"\nimport {\n convertBoundingBoxToBox,\n transformBoxPoints,\n} from \"../geometry/conversion\"\nimport { translateAxis } from \"../geometry/delta-apply\"\n\nexport function measureViewportBox(\n instance: HTMLElement,\n transformPoint?: TransformPoint\n) {\n return convertBoundingBoxToBox(\n transformBoxPoints(instance.getBoundingClientRect(), transformPoint)\n )\n}\n\nexport function measurePageBox(\n element: HTMLElement,\n rootProjectionNode: any,\n transformPagePoint?: TransformPoint\n) {\n const viewportBox = measureViewportBox(element, transformPagePoint)\n const { scroll } = rootProjectionNode\n\n if (scroll) {\n translateAxis(viewportBox.x, scroll.offset.x)\n translateAxis(viewportBox.y, scroll.offset.y)\n }\n\n return viewportBox\n}\n", "import { getValueAsType } from \"../../../value/types/utils/get-as-type\"\nimport { numberValueTypes } from \"../../../value/types/maps/number\"\nimport { transformPropOrder } from \"../../utils/keys-transform\"\nimport { ResolvedValues } from \"../../types\"\nimport { HTMLRenderState } from \"../types\"\nimport type { MotionNodeOptions } from \"../../../node/types\"\n\nconst translateAlias = {\n x: \"translateX\",\n y: \"translateY\",\n z: \"translateZ\",\n transformPerspective: \"perspective\",\n}\n\nconst numTransforms = transformPropOrder.length\n\n/**\n * Build a CSS transform style from individual x/y/scale etc properties.\n *\n * This outputs with a default order of transforms/scales/rotations, this can be customised by\n * providing a transformTemplate function.\n */\nexport function buildTransform(\n latestValues: ResolvedValues,\n transform: HTMLRenderState[\"transform\"],\n transformTemplate?: MotionNodeOptions[\"transformTemplate\"]\n) {\n // The transform string we're going to build into.\n let transformString = \"\"\n let transformIsDefault = true\n\n /**\n * Loop over all possible transforms in order, adding the ones that\n * are present to the transform string.\n */\n for (let i = 0; i < numTransforms; i++) {\n const key = transformPropOrder[i] as keyof typeof translateAlias\n const value = latestValues[key]\n\n if (value === undefined) continue\n\n let valueIsDefault = true\n if (typeof value === \"number\") {\n valueIsDefault = value === (key.startsWith(\"scale\") ? 1 : 0)\n } else {\n const parsed = parseFloat(value)\n valueIsDefault = key.startsWith(\"scale\") ? parsed === 1 : parsed === 0\n }\n\n if (!valueIsDefault || transformTemplate) {\n const valueAsType = getValueAsType(value, numberValueTypes[key])\n\n if (!valueIsDefault) {\n transformIsDefault = false\n const transformName = translateAlias[key] || key\n transformString += `${transformName}(${valueAsType}) `\n }\n\n if (transformTemplate) {\n transform[key] = valueAsType\n }\n }\n }\n\n transformString = transformString.trim()\n\n // If we have a custom `transform` template, pass our transform values and\n // generated transformString to that before returning\n if (transformTemplate) {\n transformString = transformTemplate(\n transform,\n transformIsDefault ? \"\" : transformString\n )\n } else if (transformIsDefault) {\n transformString = \"none\"\n }\n\n return transformString\n}\n", "import { getValueAsType } from \"../../../value/types/utils/get-as-type\"\nimport { numberValueTypes } from \"../../../value/types/maps/number\"\nimport { transformProps } from \"../../utils/keys-transform\"\nimport { isCSSVariableName } from \"../../../animation/utils/is-css-variable\"\nimport { ResolvedValues } from \"../../types\"\nimport { HTMLRenderState } from \"../types\"\nimport { buildTransform } from \"./build-transform\"\nimport type { MotionNodeOptions } from \"../../../node/types\"\n\nexport function buildHTMLStyles(\n state: HTMLRenderState,\n latestValues: ResolvedValues,\n transformTemplate?: MotionNodeOptions[\"transformTemplate\"]\n) {\n const { style, vars, transformOrigin } = state\n\n // Track whether we encounter any transform or transformOrigin values.\n let hasTransform = false\n let hasTransformOrigin = false\n\n /**\n * Loop over all our latest animated values and decide whether to handle them\n * as a style or CSS variable.\n *\n * Transforms and transform origins are kept separately for further processing.\n */\n for (const key in latestValues) {\n const value = latestValues[key]\n\n if (transformProps.has(key)) {\n // If this is a transform, flag to enable further transform processing\n hasTransform = true\n continue\n } else if (isCSSVariableName(key)) {\n vars[key] = value\n continue\n } else {\n // Convert the value to its default value type, ie 0 -> \"0px\"\n const valueAsType = getValueAsType(value, numberValueTypes[key])\n\n if (key.startsWith(\"origin\")) {\n // If this is a transform origin, flag and enable further transform-origin processing\n hasTransformOrigin = true\n transformOrigin[key as keyof typeof transformOrigin] =\n valueAsType\n } else {\n style[key] = valueAsType\n }\n }\n }\n\n if (!latestValues.transform) {\n if (hasTransform || transformTemplate) {\n style.transform = buildTransform(\n latestValues,\n state.transform,\n transformTemplate\n )\n } else if (style.transform) {\n /**\n * If we have previously created a transform but currently don't have any,\n * reset transform style to none.\n */\n style.transform = \"none\"\n }\n }\n\n /**\n * Build a transformOrigin style. Uses the same defaults as the browser for\n * undefined origins.\n */\n if (hasTransformOrigin) {\n const {\n originX = \"50%\",\n originY = \"50%\",\n originZ = 0,\n } = transformOrigin\n style.transformOrigin = `${originX} ${originY} ${originZ}`\n }\n}\n", "import type { MotionStyle } from \"../../VisualElement\"\nimport { HTMLRenderState } from \"../types\"\n\nexport function renderHTML(\n element: HTMLElement,\n { style, vars }: HTMLRenderState,\n styleProp?: MotionStyle,\n projection?: any\n) {\n const elementStyle = element.style\n\n let key: string\n for (key in style) {\n // CSSStyleDeclaration has [index: number]: string; in the types, so we use that as key type.\n elementStyle[key as unknown as number] = style[key] as string\n }\n\n // Write projection styles directly to element style\n projection?.applyProjectionStyles(elementStyle, styleProp)\n\n for (key in vars) {\n // Loop over any CSS variables and assign those.\n // They can only be assigned using `setProperty`.\n elementStyle.setProperty(key, vars[key] as string)\n }\n}\n", "import { px } from \"../../value/types/numbers/units\"\nimport type { Axis } from \"motion-utils\"\nimport type { ScaleCorrectorDefinition } from \"./types\"\n\nexport function pixelsToPercent(pixels: number, axis: Axis): number {\n if (axis.max === axis.min) return 0\n return (pixels / (axis.max - axis.min)) * 100\n}\n\n/**\n * We always correct borderRadius as a percentage rather than pixels to reduce paints.\n * For example, if you are projecting a box that is 100px wide with a 10px borderRadius\n * into a box that is 200px wide with a 20px borderRadius, that is actually a 10%\n * borderRadius in both states. If we animate between the two in pixels that will trigger\n * a paint each time. If we animate between the two in percentage we'll avoid a paint.\n */\nexport const correctBorderRadius: ScaleCorrectorDefinition = {\n correct: (latest, node) => {\n if (!node.target) return latest\n\n /**\n * If latest is a string, if it's a percentage we can return immediately as it's\n * going to be stretched appropriately. Otherwise, if it's a pixel, convert it to a number.\n */\n if (typeof latest === \"string\") {\n if (px.test(latest)) {\n latest = parseFloat(latest)\n } else {\n return latest\n }\n }\n\n /**\n * If latest is a number, it's a pixel value. We use the current viewportBox to calculate that\n * pixel value as a percentage of each axis\n */\n const x = pixelsToPercent(latest, node.target.x)\n const y = pixelsToPercent(latest, node.target.y)\n\n return `${x}% ${y}%`\n },\n}\n", "import { complex } from \"../../value/types/complex\"\nimport { mixNumber } from \"../../utils/mix/number\"\nimport type { ScaleCorrectorDefinition } from \"./types\"\n\nexport const correctBoxShadow: ScaleCorrectorDefinition = {\n correct: (latest: string, { treeScale, projectionDelta }) => {\n const original = latest\n const shadow = complex.parse(latest)\n\n // TODO: Doesn't support multiple shadows\n if (shadow.length > 5) return original\n\n const template = complex.createTransformer(latest)\n const offset = typeof shadow[0] !== \"number\" ? 1 : 0\n\n // Calculate the overall context scale\n const xScale = projectionDelta!.x.scale * treeScale!.x\n const yScale = projectionDelta!.y.scale * treeScale!.y\n\n // Scale x/y\n ;(shadow[0 + offset] as number) /= xScale\n ;(shadow[1 + offset] as number) /= yScale\n\n /**\n * Ideally we'd correct x and y scales individually, but because blur and\n * spread apply to both we have to take a scale average and apply that instead.\n * We could potentially improve the outcome of this by incorporating the ratio between\n * the two scales.\n */\n const averageScale = mixNumber(xScale, yScale, 0.5)\n\n // Blur\n if (typeof shadow[2 + offset] === \"number\")\n (shadow[2 + offset] as number) /= averageScale\n\n // Spread\n if (typeof shadow[3 + offset] === \"number\")\n (shadow[3 + offset] as number) /= averageScale\n\n return template(shadow)\n },\n}\n", "import { isCSSVariableName } from \"../../animation/utils/is-css-variable\"\nimport { correctBorderRadius } from \"./scale-border-radius\"\nimport { correctBoxShadow } from \"./scale-box-shadow\"\nimport type { ScaleCorrectorMap } from \"./types\"\n\nexport const scaleCorrectors: ScaleCorrectorMap = {\n borderRadius: {\n ...correctBorderRadius,\n applyTo: [\n \"borderTopLeftRadius\",\n \"borderTopRightRadius\",\n \"borderBottomLeftRadius\",\n \"borderBottomRightRadius\",\n ],\n },\n borderTopLeftRadius: correctBorderRadius,\n borderTopRightRadius: correctBorderRadius,\n borderBottomLeftRadius: correctBorderRadius,\n borderBottomRightRadius: correctBorderRadius,\n boxShadow: correctBoxShadow,\n}\n\nexport function addScaleCorrector(correctors: ScaleCorrectorMap) {\n for (const key in correctors) {\n scaleCorrectors[key] = correctors[key]\n if (isCSSVariableName(key)) {\n scaleCorrectors[key].isCSSVariable = true\n }\n }\n}\n", "import { transformProps } from \"./keys-transform\"\nimport type { MotionNodeOptions } from \"../../node/types\"\nimport {\n scaleCorrectors,\n addScaleCorrector,\n} from \"../../projection/styles/scale-correction\"\n\nexport { scaleCorrectors, addScaleCorrector }\n\nexport function isForcedMotionValue(\n key: string,\n { layout, layoutId }: MotionNodeOptions\n) {\n return (\n transformProps.has(key) ||\n key.startsWith(\"origin\") ||\n ((layout || layoutId !== undefined) &&\n (!!scaleCorrectors[key] || key === \"opacity\"))\n )\n}\n", "import { isMotionValue } from \"../../../value/utils/is-motion-value\"\nimport type { MotionNodeOptions } from \"../../../node/types\"\nimport { isForcedMotionValue } from \"../../utils/is-forced-motion-value\"\nimport type { VisualElement } from \"../../VisualElement\"\n\nexport function scrapeMotionValuesFromProps(\n props: MotionNodeOptions,\n prevProps: MotionNodeOptions,\n visualElement?: VisualElement\n) {\n const style = (props as any).style\n const prevStyle = (prevProps as any)?.style\n const newValues: { [key: string]: any } = {}\n\n if (!style) return newValues\n\n for (const key in style) {\n if (\n isMotionValue(style[key]) ||\n (prevStyle && isMotionValue(prevStyle[key])) ||\n isForcedMotionValue(key, props) ||\n visualElement?.getValue(key)?.liveStyle !== undefined\n ) {\n newValues[key] = style[key]\n }\n }\n\n return newValues\n}\n", "import type { Box } from \"motion-utils\"\nimport type { AnyResolvedKeyframe } from \"../../animation/types\"\nimport { isCSSVariableName } from \"../../animation/utils/is-css-variable\"\nimport type { MotionNodeOptions } from \"../../node/types\"\nimport { transformProps } from \"../utils/keys-transform\"\nimport {\n defaultTransformValue,\n readTransformValue,\n} from \"../dom/parse-transform\"\nimport { measureViewportBox } from \"../../projection/utils/measure\"\nimport { DOMVisualElement } from \"../dom/DOMVisualElement\"\nimport type { DOMVisualElementOptions } from \"../dom/types\"\nimport type { ResolvedValues, MotionConfigContextProps } from \"../types\"\nimport type { VisualElement } from \"../VisualElement\"\nimport { HTMLRenderState } from \"./types\"\nimport { buildHTMLStyles } from \"./utils/build-styles\"\nimport { renderHTML } from \"./utils/render\"\nimport { scrapeMotionValuesFromProps } from \"./utils/scrape-motion-values\"\n\nexport function getComputedStyle(element: HTMLElement) {\n return window.getComputedStyle(element)\n}\n\nexport class HTMLVisualElement extends DOMVisualElement<\n HTMLElement,\n HTMLRenderState,\n DOMVisualElementOptions\n> {\n type = \"html\"\n\n readValueFromInstance(\n instance: HTMLElement,\n key: string\n ): AnyResolvedKeyframe | null | undefined {\n if (transformProps.has(key)) {\n return this.projection?.isProjecting\n ? defaultTransformValue(key)\n : readTransformValue(instance, key)\n } else {\n const computedStyle = getComputedStyle(instance)\n const value =\n (isCSSVariableName(key)\n ? computedStyle.getPropertyValue(key)\n : computedStyle[key as keyof typeof computedStyle]) || 0\n\n return typeof value === \"string\" ? value.trim() : (value as number)\n }\n }\n\n measureInstanceViewportBox(\n instance: HTMLElement,\n { transformPagePoint }: MotionNodeOptions & Partial\n ): Box {\n return measureViewportBox(instance, transformPagePoint)\n }\n\n build(\n renderState: HTMLRenderState,\n latestValues: ResolvedValues,\n props: MotionNodeOptions\n ) {\n buildHTMLStyles(renderState, latestValues, props.transformTemplate)\n }\n\n scrapeMotionValuesFromProps(\n props: MotionNodeOptions,\n prevProps: MotionNodeOptions,\n visualElement: VisualElement\n ) {\n return scrapeMotionValuesFromProps(props, prevProps, visualElement)\n }\n\n renderInstance = renderHTML\n}\n", "import { ResolvedValues } from \"../../types\"\n\nconst dashKeys = {\n offset: \"stroke-dashoffset\",\n array: \"stroke-dasharray\",\n}\n\nconst camelKeys = {\n offset: \"strokeDashoffset\",\n array: \"strokeDasharray\",\n}\n\n/**\n * Build SVG path properties. Uses the path's measured length to convert\n * our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset\n * and stroke-dasharray attributes.\n *\n * This function is mutative to reduce per-frame GC.\n *\n * Note: We use unitless values for stroke-dasharray and stroke-dashoffset\n * because Safari incorrectly scales px values when the page is zoomed.\n */\nexport function buildSVGPath(\n attrs: ResolvedValues,\n length: number,\n spacing = 1,\n offset = 0,\n useDashCase: boolean = true\n): void {\n // Normalise path length by setting SVG attribute pathLength to 1\n attrs.pathLength = 1\n\n // We use dash case when setting attributes directly to the DOM node and camel case\n // when defining props on a React component.\n const keys = useDashCase ? dashKeys : camelKeys\n\n // Build the dash offset (unitless to avoid Safari zoom bug)\n attrs[keys.offset] = `${-offset}`\n\n // Build the dash array (unitless to avoid Safari zoom bug)\n attrs[keys.array] = `${length} ${spacing}`\n}\n", "import type { MotionNodeOptions } from \"../../../node/types\"\nimport { buildHTMLStyles } from \"../../html/utils/build-styles\"\nimport { ResolvedValues } from \"../../types\"\nimport { SVGRenderState } from \"../types\"\nimport { buildSVGPath } from \"./path\"\n\n/**\n * CSS Motion Path properties that should remain as CSS styles on SVG elements.\n */\nconst cssMotionPathProperties = [\n \"offsetDistance\",\n \"offsetPath\",\n \"offsetRotate\",\n \"offsetAnchor\",\n]\n\n/**\n * Build SVG visual attributes, like cx and style.transform\n */\nexport function buildSVGAttrs(\n state: SVGRenderState,\n {\n attrX,\n attrY,\n attrScale,\n pathLength,\n pathSpacing = 1,\n pathOffset = 0,\n // This is object creation, which we try to avoid per-frame.\n ...latest\n }: ResolvedValues,\n isSVGTag: boolean,\n transformTemplate?: MotionNodeOptions[\"transformTemplate\"],\n styleProp?: Record\n) {\n buildHTMLStyles(state, latest, transformTemplate)\n\n /**\n * For svg tags we just want to make sure viewBox is animatable and treat all the styles\n * as normal HTML tags.\n */\n if (isSVGTag) {\n if (state.style.viewBox) {\n state.attrs.viewBox = state.style.viewBox\n }\n return\n }\n\n state.attrs = state.style\n state.style = {}\n const { attrs, style } = state\n\n /**\n * However, we apply transforms as CSS transforms.\n * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.\n */\n if (attrs.transform) {\n style.transform = attrs.transform\n delete attrs.transform\n }\n if (style.transform || attrs.transformOrigin) {\n style.transformOrigin = attrs.transformOrigin ?? \"50% 50%\"\n delete attrs.transformOrigin\n }\n\n if (style.transform) {\n /**\n * SVG's element transform-origin uses its own median as a reference.\n * Therefore, transformBox becomes a fill-box\n */\n style.transformBox = (styleProp?.transformBox as string) ?? \"fill-box\"\n delete attrs.transformBox\n }\n\n for (const key of cssMotionPathProperties) {\n if (attrs[key] !== undefined) {\n style[key] = attrs[key]\n delete attrs[key]\n }\n }\n\n // Render attrX/attrY/attrScale as attributes\n if (attrX !== undefined) attrs.x = attrX\n if (attrY !== undefined) attrs.y = attrY\n if (attrScale !== undefined) attrs.scale = attrScale\n\n // Build SVG path if one has been defined\n if (pathLength !== undefined) {\n buildSVGPath(\n attrs,\n pathLength as number,\n pathSpacing as number,\n pathOffset as number,\n false\n )\n }\n}\n", "/**\n * A set of attribute names that are always read/written as camel case.\n */\nexport const camelCaseAttributes = new Set([\n \"baseFrequency\",\n \"diffuseConstant\",\n \"kernelMatrix\",\n \"kernelUnitLength\",\n \"keySplines\",\n \"keyTimes\",\n \"limitingConeAngle\",\n \"markerHeight\",\n \"markerWidth\",\n \"numOctaves\",\n \"targetX\",\n \"targetY\",\n \"surfaceScale\",\n \"specularConstant\",\n \"specularExponent\",\n \"stdDeviation\",\n \"tableValues\",\n \"viewBox\",\n \"gradientTransform\",\n \"pathLength\",\n \"startOffset\",\n \"textLength\",\n \"lengthAdjust\",\n])\n", "export const isSVGTag = (tag: unknown) =>\n typeof tag === \"string\" && tag.toLowerCase() === \"svg\"\n", "import type { MotionStyle } from \"../../VisualElement\"\nimport { camelToDash } from \"../../dom/utils/camel-to-dash\"\nimport { renderHTML } from \"../../html/utils/render\"\nimport { SVGRenderState } from \"../types\"\nimport { camelCaseAttributes } from \"./camel-case-attrs\"\n\nexport function renderSVG(\n element: SVGElement,\n renderState: SVGRenderState,\n _styleProp?: MotionStyle,\n projection?: any\n) {\n renderHTML(element as any, renderState, undefined, projection)\n\n for (const key in renderState.attrs) {\n element.setAttribute(\n !camelCaseAttributes.has(key) ? camelToDash(key) : key,\n renderState.attrs[key] as string\n )\n }\n}\n", "import { isMotionValue } from \"../../../value/utils/is-motion-value\"\nimport type { MotionNodeOptions } from \"../../../node/types\"\nimport { transformPropOrder } from \"../../utils/keys-transform\"\nimport { scrapeMotionValuesFromProps as scrapeHTMLMotionValuesFromProps } from \"../../html/utils/scrape-motion-values\"\nimport type { VisualElement } from \"../../VisualElement\"\n\nexport function scrapeMotionValuesFromProps(\n props: MotionNodeOptions,\n prevProps: MotionNodeOptions,\n visualElement?: VisualElement\n) {\n const newValues = scrapeHTMLMotionValuesFromProps(\n props,\n prevProps,\n visualElement\n )\n\n for (const key in props) {\n if (\n isMotionValue(props[key as keyof typeof props]) ||\n isMotionValue(prevProps[key as keyof typeof prevProps])\n ) {\n const targetKey =\n transformPropOrder.indexOf(key) !== -1\n ? \"attr\" + key.charAt(0).toUpperCase() + key.substring(1)\n : key\n\n newValues[targetKey] = props[key as keyof typeof props]\n }\n }\n\n return newValues\n}\n", "import type { AnyResolvedKeyframe } from \"../../animation/types\"\nimport type { MotionValue } from \"../../value\"\nimport type { MotionNodeOptions } from \"../../node/types\"\nimport { transformProps } from \"../utils/keys-transform\"\nimport { getDefaultValueType } from \"../../value/types/maps/defaults\"\nimport { createBox } from \"../../projection/geometry/models\"\nimport { DOMVisualElement } from \"../dom/DOMVisualElement\"\nimport type { DOMVisualElementOptions } from \"../dom/types\"\nimport { camelToDash } from \"../dom/utils/camel-to-dash\"\nimport type { ResolvedValues } from \"../types\"\nimport type { VisualElement, MotionStyle } from \"../VisualElement\"\nimport { SVGRenderState } from \"./types\"\nimport { buildSVGAttrs } from \"./utils/build-attrs\"\nimport { camelCaseAttributes } from \"./utils/camel-case-attrs\"\nimport { isSVGTag } from \"./utils/is-svg-tag\"\nimport { renderSVG } from \"./utils/render\"\nimport { scrapeMotionValuesFromProps } from \"./utils/scrape-motion-values\"\nexport class SVGVisualElement extends DOMVisualElement<\n SVGElement,\n SVGRenderState,\n DOMVisualElementOptions\n> {\n type = \"svg\"\n\n isSVGTag = false\n\n getBaseTargetFromProps(\n props: MotionNodeOptions,\n key: string\n ): AnyResolvedKeyframe | MotionValue | undefined {\n return props[key as keyof MotionNodeOptions]\n }\n\n readValueFromInstance(instance: SVGElement, key: string) {\n if (transformProps.has(key)) {\n const defaultType = getDefaultValueType(key)\n return defaultType ? defaultType.default || 0 : 0\n }\n key = !camelCaseAttributes.has(key) ? camelToDash(key) : key\n return instance.getAttribute(key)\n }\n\n measureInstanceViewportBox = createBox\n\n scrapeMotionValuesFromProps(\n props: MotionNodeOptions,\n prevProps: MotionNodeOptions,\n visualElement: VisualElement\n ) {\n return scrapeMotionValuesFromProps(props, prevProps, visualElement)\n }\n\n build(\n renderState: SVGRenderState,\n latestValues: ResolvedValues,\n props: MotionNodeOptions\n ) {\n buildSVGAttrs(\n renderState,\n latestValues,\n this.isSVGTag,\n props.transformTemplate,\n (props as any).style\n )\n }\n\n renderInstance(\n instance: SVGElement,\n renderState: SVGRenderState,\n styleProp?: MotionStyle | undefined,\n projection?: any\n ): void {\n renderSVG(instance, renderState, styleProp, projection)\n }\n\n mount(instance: SVGElement) {\n this.isSVGTag = isSVGTag(instance.tagName)\n super.mount(instance)\n }\n}\n", "import { isVariantLabel } from \"./is-variant-label\"\nimport { variantProps } from \"./variant-props\"\n\nconst numVariantProps = variantProps.length\n\ntype VariantStateContext = {\n initial?: string | string[]\n animate?: string | string[]\n exit?: string | string[]\n whileHover?: string | string[]\n whileDrag?: string | string[]\n whileFocus?: string | string[]\n whileTap?: string | string[]\n}\n\n/**\n * Get variant context from a visual element's parent chain.\n * Uses `any` type for visualElement to avoid circular dependencies.\n */\nexport function getVariantContext(\n visualElement?: any\n): undefined | VariantStateContext {\n if (!visualElement) return undefined\n\n if (!visualElement.isControllingVariants) {\n const context = visualElement.parent\n ? getVariantContext(visualElement.parent) || {}\n : {}\n if (visualElement.props.initial !== undefined) {\n context.initial = visualElement.props.initial as any\n }\n return context\n }\n\n const context: VariantStateContext = {}\n for (let i = 0; i < numVariantProps; i++) {\n const name = variantProps[i] as keyof typeof context\n const prop = visualElement.props[name]\n\n if (isVariantLabel(prop) || prop === false) {\n ;(context as any)[name] = prop\n }\n }\n\n return context\n}\n", "export function shallowCompare(next: any[], prev: any[] | null) {\n if (!Array.isArray(prev)) return false\n\n const prevLength = prev.length\n\n if (prevLength !== next.length) return false\n\n for (let i = 0; i < prevLength; i++) {\n if (prev[i] !== next[i]) return false\n }\n\n return true\n}\n", "import type {\n AnimationDefinition,\n TargetAndTransition,\n VariantLabels,\n} from \"../../node/types\"\nimport type { AnimationType } from \"../types\"\nimport type { VisualElementAnimationOptions } from \"../../animation/interfaces/types\"\nimport { animateVisualElement } from \"../../animation/interfaces/visual-element\"\nimport { calcChildStagger } from \"../../animation/utils/calc-child-stagger\"\nimport { getVariantContext } from \"./get-variant-context\"\nimport { isAnimationControls } from \"./is-animation-controls\"\nimport { isKeyframesTarget } from \"./is-keyframes-target\"\nimport { isVariantLabel } from \"./is-variant-label\"\nimport { resolveVariant } from \"./resolve-dynamic-variants\"\nimport { shallowCompare } from \"./shallow-compare\"\nimport { variantPriorityOrder } from \"./variant-props\"\n\nexport type { VisualElementAnimationOptions }\n\nexport interface AnimationState {\n animateChanges: (type?: AnimationType) => Promise\n setActive: (\n type: AnimationType,\n isActive: boolean,\n options?: VisualElementAnimationOptions\n ) => Promise\n setAnimateFunction: (fn: any) => void\n getState: () => { [key: string]: AnimationTypeState }\n reset: () => void\n}\n\ninterface DefinitionAndOptions {\n animation: AnimationDefinition\n options?: VisualElementAnimationOptions\n}\n\nexport type AnimationList = string[] | TargetAndTransition[]\n\nconst reversePriorityOrder = [...variantPriorityOrder].reverse()\nconst numAnimationTypes = variantPriorityOrder.length\n\n/**\n * Type for the animate function that can be injected.\n * This allows the animation implementation to be provided by the framework layer.\n */\nexport type AnimateFunction = (animations: DefinitionAndOptions[]) => Promise\n\nfunction createAnimateFunction(visualElement: any): AnimateFunction {\n return (animations: DefinitionAndOptions[]) => {\n return Promise.all(\n animations.map(({ animation, options }) =>\n animateVisualElement(visualElement, animation, options)\n )\n )\n }\n}\n\nexport function createAnimationState(visualElement: any): AnimationState {\n let animate = createAnimateFunction(visualElement)\n let state = createState()\n let isInitialRender = true\n /**\n * Track whether the animation state has been reset (e.g. via StrictMode\n * double-invocation or Suspense unmount/remount). On the first\n * animateChanges() call after a reset we need to behave like the initial\n * render for variant-inheritance checks, even though isInitialRender is\n * already false.\n */\n let wasReset = false\n\n /**\n * This function will be used to reduce the animation definitions for\n * each active animation type into an object of resolved values for it.\n */\n const buildResolvedTypeValues =\n (type: AnimationType) =>\n (\n acc: { [key: string]: any },\n definition: string | TargetAndTransition | undefined\n ) => {\n const resolved = resolveVariant(\n visualElement,\n definition,\n type === \"exit\"\n ? visualElement.presenceContext?.custom\n : undefined\n )\n\n if (resolved) {\n const { transition, transitionEnd, ...target } = resolved\n acc = { ...acc, ...target, ...transitionEnd }\n }\n\n return acc\n }\n\n /**\n * This just allows us to inject mocked animation functions\n * @internal\n */\n function setAnimateFunction(\n makeAnimator: (visualElement: any) => AnimateFunction\n ) {\n animate = makeAnimator(visualElement)\n }\n\n /**\n * When we receive new props, we need to:\n * 1. Create a list of protected keys for each type. This is a directory of\n * value keys that are currently being \"handled\" by types of a higher priority\n * so that whenever an animation is played of a given type, these values are\n * protected from being animated.\n * 2. Determine if an animation type needs animating.\n * 3. Determine if any values have been removed from a type and figure out\n * what to animate those to.\n */\n function animateChanges(changedActiveType?: AnimationType) {\n const { props } = visualElement\n const context = getVariantContext(visualElement.parent) || {}\n\n /**\n * A list of animations that we'll build into as we iterate through the animation\n * types. This will get executed at the end of the function.\n */\n const animations: DefinitionAndOptions[] = []\n\n /**\n * Keep track of which values have been removed. Then, as we hit lower priority\n * animation types, we can check if they contain removed values and animate to that.\n */\n const removedKeys = new Set()\n\n /**\n * A dictionary of all encountered keys. This is an object to let us build into and\n * copy it without iteration. Each time we hit an animation type we set its protected\n * keys - the keys its not allowed to animate - to the latest version of this object.\n */\n let encounteredKeys: { [key: string]: any } = {}\n\n /**\n * If a variant has been removed at a given index, and this component is controlling\n * variant animations, we want to ensure lower-priority variants are forced to animate.\n */\n let removedVariantIndex = Infinity\n\n /**\n * Iterate through all animation types in reverse priority order. For each, we want to\n * detect which values it's handling and whether or not they've changed (and therefore\n * need to be animated). If any values have been removed, we want to detect those in\n * lower priority props and flag for animation.\n */\n for (let i = 0; i < numAnimationTypes; i++) {\n const type = reversePriorityOrder[i]\n const typeState = state[type]\n const prop =\n props[type] !== undefined\n ? props[type]\n : context[type as keyof typeof context]\n const propIsVariant = isVariantLabel(prop)\n\n /**\n * If this type has *just* changed isActive status, set activeDelta\n * to that status. Otherwise set to null.\n */\n const activeDelta =\n type === changedActiveType ? typeState.isActive : null\n\n if (activeDelta === false) removedVariantIndex = i\n\n /**\n * If this prop is an inherited variant, rather than been set directly on the\n * component itself, we want to make sure we allow the parent to trigger animations.\n *\n * TODO: Can probably change this to a !isControllingVariants check\n */\n let isInherited =\n prop === context[type as keyof typeof context] &&\n prop !== props[type] &&\n propIsVariant\n\n if (\n isInherited &&\n (isInitialRender || wasReset) &&\n visualElement.manuallyAnimateOnMount\n ) {\n isInherited = false\n }\n\n /**\n * Set all encountered keys so far as the protected keys for this type. This will\n * be any key that has been animated or otherwise handled by active, higher-priortiy types.\n */\n typeState.protectedKeys = { ...encounteredKeys }\n\n // Check if we can skip analysing this prop early\n if (\n // If it isn't active and hasn't *just* been set as inactive\n (!typeState.isActive && activeDelta === null) ||\n // If we didn't and don't have any defined prop for this animation type\n (!prop && !typeState.prevProp) ||\n // Or if the prop doesn't define an animation\n isAnimationControls(prop) ||\n typeof prop === \"boolean\"\n ) {\n continue\n }\n\n /**\n * If exit is already active and wasn't just activated, skip\n * re-processing to prevent interrupting running exit animations.\n * Re-resolving exit with a changed custom value can start new\n * value animations that stop the originals, leaving the exit\n * animation promise unresolved and the component stuck in the DOM.\n */\n if (type === \"exit\" && typeState.isActive && activeDelta !== true) {\n if (typeState.prevResolvedValues) {\n encounteredKeys = {\n ...encounteredKeys,\n ...typeState.prevResolvedValues,\n }\n }\n continue\n }\n\n /**\n * As we go look through the values defined on this type, if we detect\n * a changed value or a value that was removed in a higher priority, we set\n * this to true and add this prop to the animation list.\n */\n const variantDidChange = checkVariantsDidChange(\n typeState.prevProp,\n prop\n )\n\n let shouldAnimateType =\n variantDidChange ||\n // If we're making this variant active, we want to always make it active\n (type === changedActiveType &&\n typeState.isActive &&\n !isInherited &&\n propIsVariant) ||\n // If we removed a higher-priority variant (i is in reverse order)\n (i > removedVariantIndex && propIsVariant)\n\n let handledRemovedValues = false\n\n /**\n * As animations can be set as variant lists, variants or target objects, we\n * coerce everything to an array if it isn't one already\n */\n const definitionList = Array.isArray(prop) ? prop : [prop]\n\n /**\n * Build an object of all the resolved values. We'll use this in the subsequent\n * animateChanges calls to determine whether a value has changed.\n */\n let resolvedValues = definitionList.reduce(\n buildResolvedTypeValues(type),\n {}\n )\n\n if (activeDelta === false) resolvedValues = {}\n\n /**\n * Now we need to loop through all the keys in the prev prop and this prop,\n * and decide:\n * 1. If the value has changed, and needs animating\n * 2. If it has been removed, and needs adding to the removedKeys set\n * 3. If it has been removed in a higher priority type and needs animating\n * 4. If it hasn't been removed in a higher priority but hasn't changed, and\n * needs adding to the type's protectedKeys list.\n */\n const { prevResolvedValues = {} } = typeState\n\n const allKeys = {\n ...prevResolvedValues,\n ...resolvedValues,\n }\n const markToAnimate = (key: string) => {\n shouldAnimateType = true\n if (removedKeys.has(key)) {\n handledRemovedValues = true\n removedKeys.delete(key)\n }\n typeState.needsAnimating[key] = true\n\n const motionValue = visualElement.getValue(key)\n if (motionValue) motionValue.liveStyle = false\n }\n\n for (const key in allKeys) {\n const next = resolvedValues[key]\n const prev = prevResolvedValues[key]\n\n // If we've already handled this we can just skip ahead\n if (encounteredKeys.hasOwnProperty(key)) continue\n\n /**\n * If the value has changed, we probably want to animate it.\n */\n let valueHasChanged = false\n if (isKeyframesTarget(next) && isKeyframesTarget(prev)) {\n valueHasChanged = !shallowCompare(next, prev)\n } else {\n valueHasChanged = next !== prev\n }\n\n if (valueHasChanged) {\n if (next !== undefined && next !== null) {\n // If next is defined and doesn't equal prev, it needs animating\n markToAnimate(key)\n } else {\n // If it's undefined, it's been removed.\n removedKeys.add(key)\n }\n } else if (next !== undefined && removedKeys.has(key)) {\n /**\n * If next hasn't changed and it isn't undefined, we want to check if it's\n * been removed by a higher priority\n */\n markToAnimate(key)\n } else {\n /**\n * If it hasn't changed, we add it to the list of protected values\n * to ensure it doesn't get animated.\n */\n typeState.protectedKeys[key] = true\n }\n }\n\n /**\n * Update the typeState so next time animateChanges is called we can compare the\n * latest prop and resolvedValues to these.\n */\n typeState.prevProp = prop\n typeState.prevResolvedValues = resolvedValues\n\n if (typeState.isActive) {\n encounteredKeys = { ...encounteredKeys, ...resolvedValues }\n }\n\n if (\n (isInitialRender || wasReset) &&\n visualElement.blockInitialAnimation\n ) {\n shouldAnimateType = false\n }\n\n /**\n * If this is an inherited prop we want to skip this animation\n * unless the inherited variants haven't changed on this render.\n */\n const willAnimateViaParent = isInherited && variantDidChange\n const needsAnimating = !willAnimateViaParent || handledRemovedValues\n if (shouldAnimateType && needsAnimating) {\n animations.push(\n ...definitionList.map((animation) => {\n const options: VisualElementAnimationOptions = { type }\n\n /**\n * If we're performing the initial animation, but we're not\n * rendering at the same time as the variant-controlling parent,\n * we want to use the parent's transition to calculate the stagger.\n */\n if (\n typeof animation === \"string\" &&\n (isInitialRender || wasReset) &&\n !willAnimateViaParent &&\n visualElement.manuallyAnimateOnMount &&\n visualElement.parent\n ) {\n const { parent } = visualElement\n const parentVariant = resolveVariant(\n parent,\n animation\n )\n\n if (parent.enteringChildren && parentVariant) {\n const { delayChildren } =\n parentVariant.transition || {}\n options.delay = calcChildStagger(\n parent.enteringChildren,\n visualElement,\n delayChildren\n )\n }\n }\n\n return {\n animation: animation as AnimationDefinition,\n options,\n }\n })\n )\n }\n }\n\n /**\n * If there are some removed value that haven't been dealt with,\n * we need to create a new animation that falls back either to the value\n * defined in the style prop, or the last read value.\n */\n if (removedKeys.size) {\n const fallbackAnimation: TargetAndTransition = {}\n\n /**\n * If the initial prop contains a transition we can use that, otherwise\n * allow the animation function to use the visual element's default.\n */\n if (typeof props.initial !== \"boolean\") {\n const initialTransition = resolveVariant(\n visualElement,\n Array.isArray(props.initial)\n ? props.initial[0]\n : props.initial\n )\n\n if (initialTransition && initialTransition.transition) {\n fallbackAnimation.transition = initialTransition.transition\n }\n }\n\n removedKeys.forEach((key) => {\n const fallbackTarget = visualElement.getBaseTarget(key)\n\n const motionValue = visualElement.getValue(key)\n if (motionValue) motionValue.liveStyle = true\n\n // @ts-expect-error - @mattgperry to figure if we should do something here\n fallbackAnimation[key] = fallbackTarget ?? null\n })\n\n animations.push({ animation: fallbackAnimation })\n }\n\n let shouldAnimate = Boolean(animations.length)\n\n if (\n isInitialRender &&\n (props.initial === false || props.initial === props.animate) &&\n !visualElement.manuallyAnimateOnMount\n ) {\n shouldAnimate = false\n }\n\n isInitialRender = false\n wasReset = false\n return shouldAnimate ? animate(animations) : Promise.resolve()\n }\n\n /**\n * Change whether a certain animation type is active.\n */\n function setActive(type: AnimationType, isActive: boolean) {\n // If the active state hasn't changed, we can safely do nothing here\n if (state[type].isActive === isActive) return Promise.resolve()\n\n // Propagate active change to children\n visualElement.variantChildren?.forEach((child: any) =>\n child.animationState?.setActive(type, isActive)\n )\n\n state[type].isActive = isActive\n\n const animations = animateChanges(type)\n\n for (const key in state) {\n state[key as keyof typeof state].protectedKeys = {}\n }\n\n return animations\n }\n\n return {\n animateChanges,\n setActive,\n setAnimateFunction,\n getState: () => state,\n reset: () => {\n state = createState()\n wasReset = true\n },\n }\n}\n\nexport function checkVariantsDidChange(prev: any, next: any) {\n if (typeof next === \"string\") {\n return next !== prev\n } else if (Array.isArray(next)) {\n return !shallowCompare(next, prev)\n }\n\n return false\n}\n\nexport interface AnimationTypeState {\n isActive: boolean\n protectedKeys: { [key: string]: true }\n needsAnimating: { [key: string]: boolean }\n prevResolvedValues: { [key: string]: any }\n prevProp?: VariantLabels | TargetAndTransition\n}\n\nfunction createTypeState(isActive = false): AnimationTypeState {\n return {\n isActive,\n protectedKeys: {},\n needsAnimating: {},\n prevResolvedValues: {},\n }\n}\n\nfunction createState() {\n return {\n animate: createTypeState(true),\n whileInView: createTypeState(),\n whileHover: createTypeState(),\n whileTap: createTypeState(),\n whileDrag: createTypeState(),\n whileFocus: createTypeState(),\n exit: createTypeState(),\n }\n}\n", "import { Axis, AxisDelta, Box } from \"motion-utils\"\n\n/**\n * Reset an axis to the provided origin box.\n *\n * This is a mutative operation.\n */\nexport function copyAxisInto(axis: Axis, originAxis: Axis) {\n axis.min = originAxis.min\n axis.max = originAxis.max\n}\n\n/**\n * Reset a box to the provided origin box.\n *\n * This is a mutative operation.\n */\nexport function copyBoxInto(box: Box, originBox: Box) {\n copyAxisInto(box.x, originBox.x)\n copyAxisInto(box.y, originBox.y)\n}\n\n/**\n * Reset a delta to the provided origin box.\n *\n * This is a mutative operation.\n */\nexport function copyAxisDeltaInto(delta: AxisDelta, originDelta: AxisDelta) {\n delta.translate = originDelta.translate\n delta.scale = originDelta.scale\n delta.originPoint = originDelta.originPoint\n delta.origin = originDelta.origin\n}\n", "import { Axis, AxisDelta, Box, Delta, Point } from \"motion-utils\"\nimport { mixNumber } from \"../../utils/mix/number\"\nimport { ResolvedValues } from \"../../render/types\"\n\nconst SCALE_PRECISION = 0.0001\nconst SCALE_MIN = 1 - SCALE_PRECISION\nconst SCALE_MAX = 1 + SCALE_PRECISION\nconst TRANSLATE_PRECISION = 0.01\nconst TRANSLATE_MIN = 0 - TRANSLATE_PRECISION\nconst TRANSLATE_MAX = 0 + TRANSLATE_PRECISION\n\nexport function calcLength(axis: Axis) {\n return axis.max - axis.min\n}\n\nexport function isNear(\n value: number,\n target: number,\n maxDistance: number\n): boolean {\n return Math.abs(value - target) <= maxDistance\n}\n\nexport function calcAxisDelta(\n delta: AxisDelta,\n source: Axis,\n target: Axis,\n origin: number = 0.5\n) {\n delta.origin = origin\n delta.originPoint = mixNumber(source.min, source.max, delta.origin)\n delta.scale = calcLength(target) / calcLength(source)\n delta.translate =\n mixNumber(target.min, target.max, delta.origin) - delta.originPoint\n\n if (\n (delta.scale >= SCALE_MIN && delta.scale <= SCALE_MAX) ||\n isNaN(delta.scale)\n ) {\n delta.scale = 1.0\n }\n\n if (\n (delta.translate >= TRANSLATE_MIN &&\n delta.translate <= TRANSLATE_MAX) ||\n isNaN(delta.translate)\n ) {\n delta.translate = 0.0\n }\n}\n\nexport function calcBoxDelta(\n delta: Delta,\n source: Box,\n target: Box,\n origin?: ResolvedValues\n): void {\n calcAxisDelta(\n delta.x,\n source.x,\n target.x,\n origin ? (origin.originX as number) : undefined\n )\n calcAxisDelta(\n delta.y,\n source.y,\n target.y,\n origin ? (origin.originY as number) : undefined\n )\n}\n\nexport function calcRelativeAxis(\n target: Axis,\n relative: Axis,\n parent: Axis,\n anchor: number = 0\n) {\n const anchorPoint = anchor\n ? mixNumber(parent.min, parent.max, anchor)\n : parent.min\n target.min = anchorPoint + relative.min\n target.max = target.min + calcLength(relative)\n}\n\nexport function calcRelativeBox(\n target: Box,\n relative: Box,\n parent: Box,\n anchor?: Point\n) {\n calcRelativeAxis(target.x, relative.x, parent.x, anchor?.x)\n calcRelativeAxis(target.y, relative.y, parent.y, anchor?.y)\n}\n\nexport function calcRelativeAxisPosition(\n target: Axis,\n layout: Axis,\n parent: Axis,\n anchor: number = 0\n) {\n const anchorPoint = anchor\n ? mixNumber(parent.min, parent.max, anchor)\n : parent.min\n target.min = layout.min - anchorPoint\n target.max = target.min + calcLength(layout)\n}\n\nexport function calcRelativePosition(\n target: Box,\n layout: Box,\n parent: Box,\n anchor?: Point\n) {\n calcRelativeAxisPosition(target.x, layout.x, parent.x, anchor?.x)\n calcRelativeAxisPosition(target.y, layout.y, parent.y, anchor?.y)\n}\n", "import { Axis, Box } from \"motion-utils\"\nimport { mixNumber } from \"../../utils/mix/number\"\nimport { percent } from \"../../value/types/numbers/units\"\nimport { ResolvedValues } from \"../../render/types\"\nimport { scalePoint } from \"./delta-apply\"\n\n/**\n * Remove a delta from a point. This is essentially the steps of applyPointDelta in reverse\n */\nexport function removePointDelta(\n point: number,\n translate: number,\n scale: number,\n originPoint: number,\n boxScale?: number\n): number {\n point -= translate\n point = scalePoint(point, 1 / scale, originPoint)\n\n if (boxScale !== undefined) {\n point = scalePoint(point, 1 / boxScale, originPoint)\n }\n\n return point\n}\n\n/**\n * Remove a delta from an axis. This is essentially the steps of applyAxisDelta in reverse\n */\nexport function removeAxisDelta(\n axis: Axis,\n translate: number | string = 0,\n scale: number = 1,\n origin: number = 0.5,\n boxScale?: number,\n originAxis: Axis = axis,\n sourceAxis: Axis = axis\n): void {\n if (percent.test(translate)) {\n translate = parseFloat(translate as string)\n const relativeProgress = mixNumber(\n sourceAxis.min,\n sourceAxis.max,\n translate / 100\n )\n translate = relativeProgress - sourceAxis.min\n }\n\n if (typeof translate !== \"number\") return\n\n let originPoint = mixNumber(originAxis.min, originAxis.max, origin)\n if (axis === originAxis) originPoint -= translate\n\n axis.min = removePointDelta(\n axis.min,\n translate,\n scale,\n originPoint,\n boxScale\n )\n\n axis.max = removePointDelta(\n axis.max,\n translate,\n scale,\n originPoint,\n boxScale\n )\n}\n\n/**\n * Remove a transforms from an axis. This is essentially the steps of applyAxisTransforms in reverse\n * and acts as a bridge between motion values and removeAxisDelta\n */\nexport function removeAxisTransforms(\n axis: Axis,\n transforms: ResolvedValues,\n [key, scaleKey, originKey]: string[],\n origin?: Axis,\n sourceAxis?: Axis\n) {\n removeAxisDelta(\n axis,\n transforms[key] as number,\n transforms[scaleKey] as number,\n transforms[originKey] as number,\n transforms.scale as number,\n origin,\n sourceAxis\n )\n}\n\n/**\n * The names of the motion values we want to apply as translation, scale and origin.\n */\nconst xKeys = [\"x\", \"scaleX\", \"originX\"]\nconst yKeys = [\"y\", \"scaleY\", \"originY\"]\n\n/**\n * Remove a transforms from an box. This is essentially the steps of applyAxisBox in reverse\n * and acts as a bridge between motion values and removeAxisDelta\n */\nexport function removeBoxTransforms(\n box: Box,\n transforms: ResolvedValues,\n originBox?: Box,\n sourceBox?: Box\n): void {\n removeAxisTransforms(\n box.x,\n transforms,\n xKeys,\n originBox ? originBox.x : undefined,\n sourceBox ? sourceBox.x : undefined\n )\n removeAxisTransforms(\n box.y,\n transforms,\n yKeys,\n originBox ? originBox.y : undefined,\n sourceBox ? sourceBox.y : undefined\n )\n}\n", "import { Axis, AxisDelta, Box, Delta } from \"motion-utils\"\nimport { calcLength } from \"./delta-calc\"\n\nfunction isAxisDeltaZero(delta: AxisDelta) {\n return delta.translate === 0 && delta.scale === 1\n}\n\nexport function isDeltaZero(delta: Delta) {\n return isAxisDeltaZero(delta.x) && isAxisDeltaZero(delta.y)\n}\n\nexport function axisEquals(a: Axis, b: Axis) {\n return a.min === b.min && a.max === b.max\n}\n\nexport function boxEquals(a: Box, b: Box) {\n return axisEquals(a.x, b.x) && axisEquals(a.y, b.y)\n}\n\nexport function axisEqualsRounded(a: Axis, b: Axis) {\n return (\n Math.round(a.min) === Math.round(b.min) &&\n Math.round(a.max) === Math.round(b.max)\n )\n}\n\nexport function boxEqualsRounded(a: Box, b: Box) {\n return axisEqualsRounded(a.x, b.x) && axisEqualsRounded(a.y, b.y)\n}\n\nexport function aspectRatio(box: Box): number {\n return calcLength(box.x) / calcLength(box.y)\n}\n\nexport function axisDeltaEquals(a: AxisDelta, b: AxisDelta) {\n return (\n a.translate === b.translate &&\n a.scale === b.scale &&\n a.originPoint === b.originPoint\n )\n}\n", "type Callback = (axis: \"x\" | \"y\") => void\n\nexport function eachAxis(callback: Callback) {\n return [callback(\"x\"), callback(\"y\")]\n}\n", "import type { Delta, Point } from \"motion-utils\"\nimport type { ResolvedValues } from \"../../node/types\"\n\nexport function buildProjectionTransform(\n delta: Delta,\n treeScale: Point,\n latestTransform?: ResolvedValues\n): string {\n let transform = \"\"\n\n /**\n * The translations we use to calculate are always relative to the viewport coordinate space.\n * But when we apply scales, we also scale the coordinate space of an element and its children.\n * For instance if we have a treeScale (the culmination of all parent scales) of 0.5 and we need\n * to move an element 100 pixels, we actually need to move it 200 in within that scaled space.\n */\n const xTranslate = delta.x.translate / treeScale.x\n const yTranslate = delta.y.translate / treeScale.y\n const zTranslate = latestTransform?.z || 0\n if (xTranslate || yTranslate || zTranslate) {\n transform = `translate3d(${xTranslate}px, ${yTranslate}px, ${zTranslate}px) `\n }\n\n /**\n * Apply scale correction for the tree transform.\n * This will apply scale to the screen-orientated axes.\n */\n if (treeScale.x !== 1 || treeScale.y !== 1) {\n transform += `scale(${1 / treeScale.x}, ${1 / treeScale.y}) `\n }\n\n if (latestTransform) {\n const { transformPerspective, rotate, rotateX, rotateY, skewX, skewY } =\n latestTransform\n if (transformPerspective)\n transform = `perspective(${transformPerspective}px) ${transform}`\n if (rotate) transform += `rotate(${rotate}deg) `\n if (rotateX) transform += `rotateX(${rotateX}deg) `\n if (rotateY) transform += `rotateY(${rotateY}deg) `\n if (skewX) transform += `skewX(${skewX}deg) `\n if (skewY) transform += `skewY(${skewY}deg) `\n }\n\n /**\n * Apply scale to match the size of the element to the size we want it.\n * This will apply scale to the element-orientated axes.\n */\n const elementScaleX = delta.x.scale * treeScale.x\n const elementScaleY = delta.y.scale * treeScale.y\n if (elementScaleX !== 1 || elementScaleY !== 1) {\n transform += `scale(${elementScaleX}, ${elementScaleY})`\n }\n\n return transform || \"none\"\n}\n", "import { mixNumber } from \"../../utils/mix/number\"\nimport { percent, px } from \"../../value/types/numbers/units\"\nimport type { AnyResolvedKeyframe } from \"../../animation/types\"\nimport {\n progress as calcProgress,\n circOut,\n EasingFunction,\n noop,\n} from \"motion-utils\"\nimport type { ResolvedValues } from \"../../node/types\"\n\nconst borderLabels = [\n \"borderTopLeftRadius\",\n \"borderTopRightRadius\",\n \"borderBottomLeftRadius\",\n \"borderBottomRightRadius\",\n]\nconst numBorders = borderLabels.length\n\nconst asNumber = (value: AnyResolvedKeyframe) =>\n typeof value === \"string\" ? parseFloat(value) : value\n\nconst isPx = (value: AnyResolvedKeyframe) =>\n typeof value === \"number\" || px.test(value)\n\nexport function mixValues(\n target: ResolvedValues,\n follow: ResolvedValues,\n lead: ResolvedValues,\n progress: number,\n shouldCrossfadeOpacity: boolean,\n isOnlyMember: boolean\n) {\n if (shouldCrossfadeOpacity) {\n target.opacity = mixNumber(\n 0,\n (lead.opacity as number) ?? 1,\n easeCrossfadeIn(progress)\n )\n target.opacityExit = mixNumber(\n (follow.opacity as number) ?? 1,\n 0,\n easeCrossfadeOut(progress)\n )\n } else if (isOnlyMember) {\n target.opacity = mixNumber(\n (follow.opacity as number) ?? 1,\n (lead.opacity as number) ?? 1,\n progress\n )\n }\n\n /**\n * Mix border radius\n */\n for (let i = 0; i < numBorders; i++) {\n const borderLabel = borderLabels[i]\n let followRadius = getRadius(follow, borderLabel)\n let leadRadius = getRadius(lead, borderLabel)\n\n if (followRadius === undefined && leadRadius === undefined) continue\n\n followRadius ||= 0\n leadRadius ||= 0\n\n const canMix =\n followRadius === 0 ||\n leadRadius === 0 ||\n isPx(followRadius) === isPx(leadRadius)\n\n if (canMix) {\n target[borderLabel] = Math.max(\n mixNumber(\n asNumber(followRadius),\n asNumber(leadRadius),\n progress\n ),\n 0\n )\n\n if (percent.test(leadRadius) || percent.test(followRadius)) {\n target[borderLabel] += \"%\"\n }\n } else {\n target[borderLabel] = leadRadius\n }\n }\n\n /**\n * Mix rotation\n */\n if (follow.rotate || lead.rotate) {\n target.rotate = mixNumber(\n (follow.rotate as number) || 0,\n (lead.rotate as number) || 0,\n progress\n )\n }\n}\n\nfunction getRadius(values: ResolvedValues, radiusName: string) {\n return values[radiusName] !== undefined\n ? values[radiusName]\n : values.borderRadius\n}\n\nconst easeCrossfadeIn = /*@__PURE__*/ compress(0, 0.5, circOut)\nconst easeCrossfadeOut = /*@__PURE__*/ compress(0.5, 0.95, noop)\n\nfunction compress(\n min: number,\n max: number,\n easing: EasingFunction\n): EasingFunction {\n return (p: number) => {\n // Could replace ifs with clamp\n if (p < min) return 0\n if (p > max) return 1\n return easing(calcProgress(min, max, p))\n }\n}\n", "import { animateMotionValue } from \"../interfaces/motion-value\"\nimport type {\n AnimationPlaybackControlsWithThen,\n AnyResolvedKeyframe,\n UnresolvedValueKeyframe,\n ValueAnimationTransition,\n} from \"../types\"\nimport {\n motionValue as createMotionValue,\n MotionValue,\n} from \"../../value\"\nimport { isMotionValue } from \"../../value/utils/is-motion-value\"\n\nexport function animateSingleValue(\n value: MotionValue | V,\n keyframes: V | UnresolvedValueKeyframe[],\n options?: ValueAnimationTransition\n): AnimationPlaybackControlsWithThen {\n const motionValue = isMotionValue(value) ? value : createMotionValue(value)\n\n motionValue.start(animateMotionValue(\"\", motionValue, keyframes, options))\n\n return motionValue.animation!\n}\n", "export function addDomEvent(\n target: EventTarget,\n eventName: string,\n handler: EventListener,\n options: AddEventListenerOptions = { passive: true }\n) {\n target.addEventListener(eventName, handler, options)\n\n return () => target.removeEventListener(eventName, handler)\n}\n", "import type { VisualElement } from \"../../render/VisualElement\"\n\nexport interface WithDepth {\n depth: number\n}\n\nexport const compareByDepth = (a: VisualElement, b: VisualElement) =>\n a.depth - b.depth\n", "import { addUniqueItem, removeItem } from \"motion-utils\"\nimport { compareByDepth, WithDepth } from \"./compare-by-depth\"\n\nexport class FlatTree {\n private children: WithDepth[] = []\n\n private isDirty: boolean = false\n\n add(child: WithDepth) {\n addUniqueItem(this.children, child)\n this.isDirty = true\n }\n\n remove(child: WithDepth) {\n removeItem(this.children, child)\n this.isDirty = true\n }\n\n forEach(callback: (child: WithDepth) => void) {\n this.isDirty && this.children.sort(compareByDepth)\n this.isDirty = false\n this.children.forEach(callback)\n }\n}\n", "import { cancelFrame, frame } from \"../frameloop\"\nimport { time } from \"../frameloop/sync-time\"\nimport type { FrameData } from \"../frameloop/types\"\nimport { secondsToMilliseconds } from \"motion-utils\"\n\nexport type DelayedFunction = (overshoot: number) => void\n\n/**\n * Timeout defined in ms\n */\nexport function delay(callback: DelayedFunction, timeout: number) {\n const start = time.now()\n\n const checkElapsed = ({ timestamp }: FrameData) => {\n const elapsed = timestamp - start\n\n if (elapsed >= timeout) {\n cancelFrame(checkElapsed)\n callback(elapsed - timeout)\n }\n }\n\n frame.setup(checkElapsed, true)\n\n return () => cancelFrame(checkElapsed)\n}\n\nexport function delayInSeconds(callback: DelayedFunction, timeout: number) {\n return delay(callback, secondsToMilliseconds(timeout))\n}\n", "import type { AnyResolvedKeyframe } from \"../../animation/types\"\nimport { isMotionValue } from \"./is-motion-value\"\nimport type { MotionValue } from \"../index\"\n\n/**\n * If the provided value is a MotionValue, this returns the actual value, otherwise just the value itself\n */\nexport function resolveMotionValue(\n value?: AnyResolvedKeyframe | MotionValue\n): AnyResolvedKeyframe {\n return isMotionValue(value) ? value.get() : value\n}\n", "import { addUniqueItem, removeItem } from \"motion-utils\"\nimport type { IProjectionNode } from \"../node/types\"\n\nexport class NodeStack {\n lead?: IProjectionNode\n prevLead?: IProjectionNode\n members: IProjectionNode[] = []\n\n add(node: IProjectionNode) {\n addUniqueItem(this.members, node)\n\n for (let i = this.members.length - 1; i >= 0; i--) {\n const member = this.members[i]\n if (member === node || member === this.lead || member === this.prevLead) continue\n const inst = member.instance as HTMLElement | undefined\n if ((!inst || inst.isConnected === false) && !member.snapshot) {\n removeItem(this.members, member)\n member.unmount()\n }\n }\n\n node.scheduleRender()\n }\n\n remove(node: IProjectionNode) {\n removeItem(this.members, node)\n if (node === this.prevLead) this.prevLead = undefined\n if (node === this.lead) {\n const prevLead = this.members[this.members.length - 1]\n if (prevLead) this.promote(prevLead)\n }\n }\n\n relegate(node: IProjectionNode) {\n for (let i = this.members.indexOf(node) - 1; i >= 0; i--) {\n const member = this.members[i]\n if (member.isPresent !== false && (member.instance as HTMLElement)?.isConnected !== false) {\n this.promote(member)\n return true\n }\n }\n return false\n }\n\n promote(node: IProjectionNode, preserveFollowOpacity?: boolean) {\n const prevLead = this.lead\n if (node === prevLead) return\n\n this.prevLead = prevLead\n this.lead = node\n node.show()\n\n if (prevLead) {\n prevLead.updateSnapshot()\n node.scheduleRender()\n\n const { layoutDependency: prevDep } = prevLead.options\n const { layoutDependency: nextDep } = node.options\n\n if (prevDep === undefined || prevDep !== nextDep) {\n node.resumeFrom = prevLead\n if (preserveFollowOpacity) prevLead.preserveOpacity = true\n\n if (prevLead.snapshot) {\n node.snapshot = prevLead.snapshot\n node.snapshot.latestValues =\n prevLead.animationValues || prevLead.latestValues\n }\n\n if (node.root?.isUpdating) node.isLayoutDirty = true\n }\n if (node.options.crossfade === false) prevLead.hide()\n }\n }\n\n exitAnimationComplete() {\n this.members.forEach((member) => {\n member.options.onExitComplete?.()\n member.resumingFrom?.options.onExitComplete?.()\n })\n }\n\n scheduleRender() {\n this.members.forEach(\n (member) => member.instance && member.scheduleRender(false)\n )\n }\n\n removeLeadSnapshot() {\n if (this.lead?.snapshot) this.lead.snapshot = undefined\n }\n}\n", "/**\n * This should only ever be modified on the client otherwise it'll\n * persist through server requests. If we need instanced states we\n * could lazy-init via root.\n */\nexport const globalProjectionState = {\n /**\n * Global flag as to whether the tree has animated since the last time\n * we resized the window\n */\n hasAnimatedSinceResize: true,\n\n /**\n * We set this to true once, on the first update. Any nodes added to the tree beyond that\n * update will be given a `data-projection-id` attribute.\n */\n hasEverUpdated: false,\n}\n", "import {\n Axis,\n AxisDelta,\n Box,\n clamp,\n Delta,\n noop,\n Point,\n SubscriptionManager,\n} from \"motion-utils\"\nimport { animateSingleValue } from \"../../animation/animate/single-value\"\nimport { JSAnimation } from \"../../animation/JSAnimation\"\nimport { getOptimisedAppearId } from \"../../animation/optimized-appear/get-appear-id\"\nimport { Transition, ValueAnimationOptions } from \"../../animation/types\"\nimport { getValueTransition } from \"../../animation/utils/get-value-transition\"\nimport { cancelFrame, frame, frameData, frameSteps } from \"../../frameloop\"\nimport { microtask } from \"../../frameloop/microtask\"\nimport { time } from \"../../frameloop/sync-time\"\nimport type { Process } from \"../../frameloop/types\"\nimport { HTMLVisualElement } from \"../../render/html/HTMLVisualElement\"\nimport type { ResolvedValues } from \"../../render/types\"\nimport { scaleCorrectors } from \"../../render/utils/is-forced-motion-value\"\nimport type { MotionStyle, VisualElement } from \"../../render/VisualElement\"\nimport { activeAnimations } from \"../../stats/animation-count\"\nimport { statsBuffer } from \"../../stats/buffer\"\nimport { delay } from \"../../utils/delay\"\nimport { isSVGElement } from \"../../utils/is-svg-element\"\nimport { isSVGSVGElement } from \"../../utils/is-svg-svg-element\"\nimport { mixNumber } from \"../../utils/mix/number\"\nimport { MotionValue, motionValue } from \"../../value\"\nimport { resolveMotionValue } from \"../../value/utils/resolve-motion-value\"\nimport { mixValues } from \"../animation/mix-values\"\nimport { copyAxisDeltaInto, copyAxisInto, copyBoxInto } from \"../geometry/copy\"\nimport {\n applyBoxDelta,\n applyTreeDeltas,\n transformBox,\n translateAxis,\n} from \"../geometry/delta-apply\"\nimport {\n calcBoxDelta,\n calcLength,\n calcRelativeBox,\n calcRelativePosition,\n isNear,\n} from \"../geometry/delta-calc\"\nimport { removeBoxTransforms } from \"../geometry/delta-remove\"\nimport { createBox, createDelta } from \"../geometry/models\"\nimport {\n aspectRatio,\n axisDeltaEquals,\n boxEquals,\n boxEqualsRounded,\n isDeltaZero,\n} from \"../geometry/utils\"\nimport { NodeStack } from \"../shared/stack\"\nimport { buildProjectionTransform } from \"../styles/transform\"\nimport { eachAxis } from \"../utils/each-axis\"\nimport { FlatTree } from \"../utils/flat-tree\"\nimport { has2DTranslate, hasScale, hasTransform } from \"../utils/has-transform\"\nimport { globalProjectionState } from \"./state\"\nimport {\n IProjectionNode,\n LayoutEvents,\n LayoutUpdateData,\n Measurements,\n Phase,\n ProjectionNodeConfig,\n ProjectionNodeOptions,\n ScrollMeasurements,\n} from \"./types\"\n\nconst metrics = {\n nodes: 0,\n calculatedTargetDeltas: 0,\n calculatedProjections: 0,\n}\n\nconst transformAxes = [\"\", \"X\", \"Y\", \"Z\"]\n\n/**\n * We use 1000 as the animation target as 0-1000 maps better to pixels than 0-1\n * which has a noticeable difference in spring animations\n */\nconst animationTarget = 1000\n\nlet id = 0\n\nfunction resetDistortingTransform(\n key: string,\n visualElement: VisualElement,\n values: ResolvedValues,\n sharedAnimationValues?: ResolvedValues\n) {\n const { latestValues } = visualElement\n\n // Record the distorting transform and then temporarily set it to 0\n if (latestValues[key]) {\n values[key] = latestValues[key]\n visualElement.setStaticValue(key, 0)\n if (sharedAnimationValues) {\n sharedAnimationValues[key] = 0\n }\n }\n}\n\nfunction cancelTreeOptimisedTransformAnimations(\n projectionNode: IProjectionNode\n) {\n projectionNode.hasCheckedOptimisedAppear = true\n if (projectionNode.root === projectionNode) return\n\n const { visualElement } = projectionNode.options\n\n if (!visualElement) return\n\n const appearId = getOptimisedAppearId(visualElement)\n\n if (window.MotionHasOptimisedAnimation!(appearId, \"transform\")) {\n const { layout, layoutId } = projectionNode.options\n window.MotionCancelOptimisedAnimation!(\n appearId,\n \"transform\",\n frame,\n !(layout || layoutId)\n )\n }\n\n const { parent } = projectionNode\n if (parent && !parent.hasCheckedOptimisedAppear) {\n cancelTreeOptimisedTransformAnimations(parent)\n }\n}\n\nexport function createProjectionNode({\n attachResizeListener,\n defaultParent,\n measureScroll,\n checkIsScrollRoot,\n resetTransform,\n}: ProjectionNodeConfig) {\n return class ProjectionNode implements IProjectionNode {\n /**\n * A unique ID generated for every projection node.\n */\n id: number = id++\n\n /**\n * An id that represents a unique session instigated by startUpdate.\n */\n animationId: number = 0\n\n animationCommitId = 0\n\n /**\n * A reference to the platform-native node (currently this will be a HTMLElement).\n */\n instance: I | undefined\n\n /**\n * A reference to the root projection node. There'll only ever be one tree and one root.\n */\n root: IProjectionNode\n\n /**\n * A reference to this node's parent.\n */\n parent?: IProjectionNode\n\n /**\n * A path from this node to the root node. This provides a fast way to iterate\n * back up the tree.\n */\n path: IProjectionNode[]\n\n /**\n * A Set containing all this component's children. This is used to iterate\n * through the children.\n *\n * TODO: This could be faster to iterate as a flat array stored on the root node.\n */\n children = new Set()\n\n /**\n * Options for the node. We use this to configure what kind of layout animations\n * we should perform (if any).\n */\n options: ProjectionNodeOptions = {}\n\n /**\n * A snapshot of the element's state just before the current update. This is\n * hydrated when this node's `willUpdate` method is called and scrubbed at the\n * end of the tree's `didUpdate` method.\n */\n snapshot: Measurements | undefined\n\n /**\n * A box defining the element's layout relative to the page. This will have been\n * captured with all parent scrolls and projection transforms unset.\n */\n layout: Measurements | undefined\n\n /**\n * The layout used to calculate the previous layout animation. We use this to compare\n * layouts between renders and decide whether we need to trigger a new layout animation\n * or just let the current one play out.\n */\n targetLayout?: Box\n\n /**\n * A mutable data structure we use to apply all parent transforms currently\n * acting on the element's layout. It's from here we can calculate the projectionDelta\n * required to get the element from its layout into its calculated target box.\n */\n layoutCorrected: Box\n\n /**\n * An ideal projection transform we want to apply to the element. This is calculated,\n * usually when an element's layout has changed, and we want the element to look as though\n * its in its previous layout on the next frame. From there, we animated it down to 0\n * to animate the element to its new layout.\n */\n targetDelta?: Delta\n\n /**\n * A mutable structure representing the visual bounding box on the page where we want\n * and element to appear. This can be set directly but is currently derived once a frame\n * from apply targetDelta to layout.\n */\n target?: Box\n\n /**\n * A mutable structure describing a visual bounding box relative to the element's\n * projected parent. If defined, target will be derived from this rather than targetDelta.\n * If not defined, we'll attempt to calculate on the first layout animation frame\n * based on the targets calculated from targetDelta. This will transfer a layout animation\n * from viewport-relative to parent-relative.\n */\n relativeTarget?: Box\n\n relativeTargetOrigin?: Box\n relativeParent?: IProjectionNode\n\n /**\n * We use this to detect when its safe to shut down part of a projection tree.\n * We have to keep projecting children for scale correction and relative projection\n * until all their parents stop performing layout animations.\n */\n isTreeAnimating = false\n\n isAnimationBlocked = false\n\n /**\n * If true, attempt to resolve relativeTarget.\n */\n attemptToResolveRelativeTarget?: boolean\n\n /**\n * A mutable structure that represents the target as transformed by the element's\n * latest user-set transforms (ie scale, x)\n */\n targetWithTransforms?: Box\n\n /**\n * The previous projection delta, which we can compare with the newly calculated\n * projection delta to see if we need to render.\n */\n prevProjectionDelta?: Delta\n\n /**\n * A calculated transform that will project an element from its layoutCorrected\n * into the target. This will be used by children to calculate their own layoutCorrect boxes.\n */\n projectionDelta?: Delta\n\n /**\n * A calculated transform that will project an element from its layoutCorrected\n * into the targetWithTransforms.\n */\n projectionDeltaWithTransform?: Delta\n\n /**\n * If we're tracking the scroll of this element, we store it here.\n */\n scroll?: ScrollMeasurements\n\n /**\n * Flag to true if we think this layout has been changed. We can't always know this,\n * currently we set it to true every time a component renders, or if it has a layoutDependency\n * if that has changed between renders. Additionally, components can be grouped by LayoutGroup\n * and if one node is dirtied, they all are.\n */\n isLayoutDirty = false\n\n /**\n * Flag to true if we think the projection calculations for this node needs\n * recalculating as a result of an updated transform or layout animation.\n */\n isProjectionDirty = false\n\n /**\n * Flag to true if the layout *or* transform has changed. This then gets propagated\n * throughout the projection tree, forcing any element below to recalculate on the next frame.\n */\n isSharedProjectionDirty = false\n\n /**\n * Flag transform dirty. This gets propagated throughout the whole tree but is only\n * respected by shared nodes.\n */\n isTransformDirty = false\n\n /**\n * Block layout updates for instant layout transitions throughout the tree.\n */\n updateManuallyBlocked = false\n\n updateBlockedByResize = false\n\n /**\n * Set to true between the start of the first `willUpdate` call and the end of the `didUpdate`\n * call.\n */\n isUpdating = false\n\n /**\n * If this is an SVG element we currently disable projection transforms\n */\n isSVG = false\n\n /**\n * Flag to true (during promotion) if a node doing an instant layout transition needs to reset\n * its projection styles.\n */\n needsReset = false\n\n /**\n * Flags whether this node should have its transform reset prior to measuring.\n */\n shouldResetTransform = false\n\n /**\n * Store whether this node has been checked for optimised appear animations. As\n * effects fire bottom-up, and we want to look up the tree for appear animations,\n * this makes sure we only check each path once, stopping at nodes that\n * have already been checked.\n */\n hasCheckedOptimisedAppear = false\n\n /**\n * An object representing the calculated contextual/accumulated/tree scale.\n * This will be used to scale calculcated projection transforms, as these are\n * calculated in screen-space but need to be scaled for elements to layoutly\n * make it to their calculated destinations.\n *\n * TODO: Lazy-init\n */\n treeScale: Point = { x: 1, y: 1 }\n\n /**\n * Is hydrated with a projection node if an element is animating from another.\n */\n resumeFrom?: IProjectionNode\n\n /**\n * Is hydrated with a projection node if an element is animating from another.\n */\n resumingFrom?: IProjectionNode\n\n /**\n * A reference to the element's latest animated values. This is a reference shared\n * between the element's VisualElement and the ProjectionNode.\n */\n latestValues: ResolvedValues\n\n /**\n *\n */\n eventHandlers = new Map>()\n\n nodes?: FlatTree\n\n depth: number\n\n /**\n * If transformTemplate generates a different value before/after the\n * update, we need to reset the transform.\n */\n prevTransformTemplateValue: string | undefined\n\n preserveOpacity?: boolean\n\n hasTreeAnimated = false\n\n layoutVersion: number = 0\n\n constructor(\n latestValues: ResolvedValues = {},\n parent: IProjectionNode | undefined = defaultParent?.()\n ) {\n this.latestValues = latestValues\n this.root = parent ? parent.root || parent : this\n this.path = parent ? [...parent.path, parent] : []\n this.parent = parent\n\n this.depth = parent ? parent.depth + 1 : 0\n\n for (let i = 0; i < this.path.length; i++) {\n this.path[i].shouldResetTransform = true\n }\n\n if (this.root === this) this.nodes = new FlatTree()\n }\n\n addEventListener(name: LayoutEvents, handler: any) {\n if (!this.eventHandlers.has(name)) {\n this.eventHandlers.set(name, new SubscriptionManager())\n }\n\n return this.eventHandlers.get(name)!.add(handler)\n }\n\n notifyListeners(name: LayoutEvents, ...args: any) {\n const subscriptionManager = this.eventHandlers.get(name)\n subscriptionManager && subscriptionManager.notify(...args)\n }\n\n hasListeners(name: LayoutEvents) {\n return this.eventHandlers.has(name)\n }\n\n /**\n * Lifecycles\n */\n mount(instance: I) {\n if (this.instance) return\n\n this.isSVG = isSVGElement(instance) && !isSVGSVGElement(instance)\n\n this.instance = instance\n\n const { layoutId, layout, visualElement } = this.options\n if (visualElement && !visualElement.current) {\n visualElement.mount(instance)\n }\n\n this.root.nodes!.add(this)\n this.parent && this.parent.children.add(this)\n\n if (this.root.hasTreeAnimated && (layout || layoutId)) {\n this.isLayoutDirty = true\n }\n\n if (attachResizeListener) {\n let cancelDelay: VoidFunction\n let innerWidth = 0\n\n const resizeUnblockUpdate = () =>\n (this.root.updateBlockedByResize = false)\n\n // Set initial innerWidth in a frame.read callback to batch the read\n frame.read(() => {\n innerWidth = window.innerWidth\n })\n\n attachResizeListener(instance, () => {\n const newInnerWidth = window.innerWidth\n if (newInnerWidth === innerWidth) return\n\n innerWidth = newInnerWidth\n\n this.root.updateBlockedByResize = true\n\n cancelDelay && cancelDelay()\n cancelDelay = delay(resizeUnblockUpdate, 250)\n\n if (globalProjectionState.hasAnimatedSinceResize) {\n globalProjectionState.hasAnimatedSinceResize = false\n this.nodes!.forEach(finishAnimation)\n }\n })\n }\n\n if (layoutId) {\n this.root.registerSharedNode(layoutId, this)\n }\n\n // Only register the handler if it requires layout animation\n if (\n this.options.animate !== false &&\n visualElement &&\n (layoutId || layout)\n ) {\n this.addEventListener(\n \"didUpdate\",\n ({\n delta,\n hasLayoutChanged,\n hasRelativeLayoutChanged,\n layout: newLayout,\n }: LayoutUpdateData) => {\n if (this.isTreeAnimationBlocked()) {\n this.target = undefined\n this.relativeTarget = undefined\n return\n }\n\n // TODO: Check here if an animation exists\n const layoutTransition =\n this.options.transition ||\n visualElement.getDefaultTransition() ||\n defaultLayoutTransition\n\n const {\n onLayoutAnimationStart,\n onLayoutAnimationComplete,\n } = visualElement.getProps()\n\n /**\n * The target layout of the element might stay the same,\n * but its position relative to its parent has changed.\n */\n const hasTargetChanged =\n !this.targetLayout ||\n !boxEqualsRounded(this.targetLayout, newLayout)\n /*\n * Note: Disabled to fix relative animations always triggering new\n * layout animations. If this causes further issues, we can try\n * a different approach to detecting relative target changes.\n */\n // || hasRelativeLayoutChanged\n\n /**\n * If the layout hasn't seemed to have changed, it might be that the\n * element is visually in the same place in the document but its position\n * relative to its parent has indeed changed. So here we check for that.\n */\n const hasOnlyRelativeTargetChanged =\n !hasLayoutChanged && hasRelativeLayoutChanged\n\n if (\n this.options.layoutRoot ||\n this.resumeFrom ||\n hasOnlyRelativeTargetChanged ||\n (hasLayoutChanged &&\n (hasTargetChanged || !this.currentAnimation))\n ) {\n if (this.resumeFrom) {\n this.resumingFrom = this.resumeFrom\n this.resumingFrom.resumingFrom = undefined\n }\n\n const animationOptions = {\n ...getValueTransition(\n layoutTransition,\n \"layout\"\n ),\n onPlay: onLayoutAnimationStart,\n onComplete: onLayoutAnimationComplete,\n }\n\n if (\n visualElement.shouldReduceMotion ||\n this.options.layoutRoot\n ) {\n animationOptions.delay = 0\n animationOptions.type = false\n }\n\n this.startAnimation(animationOptions)\n /**\n * Set animation origin after starting animation to avoid layout jump\n * caused by stopping previous layout animation\n */\n this.setAnimationOrigin(\n delta,\n hasOnlyRelativeTargetChanged\n )\n } else {\n /**\n * If the layout hasn't changed and we have an animation that hasn't started yet,\n * finish it immediately. Otherwise it will be animating from a location\n * that was probably never committed to screen and look like a jumpy box.\n */\n\n if (!hasLayoutChanged) {\n finishAnimation(this)\n }\n\n if (this.isLead() && this.options.onExitComplete) {\n this.options.onExitComplete()\n }\n }\n\n this.targetLayout = newLayout\n }\n )\n }\n }\n\n unmount() {\n this.options.layoutId && this.willUpdate()\n this.root.nodes!.remove(this)\n const stack = this.getStack()\n stack && stack.remove(this)\n this.parent && this.parent.children.delete(this)\n this.instance = undefined\n this.eventHandlers.clear()\n\n cancelFrame(this.updateProjection)\n }\n\n // only on the root\n blockUpdate() {\n this.updateManuallyBlocked = true\n }\n\n unblockUpdate() {\n this.updateManuallyBlocked = false\n }\n\n isUpdateBlocked() {\n return this.updateManuallyBlocked || this.updateBlockedByResize\n }\n\n isTreeAnimationBlocked() {\n return (\n this.isAnimationBlocked ||\n (this.parent && this.parent.isTreeAnimationBlocked()) ||\n false\n )\n }\n\n // Note: currently only running on root node\n startUpdate() {\n if (this.isUpdateBlocked()) return\n\n this.isUpdating = true\n\n this.nodes && this.nodes.forEach(resetSkewAndRotation)\n this.animationId++\n }\n\n getTransformTemplate() {\n const { visualElement } = this.options\n return visualElement && visualElement.getProps().transformTemplate\n }\n\n willUpdate(shouldNotifyListeners = true) {\n this.root.hasTreeAnimated = true\n\n if (this.root.isUpdateBlocked()) {\n this.options.onExitComplete && this.options.onExitComplete()\n return\n }\n\n /**\n * If we're running optimised appear animations then these must be\n * cancelled before measuring the DOM. This is so we can measure\n * the true layout of the element rather than the WAAPI animation\n * which will be unaffected by the resetSkewAndRotate step.\n *\n * Note: This is a DOM write. Worst case scenario is this is sandwiched\n * between other snapshot reads which will cause unnecessary style recalculations.\n * This has to happen here though, as we don't yet know which nodes will need\n * snapshots in startUpdate(), but we only want to cancel optimised animations\n * if a layout animation measurement is actually going to be affected by them.\n */\n if (\n window.MotionCancelOptimisedAnimation &&\n !this.hasCheckedOptimisedAppear\n ) {\n cancelTreeOptimisedTransformAnimations(this)\n }\n\n !this.root.isUpdating && this.root.startUpdate()\n\n if (this.isLayoutDirty) return\n\n this.isLayoutDirty = true\n for (let i = 0; i < this.path.length; i++) {\n const node = this.path[i]\n node.shouldResetTransform = true\n\n /**\n * Percentage translates resolve against layoutBox dimensions,\n * so ancestors with them must be re-measured after transform reset.\n */\n if (\n typeof node.latestValues.x === \"string\" ||\n typeof node.latestValues.y === \"string\"\n ) {\n node.isLayoutDirty = true\n }\n\n node.updateScroll(\"snapshot\")\n\n if (node.options.layoutRoot) {\n node.willUpdate(false)\n }\n }\n\n const { layoutId, layout } = this.options\n if (layoutId === undefined && !layout) return\n\n const transformTemplate = this.getTransformTemplate()\n this.prevTransformTemplateValue = transformTemplate\n ? transformTemplate(this.latestValues, \"\")\n : undefined\n\n this.updateSnapshot()\n shouldNotifyListeners && this.notifyListeners(\"willUpdate\")\n }\n\n // Note: Currently only running on root node\n updateScheduled = false\n\n update() {\n this.updateScheduled = false\n\n const updateWasBlocked = this.isUpdateBlocked()\n\n // When doing an instant transition, we skip the layout update,\n // but should still clean up the measurements so that the next\n // snapshot could be taken correctly.\n if (updateWasBlocked) {\n const wasBlockedByResize = this.updateBlockedByResize\n\n this.unblockUpdate()\n this.updateBlockedByResize = false\n this.clearAllSnapshots()\n\n /**\n * When blocked by resize, still measure layouts so\n * callbacks like onLayoutMeasure fire (e.g. Reorder).\n * Skip notifyLayoutUpdate to prevent animations.\n */\n if (wasBlockedByResize) {\n this.nodes!.forEach(forceLayoutMeasure)\n }\n\n this.nodes!.forEach(clearMeasurements)\n return\n }\n\n /**\n * If this is a repeat of didUpdate then ignore the animation.\n */\n if (this.animationId <= this.animationCommitId) {\n this.nodes!.forEach(clearIsLayoutDirty)\n return\n }\n\n this.animationCommitId = this.animationId\n\n if (!this.isUpdating) {\n this.nodes!.forEach(clearIsLayoutDirty)\n } else {\n this.isUpdating = false\n\n /**\n * Ensure animation-blocked nodes (e.g. during drag)\n * get measured even when memoized (willUpdate skipped).\n */\n this.nodes!.forEach(ensureDraggedNodesSnapshotted)\n\n /**\n * Write\n */\n this.nodes!.forEach(resetTransformStyle)\n\n /**\n * Read ==================\n */\n // Update layout measurements of updated children\n this.nodes!.forEach(updateLayout)\n\n /**\n * Write\n */\n // Notify listeners that the layout is updated\n this.nodes!.forEach(notifyLayoutUpdate)\n }\n\n this.clearAllSnapshots()\n\n /**\n * Manually flush any pending updates. Ideally\n * we could leave this to the following requestAnimationFrame but this seems\n * to leave a flash of incorrectly styled content.\n */\n const now = time.now()\n frameData.delta = clamp(0, 1000 / 60, now - frameData.timestamp)\n frameData.timestamp = now\n frameData.isProcessing = true\n frameSteps.update.process(frameData)\n frameSteps.preRender.process(frameData)\n frameSteps.render.process(frameData)\n frameData.isProcessing = false\n }\n\n scheduleUpdate = () => this.update()\n\n didUpdate() {\n if (!this.updateScheduled) {\n this.updateScheduled = true\n microtask.read(this.scheduleUpdate)\n }\n }\n\n clearAllSnapshots() {\n this.nodes!.forEach(clearSnapshot)\n this.sharedNodes.forEach(removeLeadSnapshots)\n }\n\n projectionUpdateScheduled = false\n scheduleUpdateProjection() {\n if (!this.projectionUpdateScheduled) {\n this.projectionUpdateScheduled = true\n frame.preRender(this.updateProjection, false, true)\n }\n }\n\n scheduleCheckAfterUnmount() {\n /**\n * If the unmounting node is in a layoutGroup and did trigger a willUpdate,\n * we manually call didUpdate to give a chance to the siblings to animate.\n * Otherwise, cleanup all snapshots to prevents future nodes from reusing them.\n */\n frame.postRender(() => {\n if (this.isLayoutDirty) {\n this.root.didUpdate()\n } else {\n this.root.checkUpdateFailed()\n }\n })\n }\n\n checkUpdateFailed = () => {\n if (this.isUpdating) {\n this.isUpdating = false\n this.clearAllSnapshots()\n }\n }\n\n /**\n * This is a multi-step process as shared nodes might be of different depths. Nodes\n * are sorted by depth order, so we need to resolve the entire tree before moving to\n * the next step.\n */\n updateProjection = () => {\n this.projectionUpdateScheduled = false\n\n /**\n * Reset debug counts. Manually resetting rather than creating a new\n * object each frame.\n */\n if (statsBuffer.value) {\n metrics.nodes =\n metrics.calculatedTargetDeltas =\n metrics.calculatedProjections =\n 0\n }\n\n this.nodes!.forEach(propagateDirtyNodes)\n this.nodes!.forEach(resolveTargetDelta)\n this.nodes!.forEach(calcProjection)\n this.nodes!.forEach(cleanDirtyNodes)\n\n if (statsBuffer.addProjectionMetrics) {\n statsBuffer.addProjectionMetrics(metrics)\n }\n }\n\n /**\n * Update measurements\n */\n updateSnapshot() {\n if (this.snapshot || !this.instance) return\n\n this.snapshot = this.measure()\n\n if (\n this.snapshot &&\n !calcLength(this.snapshot.measuredBox.x) &&\n !calcLength(this.snapshot.measuredBox.y)\n ) {\n this.snapshot = undefined\n }\n }\n\n updateLayout() {\n if (!this.instance) return\n\n this.updateScroll()\n\n if (\n !(this.options.alwaysMeasureLayout && this.isLead()) &&\n !this.isLayoutDirty\n ) {\n return\n }\n\n /**\n * When a node is mounted, it simply resumes from the prevLead's\n * snapshot instead of taking a new one, but the ancestors scroll\n * might have updated while the prevLead is unmounted. We need to\n * update the scroll again to make sure the layout we measure is\n * up to date.\n */\n if (this.resumeFrom && !this.resumeFrom.instance) {\n for (let i = 0; i < this.path.length; i++) {\n const node = this.path[i]\n node.updateScroll()\n }\n }\n\n const prevLayout = this.layout\n this.layout = this.measure(false)\n this.layoutVersion++\n if (!this.layoutCorrected) this.layoutCorrected = createBox()\n this.isLayoutDirty = false\n this.projectionDelta = undefined\n this.notifyListeners(\"measure\", this.layout.layoutBox)\n\n const { visualElement } = this.options\n visualElement &&\n visualElement.notify(\n \"LayoutMeasure\",\n this.layout.layoutBox,\n prevLayout ? prevLayout.layoutBox : undefined\n )\n }\n\n updateScroll(phase: Phase = \"measure\") {\n let needsMeasurement = Boolean(\n this.options.layoutScroll && this.instance\n )\n\n if (\n this.scroll &&\n this.scroll.animationId === this.root.animationId &&\n this.scroll.phase === phase\n ) {\n needsMeasurement = false\n }\n\n if (needsMeasurement && this.instance) {\n const isRoot = checkIsScrollRoot(this.instance)\n this.scroll = {\n animationId: this.root.animationId,\n phase,\n isRoot,\n offset: measureScroll(this.instance),\n wasRoot: this.scroll ? this.scroll.isRoot : isRoot,\n }\n }\n }\n\n resetTransform() {\n if (!resetTransform) return\n\n const isResetRequested =\n this.isLayoutDirty ||\n this.shouldResetTransform ||\n this.options.alwaysMeasureLayout\n\n const hasProjection =\n this.projectionDelta && !isDeltaZero(this.projectionDelta)\n\n const transformTemplate = this.getTransformTemplate()\n const transformTemplateValue = transformTemplate\n ? transformTemplate(this.latestValues, \"\")\n : undefined\n\n const transformTemplateHasChanged =\n transformTemplateValue !== this.prevTransformTemplateValue\n\n if (\n isResetRequested &&\n this.instance &&\n (hasProjection ||\n hasTransform(this.latestValues) ||\n transformTemplateHasChanged)\n ) {\n resetTransform(this.instance, transformTemplateValue)\n this.shouldResetTransform = false\n this.scheduleRender()\n }\n }\n\n measure(removeTransform = true) {\n const pageBox = this.measurePageBox()\n\n let layoutBox = this.removeElementScroll(pageBox)\n\n /**\n * Measurements taken during the pre-render stage\n * still have transforms applied so we remove them\n * via calculation.\n */\n if (removeTransform) {\n layoutBox = this.removeTransform(layoutBox)\n }\n\n roundBox(layoutBox)\n\n return {\n animationId: this.root.animationId,\n measuredBox: pageBox,\n layoutBox,\n latestValues: {},\n source: this.id,\n }\n }\n\n measurePageBox() {\n const { visualElement } = this.options\n if (!visualElement) return createBox()\n\n const box = visualElement.measureViewportBox()\n\n const wasInScrollRoot =\n this.scroll?.wasRoot || this.path.some(checkNodeWasScrollRoot)\n\n if (!wasInScrollRoot) {\n // Remove viewport scroll to give page-relative coordinates\n const { scroll } = this.root\n if (scroll) {\n translateAxis(box.x, scroll.offset.x)\n translateAxis(box.y, scroll.offset.y)\n }\n }\n\n return box\n }\n\n removeElementScroll(box: Box): Box {\n const boxWithoutScroll = createBox()\n copyBoxInto(boxWithoutScroll, box)\n\n if (this.scroll?.wasRoot) {\n return boxWithoutScroll\n }\n\n /**\n * Performance TODO: Keep a cumulative scroll offset down the tree\n * rather than loop back up the path.\n */\n for (let i = 0; i < this.path.length; i++) {\n const node = this.path[i]\n const { scroll, options } = node\n\n if (node !== this.root && scroll && options.layoutScroll) {\n /**\n * If this is a new scroll root, we want to remove all previous scrolls\n * from the viewport box.\n */\n if (scroll.wasRoot) {\n copyBoxInto(boxWithoutScroll, box)\n }\n\n translateAxis(boxWithoutScroll.x, scroll.offset.x)\n translateAxis(boxWithoutScroll.y, scroll.offset.y)\n }\n }\n\n return boxWithoutScroll\n }\n\n applyTransform(box: Box, transformOnly = false, output?: Box): Box {\n const withTransforms = output || createBox()\n copyBoxInto(withTransforms, box)\n for (let i = 0; i < this.path.length; i++) {\n const node = this.path[i]\n\n if (\n !transformOnly &&\n node.options.layoutScroll &&\n node.scroll &&\n node !== node.root\n ) {\n translateAxis(withTransforms.x, -node.scroll.offset.x)\n translateAxis(withTransforms.y, -node.scroll.offset.y)\n }\n\n if (!hasTransform(node.latestValues)) continue\n transformBox(\n withTransforms,\n node.latestValues,\n node.layout?.layoutBox\n )\n }\n\n if (hasTransform(this.latestValues)) {\n transformBox(\n withTransforms,\n this.latestValues,\n this.layout?.layoutBox\n )\n }\n\n return withTransforms\n }\n\n removeTransform(box: Box): Box {\n const boxWithoutTransform = createBox()\n copyBoxInto(boxWithoutTransform, box)\n\n for (let i = 0; i < this.path.length; i++) {\n const node = this.path[i]\n if (!hasTransform(node.latestValues)) continue\n\n let sourceBox: Box | undefined\n\n if (node.instance) {\n hasScale(node.latestValues) && node.updateSnapshot()\n sourceBox = createBox()\n copyBoxInto(sourceBox, node.measurePageBox())\n }\n\n removeBoxTransforms(\n boxWithoutTransform,\n node.latestValues,\n node.snapshot?.layoutBox,\n sourceBox\n )\n }\n\n if (hasTransform(this.latestValues)) {\n removeBoxTransforms(boxWithoutTransform, this.latestValues)\n }\n\n return boxWithoutTransform\n }\n\n setTargetDelta(delta: Delta) {\n this.targetDelta = delta\n this.root.scheduleUpdateProjection()\n this.isProjectionDirty = true\n }\n\n setOptions(options: ProjectionNodeOptions) {\n this.options = {\n ...this.options,\n ...options,\n crossfade:\n options.crossfade !== undefined ? options.crossfade : true,\n }\n }\n\n clearMeasurements() {\n this.scroll = undefined\n this.layout = undefined\n this.snapshot = undefined\n this.prevTransformTemplateValue = undefined\n this.targetDelta = undefined\n this.target = undefined\n this.isLayoutDirty = false\n }\n\n forceRelativeParentToResolveTarget() {\n if (!this.relativeParent) return\n\n /**\n * If the parent target isn't up-to-date, force it to update.\n * This is an unfortunate de-optimisation as it means any updating relative\n * projection will cause all the relative parents to recalculate back\n * up the tree.\n */\n if (\n this.relativeParent.resolvedRelativeTargetAt !==\n frameData.timestamp\n ) {\n this.relativeParent.resolveTargetDelta(true)\n }\n }\n\n /**\n * Frame calculations\n */\n resolvedRelativeTargetAt: number = 0.0\n resolveTargetDelta(forceRecalculation = false) {\n /**\n * Once the dirty status of nodes has been spread through the tree, we also\n * need to check if we have a shared node of a different depth that has itself\n * been dirtied.\n */\n const lead = this.getLead()\n this.isProjectionDirty ||= lead.isProjectionDirty\n this.isTransformDirty ||= lead.isTransformDirty\n this.isSharedProjectionDirty ||= lead.isSharedProjectionDirty\n\n const isShared = Boolean(this.resumingFrom) || this !== lead\n\n /**\n * We don't use transform for this step of processing so we don't\n * need to check whether any nodes have changed transform.\n */\n const canSkip = !(\n forceRecalculation ||\n (isShared && this.isSharedProjectionDirty) ||\n this.isProjectionDirty ||\n this.parent?.isProjectionDirty ||\n this.attemptToResolveRelativeTarget ||\n this.root.updateBlockedByResize\n )\n\n if (canSkip) return\n\n const { layout, layoutId } = this.options\n\n /**\n * If we have no layout, we can't perform projection, so early return\n */\n if (!this.layout || !(layout || layoutId)) return\n\n this.resolvedRelativeTargetAt = frameData.timestamp\n\n const relativeParent = this.getClosestProjectingParent()\n\n if (\n relativeParent &&\n this.linkedParentVersion !== relativeParent.layoutVersion &&\n !relativeParent.options.layoutRoot\n ) {\n this.removeRelativeTarget()\n }\n\n /**\n * If we don't have a targetDelta but do have a layout, we can attempt to resolve\n * a relativeParent. This will allow a component to perform scale correction\n * even if no animation has started.\n */\n if (!this.targetDelta && !this.relativeTarget) {\n if (\n this.options.layoutAnchor !== false &&\n relativeParent &&\n relativeParent.layout\n ) {\n this.createRelativeTarget(\n relativeParent,\n this.layout.layoutBox,\n relativeParent.layout.layoutBox\n )\n } else {\n this.removeRelativeTarget()\n }\n }\n\n /**\n * If we have no relative target or no target delta our target isn't valid\n * for this frame.\n */\n if (!this.relativeTarget && !this.targetDelta) return\n\n /**\n * Lazy-init target data structure\n */\n if (!this.target) {\n this.target = createBox()\n this.targetWithTransforms = createBox()\n }\n\n /**\n * If we've got a relative box for this component, resolve it into a target relative to the parent.\n */\n if (\n this.relativeTarget &&\n this.relativeTargetOrigin &&\n this.relativeParent &&\n this.relativeParent.target\n ) {\n this.forceRelativeParentToResolveTarget()\n\n calcRelativeBox(\n this.target,\n this.relativeTarget,\n this.relativeParent.target,\n this.options.layoutAnchor || undefined\n )\n\n /**\n * If we've only got a targetDelta, resolve it into a target\n */\n } else if (this.targetDelta) {\n if (Boolean(this.resumingFrom)) {\n this.applyTransform(\n this.layout.layoutBox,\n false,\n this.target\n )\n } else {\n copyBoxInto(this.target, this.layout.layoutBox)\n }\n\n applyBoxDelta(this.target, this.targetDelta)\n } else {\n /**\n * If no target, use own layout as target\n */\n copyBoxInto(this.target, this.layout.layoutBox)\n }\n\n /**\n * If we've been told to attempt to resolve a relative target, do so.\n */\n if (this.attemptToResolveRelativeTarget) {\n this.attemptToResolveRelativeTarget = false\n\n if (\n this.options.layoutAnchor !== false &&\n relativeParent &&\n Boolean(relativeParent.resumingFrom) ===\n Boolean(this.resumingFrom) &&\n !relativeParent.options.layoutScroll &&\n relativeParent.target &&\n this.animationProgress !== 1\n ) {\n this.createRelativeTarget(\n relativeParent,\n this.target,\n relativeParent.target\n )\n } else {\n this.relativeParent = this.relativeTarget = undefined\n }\n }\n\n /**\n * Increase debug counter for resolved target deltas\n */\n if (statsBuffer.value) {\n metrics.calculatedTargetDeltas++\n }\n }\n\n getClosestProjectingParent() {\n if (\n !this.parent ||\n hasScale(this.parent.latestValues) ||\n has2DTranslate(this.parent.latestValues)\n ) {\n return undefined\n }\n\n if (this.parent.isProjecting()) {\n return this.parent\n } else {\n return this.parent.getClosestProjectingParent()\n }\n }\n\n isProjecting() {\n return Boolean(\n (this.relativeTarget ||\n this.targetDelta ||\n this.options.layoutRoot) &&\n this.layout\n )\n }\n\n linkedParentVersion: number = 0\n createRelativeTarget(\n relativeParent: IProjectionNode,\n layout: Box,\n parentLayout: Box\n ) {\n this.relativeParent = relativeParent\n this.linkedParentVersion = relativeParent.layoutVersion\n this.forceRelativeParentToResolveTarget()\n this.relativeTarget = createBox()\n this.relativeTargetOrigin = createBox()\n calcRelativePosition(\n this.relativeTargetOrigin,\n layout,\n parentLayout,\n this.options.layoutAnchor || undefined\n )\n\n copyBoxInto(this.relativeTarget, this.relativeTargetOrigin)\n }\n\n removeRelativeTarget() {\n this.relativeParent = this.relativeTarget = undefined\n }\n\n hasProjected: boolean = false\n\n calcProjection() {\n const lead = this.getLead()\n const isShared = Boolean(this.resumingFrom) || this !== lead\n\n let canSkip = true\n\n /**\n * If this is a normal layout animation and neither this node nor its nearest projecting\n * is dirty then we can't skip.\n */\n if (this.isProjectionDirty || this.parent?.isProjectionDirty) {\n canSkip = false\n }\n\n /**\n * If this is a shared layout animation and this node's shared projection is dirty then\n * we can't skip.\n */\n if (\n isShared &&\n (this.isSharedProjectionDirty || this.isTransformDirty)\n ) {\n canSkip = false\n }\n\n /**\n * If we have resolved the target this frame we must recalculate the\n * projection to ensure it visually represents the internal calculations.\n */\n if (this.resolvedRelativeTargetAt === frameData.timestamp) {\n canSkip = false\n }\n\n if (canSkip) return\n\n const { layout, layoutId } = this.options\n\n /**\n * If this section of the tree isn't animating we can\n * delete our target sources for the following frame.\n */\n this.isTreeAnimating = Boolean(\n (this.parent && this.parent.isTreeAnimating) ||\n this.currentAnimation ||\n this.pendingAnimation\n )\n if (!this.isTreeAnimating) {\n this.targetDelta = this.relativeTarget = undefined\n }\n\n if (!this.layout || !(layout || layoutId)) return\n\n /**\n * Reset the corrected box with the latest values from box, as we're then going\n * to perform mutative operations on it.\n */\n copyBoxInto(this.layoutCorrected, this.layout.layoutBox)\n\n /**\n * Record previous tree scales before updating.\n */\n const prevTreeScaleX = this.treeScale.x\n const prevTreeScaleY = this.treeScale.y\n /**\n * Apply all the parent deltas to this box to produce the corrected box. This\n * is the layout box, as it will appear on screen as a result of the transforms of its parents.\n */\n applyTreeDeltas(\n this.layoutCorrected,\n this.treeScale,\n this.path,\n isShared\n )\n\n /**\n * If this layer needs to perform scale correction but doesn't have a target,\n * use the layout as the target.\n */\n if (\n lead.layout &&\n !lead.target &&\n (this.treeScale.x !== 1 || this.treeScale.y !== 1)\n ) {\n lead.target = lead.layout.layoutBox\n lead.targetWithTransforms = createBox()\n }\n\n const { target } = lead\n\n if (!target) {\n /**\n * If we don't have a target to project into, but we were previously\n * projecting, we want to remove the stored transform and schedule\n * a render to ensure the elements reflect the removed transform.\n */\n if (this.prevProjectionDelta) {\n this.createProjectionDeltas()\n this.scheduleRender()\n }\n\n return\n }\n\n if (!this.projectionDelta || !this.prevProjectionDelta) {\n this.createProjectionDeltas()\n } else {\n copyAxisDeltaInto(\n this.prevProjectionDelta.x,\n this.projectionDelta.x\n )\n copyAxisDeltaInto(\n this.prevProjectionDelta.y,\n this.projectionDelta.y\n )\n }\n\n /**\n * Update the delta between the corrected box and the target box before user-set transforms were applied.\n * This will allow us to calculate the corrected borderRadius and boxShadow to compensate\n * for our layout reprojection, but still allow them to be scaled correctly by the user.\n * It might be that to simplify this we may want to accept that user-set scale is also corrected\n * and we wouldn't have to keep and calc both deltas, OR we could support a user setting\n * to allow people to choose whether these styles are corrected based on just the\n * layout reprojection or the final bounding box.\n */\n calcBoxDelta(\n this.projectionDelta!,\n this.layoutCorrected,\n target,\n this.latestValues\n )\n\n if (\n this.treeScale.x !== prevTreeScaleX ||\n this.treeScale.y !== prevTreeScaleY ||\n !axisDeltaEquals(\n this.projectionDelta!.x,\n this.prevProjectionDelta!.x\n ) ||\n !axisDeltaEquals(\n this.projectionDelta!.y,\n this.prevProjectionDelta!.y\n )\n ) {\n this.hasProjected = true\n this.scheduleRender()\n this.notifyListeners(\"projectionUpdate\", target)\n }\n\n /**\n * Increase debug counter for recalculated projections\n */\n if (statsBuffer.value) {\n metrics.calculatedProjections++\n }\n }\n\n isVisible = true\n hide() {\n this.isVisible = false\n // TODO: Schedule render\n }\n show() {\n this.isVisible = true\n // TODO: Schedule render\n }\n\n scheduleRender(notifyAll = true) {\n this.options.visualElement?.scheduleRender()\n if (notifyAll) {\n const stack = this.getStack()\n stack && stack.scheduleRender()\n }\n if (this.resumingFrom && !this.resumingFrom.instance) {\n this.resumingFrom = undefined\n }\n }\n\n createProjectionDeltas() {\n this.prevProjectionDelta = createDelta()\n this.projectionDelta = createDelta()\n this.projectionDeltaWithTransform = createDelta()\n }\n\n /**\n * Animation\n */\n animationValues?: ResolvedValues\n pendingAnimation?: Process\n currentAnimation?: JSAnimation\n mixTargetDelta: (progress: number) => void\n animationProgress = 0\n\n setAnimationOrigin(\n delta: Delta,\n hasOnlyRelativeTargetChanged: boolean = false\n ) {\n const snapshot = this.snapshot\n const snapshotLatestValues = snapshot ? snapshot.latestValues : {}\n const mixedValues = { ...this.latestValues }\n\n const targetDelta = createDelta()\n if (\n !this.relativeParent ||\n !this.relativeParent.options.layoutRoot\n ) {\n this.relativeTarget = this.relativeTargetOrigin = undefined\n }\n this.attemptToResolveRelativeTarget = !hasOnlyRelativeTargetChanged\n\n const relativeLayout = createBox()\n\n const snapshotSource = snapshot ? snapshot.source : undefined\n const layoutSource = this.layout ? this.layout.source : undefined\n const isSharedLayoutAnimation = snapshotSource !== layoutSource\n const stack = this.getStack()\n const isOnlyMember = !stack || stack.members.length <= 1\n const shouldCrossfadeOpacity = Boolean(\n isSharedLayoutAnimation &&\n !isOnlyMember &&\n this.options.crossfade === true &&\n !this.path.some(hasOpacityCrossfade)\n )\n\n this.animationProgress = 0\n\n let prevRelativeTarget: Box\n\n this.mixTargetDelta = (latest: number) => {\n const progress = latest / 1000\n\n mixAxisDelta(targetDelta.x, delta.x, progress)\n mixAxisDelta(targetDelta.y, delta.y, progress)\n this.setTargetDelta(targetDelta)\n\n if (\n this.relativeTarget &&\n this.relativeTargetOrigin &&\n this.layout &&\n this.relativeParent &&\n this.relativeParent.layout\n ) {\n calcRelativePosition(\n relativeLayout,\n this.layout.layoutBox,\n this.relativeParent.layout.layoutBox,\n this.options.layoutAnchor || undefined\n )\n mixBox(\n this.relativeTarget,\n this.relativeTargetOrigin,\n relativeLayout,\n progress\n )\n\n /**\n * If this is an unchanged relative target we can consider the\n * projection not dirty.\n */\n if (\n prevRelativeTarget &&\n boxEquals(this.relativeTarget, prevRelativeTarget)\n ) {\n this.isProjectionDirty = false\n }\n\n if (!prevRelativeTarget) prevRelativeTarget = createBox()\n copyBoxInto(prevRelativeTarget, this.relativeTarget)\n }\n\n if (isSharedLayoutAnimation) {\n this.animationValues = mixedValues\n\n mixValues(\n mixedValues,\n snapshotLatestValues,\n this.latestValues,\n progress,\n shouldCrossfadeOpacity,\n isOnlyMember\n )\n }\n\n this.root.scheduleUpdateProjection()\n this.scheduleRender()\n\n this.animationProgress = progress\n }\n\n this.mixTargetDelta(this.options.layoutRoot ? 1000 : 0)\n }\n\n motionValue?: MotionValue\n startAnimation(options: ValueAnimationOptions) {\n this.notifyListeners(\"animationStart\")\n\n this.currentAnimation?.stop()\n this.resumingFrom?.currentAnimation?.stop()\n\n if (this.pendingAnimation) {\n cancelFrame(this.pendingAnimation)\n this.pendingAnimation = undefined\n }\n\n /**\n * Start the animation in the next frame to have a frame with progress 0,\n * where the target is the same as when the animation started, so we can\n * calculate the relative positions correctly for instant transitions.\n */\n this.pendingAnimation = frame.update(() => {\n globalProjectionState.hasAnimatedSinceResize = true\n\n activeAnimations.layout++\n this.motionValue ||= motionValue(0)\n this.motionValue.jump(0, false)\n\n this.currentAnimation = animateSingleValue(\n this.motionValue,\n [0, 1000],\n {\n ...(options as any),\n velocity: 0,\n isSync: true,\n onUpdate: (latest: number) => {\n this.mixTargetDelta(latest)\n options.onUpdate && options.onUpdate(latest)\n },\n onStop: () => {\n activeAnimations.layout--\n },\n onComplete: () => {\n activeAnimations.layout--\n options.onComplete && options.onComplete()\n this.completeAnimation()\n },\n }\n ) as JSAnimation\n\n if (this.resumingFrom) {\n this.resumingFrom.currentAnimation = this.currentAnimation\n }\n\n this.pendingAnimation = undefined\n })\n }\n\n completeAnimation() {\n if (this.resumingFrom) {\n this.resumingFrom.currentAnimation = undefined\n this.resumingFrom.preserveOpacity = undefined\n }\n\n const stack = this.getStack()\n stack && stack.exitAnimationComplete()\n this.resumingFrom =\n this.currentAnimation =\n this.animationValues =\n undefined\n\n this.notifyListeners(\"animationComplete\")\n }\n\n finishAnimation() {\n if (this.currentAnimation) {\n this.mixTargetDelta && this.mixTargetDelta(animationTarget)\n this.currentAnimation.stop()\n }\n\n this.completeAnimation()\n }\n\n applyTransformsToTarget() {\n const lead = this.getLead()\n let { targetWithTransforms, target, layout, latestValues } = lead\n\n if (!targetWithTransforms || !target || !layout) return\n\n /**\n * If we're only animating position, and this element isn't the lead element,\n * then instead of projecting into the lead box we instead want to calculate\n * a new target that aligns the two boxes but maintains the layout shape.\n */\n if (\n this !== lead &&\n this.layout &&\n layout &&\n shouldAnimatePositionOnly(\n this.options.animationType,\n this.layout.layoutBox,\n layout.layoutBox\n )\n ) {\n target = this.target || createBox()\n\n const xLength = calcLength(this.layout!.layoutBox.x)\n target!.x.min = lead.target!.x.min\n target!.x.max = target.x.min + xLength\n\n const yLength = calcLength(this.layout!.layoutBox.y)\n target!.y.min = lead.target!.y.min\n target!.y.max = target.y.min + yLength\n }\n\n copyBoxInto(targetWithTransforms, target)\n\n /**\n * Apply the latest user-set transforms to the targetBox to produce the targetBoxFinal.\n * This is the final box that we will then project into by calculating a transform delta and\n * applying it to the corrected box.\n */\n transformBox(targetWithTransforms, latestValues)\n\n /**\n * Update the delta between the corrected box and the final target box, after\n * user-set transforms are applied to it. This will be used by the renderer to\n * create a transform style that will reproject the element from its layout layout\n * into the desired bounding box.\n */\n calcBoxDelta(\n this.projectionDeltaWithTransform!,\n this.layoutCorrected,\n targetWithTransforms!,\n latestValues\n )\n }\n\n /**\n * Shared layout\n */\n // TODO Only running on root node\n sharedNodes: Map = new Map()\n registerSharedNode(layoutId: string, node: IProjectionNode) {\n if (!this.sharedNodes.has(layoutId)) {\n this.sharedNodes.set(layoutId, new NodeStack())\n }\n\n const stack = this.sharedNodes.get(layoutId)!\n stack.add(node)\n\n const config = node.options.initialPromotionConfig\n node.promote({\n transition: config ? config.transition : undefined,\n preserveFollowOpacity:\n config && config.shouldPreserveFollowOpacity\n ? config.shouldPreserveFollowOpacity(node)\n : undefined,\n })\n }\n\n isLead(): boolean {\n const stack = this.getStack()\n return stack ? stack.lead === this : true\n }\n\n getLead() {\n const { layoutId } = this.options\n return layoutId ? this.getStack()?.lead || this : this\n }\n\n getPrevLead() {\n const { layoutId } = this.options\n return layoutId ? this.getStack()?.prevLead : undefined\n }\n\n getStack() {\n const { layoutId } = this.options\n if (layoutId) return this.root.sharedNodes.get(layoutId)\n }\n\n promote({\n needsReset,\n transition,\n preserveFollowOpacity,\n }: {\n needsReset?: boolean\n transition?: Transition\n preserveFollowOpacity?: boolean\n } = {}) {\n const stack = this.getStack()\n if (stack) stack.promote(this, preserveFollowOpacity)\n\n if (needsReset) {\n this.projectionDelta = undefined\n this.needsReset = true\n }\n if (transition) this.setOptions({ transition })\n }\n\n relegate(): boolean {\n const stack = this.getStack()\n if (stack) {\n return stack.relegate(this)\n } else {\n return false\n }\n }\n\n resetSkewAndRotation() {\n const { visualElement } = this.options\n\n if (!visualElement) return\n\n // If there's no detected skew or rotation values, we can early return without a forced render.\n let hasDistortingTransform = false\n\n /**\n * An unrolled check for rotation values. Most elements don't have any rotation and\n * skipping the nested loop and new object creation is 50% faster.\n */\n const { latestValues } = visualElement\n if (\n latestValues.z ||\n latestValues.rotate ||\n latestValues.rotateX ||\n latestValues.rotateY ||\n latestValues.rotateZ ||\n latestValues.skewX ||\n latestValues.skewY\n ) {\n hasDistortingTransform = true\n }\n\n // If there's no distorting values, we don't need to do any more.\n if (!hasDistortingTransform) return\n\n const resetValues: ResolvedValues = {}\n\n if (latestValues.z) {\n resetDistortingTransform(\n \"z\",\n visualElement,\n resetValues,\n this.animationValues\n )\n }\n\n // Check the skew and rotate value of all axes and reset to 0\n for (let i = 0; i < transformAxes.length; i++) {\n resetDistortingTransform(\n `rotate${transformAxes[i]}`,\n visualElement,\n resetValues,\n this.animationValues\n )\n resetDistortingTransform(\n `skew${transformAxes[i]}`,\n visualElement,\n resetValues,\n this.animationValues\n )\n }\n\n // Force a render of this element to apply the transform with all skews and rotations\n // set to 0.\n visualElement.render()\n\n // Put back all the values we reset\n for (const key in resetValues) {\n visualElement.setStaticValue(key, resetValues[key])\n if (this.animationValues) {\n this.animationValues[key] = resetValues[key]\n }\n }\n\n // Schedule a render for the next frame. This ensures we won't visually\n // see the element with the reset rotate value applied.\n visualElement.scheduleRender()\n }\n\n applyProjectionStyles(\n targetStyle: any, // CSSStyleDeclaration - doesn't allow numbers to be assigned to properties\n styleProp?: MotionStyle\n ) {\n if (!this.instance || this.isSVG) return\n\n if (!this.isVisible) {\n targetStyle.visibility = \"hidden\"\n return\n }\n\n const transformTemplate = this.getTransformTemplate()\n\n if (this.needsReset) {\n this.needsReset = false\n\n targetStyle.visibility = \"\"\n targetStyle.opacity = \"\"\n targetStyle.pointerEvents =\n resolveMotionValue(styleProp?.pointerEvents) || \"\"\n targetStyle.transform = transformTemplate\n ? transformTemplate(this.latestValues, \"\")\n : \"none\"\n return\n }\n\n const lead = this.getLead()\n if (!this.projectionDelta || !this.layout || !lead.target) {\n if (this.options.layoutId) {\n targetStyle.opacity =\n this.latestValues.opacity !== undefined\n ? this.latestValues.opacity\n : 1\n targetStyle.pointerEvents =\n resolveMotionValue(styleProp?.pointerEvents) || \"\"\n }\n if (this.hasProjected && !hasTransform(this.latestValues)) {\n targetStyle.transform = transformTemplate\n ? transformTemplate({}, \"\")\n : \"none\"\n this.hasProjected = false\n }\n\n return\n }\n\n targetStyle.visibility = \"\"\n\n const valuesToRender = lead.animationValues || lead.latestValues\n this.applyTransformsToTarget()\n\n let transform = buildProjectionTransform(\n this.projectionDeltaWithTransform!,\n this.treeScale,\n valuesToRender\n )\n\n if (transformTemplate) {\n transform = transformTemplate(valuesToRender, transform)\n }\n\n targetStyle.transform = transform\n\n const { x, y } = this.projectionDelta\n targetStyle.transformOrigin = `${x.origin * 100}% ${\n y.origin * 100\n }% 0`\n\n if (lead.animationValues) {\n /**\n * If the lead component is animating, assign this either the entering/leaving\n * opacity\n */\n targetStyle.opacity =\n lead === this\n ? valuesToRender.opacity ??\n this.latestValues.opacity ??\n 1\n : this.preserveOpacity\n ? this.latestValues.opacity\n : valuesToRender.opacityExit\n } else {\n /**\n * Or we're not animating at all, set the lead component to its layout\n * opacity and other components to hidden.\n */\n targetStyle.opacity =\n lead === this\n ? valuesToRender.opacity !== undefined\n ? valuesToRender.opacity\n : \"\"\n : valuesToRender.opacityExit !== undefined\n ? valuesToRender.opacityExit\n : 0\n }\n\n /**\n * Apply scale correction\n */\n for (const key in scaleCorrectors) {\n if (valuesToRender[key] === undefined) continue\n\n const { correct, applyTo, isCSSVariable } = scaleCorrectors[key]\n\n /**\n * Only apply scale correction to the value if we have an\n * active projection transform. Otherwise these values become\n * vulnerable to distortion if the element changes size without\n * a corresponding layout animation.\n */\n const corrected =\n transform === \"none\"\n ? valuesToRender[key]\n : correct(valuesToRender[key], lead)\n\n if (applyTo) {\n const num = applyTo.length\n for (let i = 0; i < num; i++) {\n targetStyle[applyTo[i] as any] = corrected\n }\n } else {\n // If this is a CSS variable, set it directly on the instance.\n // Replacing this function from creating styles to setting them\n // would be a good place to remove per frame object creation\n if (isCSSVariable) {\n ;(\n this.options.visualElement as HTMLVisualElement\n ).renderState.vars[key] = corrected\n } else {\n targetStyle[key as any] = corrected\n }\n }\n }\n\n /**\n * Disable pointer events on follow components. This is to ensure\n * that if a follow component covers a lead component it doesn't block\n * pointer events on the lead.\n */\n if (this.options.layoutId) {\n targetStyle.pointerEvents =\n lead === this\n ? resolveMotionValue(styleProp?.pointerEvents) || \"\"\n : \"none\"\n }\n }\n\n clearSnapshot() {\n this.resumeFrom = this.snapshot = undefined\n }\n\n // Only run on root\n resetTree() {\n this.root.nodes!.forEach((node: IProjectionNode) =>\n node.currentAnimation?.stop()\n )\n this.root.nodes!.forEach(clearMeasurements)\n this.root.sharedNodes.clear()\n }\n }\n}\n\nfunction updateLayout(node: IProjectionNode) {\n node.updateLayout()\n}\n\nfunction notifyLayoutUpdate(node: IProjectionNode) {\n const snapshot = node.resumeFrom?.snapshot || node.snapshot\n\n if (\n node.isLead() &&\n node.layout &&\n snapshot &&\n node.hasListeners(\"didUpdate\")\n ) {\n const { layoutBox: layout, measuredBox: measuredLayout } = node.layout\n const { animationType } = node.options\n\n const isShared = snapshot.source !== node.layout.source\n\n // TODO Maybe we want to also resize the layout snapshot so we don't trigger\n // animations for instance if layout=\"size\" and an element has only changed position\n if (animationType === \"size\") {\n eachAxis((axis) => {\n const axisSnapshot = isShared\n ? snapshot.measuredBox[axis]\n : snapshot.layoutBox[axis]\n const length = calcLength(axisSnapshot)\n axisSnapshot.min = layout[axis].min\n axisSnapshot.max = axisSnapshot.min + length\n })\n } else if (animationType === \"x\" || animationType === \"y\") {\n const snapAxis = animationType === \"x\" ? \"y\" : \"x\"\n copyAxisInto(\n isShared\n ? snapshot.measuredBox[snapAxis]\n : snapshot.layoutBox[snapAxis],\n layout[snapAxis]\n )\n } else if (\n shouldAnimatePositionOnly(animationType, snapshot.layoutBox, layout)\n ) {\n eachAxis((axis) => {\n const axisSnapshot = isShared\n ? snapshot.measuredBox[axis]\n : snapshot.layoutBox[axis]\n const length = calcLength(layout[axis])\n axisSnapshot.max = axisSnapshot.min + length\n\n /**\n * Ensure relative target gets resized and rerendererd\n */\n if (node.relativeTarget && !node.currentAnimation) {\n node.isProjectionDirty = true\n node.relativeTarget[axis].max =\n node.relativeTarget[axis].min + length\n }\n })\n }\n\n const layoutDelta = createDelta()\n\n calcBoxDelta(layoutDelta, layout, snapshot.layoutBox)\n const visualDelta = createDelta()\n if (isShared) {\n calcBoxDelta(\n visualDelta,\n node.applyTransform(measuredLayout, true),\n snapshot.measuredBox\n )\n } else {\n calcBoxDelta(visualDelta, layout, snapshot.layoutBox)\n }\n\n const hasLayoutChanged = !isDeltaZero(layoutDelta)\n let hasRelativeLayoutChanged = false\n\n if (!node.resumeFrom) {\n const relativeParent = node.getClosestProjectingParent()\n\n /**\n * If the relativeParent is itself resuming from a different element then\n * the relative snapshot is not relavent\n */\n if (relativeParent && !relativeParent.resumeFrom) {\n const { snapshot: parentSnapshot, layout: parentLayout } =\n relativeParent\n\n if (parentSnapshot && parentLayout) {\n const anchor =\n node.options.layoutAnchor || undefined\n\n const relativeSnapshot = createBox()\n calcRelativePosition(\n relativeSnapshot,\n snapshot.layoutBox,\n parentSnapshot.layoutBox,\n anchor\n )\n\n const relativeLayout = createBox()\n calcRelativePosition(\n relativeLayout,\n layout,\n parentLayout.layoutBox,\n anchor\n )\n\n if (!boxEqualsRounded(relativeSnapshot, relativeLayout)) {\n hasRelativeLayoutChanged = true\n }\n\n if (relativeParent.options.layoutRoot) {\n node.relativeTarget = relativeLayout\n node.relativeTargetOrigin = relativeSnapshot\n node.relativeParent = relativeParent\n }\n }\n }\n }\n\n node.notifyListeners(\"didUpdate\", {\n layout,\n snapshot,\n delta: visualDelta,\n layoutDelta,\n hasLayoutChanged,\n hasRelativeLayoutChanged,\n })\n } else if (node.isLead()) {\n const { onExitComplete } = node.options\n onExitComplete && onExitComplete()\n }\n\n /**\n * Clearing transition\n * TODO: Investigate why this transition is being passed in as {type: false } from Framer\n * and why we need it at all\n */\n node.options.transition = undefined\n}\n\nexport function propagateDirtyNodes(node: IProjectionNode) {\n /**\n * Increase debug counter for nodes encountered this frame\n */\n if (statsBuffer.value) {\n metrics.nodes++\n }\n\n if (!node.parent) return\n\n /**\n * If this node isn't projecting, propagate isProjectionDirty. It will have\n * no performance impact but it will allow the next child that *is* projecting\n * but *isn't* dirty to just check its parent to see if *any* ancestor needs\n * correcting.\n */\n if (!node.isProjecting()) {\n node.isProjectionDirty = node.parent.isProjectionDirty\n }\n\n /**\n * Propagate isSharedProjectionDirty and isTransformDirty\n * throughout the whole tree. A future revision can take another look at\n * this but for safety we still recalcualte shared nodes.\n */\n node.isSharedProjectionDirty ||= Boolean(\n node.isProjectionDirty ||\n node.parent.isProjectionDirty ||\n node.parent.isSharedProjectionDirty\n )\n\n node.isTransformDirty ||= node.parent.isTransformDirty\n}\n\nexport function cleanDirtyNodes(node: IProjectionNode) {\n node.isProjectionDirty =\n node.isSharedProjectionDirty =\n node.isTransformDirty =\n false\n}\n\nfunction clearSnapshot(node: IProjectionNode) {\n node.clearSnapshot()\n}\n\nfunction clearMeasurements(node: IProjectionNode) {\n node.clearMeasurements()\n}\n\nfunction forceLayoutMeasure(node: IProjectionNode) {\n node.isLayoutDirty = true\n node.updateLayout()\n}\n\nfunction clearIsLayoutDirty(node: IProjectionNode) {\n node.isLayoutDirty = false\n}\n\n/**\n * When a node is animation-blocked (e.g. during drag) and its component\n * didn't re-render (memoized), willUpdate() is never called so there's\n * no snapshot. Use the previous layout as a snapshot and mark dirty so\n * resetTransform/updateLayout/notifyLayoutUpdate process it normally.\n */\nfunction ensureDraggedNodesSnapshotted(node: IProjectionNode) {\n if (node.isAnimationBlocked && node.layout && !node.isLayoutDirty) {\n node.snapshot = node.layout\n node.isLayoutDirty = true\n }\n}\n\nfunction resetTransformStyle(node: IProjectionNode) {\n const { visualElement } = node.options\n if (visualElement && visualElement.getProps().onBeforeLayoutMeasure) {\n visualElement.notify(\"BeforeLayoutMeasure\")\n }\n\n node.resetTransform()\n}\n\nfunction finishAnimation(node: IProjectionNode) {\n node.finishAnimation()\n node.targetDelta = node.relativeTarget = node.target = undefined\n node.isProjectionDirty = true\n}\n\nfunction resolveTargetDelta(node: IProjectionNode) {\n node.resolveTargetDelta()\n}\n\nfunction calcProjection(node: IProjectionNode) {\n node.calcProjection()\n}\n\nfunction resetSkewAndRotation(node: IProjectionNode) {\n node.resetSkewAndRotation()\n}\n\nfunction removeLeadSnapshots(stack: NodeStack) {\n stack.removeLeadSnapshot()\n}\n\nexport function mixAxisDelta(output: AxisDelta, delta: AxisDelta, p: number) {\n output.translate = mixNumber(delta.translate, 0, p)\n output.scale = mixNumber(delta.scale, 1, p)\n output.origin = delta.origin\n output.originPoint = delta.originPoint\n}\n\nexport function mixAxis(output: Axis, from: Axis, to: Axis, p: number) {\n output.min = mixNumber(from.min, to.min, p)\n output.max = mixNumber(from.max, to.max, p)\n}\n\nexport function mixBox(output: Box, from: Box, to: Box, p: number) {\n mixAxis(output.x, from.x, to.x, p)\n mixAxis(output.y, from.y, to.y, p)\n}\n\nfunction hasOpacityCrossfade(node: IProjectionNode) {\n return (\n node.animationValues && node.animationValues.opacityExit !== undefined\n )\n}\n\nconst defaultLayoutTransition = {\n duration: 0.45,\n ease: [0.4, 0, 0.1, 1],\n}\n\nconst userAgentContains = (string: string) =>\n typeof navigator !== \"undefined\" &&\n navigator.userAgent &&\n navigator.userAgent.toLowerCase().includes(string)\n\n/**\n * Measured bounding boxes must be rounded in Safari and\n * left untouched in Chrome, otherwise non-integer layouts within scaled-up elements\n * can appear to jump.\n */\nconst roundPoint =\n userAgentContains(\"applewebkit/\") && !userAgentContains(\"chrome/\")\n ? Math.round\n : noop\n\nfunction roundAxis(axis: Axis): void {\n // Round to the nearest .5 pixels to support subpixel layouts\n axis.min = roundPoint(axis.min)\n axis.max = roundPoint(axis.max)\n}\n\nfunction roundBox(box: Box): void {\n roundAxis(box.x)\n roundAxis(box.y)\n}\n\nfunction shouldAnimatePositionOnly(\n animationType: string | undefined,\n snapshot: Box,\n layout: Box\n) {\n return (\n animationType === \"position\" ||\n (animationType === \"preserve-aspect\" &&\n !isNear(aspectRatio(snapshot), aspectRatio(layout), 0.2))\n )\n}\n\nfunction checkNodeWasScrollRoot(node: IProjectionNode) {\n return node !== node.root && node.scroll?.wasRoot\n}\n", "import { addDomEvent } from \"../../events/add-dom-event\"\nimport { createProjectionNode } from \"./create-projection-node\"\n\nexport const DocumentProjectionNode = createProjectionNode({\n attachResizeListener: (\n ref: Window | Element,\n notify: VoidFunction\n ): VoidFunction => addDomEvent(ref, \"resize\", notify),\n measureScroll: () => ({\n x: document.documentElement.scrollLeft || document.body?.scrollLeft || 0,\n y: document.documentElement.scrollTop || document.body?.scrollTop || 0,\n }),\n checkIsScrollRoot: () => true,\n})\n", "import { createProjectionNode } from \"./create-projection-node\"\nimport { DocumentProjectionNode } from \"./DocumentProjectionNode\"\nimport { IProjectionNode } from \"./types\"\n\nexport const rootProjectionNode: { current: IProjectionNode | undefined } = {\n current: undefined,\n}\n\nexport const HTMLProjectionNode = createProjectionNode({\n measureScroll: (instance) => ({\n x: instance.scrollLeft,\n y: instance.scrollTop,\n }),\n defaultParent: () => {\n if (!rootProjectionNode.current) {\n const documentNode = new DocumentProjectionNode({})\n documentNode.mount(window)\n documentNode.setOptions({ layoutScroll: true })\n rootProjectionNode.current = documentNode\n }\n return rootProjectionNode.current\n },\n resetTransform: (instance, value) => {\n instance.style.transform = value !== undefined ? value : \"none\"\n },\n checkIsScrollRoot: (instance) =>\n Boolean(window.getComputedStyle(instance).position === \"fixed\"),\n})\n", "export { AsyncMotionValueAnimation } from './animation/AsyncMotionValueAnimation.mjs';\nexport { GroupAnimation } from './animation/GroupAnimation.mjs';\nexport { GroupAnimationWithThen } from './animation/GroupAnimationWithThen.mjs';\nexport { JSAnimation, animateValue } from './animation/JSAnimation.mjs';\nexport { NativeAnimation } from './animation/NativeAnimation.mjs';\nexport { NativeAnimationExtended } from './animation/NativeAnimationExtended.mjs';\nexport { NativeAnimationWrapper } from './animation/NativeAnimationWrapper.mjs';\nexport { animationMapKey, getAnimationMap } from './animation/utils/active-animations.mjs';\nexport { calcChildStagger } from './animation/utils/calc-child-stagger.mjs';\nexport { getVariableValue, parseCSSVariable } from './animation/utils/css-variables-conversion.mjs';\nexport { getDefaultTransition } from './animation/utils/default-transitions.mjs';\nexport { getFinalKeyframe } from './animation/keyframes/get-final.mjs';\nexport { getValueTransition } from './animation/utils/get-value-transition.mjs';\nexport { resolveTransition } from './animation/utils/resolve-transition.mjs';\nexport { containsCSSVariable, isCSSVariableName, isCSSVariableToken } from './animation/utils/is-css-variable.mjs';\nexport { isTransitionDefined } from './animation/utils/is-transition-defined.mjs';\nexport { makeAnimationInstant } from './animation/utils/make-animation-instant.mjs';\nexport { animateMotionValue } from './animation/interfaces/motion-value.mjs';\nexport { animateVisualElement } from './animation/interfaces/visual-element.mjs';\nexport { animateTarget } from './animation/interfaces/visual-element-target.mjs';\nexport { animateVariant } from './animation/interfaces/visual-element-variant.mjs';\nexport { optimizedAppearDataAttribute, optimizedAppearDataId } from './animation/optimized-appear/data-id.mjs';\nexport { getOptimisedAppearId } from './animation/optimized-appear/get-appear-id.mjs';\nexport { inertia } from './animation/generators/inertia.mjs';\nexport { defaultEasing, keyframes } from './animation/generators/keyframes.mjs';\nexport { spring } from './animation/generators/spring.mjs';\nexport { calcGeneratorDuration, maxGeneratorDuration } from './animation/generators/utils/calc-duration.mjs';\nexport { createGeneratorEasing } from './animation/generators/utils/create-generator-easing.mjs';\nexport { isGenerator } from './animation/generators/utils/is-generator.mjs';\nexport { DOMKeyframesResolver } from './animation/keyframes/DOMKeyframesResolver.mjs';\nexport { KeyframeResolver, flushKeyframeResolvers } from './animation/keyframes/KeyframesResolver.mjs';\nexport { defaultOffset } from './animation/keyframes/offsets/default.mjs';\nexport { fillOffset } from './animation/keyframes/offsets/fill.mjs';\nexport { convertOffsetToTimes } from './animation/keyframes/offsets/time.mjs';\nexport { applyPxDefaults } from './animation/keyframes/utils/apply-px-defaults.mjs';\nexport { fillWildcards } from './animation/keyframes/utils/fill-wildcards.mjs';\nexport { cubicBezierAsString } from './animation/waapi/easing/cubic-bezier.mjs';\nexport { isWaapiSupportedEasing } from './animation/waapi/easing/is-supported.mjs';\nexport { mapEasingToNativeEasing } from './animation/waapi/easing/map-easing.mjs';\nexport { supportedWaapiEasing } from './animation/waapi/easing/supported.mjs';\nexport { startWaapiAnimation } from './animation/waapi/start-waapi-animation.mjs';\nexport { supportsPartialKeyframes } from './animation/waapi/supports/partial-keyframes.mjs';\nexport { supportsBrowserAnimation } from './animation/waapi/supports/waapi.mjs';\nexport { acceleratedValues } from './animation/waapi/utils/accelerated-values.mjs';\nexport { applyGeneratorOptions } from './animation/waapi/utils/apply-generator.mjs';\nexport { generateLinearEasing } from './animation/waapi/utils/linear.mjs';\nexport { addAttrValue, attrEffect } from './effects/attr/index.mjs';\nexport { propEffect } from './effects/prop/index.mjs';\nexport { addStyleValue, styleEffect } from './effects/style/index.mjs';\nexport { svgEffect } from './effects/svg/index.mjs';\nexport { createRenderBatcher } from './frameloop/batcher.mjs';\nexport { cancelMicrotask, microtask } from './frameloop/microtask.mjs';\nexport { time } from './frameloop/sync-time.mjs';\nexport { isDragActive, isDragging } from './gestures/drag/state/is-active.mjs';\nexport { setDragLock } from './gestures/drag/state/set-active.mjs';\nexport { hover } from './gestures/hover.mjs';\nexport { press } from './gestures/press/index.mjs';\nexport { isElementKeyboardAccessible, isElementTextInput } from './gestures/press/utils/is-keyboard-accessible.mjs';\nexport { isNodeOrChild } from './gestures/utils/is-node-or-child.mjs';\nexport { isPrimaryPointer } from './gestures/utils/is-primary-pointer.mjs';\nexport { defaultTransformValue, parseValueFromTransform, readTransformValue } from './render/dom/parse-transform.mjs';\nexport { getComputedStyle } from './render/dom/style-computed.mjs';\nexport { setStyle } from './render/dom/style-set.mjs';\nexport { isKeyframesTarget } from './render/utils/is-keyframes-target.mjs';\nexport { positionalKeys } from './render/utils/keys-position.mjs';\nexport { transformPropOrder, transformProps } from './render/utils/keys-transform.mjs';\nexport { resize } from './resize/index.mjs';\nexport { observeTimeline } from './scroll/observe.mjs';\nexport { recordStats } from './stats/index.mjs';\nexport { activeAnimations } from './stats/animation-count.mjs';\nexport { statsBuffer } from './stats/buffer.mjs';\nexport { interpolate } from './utils/interpolate.mjs';\nexport { isHTMLElement } from './utils/is-html-element.mjs';\nexport { isSVGElement } from './utils/is-svg-element.mjs';\nexport { isSVGSVGElement } from './utils/is-svg-svg-element.mjs';\nexport { mix } from './utils/mix/index.mjs';\nexport { mixColor, mixLinearColor } from './utils/mix/color.mjs';\nexport { getMixer, mixArray, mixComplex, mixObject } from './utils/mix/complex.mjs';\nexport { mixImmediate } from './utils/mix/immediate.mjs';\nexport { mixNumber } from './utils/mix/number.mjs';\nexport { invisibleValues, mixVisibility } from './utils/mix/visibility.mjs';\nexport { resolveElements } from './utils/resolve-elements.mjs';\nexport { getOriginIndex, stagger } from './utils/stagger.mjs';\nexport { supportsFlags } from './utils/supports/flags.mjs';\nexport { supportsLinearEasing } from './utils/supports/linear-easing.mjs';\nexport { supportsScrollTimeline, supportsViewTimeline } from './utils/supports/scroll-timeline.mjs';\nexport { transform } from './utils/transform.mjs';\nexport { MotionValue, collectMotionValues, motionValue } from './value/index.mjs';\nexport { attachFollow, followValue } from './value/follow-value.mjs';\nexport { mapValue } from './value/map-value.mjs';\nexport { attachSpring, springValue } from './value/spring-value.mjs';\nexport { transformValue } from './value/transform-value.mjs';\nexport { color } from './value/types/color/index.mjs';\nexport { hex } from './value/types/color/hex.mjs';\nexport { hsla } from './value/types/color/hsla.mjs';\nexport { hslaToRgba } from './value/types/color/hsla-to-rgba.mjs';\nexport { rgbUnit, rgba } from './value/types/color/rgba.mjs';\nexport { analyseComplexValue, complex } from './value/types/complex/index.mjs';\nexport { dimensionValueTypes, findDimensionValueType } from './value/types/dimensions.mjs';\nexport { defaultValueTypes, getDefaultValueType } from './value/types/maps/defaults.mjs';\nexport { numberValueTypes } from './value/types/maps/number.mjs';\nexport { transformValueTypes } from './value/types/maps/transform.mjs';\nexport { alpha, number, scale } from './value/types/numbers/index.mjs';\nexport { degrees, percent, progressPercentage, px, vh, vw } from './value/types/numbers/units.mjs';\nexport { testValueType } from './value/types/test.mjs';\nexport { getAnimatableNone } from './value/types/utils/animatable-none.mjs';\nexport { findValueType } from './value/types/utils/find.mjs';\nexport { getValueAsType } from './value/types/utils/get-as-type.mjs';\nexport { isMotionValue } from './value/utils/is-motion-value.mjs';\nexport { addValueToWillChange } from './value/will-change/add-will-change.mjs';\nexport { isWillChangeMotionValue } from './value/will-change/is.mjs';\nexport { ViewTransitionBuilder, animateView } from './view/index.mjs';\nexport { getViewAnimationLayerInfo } from './view/utils/get-layer-info.mjs';\nexport { getViewAnimations } from './view/utils/get-view-animations.mjs';\nexport { DOMVisualElement } from './render/dom/DOMVisualElement.mjs';\nexport { Feature } from './render/Feature.mjs';\nexport { HTMLVisualElement } from './render/html/HTMLVisualElement.mjs';\nexport { ObjectVisualElement } from './render/object/ObjectVisualElement.mjs';\nexport { visualElementStore } from './render/store.mjs';\nexport { SVGVisualElement } from './render/svg/SVGVisualElement.mjs';\nexport { VisualElement, getFeatureDefinitions, setFeatureDefinitions } from './render/VisualElement.mjs';\nexport { checkVariantsDidChange, createAnimationState } from './render/utils/animation-state.mjs';\nexport { getVariantContext } from './render/utils/get-variant-context.mjs';\nexport { isAnimationControls } from './render/utils/is-animation-controls.mjs';\nexport { isControllingVariants, isVariantNode } from './render/utils/is-controlling-variants.mjs';\nexport { isForcedMotionValue } from './render/utils/is-forced-motion-value.mjs';\nexport { isVariantLabel } from './render/utils/is-variant-label.mjs';\nexport { updateMotionValuesFromProps } from './render/utils/motion-values.mjs';\nexport { resolveVariant } from './render/utils/resolve-dynamic-variants.mjs';\nexport { resolveVariantFromProps } from './render/utils/resolve-variants.mjs';\nexport { setTarget } from './render/utils/setters.mjs';\nexport { variantPriorityOrder, variantProps } from './render/utils/variant-props.mjs';\nexport { initPrefersReducedMotion } from './render/utils/reduced-motion/index.mjs';\nexport { convertBoundingBoxToBox, convertBoxToBoundingBox, transformBoxPoints } from './projection/geometry/conversion.mjs';\nexport { copyAxisDeltaInto, copyAxisInto, copyBoxInto } from './projection/geometry/copy.mjs';\nexport { applyAxisDelta, applyBoxDelta, applyPointDelta, applyTreeDeltas, scalePoint, transformAxis, transformBox, translateAxis } from './projection/geometry/delta-apply.mjs';\nexport { calcAxisDelta, calcBoxDelta, calcLength, calcRelativeAxis, calcRelativeAxisPosition, calcRelativeBox, calcRelativePosition, isNear } from './projection/geometry/delta-calc.mjs';\nexport { removeAxisDelta, removeAxisTransforms, removeBoxTransforms, removePointDelta } from './projection/geometry/delta-remove.mjs';\nexport { createAxis, createAxisDelta, createBox, createDelta } from './projection/geometry/models.mjs';\nexport { aspectRatio, axisDeltaEquals, axisEquals, axisEqualsRounded, boxEquals, boxEqualsRounded, isDeltaZero } from './projection/geometry/utils.mjs';\nexport { eachAxis } from './projection/utils/each-axis.mjs';\nexport { has2DTranslate, hasScale, hasTransform } from './projection/utils/has-transform.mjs';\nexport { measurePageBox, measureViewportBox } from './projection/utils/measure.mjs';\nexport { correctBorderRadius, pixelsToPercent } from './projection/styles/scale-border-radius.mjs';\nexport { correctBoxShadow } from './projection/styles/scale-box-shadow.mjs';\nexport { buildProjectionTransform } from './projection/styles/transform.mjs';\nexport { mixValues } from './projection/animation/mix-values.mjs';\nexport { animateSingleValue } from './animation/animate/single-value.mjs';\nexport { addDomEvent } from './events/add-dom-event.mjs';\nexport { compareByDepth } from './projection/utils/compare-by-depth.mjs';\nexport { FlatTree } from './projection/utils/flat-tree.mjs';\nexport { delay, delayInSeconds } from './utils/delay.mjs';\nexport { resolveMotionValue } from './value/utils/resolve-motion-value.mjs';\nexport { cleanDirtyNodes, createProjectionNode, propagateDirtyNodes } from './projection/node/create-projection-node.mjs';\nexport { DocumentProjectionNode } from './projection/node/DocumentProjectionNode.mjs';\nexport { nodeGroup } from './projection/node/group.mjs';\nexport { HTMLProjectionNode, rootProjectionNode } from './projection/node/HTMLProjectionNode.mjs';\nexport { globalProjectionState } from './projection/node/state.mjs';\nexport { NodeStack } from './projection/shared/stack.mjs';\nexport { camelToDash } from './render/dom/utils/camel-to-dash.mjs';\nexport { buildHTMLStyles } from './render/html/utils/build-styles.mjs';\nexport { buildTransform } from './render/html/utils/build-transform.mjs';\nexport { renderHTML } from './render/html/utils/render.mjs';\nexport { scrapeMotionValuesFromProps as scrapeHTMLMotionValuesFromProps } from './render/html/utils/scrape-motion-values.mjs';\nexport { buildSVGAttrs } from './render/svg/utils/build-attrs.mjs';\nexport { camelCaseAttributes } from './render/svg/utils/camel-case-attrs.mjs';\nexport { isSVGTag } from './render/svg/utils/is-svg-tag.mjs';\nexport { buildSVGPath } from './render/svg/utils/path.mjs';\nexport { renderSVG } from './render/svg/utils/render.mjs';\nexport { scrapeMotionValuesFromProps as scrapeSVGMotionValuesFromProps } from './render/svg/utils/scrape-motion-values.mjs';\nexport { LayoutAnimationBuilder, parseAnimateLayoutArgs } from './layout/LayoutAnimationBuilder.mjs';\nexport { cancelSync, sync } from './frameloop/index-legacy.mjs';\nexport { addScaleCorrector, scaleCorrectors } from './projection/styles/scale-correction.mjs';\nexport { cancelFrame, frame, frameData, frameSteps } from './frameloop/frame.mjs';\nexport { hasReducedMotionListener, prefersReducedMotion } from './render/utils/reduced-motion/state.mjs';\n//# sourceMappingURL=index.mjs.map\n", "\"use client\"\n\nimport type { Transition } from \"motion-dom\"\nimport { TransformPoint } from \"motion-utils\"\nimport { createContext } from \"react\"\n\nexport type ReducedMotionConfig = \"always\" | \"never\" | \"user\"\n\n/**\n * @public\n */\nexport interface MotionConfigContext {\n /**\n * Internal, exported only for usage in Framer\n */\n transformPagePoint: TransformPoint\n\n /**\n * Internal. Determines whether this is a static context ie the Framer canvas. If so,\n * it'll disable all dynamic functionality.\n */\n isStatic: boolean\n\n /**\n * Defines a new default transition for the entire tree.\n *\n * @public\n */\n transition?: Transition\n\n /**\n * If true, will respect the device prefersReducedMotion setting by switching\n * transform animations off.\n *\n * @public\n */\n reducedMotion?: ReducedMotionConfig\n\n /**\n * A custom `nonce` attribute used when wanting to enforce a Content Security Policy (CSP).\n * For more details see:\n * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src#unsafe_inline_styles\n *\n * @public\n */\n nonce?: string\n\n /**\n * If true, all animations will be skipped and values will be set instantly.\n * Useful for E2E tests and visual regression testing.\n *\n * @public\n */\n skipAnimations?: boolean\n\n}\n\n/**\n * @public\n */\nexport const MotionConfigContext = createContext({\n transformPagePoint: (p) => p,\n isStatic: false,\n reducedMotion: \"never\",\n})\n", "/**\n * Taken from https://github.com/radix-ui/primitives/blob/main/packages/react/compose-refs/src/compose-refs.tsx\n */\nimport * as React from \"react\"\n\ntype PossibleRef = React.Ref | undefined\n\n/**\n * Set a given ref to a given value\n * This utility takes care of different types of refs: callback refs and RefObject(s)\n */\nfunction setRef(ref: PossibleRef, value: T): void | (() => void) {\n if (typeof ref === \"function\") {\n return ref(value)\n } else if (ref !== null && ref !== undefined) {\n ;(ref as React.MutableRefObject).current = value\n }\n}\n\n/**\n * A utility to compose multiple refs together\n * Accepts callback refs and RefObject(s)\n */\nfunction composeRefs(...refs: PossibleRef[]): React.RefCallback {\n return (node) => {\n let hasCleanup = false\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node)\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true\n }\n return cleanup\n })\n // React <19 will log an error to the console if a callback ref returns a\n // value. We don't use ref cleanups internally so this will only happen if a\n // user's ref callback returns a value, which we only expect if they are\n // using the cleanup functionality added in React 19.\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i]\n if (typeof cleanup === \"function\") {\n cleanup()\n } else {\n setRef(refs[i], null)\n }\n }\n }\n }\n }\n}\n\n/**\n * A custom hook that composes multiple refs\n * Accepts callback refs and RefObject(s)\n */\nfunction useComposedRefs(...refs: PossibleRef[]): React.RefCallback {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return React.useCallback(composeRefs(...refs), refs)\n}\n\nexport { useComposedRefs }\n", "\"use client\"\n\nimport { isHTMLElement } from \"motion-dom\"\nimport * as React from \"react\"\nimport { useContext, useId, useInsertionEffect, useRef } from \"react\"\n\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport { useComposedRefs } from \"../../utils/use-composed-ref\"\n\ninterface Size {\n width: number\n height: number\n top: number\n left: number\n right: number\n bottom: number\n}\n\ninterface Props {\n children: React.ReactElement\n isPresent: boolean\n anchorX?: \"left\" | \"right\"\n anchorY?: \"top\" | \"bottom\"\n root?: HTMLElement | ShadowRoot\n pop?: boolean\n}\n\ninterface MeasureProps extends Props {\n childRef: React.RefObject\n sizeRef: React.RefObject\n}\n\n/**\n * Measurement functionality has to be within a separate component\n * to leverage snapshot lifecycle.\n */\nclass PopChildMeasure extends React.Component {\n getSnapshotBeforeUpdate(prevProps: MeasureProps) {\n const element = this.props.childRef.current\n if (isHTMLElement(element) && prevProps.isPresent && !this.props.isPresent && this.props.pop !== false) {\n const parent = element.offsetParent\n const parentWidth = isHTMLElement(parent)\n ? parent.offsetWidth || 0\n : 0\n const parentHeight = isHTMLElement(parent)\n ? parent.offsetHeight || 0\n : 0\n\n const computedStyle = getComputedStyle(element)\n const size = this.props.sizeRef.current!\n size.height = parseFloat(computedStyle.height)\n size.width = parseFloat(computedStyle.width)\n size.top = element.offsetTop\n size.left = element.offsetLeft\n size.right = parentWidth - size.width - size.left\n size.bottom = parentHeight - size.height - size.top\n }\n\n return null\n }\n\n /**\n * Required with getSnapshotBeforeUpdate to stop React complaining.\n */\n componentDidUpdate() {}\n\n render() {\n return this.props.children\n }\n}\n\nexport function PopChild({ children, isPresent, anchorX, anchorY, root, pop }: Props) {\n const id = useId()\n const ref = useRef(null)\n const size = useRef({\n width: 0,\n height: 0,\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n })\n const { nonce } = useContext(MotionConfigContext)\n /**\n * In React 19, refs are passed via props.ref instead of element.ref.\n * We check props.ref first (React 19) and fall back to element.ref (React 18).\n */\n const childRef =\n (children.props as { ref?: React.Ref })?.ref ??\n (children as unknown as { ref?: React.Ref })?.ref\n const composedRef = useComposedRefs(ref, childRef)\n\n /**\n * We create and inject a style block so we can apply this explicit\n * sizing in a non-destructive manner by just deleting the style block.\n *\n * We can't apply size via render as the measurement happens\n * in getSnapshotBeforeUpdate (post-render), likewise if we apply the\n * styles directly on the DOM node, we might be overwriting\n * styles set via the style prop.\n */\n useInsertionEffect(() => {\n const { width, height, top, left, right, bottom } = size.current\n if (isPresent || pop === false || !ref.current || !width || !height) return\n\n const x = anchorX === \"left\" ? `left: ${left}` : `right: ${right}`\n const y = anchorY === \"bottom\" ? `bottom: ${bottom}` : `top: ${top}`\n\n ref.current.dataset.motionPopId = id\n\n const style = document.createElement(\"style\")\n if (nonce) style.nonce = nonce\n\n const parent = root ?? document.head\n parent.appendChild(style)\n\n if (style.sheet) {\n style.sheet.insertRule(`\n [data-motion-pop-id=\"${id}\"] {\n position: absolute !important;\n width: ${width}px !important;\n height: ${height}px !important;\n ${x}px !important;\n ${y}px !important;\n }\n `)\n }\n\n return () => {\n ref.current?.removeAttribute(\"data-motion-pop-id\")\n if (parent.contains(style)) {\n parent.removeChild(style)\n }\n }\n }, [isPresent])\n\n return (\n \n {pop === false\n ? children\n : React.cloneElement(children as any, { ref: composedRef })}\n \n )\n}\n", "\"use client\"\n\nimport * as React from \"react\"\nimport { useId, useMemo } from \"react\"\nimport {\n PresenceContext,\n type PresenceContextProps,\n} from \"../../context/PresenceContext\"\nimport { VariantLabels } from \"../../motion/types\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { PopChild } from \"./PopChild\"\n\ninterface PresenceChildProps {\n children: React.ReactElement\n isPresent: boolean\n onExitComplete?: () => void\n initial?: false | VariantLabels\n custom?: any\n presenceAffectsLayout: boolean\n mode: \"sync\" | \"popLayout\" | \"wait\"\n anchorX?: \"left\" | \"right\"\n anchorY?: \"top\" | \"bottom\"\n root?: HTMLElement | ShadowRoot\n}\n\nexport const PresenceChild = ({\n children,\n initial,\n isPresent,\n onExitComplete,\n custom,\n presenceAffectsLayout,\n mode,\n anchorX,\n anchorY,\n root\n}: PresenceChildProps) => {\n const presenceChildren = useConstant(newChildrenMap)\n const id = useId()\n\n let isReusedContext = true\n let context = useMemo((): PresenceContextProps => {\n isReusedContext = false\n return {\n id,\n initial,\n isPresent,\n custom,\n onExitComplete: (childId: string) => {\n presenceChildren.set(childId, true)\n\n for (const isComplete of presenceChildren.values()) {\n if (!isComplete) return // can stop searching when any is incomplete\n }\n\n onExitComplete && onExitComplete()\n },\n register: (childId: string) => {\n presenceChildren.set(childId, false)\n return () => presenceChildren.delete(childId)\n },\n }\n }, [isPresent, presenceChildren, onExitComplete])\n\n /**\n * If the presence of a child affects the layout of the components around it,\n * we want to make a new context value to ensure they get re-rendered\n * so they can detect that layout change.\n */\n if (presenceAffectsLayout && isReusedContext) {\n context = { ...context }\n }\n\n useMemo(() => {\n presenceChildren.forEach((_, key) => presenceChildren.set(key, false))\n }, [isPresent])\n\n /**\n * If there's no `motion` components to fire exit animations, we want to remove this\n * component immediately.\n */\n React.useEffect(() => {\n !isPresent &&\n !presenceChildren.size &&\n onExitComplete &&\n onExitComplete()\n }, [isPresent])\n\n children = (\n \n {children}\n \n )\n\n return (\n \n {children}\n \n )\n}\n\nfunction newChildrenMap(): Map {\n return new Map()\n}\n", "\"use client\"\n\nimport { useCallback, useContext, useEffect, useId } from \"react\"\nimport {\n PresenceContext,\n PresenceContextProps,\n} from \"../../context/PresenceContext\"\n\nexport type SafeToRemove = () => void\n\ntype AlwaysPresent = [true, null]\n\ntype Present = [true]\n\ntype NotPresent = [false, SafeToRemove]\n\n/**\n * When a component is the child of `AnimatePresence`, it can use `usePresence`\n * to access information about whether it's still present in the React tree.\n *\n * ```jsx\n * import { usePresence } from \"framer-motion\"\n *\n * export const Component = () => {\n * const [isPresent, safeToRemove] = usePresence()\n *\n * useEffect(() => {\n * !isPresent && setTimeout(safeToRemove, 1000)\n * }, [isPresent])\n *\n * return

    \n * }\n * ```\n *\n * If `isPresent` is `false`, it means that a component has been removed from the tree,\n * but `AnimatePresence` won't really remove it until `safeToRemove` has been called.\n *\n * @public\n */\nexport function usePresence(\n subscribe: boolean = true\n): AlwaysPresent | Present | NotPresent {\n const context = useContext(PresenceContext)\n\n if (context === null) return [true, null]\n\n const { isPresent, onExitComplete, register } = context\n\n // It's safe to call the following hooks conditionally (after an early return) because the context will always\n // either be null or non-null for the lifespan of the component.\n\n const id = useId()\n useEffect(() => {\n if (subscribe) {\n return register(id)\n }\n }, [subscribe])\n\n const safeToRemove = useCallback(\n () => subscribe && onExitComplete && onExitComplete(id),\n [id, onExitComplete, subscribe]\n )\n\n return !isPresent && onExitComplete ? [false, safeToRemove] : [true]\n}\n\n/**\n * Similar to `usePresence`, except `useIsPresent` simply returns whether or not the component is present.\n * There is no `safeToRemove` function.\n *\n * ```jsx\n * import { useIsPresent } from \"framer-motion\"\n *\n * export const Component = () => {\n * const isPresent = useIsPresent()\n *\n * useEffect(() => {\n * !isPresent && console.log(\"I've been removed!\")\n * }, [isPresent])\n *\n * return
    \n * }\n * ```\n *\n * @public\n */\nexport function useIsPresent() {\n return isPresent(useContext(PresenceContext))\n}\n\nexport function isPresent(context: PresenceContextProps | null) {\n return context === null ? true : context.isPresent\n}\n", "import { isValidElement, Children, ReactElement, ReactNode } from \"react\"\n\nexport type ComponentKey = string | number\n\nexport const getChildKey = (child: ReactElement): ComponentKey =>\n child.key || \"\"\n\nexport function onlyElements(children: ReactNode): ReactElement[] {\n const filtered: ReactElement[] = []\n\n // We use forEach here instead of map as map mutates the component key by preprending `.$`\n Children.forEach(children, (child) => {\n if (isValidElement(child)) filtered.push(child)\n })\n\n return filtered\n}\n", "\"use client\"\n\nimport * as React from \"react\"\nimport { useContext, useMemo, useRef, useState } from \"react\"\nimport { LayoutGroupContext } from \"../../context/LayoutGroupContext\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { useIsomorphicLayoutEffect } from \"../../utils/use-isomorphic-effect\"\nimport { PresenceChild } from \"./PresenceChild\"\nimport { AnimatePresenceProps } from \"./types\"\nimport { usePresence } from \"./use-presence\"\nimport { ComponentKey, getChildKey, onlyElements } from \"./utils\"\n\n/**\n * `AnimatePresence` enables the animation of components that have been removed from the tree.\n *\n * When adding/removing more than a single child, every child **must** be given a unique `key` prop.\n *\n * Any `motion` components that have an `exit` property defined will animate out when removed from\n * the tree.\n *\n * ```jsx\n * import { motion, AnimatePresence } from 'framer-motion'\n *\n * export const Items = ({ items }) => (\n * \n * {items.map(item => (\n * \n * ))}\n * \n * )\n * ```\n *\n * You can sequence exit animations throughout a tree using variants.\n *\n * If a child contains multiple `motion` components with `exit` props, it will only unmount the child\n * once all `motion` components have finished animating out. Likewise, any components using\n * `usePresence` all need to call `safeToRemove`.\n *\n * @public\n */\nexport const AnimatePresence = ({\n children,\n custom,\n initial = true,\n onExitComplete,\n presenceAffectsLayout = true,\n mode = \"sync\",\n propagate = false,\n anchorX = \"left\",\n anchorY = \"top\",\n root\n}: React.PropsWithChildren) => {\n const [isParentPresent, safeToRemove] = usePresence(propagate)\n\n /**\n * Filter any children that aren't ReactElements. We can only track components\n * between renders with a props.key.\n */\n const presentChildren = useMemo(() => onlyElements(children), [children])\n\n /**\n * Track the keys of the currently rendered children. This is used to\n * determine which children are exiting.\n */\n const presentKeys =\n propagate && !isParentPresent ? [] : presentChildren.map(getChildKey)\n\n /**\n * If `initial={false}` we only want to pass this to components in the first render.\n */\n const isInitialRender = useRef(true)\n\n /**\n * A ref containing the currently present children. When all exit animations\n * are complete, we use this to re-render the component with the latest children\n * *committed* rather than the latest children *rendered*.\n */\n const pendingPresentChildren = useRef(presentChildren)\n\n /**\n * Track which exiting children have finished animating out.\n */\n const exitComplete = useConstant(() => new Map())\n\n /**\n * Track which components are currently processing exit to prevent duplicate processing.\n */\n const exitingComponents = useRef(new Set())\n\n /**\n * Save children to render as React state. To ensure this component is concurrent-safe,\n * we check for exiting children via an effect.\n */\n const [diffedChildren, setDiffedChildren] = useState(presentChildren)\n const [renderedChildren, setRenderedChildren] = useState(presentChildren)\n\n useIsomorphicLayoutEffect(() => {\n isInitialRender.current = false\n pendingPresentChildren.current = presentChildren\n\n /**\n * Update complete status of exiting children.\n */\n for (let i = 0; i < renderedChildren.length; i++) {\n const key = getChildKey(renderedChildren[i])\n\n if (!presentKeys.includes(key)) {\n if (exitComplete.get(key) !== true) {\n exitComplete.set(key, false)\n }\n } else {\n exitComplete.delete(key)\n exitingComponents.current.delete(key)\n }\n }\n }, [renderedChildren, presentKeys.length, presentKeys.join(\"-\")])\n\n const exitingChildren: any[] = []\n\n if (presentChildren !== diffedChildren) {\n let nextChildren = [...presentChildren]\n\n /**\n * Loop through all the currently rendered components and decide which\n * are exiting.\n */\n for (let i = 0; i < renderedChildren.length; i++) {\n const child = renderedChildren[i]\n const key = getChildKey(child)\n\n if (!presentKeys.includes(key)) {\n nextChildren.splice(i, 0, child)\n exitingChildren.push(child)\n }\n }\n\n /**\n * If we're in \"wait\" mode, and we have exiting children, we want to\n * only render these until they've all exited.\n */\n if (mode === \"wait\" && exitingChildren.length) {\n nextChildren = exitingChildren\n }\n\n setRenderedChildren(onlyElements(nextChildren))\n setDiffedChildren(presentChildren)\n\n /**\n * Early return to ensure once we've set state with the latest diffed\n * children, we can immediately re-render.\n */\n return null\n }\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n mode === \"wait\" &&\n renderedChildren.length > 1\n ) {\n console.warn(\n `You're attempting to animate multiple children within AnimatePresence, but its mode is set to \"wait\". This will lead to odd visual behaviour.`\n )\n }\n\n /**\n * If we've been provided a forceRender function by the LayoutGroupContext,\n * we can use it to force a re-render amongst all surrounding components once\n * all components have finished animating out.\n */\n const { forceRender } = useContext(LayoutGroupContext)\n\n return (\n <>\n {renderedChildren.map((child) => {\n const key = getChildKey(child)\n\n const isPresent =\n propagate && !isParentPresent\n ? false\n : presentChildren === renderedChildren ||\n presentKeys.includes(key)\n\n const onExit = () => {\n if (exitingComponents.current.has(key)) {\n return\n }\n\n if (exitComplete.has(key)) {\n exitingComponents.current.add(key)\n exitComplete.set(key, true)\n } else {\n return\n }\n\n let isEveryExitComplete = true\n exitComplete.forEach((isExitComplete) => {\n if (!isExitComplete) isEveryExitComplete = false\n })\n\n if (isEveryExitComplete) {\n forceRender?.()\n setRenderedChildren(pendingPresentChildren.current)\n\n propagate && safeToRemove?.()\n\n onExitComplete && onExitComplete()\n }\n }\n\n return (\n \n {child}\n \n )\n })}\n \n )\n}\n", "\"use client\"\n\nimport { createContext } from \"react\"\nimport { CreateVisualElement } from \"../render/types\"\n\nexport interface LazyContextProps {\n renderer?: CreateVisualElement\n strict: boolean\n}\n\nexport const LazyContext = createContext({ strict: false })\n", "import { getFeatureDefinitions, setFeatureDefinitions } from \"motion-dom\"\nimport { MotionProps } from \"../types\"\nimport { FeatureDefinitions } from \"./types\"\n\nconst featureProps = {\n animation: [\n \"animate\",\n \"variants\",\n \"whileHover\",\n \"whileTap\",\n \"exit\",\n \"whileInView\",\n \"whileFocus\",\n \"whileDrag\",\n ],\n exit: [\"exit\"],\n drag: [\"drag\", \"dragControls\"],\n focus: [\"whileFocus\"],\n hover: [\"whileHover\", \"onHoverStart\", \"onHoverEnd\"],\n tap: [\"whileTap\", \"onTap\", \"onTapStart\", \"onTapCancel\"],\n pan: [\"onPan\", \"onPanStart\", \"onPanSessionStart\", \"onPanEnd\"],\n inView: [\"whileInView\", \"onViewportEnter\", \"onViewportLeave\"],\n layout: [\"layout\", \"layoutId\"],\n}\n\nlet isInitialized = false\n\n/**\n * Initialize feature definitions with isEnabled checks.\n * This must be called before any motion components are rendered.\n */\nexport function initFeatureDefinitions() {\n if (isInitialized) return\n\n const initialFeatureDefinitions: Partial = {}\n\n for (const key in featureProps) {\n initialFeatureDefinitions[\n key as keyof typeof initialFeatureDefinitions\n ] = {\n isEnabled: (props: MotionProps) =>\n featureProps[key as keyof typeof featureProps].some(\n (name: string) => !!props[name as keyof typeof props]\n ),\n }\n }\n\n setFeatureDefinitions(initialFeatureDefinitions)\n isInitialized = true\n}\n\n/**\n * Get the current feature definitions, initializing if needed.\n */\nexport function getInitializedFeatureDefinitions(): Partial {\n initFeatureDefinitions()\n return getFeatureDefinitions()\n}\n", "import { setFeatureDefinitions } from \"motion-dom\"\nimport { getInitializedFeatureDefinitions } from \"./definitions\"\nimport { FeaturePackages } from \"./types\"\n\nexport function loadFeatures(features: FeaturePackages) {\n const featureDefinitions = getInitializedFeatureDefinitions()\n\n for (const key in features) {\n featureDefinitions[key as keyof typeof featureDefinitions] = {\n ...featureDefinitions[key as keyof typeof featureDefinitions],\n ...features[key as keyof typeof features],\n } as any\n }\n\n setFeatureDefinitions(featureDefinitions)\n}\n", "import { MotionProps } from \"../types\"\n\n/**\n * A list of all valid MotionProps.\n *\n * @privateRemarks\n * This doesn't throw if a `MotionProp` name is missing - it should.\n */\nconst validMotionProps = new Set([\n \"animate\",\n \"exit\",\n \"variants\",\n \"initial\",\n \"style\",\n \"values\",\n \"variants\",\n \"transition\",\n \"transformTemplate\",\n \"custom\",\n \"inherit\",\n \"onBeforeLayoutMeasure\",\n \"onAnimationStart\",\n \"onAnimationComplete\",\n \"onUpdate\",\n \"onDragStart\",\n \"onDrag\",\n \"onDragEnd\",\n \"onMeasureDragConstraints\",\n \"onDirectionLock\",\n \"onDragTransitionEnd\",\n \"_dragX\",\n \"_dragY\",\n \"onHoverStart\",\n \"onHoverEnd\",\n \"onViewportEnter\",\n \"onViewportLeave\",\n \"globalTapTarget\",\n \"propagate\",\n \"ignoreStrict\",\n \"viewport\",\n])\n\n/**\n * Check whether a prop name is a valid `MotionProp` key.\n *\n * @param key - Name of the property to check\n * @returns `true` is key is a valid `MotionProp`.\n *\n * @public\n */\nexport function isValidMotionProp(key: string) {\n return (\n key.startsWith(\"while\") ||\n (key.startsWith(\"drag\") && key !== \"draggable\") ||\n key.startsWith(\"layout\") ||\n key.startsWith(\"onTap\") ||\n key.startsWith(\"onPan\") ||\n key.startsWith(\"onLayout\") ||\n validMotionProps.has(key as keyof MotionProps)\n )\n}\n", "import { isMotionValue } from \"motion-dom\"\nimport type { MotionProps } from \"../../../motion/types\"\nimport { isValidMotionProp } from \"../../../motion/utils/valid-prop\"\n\nlet shouldForward = (key: string) => !isValidMotionProp(key)\n\nexport type IsValidProp = (key: string) => boolean\n\nexport function loadExternalIsValidProp(isValidProp?: IsValidProp) {\n if (typeof isValidProp !== \"function\") return\n\n // Explicitly filter our events\n shouldForward = (key: string) =>\n key.startsWith(\"on\") ? !isValidMotionProp(key) : isValidProp(key)\n}\n\n/**\n * Emotion and Styled Components both allow users to pass through arbitrary props to their components\n * to dynamically generate CSS. They both use the `@emotion/is-prop-valid` package to determine which\n * of these should be passed to the underlying DOM node.\n *\n * However, when styling a Motion component `styled(motion.div)`, both packages pass through *all* props\n * as it's seen as an arbitrary component rather than a DOM node. Motion only allows arbitrary props\n * passed through the `custom` prop so it doesn't *need* the payload or computational overhead of\n * `@emotion/is-prop-valid`, however to fix this problem we need to use it.\n *\n * By making it an optionalDependency we can offer this functionality only in the situations where it's\n * actually required.\n */\ntry {\n /**\n * We attempt to import this package but require won't be defined in esm environments, in that case\n * isPropValid will have to be provided via `MotionContext`. In a 6.0.0 this should probably be removed\n * in favour of explicit injection.\n *\n * String concatenation prevents bundlers like webpack (e.g. Storybook)\n * from statically resolving this optional dependency at build time.\n */\n const emotionPkg = \"@emotion/is-prop-\" + \"valid\"\n loadExternalIsValidProp(require(emotionPkg).default)\n} catch {\n // We don't need to actually do anything here - the fallback is the existing `isPropValid`.\n}\n\nexport function filterProps(\n props: MotionProps,\n isDom: boolean,\n forwardMotionProps: boolean\n) {\n const filteredProps: MotionProps = {}\n\n for (const key in props) {\n /**\n * values is considered a valid prop by Emotion, so if it's present\n * this will be rendered out to the DOM unless explicitly filtered.\n *\n * We check the type as it could be used with the `feColorMatrix`\n * element, which we support.\n */\n if (key === \"values\" && typeof props.values === \"object\") continue\n\n if (isMotionValue(props[key as keyof typeof props])) continue\n\n if (\n shouldForward(key) ||\n (forwardMotionProps === true && isValidMotionProp(key)) ||\n (!isDom && !isValidMotionProp(key)) ||\n // If trying to use native HTML drag events, forward drag listeners\n (props[\"draggable\" as keyof MotionProps] &&\n key.startsWith(\"onDrag\"))\n ) {\n filteredProps[key as keyof MotionProps] =\n props[key as keyof MotionProps]\n }\n }\n\n return filteredProps\n}\n", "\"use client\"\n\nimport * as React from \"react\"\nimport { useContext, useMemo } from \"react\"\nimport { resolveTransition } from \"motion-dom\"\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport {\n loadExternalIsValidProp,\n IsValidProp,\n} from \"../../render/dom/utils/filter-props\"\nimport { useConstant } from \"../../utils/use-constant\"\n\nexport interface MotionConfigProps extends Partial {\n children?: React.ReactNode\n isValidProp?: IsValidProp\n}\n\n/**\n * `MotionConfig` is used to set configuration options for all children `motion` components.\n *\n * ```jsx\n * import { motion, MotionConfig } from \"framer-motion\"\n *\n * export function App() {\n * return (\n * \n * \n * \n * )\n * }\n * ```\n *\n * @public\n */\nexport function MotionConfig({\n children,\n isValidProp,\n ...config\n}: MotionConfigProps) {\n isValidProp && loadExternalIsValidProp(isValidProp)\n\n /**\n * Inherit props from any parent MotionConfig components\n */\n const parentConfig = useContext(MotionConfigContext)\n config = { ...parentConfig, ...config }\n\n config.transition = resolveTransition(\n config.transition,\n parentConfig.transition\n )\n\n /**\n * Don't allow isStatic to change between renders as it affects how many hooks\n * motion components fire.\n */\n config.isStatic = useConstant(() => config.isStatic)\n\n /**\n * Creating a new config context object will re-render every `motion` component\n * every time it renders. So we only want to create a new one sparingly.\n */\n const context = useMemo(\n () => config,\n [\n JSON.stringify(config.transition),\n config.transformPagePoint,\n config.reducedMotion,\n config.skipAnimations,\n ]\n )\n\n return (\n \n {children}\n \n )\n}\n", "\"use client\"\n\nimport type { VisualElement } from \"motion-dom\"\nimport { createContext } from \"react\"\n\nexport interface MotionContextProps {\n visualElement?: VisualElement\n initial?: false | string | string[]\n animate?: string | string[]\n}\n\nexport const MotionContext = /* @__PURE__ */ createContext(\n {}\n)\n", "import { isControllingVariants, isVariantLabel } from \"motion-dom\"\nimport type { MotionContextProps } from \".\"\nimport { MotionProps } from \"../../motion/types\"\n\nexport function getCurrentTreeVariants(\n props: MotionProps,\n context: MotionContextProps\n): MotionContextProps {\n if (isControllingVariants(props)) {\n const { initial, animate } = props\n return {\n initial:\n initial === false || isVariantLabel(initial)\n ? (initial as any)\n : undefined,\n animate: isVariantLabel(animate) ? animate : undefined,\n }\n }\n return props.inherit !== false ? context : {}\n}\n", "\"use client\"\n\nimport { useContext, useMemo } from \"react\"\nimport { MotionContext, type MotionContextProps } from \".\"\nimport { MotionProps } from \"../../motion/types\"\nimport { getCurrentTreeVariants } from \"./utils\"\n\nexport function useCreateMotionContext(\n props: MotionProps\n): MotionContextProps {\n const { initial, animate } = getCurrentTreeVariants(\n props,\n useContext(MotionContext)\n )\n\n return useMemo(\n () => ({ initial, animate }),\n [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]\n )\n}\n\nfunction variantLabelsAsDependency(\n prop: undefined | string | string[] | boolean\n) {\n return Array.isArray(prop) ? prop.join(\" \") : prop\n}\n", "import { HTMLRenderState } from \"../types\"\n\nexport const createHtmlRenderState = (): HTMLRenderState => ({\n style: {},\n transform: {},\n transformOrigin: {},\n vars: {},\n})\n", "\"use client\"\n\nimport { AnyResolvedKeyframe, buildHTMLStyles, isForcedMotionValue, isMotionValue, MotionValue } from \"motion-dom\"\nimport { HTMLProps, useMemo } from \"react\"\nimport { MotionProps } from \"../../motion/types\"\nimport { ResolvedValues } from \"../types\"\nimport { createHtmlRenderState } from \"./utils/create-render-state\"\n\nexport function copyRawValuesOnly(\n target: ResolvedValues,\n source: { [key: string]: AnyResolvedKeyframe | MotionValue },\n props: MotionProps\n) {\n for (const key in source) {\n if (!isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {\n target[key] = source[key] as AnyResolvedKeyframe\n }\n }\n}\n\nfunction useInitialMotionValues(\n { transformTemplate }: MotionProps,\n visualState: ResolvedValues\n) {\n return useMemo(() => {\n const state = createHtmlRenderState()\n\n buildHTMLStyles(state, visualState, transformTemplate)\n\n return Object.assign({}, state.vars, state.style)\n }, [visualState])\n}\n\nfunction useStyle(\n props: MotionProps,\n visualState: ResolvedValues\n): ResolvedValues {\n const styleProp = props.style || {}\n const style = {}\n\n /**\n * Copy non-Motion Values straight into style\n */\n copyRawValuesOnly(style, styleProp as any, props)\n\n Object.assign(style, useInitialMotionValues(props, visualState))\n\n return style\n}\n\nexport function useHTMLProps(\n props: MotionProps & HTMLProps,\n visualState: ResolvedValues\n) {\n // The `any` isn't ideal but it is the type of createElement props argument\n const htmlProps: any = {}\n const style = useStyle(props, visualState)\n\n if (props.drag && props.dragListener !== false) {\n // Disable the ghost element when a user drags\n htmlProps.draggable = false\n\n // Disable text selection\n style.userSelect =\n style.WebkitUserSelect =\n style.WebkitTouchCallout =\n \"none\"\n\n // Disable scrolling on the draggable direction\n style.touchAction =\n props.drag === true\n ? \"none\"\n : `pan-${props.drag === \"x\" ? \"y\" : \"x\"}`\n }\n\n if (\n props.tabIndex === undefined &&\n (props.onTap || props.onTapStart || props.whileTap)\n ) {\n htmlProps.tabIndex = 0\n }\n\n htmlProps.style = style\n\n return htmlProps\n}\n", "import { createHtmlRenderState } from \"../../html/utils/create-render-state\"\nimport { SVGRenderState } from \"../types\"\n\nexport const createSvgRenderState = (): SVGRenderState => ({\n ...createHtmlRenderState(),\n attrs: {},\n})\n", "\"use client\"\n\nimport { buildSVGAttrs, isSVGTag } from \"motion-dom\"\nimport { useMemo } from \"react\"\nimport { MotionProps } from \"../../motion/types\"\nimport { copyRawValuesOnly } from \"../html/use-props\"\nimport { ResolvedValues } from \"../types\"\nimport { createSvgRenderState } from \"./utils/create-render-state\"\n\nexport function useSVGProps(\n props: MotionProps,\n visualState: ResolvedValues,\n _isStatic: boolean,\n Component: string | React.ComponentType>\n) {\n const visualProps = useMemo(() => {\n const state = createSvgRenderState()\n\n buildSVGAttrs(\n state,\n visualState,\n isSVGTag(Component),\n props.transformTemplate,\n props.style\n )\n\n return {\n ...state.attrs,\n style: { ...state.style },\n }\n }, [visualState])\n\n if (props.style) {\n const rawStyles = {}\n copyRawValuesOnly(rawStyles, props.style as any, props)\n visualProps.style = { ...rawStyles, ...visualProps.style }\n }\n\n return visualProps\n}\n", "/**\n * We keep these listed separately as we use the lowercase tag names as part\n * of the runtime bundle to detect SVG components\n */\nexport const lowercaseSVGElements = [\n \"animate\",\n \"circle\",\n \"defs\",\n \"desc\",\n \"ellipse\",\n \"g\",\n \"image\",\n \"line\",\n \"filter\",\n \"marker\",\n \"mask\",\n \"metadata\",\n \"path\",\n \"pattern\",\n \"polygon\",\n \"polyline\",\n \"rect\",\n \"stop\",\n \"switch\",\n \"symbol\",\n \"svg\",\n \"text\",\n \"tspan\",\n \"use\",\n \"view\",\n]\n", "import * as React from \"react\"\nimport { lowercaseSVGElements } from \"../../svg/lowercase-elements\"\n\nexport function isSVGComponent(Component: string | React.ComponentType) {\n if (\n /**\n * If it's not a string, it's a custom React component. Currently we only support\n * HTML custom React components.\n */\n typeof Component !== \"string\" ||\n /**\n * If it contains a dash, the element is a custom HTML webcomponent.\n */\n Component.includes(\"-\")\n ) {\n return false\n } else if (\n /**\n * If it's in our list of lowercase SVG tags, it's an SVG component\n */\n lowercaseSVGElements.indexOf(Component) > -1 ||\n /**\n * If it contains a capital letter, it's an SVG component\n */\n /[A-Z]/u.test(Component)\n ) {\n return true\n }\n\n return false\n}\n", "\"use client\"\n\nimport { isMotionValue } from \"motion-dom\"\nimport { Fragment, createElement, useMemo } from \"react\"\nimport { MotionProps } from \"../../motion/types\"\nimport { VisualState } from \"../../motion/utils/use-visual-state\"\nimport { HTMLRenderState } from \"../html/types\"\nimport { useHTMLProps } from \"../html/use-props\"\nimport { SVGRenderState } from \"../svg/types\"\nimport { useSVGProps } from \"../svg/use-props\"\nimport { DOMMotionComponents } from \"./types\"\nimport { filterProps } from \"./utils/filter-props\"\nimport { isSVGComponent } from \"./utils/is-svg-component\"\n\nexport function useRender<\n Props = {},\n TagName extends keyof DOMMotionComponents | string = \"div\"\n>(\n Component: TagName | string | React.ComponentType,\n props: MotionProps,\n ref: React.Ref,\n {\n latestValues,\n }: VisualState,\n isStatic: boolean,\n forwardMotionProps: boolean = false,\n isSVG?: boolean\n) {\n const useVisualProps =\n (isSVG ?? isSVGComponent(Component)) ? useSVGProps : useHTMLProps\n\n const visualProps = useVisualProps(\n props as any,\n latestValues,\n isStatic,\n Component as any\n )\n const filteredProps = filterProps(\n props,\n typeof Component === \"string\",\n forwardMotionProps\n )\n const elementProps =\n Component !== Fragment ? { ...filteredProps, ...visualProps, ref } : {}\n\n /**\n * If component has been handed a motion value as its child,\n * memoise its initial value and render that. Subsequent updates\n * will be handled by the onChange handler\n */\n const { children } = props\n const renderedChildren = useMemo(\n () => (isMotionValue(children) ? children.get() : children),\n [children]\n )\n\n return createElement(Component, {\n ...elementProps,\n children: renderedChildren,\n })\n}\n", "\"use client\"\n\nimport {\n AnyResolvedKeyframe,\n isAnimationControls,\n isControllingVariants as checkIsControllingVariants,\n isVariantNode as checkIsVariantNode,\n ResolvedValues,\n resolveVariantFromProps,\n} from \"motion-dom\"\nimport { useContext } from \"react\"\nimport { MotionContext, MotionContextProps } from \"../../context/MotionContext\"\nimport {\n PresenceContext,\n type PresenceContextProps,\n} from \"../../context/PresenceContext\"\nimport { ScrapeMotionValuesFromProps } from \"../../render/types\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { resolveMotionValue } from \"motion-dom\"\nimport { MotionProps } from \"../types\"\n\nexport interface VisualState {\n renderState: RenderState\n latestValues: ResolvedValues\n onMount?: (instance: Instance) => void\n}\n\nexport type UseVisualState = (\n props: MotionProps,\n isStatic: boolean\n) => VisualState\n\nexport interface UseVisualStateConfig {\n scrapeMotionValuesFromProps: ScrapeMotionValuesFromProps\n createRenderState: () => RenderState\n}\n\nfunction makeState(\n {\n scrapeMotionValuesFromProps,\n createRenderState,\n }: UseVisualStateConfig,\n props: MotionProps,\n context: MotionContextProps,\n presenceContext: PresenceContextProps | null\n) {\n const state: VisualState = {\n latestValues: makeLatestValues(\n props,\n context,\n presenceContext,\n scrapeMotionValuesFromProps\n ),\n renderState: createRenderState(),\n }\n\n return state\n}\n\nfunction makeLatestValues(\n props: MotionProps,\n context: MotionContextProps,\n presenceContext: PresenceContextProps | null,\n scrapeMotionValues: ScrapeMotionValuesFromProps\n) {\n const values: ResolvedValues = {}\n\n const motionValues = scrapeMotionValues(props, {})\n for (const key in motionValues) {\n values[key] = resolveMotionValue(motionValues[key])\n }\n\n let { initial, animate } = props\n const isControllingVariants = checkIsControllingVariants(props)\n const isVariantNode = checkIsVariantNode(props)\n\n if (\n context &&\n isVariantNode &&\n !isControllingVariants &&\n props.inherit !== false\n ) {\n if (initial === undefined) initial = context.initial\n if (animate === undefined) animate = context.animate\n }\n\n let isInitialAnimationBlocked = presenceContext\n ? presenceContext.initial === false\n : false\n isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false\n\n const variantToSet = isInitialAnimationBlocked ? animate : initial\n\n if (\n variantToSet &&\n typeof variantToSet !== \"boolean\" &&\n !isAnimationControls(variantToSet)\n ) {\n const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet]\n for (let i = 0; i < list.length; i++) {\n const resolved = resolveVariantFromProps(props, list[i] as any)\n if (resolved) {\n const { transitionEnd, transition, ...target } = resolved\n for (const key in target) {\n let valueTarget = target[key as keyof typeof target]\n\n if (Array.isArray(valueTarget)) {\n /**\n * Take final keyframe if the initial animation is blocked because\n * we want to initialise at the end of that blocked animation.\n */\n const index = isInitialAnimationBlocked\n ? valueTarget.length - 1\n : 0\n valueTarget = valueTarget[index] as any\n }\n\n if (valueTarget !== null) {\n values[key] = valueTarget as AnyResolvedKeyframe\n }\n }\n for (const key in transitionEnd) {\n values[key] = transitionEnd[\n key as keyof typeof transitionEnd\n ] as AnyResolvedKeyframe\n }\n }\n }\n }\n\n return values\n}\n\nexport const makeUseVisualState =\n (config: UseVisualStateConfig): UseVisualState =>\n (props: MotionProps, isStatic: boolean): VisualState => {\n const context = useContext(MotionContext)\n const presenceContext = useContext(PresenceContext)\n const make = () => makeState(config, props, context, presenceContext)\n\n return isStatic ? make() : useConstant(make)\n }\n", "\"use client\"\n\nimport { scrapeHTMLMotionValuesFromProps } from \"motion-dom\"\nimport { makeUseVisualState } from \"../../motion/utils/use-visual-state\"\nimport { createHtmlRenderState } from \"./utils/create-render-state\"\n\nexport const useHTMLVisualState = /*@__PURE__*/ makeUseVisualState({\n scrapeMotionValuesFromProps: scrapeHTMLMotionValuesFromProps,\n createRenderState: createHtmlRenderState,\n})\n", "\"use client\"\n\nimport { scrapeSVGMotionValuesFromProps } from \"motion-dom\"\nimport { makeUseVisualState } from \"../../motion/utils/use-visual-state\"\nimport { createSvgRenderState } from \"./utils/create-render-state\"\n\nexport const useSVGVisualState = /*@__PURE__*/ makeUseVisualState({\n scrapeMotionValuesFromProps: scrapeSVGMotionValuesFromProps,\n createRenderState: createSvgRenderState,\n})\n", "export const motionComponentSymbol = Symbol.for(\"motionComponentSymbol\")\n", "\"use client\"\n\nimport type { VisualElement } from \"motion-dom\"\nimport * as React from \"react\"\nimport { useCallback, useInsertionEffect, useRef } from \"react\"\nimport { VisualState } from \"./use-visual-state\"\n\n/**\n * Creates a ref function that, when called, hydrates the provided\n * external ref and VisualElement.\n */\nexport function useMotionRef(\n visualState: VisualState,\n visualElement?: VisualElement | null,\n externalRef?: React.Ref\n): React.Ref {\n /**\n * Store externalRef in a ref to avoid including it in the useCallback\n * dependency array. Including externalRef in dependencies causes issues\n * with libraries like Radix UI that create new callback refs on each render\n * when using asChild - this would cause the callback to be recreated,\n * triggering element remounts and breaking AnimatePresence exit animations.\n */\n const externalRefContainer = useRef(externalRef)\n useInsertionEffect(() => {\n externalRefContainer.current = externalRef\n })\n\n // Store cleanup function returned by callback refs (React 19 feature)\n const refCleanup = useRef<(() => void) | null>(null)\n\n return useCallback(\n (instance: Instance) => {\n if (instance) {\n visualState.onMount?.(instance)\n }\n\n const ref = externalRefContainer.current\n if (typeof ref === \"function\") {\n if (instance) {\n const cleanup = ref(instance)\n if (typeof cleanup === \"function\") {\n refCleanup.current = cleanup\n }\n } else if (refCleanup.current) {\n refCleanup.current()\n refCleanup.current = null\n } else {\n ref(instance)\n }\n } else if (ref) {\n ;(ref as React.MutableRefObject).current = instance\n }\n\n if (visualElement) {\n instance ? visualElement.mount(instance) : visualElement.unmount()\n }\n },\n [visualElement]\n )\n}\n", "import { MutableRefObject } from \"./safe-react-types\"\n\nexport function isRefObject(ref: any): ref is MutableRefObject {\n return (\n ref &&\n typeof ref === \"object\" &&\n Object.prototype.hasOwnProperty.call(ref, \"current\")\n )\n}\n", "\"use client\"\n\nimport {\n optimizedAppearDataAttribute,\n type HTMLRenderState,\n type SVGRenderState,\n type VisualElement,\n} from \"motion-dom\"\nimport * as React from \"react\"\nimport { useContext, useEffect, useInsertionEffect, useRef } from \"react\"\nimport { LazyContext } from \"../../context/LazyContext\"\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport { MotionContext } from \"../../context/MotionContext\"\nimport { PresenceContext } from \"../../context/PresenceContext\"\nimport {\n InitialPromotionConfig,\n SwitchLayoutGroupContext,\n} from \"../../context/SwitchLayoutGroupContext\"\nimport { MotionProps } from \"../../motion/types\"\nimport type { IProjectionNode } from \"motion-dom\"\nimport { DOMMotionComponents } from \"../../render/dom/types\"\nimport { CreateVisualElement } from \"../../render/types\"\nimport { isRefObject } from \"../../utils/is-ref-object\"\nimport { useIsomorphicLayoutEffect } from \"../../utils/use-isomorphic-effect\"\nimport { VisualState } from \"./use-visual-state\"\n\nexport function useVisualElement<\n Props,\n TagName extends keyof DOMMotionComponents | string\n>(\n Component: TagName | string | React.ComponentType,\n visualState:\n | VisualState\n | VisualState,\n props: MotionProps & Partial,\n createVisualElement?: CreateVisualElement,\n ProjectionNodeConstructor?: any,\n isSVG?: boolean\n): VisualElement | undefined {\n const { visualElement: parent } = useContext(MotionContext)\n const lazyContext = useContext(LazyContext)\n const presenceContext = useContext(PresenceContext)\n const motionConfig = useContext(MotionConfigContext)\n const reducedMotionConfig = motionConfig.reducedMotion\n const skipAnimations = motionConfig.skipAnimations\n\n const visualElementRef = useRef | null>(null)\n\n /**\n * Track whether the component has been through React's commit phase.\n * Used to detect when LazyMotion features load after the component has mounted.\n */\n const hasMountedOnce = useRef(false)\n\n /**\n * If we haven't preloaded a renderer, check to see if we have one lazy-loaded\n */\n createVisualElement =\n createVisualElement ||\n (lazyContext.renderer as CreateVisualElement)\n\n if (!visualElementRef.current && createVisualElement) {\n visualElementRef.current = createVisualElement(Component, {\n visualState,\n parent,\n props,\n presenceContext,\n blockInitialAnimation: presenceContext\n ? presenceContext.initial === false\n : false,\n reducedMotionConfig,\n skipAnimations,\n isSVG,\n })\n\n /**\n * If the component has already mounted before features loaded (e.g. via\n * LazyMotion with async feature loading), we need to force the initial\n * animation to run. Otherwise state changes that occurred before features\n * loaded will be lost and the element will snap to its final state.\n */\n if (hasMountedOnce.current && visualElementRef.current) {\n visualElementRef.current.manuallyAnimateOnMount = true\n }\n }\n\n const visualElement = visualElementRef.current\n\n /**\n * Load Motion gesture and animation features. These are rendered as renderless\n * components so each feature can optionally make use of React lifecycle methods.\n */\n const initialLayoutGroupConfig = useContext(SwitchLayoutGroupContext)\n\n if (\n visualElement &&\n !visualElement.projection &&\n ProjectionNodeConstructor &&\n (visualElement.type === \"html\" || visualElement.type === \"svg\")\n ) {\n createProjectionNode(\n visualElementRef.current!,\n props,\n ProjectionNodeConstructor,\n initialLayoutGroupConfig\n )\n }\n\n const isMounted = useRef(false)\n useInsertionEffect(() => {\n /**\n * Check the component has already mounted before calling\n * `update` unnecessarily. This ensures we skip the initial update.\n */\n if (visualElement && isMounted.current) {\n visualElement.update(props, presenceContext)\n }\n })\n\n /**\n * Cache this value as we want to know whether HandoffAppearAnimations\n * was present on initial render - it will be deleted after this.\n */\n const optimisedAppearId =\n props[optimizedAppearDataAttribute as keyof typeof props]\n const wantsHandoff = useRef(\n Boolean(optimisedAppearId) &&\n typeof window !== \"undefined\" &&\n !window.MotionHandoffIsComplete?.(optimisedAppearId) &&\n window.MotionHasOptimisedAnimation?.(optimisedAppearId)\n )\n\n useIsomorphicLayoutEffect(() => {\n /**\n * Track that this component has mounted. This is used to detect when\n * LazyMotion features load after the component has already committed.\n */\n hasMountedOnce.current = true\n\n if (!visualElement) return\n\n isMounted.current = true\n window.MotionIsMounted = true\n\n visualElement.updateFeatures()\n visualElement.scheduleRenderMicrotask()\n\n /**\n * Ideally this function would always run in a useEffect.\n *\n * However, if we have optimised appear animations to handoff from,\n * it needs to happen synchronously to ensure there's no flash of\n * incorrect styles in the event of a hydration error.\n *\n * So if we detect a situtation where optimised appear animations\n * are running, we use useLayoutEffect to trigger animations.\n */\n if (wantsHandoff.current && visualElement.animationState) {\n visualElement.animationState.animateChanges()\n }\n })\n\n useEffect(() => {\n if (!visualElement) return\n\n if (!wantsHandoff.current && visualElement.animationState) {\n visualElement.animationState.animateChanges()\n }\n\n if (wantsHandoff.current) {\n // This ensures all future calls to animateChanges() in this component will run in useEffect\n queueMicrotask(() => {\n window.MotionHandoffMarkAsComplete?.(optimisedAppearId)\n })\n\n wantsHandoff.current = false\n }\n\n /**\n * Now we've finished triggering animations for this element we\n * can wipe the enteringChildren set for the next render.\n */\n visualElement.enteringChildren = undefined\n })\n\n return visualElement!\n}\n\nfunction createProjectionNode(\n visualElement: VisualElement,\n props: MotionProps,\n ProjectionNodeConstructor: any,\n initialPromotionConfig?: InitialPromotionConfig\n) {\n const {\n layoutId,\n layout,\n drag,\n dragConstraints,\n layoutScroll,\n layoutRoot,\n layoutAnchor,\n layoutCrossfade,\n } = props\n\n visualElement.projection = new ProjectionNodeConstructor(\n visualElement.latestValues,\n props[\"data-framer-portal-id\"]\n ? undefined\n : getClosestProjectingNode(visualElement.parent)\n ) as IProjectionNode\n\n visualElement.projection.setOptions({\n layoutId,\n layout,\n alwaysMeasureLayout:\n Boolean(drag) || (dragConstraints && isRefObject(dragConstraints)),\n visualElement,\n /**\n * TODO: Update options in an effect. This could be tricky as it'll be too late\n * to update by the time layout animations run.\n * We also need to fix this safeToRemove by linking it up to the one returned by usePresence,\n * ensuring it gets called if there's no potential layout animations.\n *\n */\n animationType: typeof layout === \"string\" ? layout : \"both\",\n initialPromotionConfig,\n crossfade: layoutCrossfade,\n layoutScroll,\n layoutRoot,\n layoutAnchor,\n })\n}\n\nfunction getClosestProjectingNode(\n visualElement?: VisualElement<\n unknown,\n unknown,\n { allowProjection?: boolean }\n >\n): IProjectionNode | undefined {\n if (!visualElement) return undefined\n\n return visualElement.options.allowProjection !== false\n ? visualElement.projection\n : getClosestProjectingNode(visualElement.parent)\n}\n", "\"use client\"\n\nimport { invariant, warning } from \"motion-utils\"\nimport * as React from \"react\"\nimport { forwardRef, useContext } from \"react\"\nimport { LayoutGroupContext } from \"../context/LayoutGroupContext\"\nimport { LazyContext } from \"../context/LazyContext\"\nimport { MotionConfigContext } from \"../context/MotionConfigContext\"\nimport { MotionContext } from \"../context/MotionContext\"\nimport { useCreateMotionContext } from \"../context/MotionContext/create\"\nimport { DOMMotionComponents } from \"../render/dom/types\"\nimport { useRender } from \"../render/dom/use-render\"\nimport { isSVGComponent } from \"../render/dom/utils/is-svg-component\"\nimport { HTMLRenderState } from \"../render/html/types\"\nimport { useHTMLVisualState } from \"../render/html/use-html-visual-state\"\nimport { SVGRenderState } from \"../render/svg/types\"\nimport { useSVGVisualState } from \"../render/svg/use-svg-visual-state\"\nimport { CreateVisualElement } from \"../render/types\"\nimport { getInitializedFeatureDefinitions } from \"./features/definitions\"\nimport { loadFeatures } from \"./features/load-features\"\nimport { FeatureBundle, FeaturePackages } from \"./features/types\"\nimport { MotionProps } from \"./types\"\nimport { motionComponentSymbol } from \"./utils/symbol\"\nimport { useMotionRef } from \"./utils/use-motion-ref\"\nimport { useVisualElement } from \"./utils/use-visual-element\"\n\nexport interface MotionComponentConfig<\n TagName extends keyof DOMMotionComponents | string = \"div\"\n> {\n preloadedFeatures?: FeatureBundle\n createVisualElement?: CreateVisualElement\n Component: TagName | React.ComponentType>\n forwardMotionProps?: boolean\n}\n\nexport type MotionComponentProps = {\n [K in Exclude]?: Props[K]\n} & MotionProps\n\nexport type MotionComponent = T extends keyof DOMMotionComponents\n ? DOMMotionComponents[T]\n : React.ComponentType<\n Omit, \"children\"> & {\n children?: \"children\" extends keyof P\n ? P[\"children\"] | MotionComponentProps

    [\"children\"]\n : MotionComponentProps

    [\"children\"]\n }\n >\n\nexport interface MotionComponentOptions {\n forwardMotionProps?: boolean\n /**\n * Specify whether the component renders an HTML or SVG element.\n * This is useful when wrapping custom SVG components that need\n * SVG-specific attribute handling (like viewBox animation).\n * By default, Motion auto-detects based on the component name,\n * but custom React components are always treated as HTML.\n */\n type?: \"html\" | \"svg\"\n}\n\n/**\n * Create a `motion` component.\n *\n * This function accepts a Component argument, which can be either a string (ie \"div\"\n * for `motion.div`), or an actual React component.\n *\n * Alongside this is a config option which provides a way of rendering the provided\n * component \"offline\", or outside the React render cycle.\n */\nexport function createMotionComponent<\n Props,\n TagName extends keyof DOMMotionComponents | string = \"div\"\n>(\n Component: TagName | string | React.ComponentType,\n { forwardMotionProps = false, type }: MotionComponentOptions = {},\n preloadedFeatures?: FeaturePackages,\n createVisualElement?: CreateVisualElement\n) {\n preloadedFeatures && loadFeatures(preloadedFeatures)\n\n /**\n * Determine whether to use SVG or HTML rendering based on:\n * 1. Explicit `type` option (highest priority)\n * 2. Auto-detection via `isSVGComponent`\n */\n const isSVG = type ? type === \"svg\" : isSVGComponent(Component)\n const useVisualState = isSVG ? useSVGVisualState : useHTMLVisualState\n\n function MotionDOMComponent(\n props: MotionComponentProps,\n externalRef?: React.Ref\n ) {\n /**\n * If we need to measure the element we load this functionality in a\n * separate class component in order to gain access to getSnapshotBeforeUpdate.\n */\n let MeasureLayout: undefined | React.ComponentType\n\n const configAndProps = {\n ...useContext(MotionConfigContext),\n ...props,\n layoutId: useLayoutId(props),\n }\n\n const { isStatic } = configAndProps\n\n const context = useCreateMotionContext(props)\n\n const visualState = useVisualState(props, isStatic)\n\n if (!isStatic && typeof window !== \"undefined\") {\n useStrictMode(configAndProps, preloadedFeatures)\n\n const layoutProjection = getProjectionFunctionality(configAndProps)\n MeasureLayout = layoutProjection.MeasureLayout\n\n /**\n * Create a VisualElement for this component. A VisualElement provides a common\n * interface to renderer-specific APIs (ie DOM/Three.js etc) as well as\n * providing a way of rendering to these APIs outside of the React render loop\n * for more performant animations and interactions\n */\n context.visualElement = useVisualElement(\n Component,\n visualState,\n configAndProps,\n createVisualElement,\n layoutProjection.ProjectionNode,\n isSVG\n )\n }\n\n /**\n * The mount order and hierarchy is specific to ensure our element ref\n * is hydrated by the time features fire their effects.\n */\n return (\n \n {MeasureLayout && context.visualElement ? (\n \n ) : null}\n {useRender(\n Component,\n props,\n useMotionRef<\n HTMLElement | SVGElement,\n HTMLRenderState | SVGRenderState\n >(visualState, context.visualElement, externalRef),\n visualState,\n isStatic,\n forwardMotionProps,\n isSVG\n )}\n \n )\n }\n\n MotionDOMComponent.displayName = `motion.${\n typeof Component === \"string\"\n ? Component\n : `create(${Component.displayName ?? Component.name ?? \"\"})`\n }`\n\n const ForwardRefMotionComponent = forwardRef(MotionDOMComponent as any)\n ;(ForwardRefMotionComponent as any)[motionComponentSymbol] = Component\n\n return ForwardRefMotionComponent as MotionComponent\n}\n\nfunction useLayoutId({ layoutId }: MotionProps) {\n const layoutGroupId = useContext(LayoutGroupContext).id\n return layoutGroupId && layoutId !== undefined\n ? layoutGroupId + \"-\" + layoutId\n : layoutId\n}\n\nfunction useStrictMode(\n configAndProps: MotionProps,\n preloadedFeatures?: FeaturePackages\n) {\n const isStrict = useContext(LazyContext).strict\n\n /**\n * If we're in development mode, check to make sure we're not rendering a motion component\n * as a child of LazyMotion, as this will break the file-size benefits of using it.\n */\n if (\n process.env.NODE_ENV !== \"production\" &&\n preloadedFeatures &&\n isStrict\n ) {\n const strictMessage =\n \"You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.\"\n configAndProps.ignoreStrict\n ? warning(false, strictMessage, \"lazy-strict-mode\")\n : invariant(false, strictMessage, \"lazy-strict-mode\")\n }\n}\n\nfunction getProjectionFunctionality(props: MotionProps) {\n const featureDefinitions = getInitializedFeatureDefinitions()\n const { drag, layout } = featureDefinitions\n\n if (!drag && !layout) return {}\n\n const combined = { ...drag, ...layout }\n\n return {\n MeasureLayout:\n drag?.isEnabled(props) || layout?.isEnabled(props)\n ? combined.MeasureLayout\n : undefined,\n ProjectionNode: combined.ProjectionNode,\n }\n}\n", "import { warnOnce } from \"motion-utils\"\nimport { createMotionComponent, MotionComponentOptions } from \"../../motion\"\nimport { FeaturePackages } from \"../../motion/features/types\"\nimport { MotionProps } from \"../../motion/types\"\nimport { DOMMotionComponents } from \"../dom/types\"\nimport { CreateVisualElement } from \"../types\"\n\n/**\n * I'd rather the return type of `custom` to be implicit but this throws\n * incorrect relative paths in the exported types and API Extractor throws\n * a wobbly.\n */\ntype ComponentProps = React.PropsWithoutRef &\n React.RefAttributes\nexport type CustomDomComponent = React.ComponentType<\n ComponentProps\n>\n\ntype MotionProxy = typeof createMotionComponent &\n DOMMotionComponents & { create: typeof createMotionComponent }\n\nexport function createMotionProxy(\n preloadedFeatures?: FeaturePackages,\n createVisualElement?: CreateVisualElement\n): MotionProxy {\n if (typeof Proxy === \"undefined\") {\n return createMotionComponent as MotionProxy\n }\n\n /**\n * A cache of generated `motion` components, e.g `motion.div`, `motion.input` etc.\n * Rather than generating them anew every render.\n */\n const componentCache = new Map()\n\n const factory = (Component: string, options?: MotionComponentOptions) => {\n return createMotionComponent(\n Component,\n options,\n preloadedFeatures,\n createVisualElement\n )\n }\n\n /**\n * Support for deprecated`motion(Component)` pattern\n */\n const deprecatedFactoryFunction = (\n Component: string,\n options?: MotionComponentOptions\n ) => {\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n false,\n \"motion() is deprecated. Use motion.create() instead.\"\n )\n }\n return factory(Component, options)\n }\n\n return new Proxy(deprecatedFactoryFunction, {\n /**\n * Called when `motion` is referenced with a prop: `motion.div`, `motion.input` etc.\n * The prop name is passed through as `key` and we can use that to generate a `motion`\n * DOM component with that name.\n */\n get: (_target, key: string) => {\n if (key === \"create\") return factory\n\n /**\n * If this element doesn't exist in the component cache, create it and cache.\n */\n if (!componentCache.has(key)) {\n componentCache.set(\n key,\n createMotionComponent(\n key,\n undefined,\n preloadedFeatures,\n createVisualElement\n )\n )\n }\n\n return componentCache.get(key)!\n },\n }) as MotionProxy\n}\n", "import { HTMLVisualElement, SVGVisualElement } from \"motion-dom\"\nimport { ComponentType, Fragment } from \"react\"\nimport { CreateVisualElement, VisualElementOptions } from \"../types\"\nimport { isSVGComponent } from \"./utils/is-svg-component\"\n\nexport const createDomVisualElement: CreateVisualElement = (\n Component: string | ComponentType>,\n options: VisualElementOptions\n) => {\n /**\n * Use explicit isSVG override if provided, otherwise auto-detect\n */\n const isSVG = options.isSVG ?? isSVGComponent(Component)\n\n return isSVG\n ? new SVGVisualElement(options)\n : new HTMLVisualElement(options, {\n allowProjection: Component !== Fragment,\n })\n}\n", "import {\n createAnimationState,\n Feature,\n isAnimationControls,\n type VisualElement,\n} from \"motion-dom\"\n\nexport class AnimationFeature extends Feature {\n unmountControls?: () => void\n\n /**\n * We dynamically generate the AnimationState manager as it contains a reference\n * to the underlying animation library. We only want to load that if we load this,\n * so people can optionally code split it out using the `m` component.\n */\n constructor(node: VisualElement) {\n super(node)\n node.animationState ||= createAnimationState(node)\n }\n\n updateAnimationControlsSubscription() {\n const { animate } = this.node.getProps()\n if (isAnimationControls(animate)) {\n this.unmountControls = animate.subscribe(this.node)\n }\n }\n\n /**\n * Subscribe any provided AnimationControls to the component's VisualElement\n */\n mount() {\n this.updateAnimationControlsSubscription()\n }\n\n update() {\n const { animate } = this.node.getProps()\n const { animate: prevAnimate } = this.node.prevProps || {}\n if (animate !== prevAnimate) {\n this.updateAnimationControlsSubscription()\n }\n }\n\n unmount() {\n this.node.animationState!.reset()\n this.unmountControls?.()\n }\n}\n", "import { Feature, resolveVariant } from \"motion-dom\"\n\nlet id = 0\n\nexport class ExitAnimationFeature extends Feature {\n private id: number = id++\n private isExitComplete = false\n\n update() {\n if (!this.node.presenceContext) return\n\n const { isPresent, onExitComplete } = this.node.presenceContext\n const { isPresent: prevIsPresent } = this.node.prevPresenceContext || {}\n\n if (!this.node.animationState || isPresent === prevIsPresent) {\n return\n }\n\n if (isPresent && prevIsPresent === false) {\n /**\n * When re-entering, if the exit animation already completed\n * (element is at rest), reset to initial values so the enter\n * animation replays from the correct position.\n */\n if (this.isExitComplete) {\n const { initial, custom } = this.node.getProps()\n\n if (typeof initial === \"string\") {\n const resolved = resolveVariant(\n this.node,\n initial,\n custom\n )\n if (resolved) {\n const { transition, transitionEnd, ...target } =\n resolved\n for (const key in target) {\n this.node\n .getValue(key)\n ?.jump(\n target[\n key as keyof typeof target\n ] as any\n )\n }\n }\n }\n\n this.node.animationState.reset()\n this.node.animationState.animateChanges()\n } else {\n this.node.animationState.setActive(\"exit\", false)\n }\n\n this.isExitComplete = false\n return\n }\n\n const exitAnimation = this.node.animationState.setActive(\n \"exit\",\n !isPresent\n )\n\n if (onExitComplete && !isPresent) {\n exitAnimation.then(() => {\n this.isExitComplete = true\n onExitComplete(this.id)\n })\n }\n }\n\n mount() {\n const { register, onExitComplete } = this.node.presenceContext || {}\n\n if (onExitComplete) {\n onExitComplete(this.id)\n }\n\n if (register) {\n this.unmount = register(this.id)\n }\n }\n\n unmount() {}\n}\n", "import { AnimationFeature } from \"./animation\"\nimport { ExitAnimationFeature } from \"./animation/exit\"\nimport { FeaturePackages } from \"./types\"\n\nexport const animations: FeaturePackages = {\n animation: {\n Feature: AnimationFeature,\n },\n exit: {\n Feature: ExitAnimationFeature,\n },\n}\n", "import { EventInfo, isPrimaryPointer } from \"motion-dom\"\n\nexport type EventListenerWithPointInfo = (\n e: PointerEvent,\n info: EventInfo\n) => void\n\nexport function extractEventInfo(event: PointerEvent): EventInfo {\n return {\n point: {\n x: event.pageX,\n y: event.pageY,\n },\n }\n}\n\nexport const addPointerInfo =\n (handler: EventListenerWithPointInfo): EventListener =>\n (event: PointerEvent) =>\n isPrimaryPointer(event) && handler(event, extractEventInfo(event))\n", "import { addDomEvent } from \"motion-dom\"\nimport { addPointerInfo, EventListenerWithPointInfo } from \"./event-info\"\n\nexport function addPointerEvent(\n target: EventTarget,\n eventName: string,\n handler: EventListenerWithPointInfo,\n options?: AddEventListenerOptions\n) {\n return addDomEvent(target, eventName, addPointerInfo(handler), options)\n}\n", "import type { VisualElement } from \"motion-dom\"\n\n// Fixes https://github.com/motiondivision/motion/issues/2270\nexport const getContextWindow = ({ current }: VisualElement) => {\n return current ? current.ownerDocument.defaultView : null\n}\n", "import { Point } from \"motion-utils\"\n\nexport const distance = (a: number, b: number) => Math.abs(a - b)\n\nexport function distance2D(a: Point, b: Point): number {\n // Multi-dimensional\n const xDelta = distance(a.x, b.x)\n const yDelta = distance(a.y, b.y)\n return Math.sqrt(xDelta ** 2 + yDelta ** 2)\n}\n", "import type { EventInfo, PanHandler } from \"motion-dom\"\nimport { cancelFrame, frame, frameData, isPrimaryPointer } from \"motion-dom\"\nimport {\n millisecondsToSeconds,\n pipe,\n Point,\n secondsToMilliseconds,\n TransformPoint,\n} from \"motion-utils\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { extractEventInfo } from \"../../events/event-info\"\nimport { distance2D } from \"../../utils/distance\"\n\ninterface PanSessionHandlers {\n onSessionStart: PanHandler\n onStart: PanHandler\n onMove: PanHandler\n onEnd: PanHandler\n onSessionEnd: PanHandler\n resumeAnimation: () => void\n}\n\ninterface PanSessionOptions {\n transformPagePoint?: TransformPoint\n dragSnapToOrigin?: boolean | \"x\" | \"y\"\n distanceThreshold?: number\n contextWindow?: (Window & typeof globalThis) | null\n /**\n * Element being dragged. When provided, scroll events on its\n * ancestors and window are compensated so the gesture continues\n * smoothly during scroll.\n */\n element?: HTMLElement | null\n}\n\ninterface TimestampedPoint extends Point {\n timestamp: number\n}\n\nconst overflowStyles = /*#__PURE__*/ new Set([\"auto\", \"scroll\"])\n\n/**\n * @internal\n */\nexport class PanSession {\n /**\n * @internal\n */\n private history: TimestampedPoint[]\n\n /**\n * @internal\n */\n private startEvent: PointerEvent | null = null\n\n /**\n * @internal\n */\n private lastMoveEvent: PointerEvent | null = null\n\n /**\n * @internal\n */\n private lastMoveEventInfo: EventInfo | null = null\n\n /**\n * Raw (untransformed) event info, re-transformed each frame\n * so transformPagePoint sees the current parent matrix.\n * @internal\n */\n private lastRawMoveEventInfo: EventInfo | null = null\n\n /**\n * @internal\n */\n private transformPagePoint?: TransformPoint\n\n /**\n * @internal\n */\n private handlers: Partial = {}\n\n /**\n * @internal\n */\n private removeListeners: Function\n\n /**\n * For determining if an animation should resume after it is interupted\n *\n * @internal\n */\n private dragSnapToOrigin: boolean | \"x\" | \"y\"\n\n /**\n * The distance after which panning should start.\n *\n * @internal\n */\n private distanceThreshold: number\n\n /**\n * @internal\n */\n private contextWindow: PanSessionOptions[\"contextWindow\"] = window\n\n /**\n * Scroll positions of scrollable ancestors and window.\n * @internal\n */\n private scrollPositions: Map = new Map()\n\n /**\n * Cleanup function for scroll listeners.\n * @internal\n */\n private removeScrollListeners: (() => void) | null = null\n\n constructor(\n event: PointerEvent,\n handlers: Partial,\n {\n transformPagePoint,\n contextWindow = window,\n dragSnapToOrigin = false,\n distanceThreshold = 3,\n element,\n }: PanSessionOptions = {}\n ) {\n // If we have more than one touch, don't start detecting this gesture\n if (!isPrimaryPointer(event)) return\n\n this.dragSnapToOrigin = dragSnapToOrigin\n this.handlers = handlers\n this.transformPagePoint = transformPagePoint\n this.distanceThreshold = distanceThreshold\n this.contextWindow = contextWindow || window\n\n const info = extractEventInfo(event)\n const initialInfo = transformPoint(info, this.transformPagePoint)\n const { point } = initialInfo\n\n const { timestamp } = frameData\n\n this.history = [{ ...point, timestamp }]\n\n const { onSessionStart } = handlers\n onSessionStart &&\n onSessionStart(event, getPanInfo(initialInfo, this.history))\n\n this.removeListeners = pipe(\n addPointerEvent(\n this.contextWindow,\n \"pointermove\",\n this.handlePointerMove\n ),\n addPointerEvent(\n this.contextWindow,\n \"pointerup\",\n this.handlePointerUp\n ),\n addPointerEvent(\n this.contextWindow,\n \"pointercancel\",\n this.handlePointerUp\n )\n )\n\n // Start scroll tracking if element provided\n if (element) {\n this.startScrollTracking(element)\n }\n }\n\n /**\n * Start tracking scroll on ancestors and window.\n */\n private startScrollTracking(element: HTMLElement): void {\n // Store initial scroll positions for scrollable ancestors\n let current = element.parentElement\n while (current) {\n const style = getComputedStyle(current)\n if (\n overflowStyles.has(style.overflowX) ||\n overflowStyles.has(style.overflowY)\n ) {\n this.scrollPositions.set(current, {\n x: current.scrollLeft,\n y: current.scrollTop,\n })\n }\n current = current.parentElement\n }\n\n // Track window scroll\n this.scrollPositions.set(window, {\n x: window.scrollX,\n y: window.scrollY,\n })\n\n // Capture listener catches element scroll events as they bubble\n window.addEventListener(\"scroll\", this.onElementScroll, {\n capture: true,\n })\n\n // Direct window scroll listener (window scroll doesn't bubble)\n window.addEventListener(\"scroll\", this.onWindowScroll)\n\n this.removeScrollListeners = () => {\n window.removeEventListener(\"scroll\", this.onElementScroll, {\n capture: true,\n })\n window.removeEventListener(\"scroll\", this.onWindowScroll)\n }\n }\n\n private onElementScroll = (event: Event): void => {\n this.handleScroll(event.target as Element)\n }\n\n private onWindowScroll = (): void => {\n this.handleScroll(window)\n }\n\n /**\n * Handle scroll compensation during drag.\n *\n * For element scroll: adjusts history origin since pageX/pageY doesn't change.\n * For window scroll: adjusts lastMoveEventInfo since pageX/pageY would change.\n */\n private handleScroll(target: Element | Window): void {\n const initial = this.scrollPositions.get(target)\n if (!initial) return\n\n const isWindow = target === window\n const current = isWindow\n ? { x: window.scrollX, y: window.scrollY }\n : {\n x: (target as Element).scrollLeft,\n y: (target as Element).scrollTop,\n }\n\n const delta = { x: current.x - initial.x, y: current.y - initial.y }\n if (delta.x === 0 && delta.y === 0) return\n\n if (isWindow) {\n // Window scroll: pageX/pageY changes, so update lastMoveEventInfo\n if (this.lastMoveEventInfo) {\n this.lastMoveEventInfo.point.x += delta.x\n this.lastMoveEventInfo.point.y += delta.y\n }\n } else {\n // Element scroll: pageX/pageY unchanged, so adjust history origin\n if (this.history.length > 0) {\n this.history[0].x -= delta.x\n this.history[0].y -= delta.y\n }\n }\n\n this.scrollPositions.set(target, current)\n frame.update(this.updatePoint, true)\n }\n\n private updatePoint = () => {\n if (!(this.lastMoveEvent && this.lastMoveEventInfo)) return\n\n // Re-transform raw point through current transformPagePoint so\n // animated parent transforms (e.g. rotation) are picked up each frame\n if (this.lastRawMoveEventInfo) {\n this.lastMoveEventInfo = transformPoint(\n this.lastRawMoveEventInfo,\n this.transformPagePoint\n )\n }\n\n const info = getPanInfo(this.lastMoveEventInfo, this.history)\n const isPanStarted = this.startEvent !== null\n\n // Only start panning if the offset is larger than 3 pixels. If we make it\n // any larger than this we'll want to reset the pointer history\n // on the first update to avoid visual snapping to the cursor.\n const isDistancePastThreshold =\n distance2D(info.offset, { x: 0, y: 0 }) >= this.distanceThreshold\n\n if (!isPanStarted && !isDistancePastThreshold) return\n\n const { point } = info\n const { timestamp } = frameData\n this.history.push({ ...point, timestamp })\n\n const { onStart, onMove } = this.handlers\n\n if (!isPanStarted) {\n onStart && onStart(this.lastMoveEvent, info)\n this.startEvent = this.lastMoveEvent\n }\n\n onMove && onMove(this.lastMoveEvent, info)\n }\n\n private handlePointerMove = (event: PointerEvent, info: EventInfo) => {\n this.lastMoveEvent = event\n this.lastRawMoveEventInfo = info\n this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint)\n\n // Throttle mouse move event to once per frame\n frame.update(this.updatePoint, true)\n }\n\n private handlePointerUp = (event: PointerEvent, info: EventInfo) => {\n this.end()\n\n const { onEnd, onSessionEnd, resumeAnimation } = this.handlers\n\n // Resume animation if dragSnapToOrigin is set OR if no drag started (user just clicked)\n // This ensures constraint animations continue when interrupted by a click\n if (this.dragSnapToOrigin || !this.startEvent) {\n resumeAnimation && resumeAnimation()\n }\n if (!(this.lastMoveEvent && this.lastMoveEventInfo)) return\n\n const panInfo = getPanInfo(\n event.type === \"pointercancel\"\n ? this.lastMoveEventInfo\n : transformPoint(info, this.transformPagePoint),\n this.history\n )\n\n if (this.startEvent && onEnd) {\n onEnd(event, panInfo)\n }\n\n onSessionEnd && onSessionEnd(event, panInfo)\n }\n\n updateHandlers(handlers: Partial) {\n this.handlers = handlers\n }\n\n end() {\n this.removeListeners && this.removeListeners()\n this.removeScrollListeners && this.removeScrollListeners()\n this.scrollPositions.clear()\n cancelFrame(this.updatePoint)\n }\n}\n\nfunction transformPoint(\n info: EventInfo,\n transformPagePoint?: (point: Point) => Point\n) {\n return transformPagePoint ? { point: transformPagePoint(info.point) } : info\n}\n\nfunction subtractPoint(a: Point, b: Point): Point {\n return { x: a.x - b.x, y: a.y - b.y }\n}\n\nfunction getPanInfo({ point }: EventInfo, history: TimestampedPoint[]) {\n return {\n point,\n delta: subtractPoint(point, lastDevicePoint(history)),\n offset: subtractPoint(point, startDevicePoint(history)),\n velocity: getVelocity(history, 0.1),\n }\n}\n\nfunction startDevicePoint(history: TimestampedPoint[]): TimestampedPoint {\n return history[0]\n}\n\nfunction lastDevicePoint(history: TimestampedPoint[]): TimestampedPoint {\n return history[history.length - 1]\n}\n\nfunction getVelocity(history: TimestampedPoint[], timeDelta: number): Point {\n if (history.length < 2) {\n return { x: 0, y: 0 }\n }\n\n let i = history.length - 1\n let timestampedPoint: TimestampedPoint | null = null\n const lastPoint = lastDevicePoint(history)\n while (i >= 0) {\n timestampedPoint = history[i]\n if (\n lastPoint.timestamp - timestampedPoint.timestamp >\n secondsToMilliseconds(timeDelta)\n ) {\n break\n }\n i--\n }\n\n if (!timestampedPoint) {\n return { x: 0, y: 0 }\n }\n\n /**\n * If the selected point is the pointer-down origin (history[0]),\n * there are better movement points available, and the time gap\n * is suspiciously large (>2x timeDelta), use the next point instead.\n * This prevents stale pointer-down points from diluting velocity\n * in hold-then-flick gestures.\n */\n if (\n timestampedPoint === history[0] &&\n history.length > 2 &&\n lastPoint.timestamp - timestampedPoint.timestamp >\n secondsToMilliseconds(timeDelta) * 2\n ) {\n timestampedPoint = history[1]\n }\n\n const time = millisecondsToSeconds(\n lastPoint.timestamp - timestampedPoint.timestamp\n )\n if (time === 0) {\n return { x: 0, y: 0 }\n }\n\n const currentVelocity = {\n x: (lastPoint.x - timestampedPoint.x) / time,\n y: (lastPoint.y - timestampedPoint.y) / time,\n }\n\n if (currentVelocity.x === Infinity) {\n currentVelocity.x = 0\n }\n if (currentVelocity.y === Infinity) {\n currentVelocity.y = 0\n }\n\n return currentVelocity\n}\n", "import { calcLength, mixNumber, type DragElastic, type ResolvedConstraints } from \"motion-dom\"\nimport {\n Axis,\n BoundingBox,\n Box,\n progress as calcProgress,\n clamp,\n Point,\n} from \"motion-utils\"\n\n/**\n * Apply constraints to a point. These constraints are both physical along an\n * axis, and an elastic factor that determines how much to constrain the point\n * by if it does lie outside the defined parameters.\n */\nexport function applyConstraints(\n point: number,\n { min, max }: Partial,\n elastic?: Axis\n): number {\n if (min !== undefined && point < min) {\n // If we have a min point defined, and this is outside of that, constrain\n point = elastic\n ? mixNumber(min, point, elastic.min)\n : Math.max(point, min)\n } else if (max !== undefined && point > max) {\n // If we have a max point defined, and this is outside of that, constrain\n point = elastic\n ? mixNumber(max, point, elastic.max)\n : Math.min(point, max)\n }\n\n return point\n}\n\n/**\n * Calculates a min projection point based on a pointer, pointer progress\n * within the drag target, and constraints.\n *\n * For instance if an element was 100px width, we were dragging from 0.25\n * along this axis, the pointer is at 200px, and there were no constraints,\n * we would calculate a min projection point of 175px.\n */\nexport function calcConstrainedMinPoint(\n point: number,\n length: number,\n progress: number,\n constraints?: Partial,\n elastic?: Axis\n): number {\n // Calculate a min point for this axis and apply it to the current pointer\n const min = point - length * progress\n\n return constraints ? applyConstraints(min, constraints, elastic) : min\n}\n\n/**\n * Calculate constraints in terms of the viewport when defined relatively to the\n * measured axis. This is measured from the nearest edge, so a max constraint of 200\n * on an axis with a max value of 300 would return a constraint of 500 - axis length\n */\nexport function calcRelativeAxisConstraints(\n axis: Axis,\n min?: number,\n max?: number\n): Partial {\n return {\n min: min !== undefined ? axis.min + min : undefined,\n max:\n max !== undefined\n ? axis.max + max - (axis.max - axis.min)\n : undefined,\n }\n}\n\n/**\n * Calculate constraints in terms of the viewport when\n * defined relatively to the measured bounding box.\n */\nexport function calcRelativeConstraints(\n layoutBox: Box,\n { top, left, bottom, right }: Partial\n): ResolvedConstraints {\n return {\n x: calcRelativeAxisConstraints(layoutBox.x, left, right),\n y: calcRelativeAxisConstraints(layoutBox.y, top, bottom),\n }\n}\n\n/**\n * Calculate viewport constraints when defined as another viewport-relative axis\n */\nexport function calcViewportAxisConstraints(\n layoutAxis: Axis,\n constraintsAxis: Axis\n) {\n let min = constraintsAxis.min - layoutAxis.min\n let max = constraintsAxis.max - layoutAxis.max\n\n // If the constraints axis is actually smaller than the layout axis then we can\n // flip the constraints\n if (\n constraintsAxis.max - constraintsAxis.min <\n layoutAxis.max - layoutAxis.min\n ) {\n ;[min, max] = [max, min]\n }\n\n return { min, max }\n}\n\n/**\n * Calculate viewport constraints when defined as another viewport-relative box\n */\nexport function calcViewportConstraints(layoutBox: Box, constraintsBox: Box) {\n return {\n x: calcViewportAxisConstraints(layoutBox.x, constraintsBox.x),\n y: calcViewportAxisConstraints(layoutBox.y, constraintsBox.y),\n }\n}\n\n/**\n * Calculate a transform origin relative to the source axis, between 0-1, that results\n * in an asthetically pleasing scale/transform needed to project from source to target.\n */\nexport function calcOrigin(source: Axis, target: Axis): number {\n let origin = 0.5\n const sourceLength = calcLength(source)\n const targetLength = calcLength(target)\n\n if (targetLength > sourceLength) {\n origin = calcProgress(target.min, target.max - sourceLength, source.min)\n } else if (sourceLength > targetLength) {\n origin = calcProgress(source.min, source.max - targetLength, target.min)\n }\n\n return clamp(0, 1, origin)\n}\n\n/**\n * Calculate the relative progress of one constraints box relative to another.\n * Imagine a page scroll bar. At the top, this would return 0, at the bottom, 1.\n * Anywhere in-between, a value between 0 and 1.\n *\n * This also handles flipped constraints, for instance a draggable container within\n * a smaller viewport like a scrollable view.\n */\nexport function calcProgressWithinConstraints(\n layoutBox: Box,\n constraintsBox: Box\n): Point {\n return {\n x: calcOrigin(layoutBox.x, constraintsBox.x),\n y: calcOrigin(layoutBox.y, constraintsBox.y),\n }\n}\n\n/**\n * Calculate the an axis position based on two axes and a progress value.\n */\nexport function calcPositionFromProgress(\n axis: Axis,\n constraints: Axis,\n progress: number\n): Axis {\n const axisLength = axis.max - axis.min\n const min = mixNumber(\n constraints.min,\n constraints.max - axisLength,\n progress\n )\n return { min, max: min + axisLength }\n}\n\n/**\n * Rebase the calculated viewport constraints relative to the layout.min point.\n */\nexport function rebaseAxisConstraints(\n layout: Axis,\n constraints: Partial\n): Partial {\n const relativeConstraints: Partial = {}\n\n if (constraints.min !== undefined) {\n relativeConstraints.min = constraints.min - layout.min\n }\n\n if (constraints.max !== undefined) {\n relativeConstraints.max = constraints.max - layout.min\n }\n\n return relativeConstraints\n}\n\nexport const defaultElastic = 0.35\n/**\n * Accepts a dragElastic prop and returns resolved elastic values for each axis.\n */\nexport function resolveDragElastic(\n dragElastic: DragElastic = defaultElastic\n): Box {\n if (dragElastic === false) {\n dragElastic = 0\n } else if (dragElastic === true) {\n dragElastic = defaultElastic\n }\n\n return {\n x: resolveAxisElastic(dragElastic, \"left\", \"right\"),\n y: resolveAxisElastic(dragElastic, \"top\", \"bottom\"),\n }\n}\n\nexport function resolveAxisElastic(\n dragElastic: DragElastic,\n minLabel: string,\n maxLabel: string\n): Axis {\n return {\n min: resolvePointElastic(dragElastic, minLabel),\n max: resolvePointElastic(dragElastic, maxLabel),\n }\n}\n\nexport function resolvePointElastic(\n dragElastic: DragElastic,\n label: string\n): number {\n return typeof dragElastic === \"number\"\n ? dragElastic\n : dragElastic[label as keyof typeof dragElastic] || 0\n}\n", "import {\n addValueToWillChange,\n animateMotionValue,\n calcLength,\n convertBoundingBoxToBox,\n convertBoxToBoundingBox,\n createBox,\n eachAxis,\n frame,\n isElementTextInput,\n measurePageBox,\n mixNumber,\n PanInfo,\n percent,\n ResolvedConstraints,\n resize,\n setDragLock,\n Transition,\n type VisualElement,\n} from \"motion-dom\"\nimport { Axis, Point, invariant } from \"motion-utils\"\nimport { addDomEvent, type LayoutUpdateData } from \"motion-dom\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { extractEventInfo } from \"../../events/event-info\"\nimport { MotionProps } from \"../../motion/types\"\nimport { getContextWindow } from \"../../utils/get-context-window\"\nimport { isRefObject } from \"../../utils/is-ref-object\"\nimport { PanSession } from \"../pan/PanSession\"\nimport {\n applyConstraints,\n calcOrigin,\n calcRelativeConstraints,\n calcViewportConstraints,\n defaultElastic,\n rebaseAxisConstraints,\n resolveDragElastic,\n} from \"./utils/constraints\"\n\nexport const elementDragControls = new WeakMap<\n VisualElement,\n VisualElementDragControls\n>()\n\nexport interface DragControlOptions {\n /**\n * This distance after which dragging starts and a direction is locked in.\n *\n * @public\n */\n distanceThreshold?: number\n\n /**\n * Whether to immediately snap to the cursor when dragging starts.\n *\n * @public\n */\n snapToCursor?: boolean\n}\n\ntype DragDirection = \"x\" | \"y\"\n\nexport class VisualElementDragControls {\n private visualElement: VisualElement\n\n private panSession?: PanSession\n\n private openDragLock: VoidFunction | null = null\n\n isDragging = false\n private currentDirection: DragDirection | null = null\n\n private originPoint: Point = { x: 0, y: 0 }\n\n /**\n * The permitted boundaries of travel, in pixels.\n */\n private constraints: ResolvedConstraints | false = false\n\n private hasMutatedConstraints = false\n\n /**\n * The per-axis resolved elastic values.\n */\n private elastic = createBox()\n\n /**\n * The latest pointer event. Used as fallback when the `cancel` and `stop` functions are called without arguments.\n */\n private latestPointerEvent: PointerEvent | null = null\n\n /**\n * The latest pan info. Used as fallback when the `cancel` and `stop` functions are called without arguments.\n */\n private latestPanInfo: PanInfo | null = null\n\n constructor(visualElement: VisualElement) {\n this.visualElement = visualElement\n }\n\n start(\n originEvent: PointerEvent,\n { snapToCursor = false, distanceThreshold }: DragControlOptions = {}\n ) {\n /**\n * Don't start dragging if this component is exiting\n */\n const { presenceContext } = this.visualElement\n if (presenceContext && presenceContext.isPresent === false) return\n\n const onSessionStart = (event: PointerEvent) => {\n if (snapToCursor) {\n this.snapToCursor(extractEventInfo(event).point)\n }\n this.stopAnimation()\n }\n\n const onStart = (event: PointerEvent, info: PanInfo) => {\n // Attempt to grab the global drag gesture lock - maybe make this part of PanSession\n const { drag, dragPropagation, onDragStart } = this.getProps()\n\n if (drag && !dragPropagation) {\n if (this.openDragLock) this.openDragLock()\n\n this.openDragLock = setDragLock(drag)\n\n // If we don 't have the lock, don't start dragging\n if (!this.openDragLock) return\n }\n\n this.latestPointerEvent = event\n this.latestPanInfo = info\n this.isDragging = true\n\n this.currentDirection = null\n\n this.resolveConstraints()\n\n if (this.visualElement.projection) {\n this.visualElement.projection.isAnimationBlocked = true\n this.visualElement.projection.target = undefined\n }\n\n /**\n * Record gesture origin and pointer offset\n */\n eachAxis((axis) => {\n let current = this.getAxisMotionValue(axis).get() || 0\n\n /**\n * If the MotionValue is a percentage value convert to px\n */\n if (percent.test(current)) {\n const { projection } = this.visualElement\n\n if (projection && projection.layout) {\n const measuredAxis = projection.layout.layoutBox[axis]\n\n if (measuredAxis) {\n const length = calcLength(measuredAxis)\n current = length * (parseFloat(current) / 100)\n }\n }\n }\n\n this.originPoint[axis] = current\n })\n\n // Fire onDragStart event\n if (onDragStart) {\n frame.update(() => onDragStart(event, info), false, true)\n }\n\n addValueToWillChange(this.visualElement, \"transform\")\n\n const { animationState } = this.visualElement\n animationState && animationState.setActive(\"whileDrag\", true)\n }\n\n const onMove = (event: PointerEvent, info: PanInfo) => {\n this.latestPointerEvent = event\n this.latestPanInfo = info\n\n const {\n dragPropagation,\n dragDirectionLock,\n onDirectionLock,\n onDrag,\n } = this.getProps()\n\n // If we didn't successfully receive the gesture lock, early return.\n if (!dragPropagation && !this.openDragLock) return\n\n const { offset } = info\n // Attempt to detect drag direction if directionLock is true\n if (dragDirectionLock && this.currentDirection === null) {\n this.currentDirection = getCurrentDirection(offset)\n\n // If we've successfully set a direction, notify listener\n if (this.currentDirection !== null) {\n onDirectionLock && onDirectionLock(this.currentDirection)\n }\n\n return\n }\n\n // Update each point with the latest position\n this.updateAxis(\"x\", info.point, offset)\n this.updateAxis(\"y\", info.point, offset)\n\n /**\n * Ideally we would leave the renderer to fire naturally at the end of\n * this frame but if the element is about to change layout as the result\n * of a re-render we want to ensure the browser can read the latest\n * bounding box to ensure the pointer and element don't fall out of sync.\n */\n this.visualElement.render()\n\n /**\n * This must fire after the render call as it might trigger a state\n * change which itself might trigger a layout update.\n */\n if (onDrag) {\n frame.update(() => onDrag(event, info), false, true)\n }\n }\n\n const onSessionEnd = (event: PointerEvent, info: PanInfo) => {\n this.latestPointerEvent = event\n this.latestPanInfo = info\n\n this.stop(event, info)\n\n this.latestPointerEvent = null\n this.latestPanInfo = null\n }\n\n const resumeAnimation = () => {\n const { dragSnapToOrigin: snap } = this.getProps()\n if (snap || this.constraints) {\n this.startAnimation({ x: 0, y: 0 })\n }\n }\n\n const { dragSnapToOrigin } = this.getProps()\n this.panSession = new PanSession(\n originEvent,\n {\n onSessionStart,\n onStart,\n onMove,\n onSessionEnd,\n resumeAnimation,\n },\n {\n transformPagePoint: this.visualElement.getTransformPagePoint(),\n dragSnapToOrigin,\n distanceThreshold,\n contextWindow: getContextWindow(this.visualElement),\n element: this.visualElement.current,\n }\n )\n }\n\n /**\n * @internal\n */\n stop(event?: PointerEvent, panInfo?: PanInfo) {\n const finalEvent = event || this.latestPointerEvent\n const finalPanInfo = panInfo || this.latestPanInfo\n\n const isDragging = this.isDragging\n this.cancel()\n if (!isDragging || !finalPanInfo || !finalEvent) return\n\n const { velocity } = finalPanInfo\n this.startAnimation(velocity)\n\n const { onDragEnd } = this.getProps()\n if (onDragEnd) {\n frame.postRender(() => onDragEnd(finalEvent, finalPanInfo))\n }\n }\n\n /**\n * @internal\n */\n cancel() {\n this.isDragging = false\n\n const { projection, animationState } = this.visualElement\n\n if (projection) {\n projection.isAnimationBlocked = false\n }\n\n this.endPanSession()\n\n const { dragPropagation } = this.getProps()\n\n if (!dragPropagation && this.openDragLock) {\n this.openDragLock()\n this.openDragLock = null\n }\n\n animationState && animationState.setActive(\"whileDrag\", false)\n }\n\n /**\n * Clean up the pan session without modifying other drag state.\n * This is used during unmount to ensure event listeners are removed\n * without affecting projection animations or drag locks.\n * @internal\n */\n endPanSession() {\n this.panSession && this.panSession.end()\n this.panSession = undefined\n }\n\n private updateAxis(axis: DragDirection, _point: Point, offset?: Point) {\n const { drag } = this.getProps()\n\n // If we're not dragging this axis, do an early return.\n if (!offset || !shouldDrag(axis, drag, this.currentDirection)) return\n\n const axisValue = this.getAxisMotionValue(axis)\n let next = this.originPoint[axis] + offset[axis]\n\n // Apply constraints\n if (this.constraints && this.constraints[axis]) {\n next = applyConstraints(\n next,\n this.constraints[axis],\n this.elastic[axis]\n )\n }\n\n axisValue.set(next)\n }\n\n private resolveConstraints() {\n const { dragConstraints, dragElastic } = this.getProps()\n\n const layout =\n this.visualElement.projection &&\n !this.visualElement.projection.layout\n ? this.visualElement.projection.measure(false)\n : this.visualElement.projection?.layout\n\n const prevConstraints = this.constraints\n\n if (dragConstraints && isRefObject(dragConstraints)) {\n if (!this.constraints) {\n this.constraints = this.resolveRefConstraints()\n }\n } else {\n if (dragConstraints && layout) {\n this.constraints = calcRelativeConstraints(\n layout.layoutBox,\n dragConstraints\n )\n } else {\n this.constraints = false\n }\n }\n\n this.elastic = resolveDragElastic(dragElastic)\n\n /**\n * If we're outputting to external MotionValues, we want to rebase the measured constraints\n * from viewport-relative to component-relative. This only applies to relative (non-ref)\n * constraints, as ref-based constraints from calcViewportConstraints are already in the\n * correct coordinate space for the motion value transform offset.\n */\n if (\n prevConstraints !== this.constraints &&\n !isRefObject(dragConstraints) &&\n layout &&\n this.constraints &&\n !this.hasMutatedConstraints\n ) {\n eachAxis((axis) => {\n if (\n this.constraints !== false &&\n this.getAxisMotionValue(axis)\n ) {\n this.constraints[axis] = rebaseAxisConstraints(\n layout.layoutBox[axis],\n this.constraints[axis]\n )\n }\n })\n }\n }\n\n private resolveRefConstraints() {\n const { dragConstraints: constraints, onMeasureDragConstraints } =\n this.getProps()\n if (!constraints || !isRefObject(constraints)) return false\n\n const constraintsElement = constraints.current as HTMLElement\n\n invariant(\n constraintsElement !== null,\n \"If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.\",\n \"drag-constraints-ref\"\n )\n\n const { projection } = this.visualElement\n\n // TODO\n if (!projection || !projection.layout) return false\n\n const constraintsBox = measurePageBox(\n constraintsElement,\n projection.root!,\n this.visualElement.getTransformPagePoint()\n )\n\n let measuredConstraints = calcViewportConstraints(\n projection.layout.layoutBox,\n constraintsBox\n )\n\n /**\n * If there's an onMeasureDragConstraints listener we call it and\n * if different constraints are returned, set constraints to that\n */\n if (onMeasureDragConstraints) {\n const userConstraints = onMeasureDragConstraints(\n convertBoxToBoundingBox(measuredConstraints)\n )\n\n this.hasMutatedConstraints = !!userConstraints\n\n if (userConstraints) {\n measuredConstraints = convertBoundingBoxToBox(userConstraints)\n }\n }\n\n return measuredConstraints\n }\n\n private startAnimation(velocity: Point) {\n const {\n drag,\n dragMomentum,\n dragElastic,\n dragTransition,\n dragSnapToOrigin,\n onDragTransitionEnd,\n } = this.getProps()\n\n const constraints: Partial = this.constraints || {}\n\n const momentumAnimations = eachAxis((axis) => {\n if (!shouldDrag(axis, drag, this.currentDirection)) {\n return\n }\n\n let transition = (constraints && constraints[axis]) || {}\n\n if (\n dragSnapToOrigin === true ||\n (dragSnapToOrigin as unknown) === axis\n )\n transition = { min: 0, max: 0 }\n\n /**\n * Overdamp the boundary spring if `dragElastic` is disabled. There's still a frame\n * of spring animations so we should look into adding a disable spring option to `inertia`.\n * We could do something here where we affect the `bounceStiffness` and `bounceDamping`\n * using the value of `dragElastic`.\n */\n const bounceStiffness = dragElastic ? 200 : 1000000\n const bounceDamping = dragElastic ? 40 : 10000000\n\n const inertia: Transition = {\n type: \"inertia\",\n velocity: dragMomentum ? velocity[axis] : 0,\n bounceStiffness,\n bounceDamping,\n timeConstant: 750,\n restDelta: 1,\n restSpeed: 10,\n ...dragTransition,\n ...transition,\n }\n\n // If we're not animating on an externally-provided `MotionValue` we can use the\n // component's animation controls which will handle interactions with whileHover (etc),\n // otherwise we just have to animate the `MotionValue` itself.\n return this.startAxisValueAnimation(axis, inertia)\n })\n\n // Run all animations and then resolve the new drag constraints.\n return Promise.all(momentumAnimations).then(onDragTransitionEnd)\n }\n\n private startAxisValueAnimation(\n axis: DragDirection,\n transition: Transition\n ) {\n const axisValue = this.getAxisMotionValue(axis)\n\n addValueToWillChange(this.visualElement, axis)\n\n return axisValue.start(\n animateMotionValue(\n axis,\n axisValue,\n 0,\n transition,\n this.visualElement,\n false\n )\n )\n }\n\n private stopAnimation() {\n eachAxis((axis) => this.getAxisMotionValue(axis).stop())\n }\n\n /**\n * Drag works differently depending on which props are provided.\n *\n * - If _dragX and _dragY are provided, we output the gesture delta directly to those motion values.\n * - Otherwise, we apply the delta to the x/y motion values.\n */\n private getAxisMotionValue(axis: DragDirection) {\n const dragKey =\n `_drag${axis.toUpperCase()}` as `_drag${Uppercase}`\n const props = this.visualElement.getProps()\n const externalMotionValue = props[dragKey]\n\n return externalMotionValue\n ? externalMotionValue\n : this.visualElement.getValue(\n axis,\n (props.initial\n ? props.initial[axis as keyof typeof props.initial]\n : undefined) || 0\n )\n }\n\n private snapToCursor(point: Point) {\n eachAxis((axis) => {\n const { drag } = this.getProps()\n\n // If we're not dragging this axis, do an early return.\n if (!shouldDrag(axis, drag, this.currentDirection)) return\n\n const { projection } = this.visualElement\n const axisValue = this.getAxisMotionValue(axis)\n\n if (projection && projection.layout) {\n const { min, max } = projection.layout.layoutBox[axis]\n\n /**\n * The layout measurement includes the current transform value,\n * so we need to add it back to get the correct snap position.\n * This fixes an issue where elements with initial coordinates\n * would snap to the wrong position on the first drag.\n */\n const current = axisValue.get() || 0\n\n axisValue.set(point[axis] - mixNumber(min, max, 0.5) + current)\n }\n })\n }\n\n /**\n * When the viewport resizes we want to check if the measured constraints\n * have changed and, if so, reposition the element within those new constraints\n * relative to where it was before the resize.\n */\n scalePositionWithinConstraints() {\n if (!this.visualElement.current) return\n\n const { drag, dragConstraints } = this.getProps()\n const { projection } = this.visualElement\n if (!isRefObject(dragConstraints) || !projection || !this.constraints)\n return\n\n /**\n * Stop current animations as there can be visual glitching if we try to do\n * this mid-animation\n */\n this.stopAnimation()\n\n /**\n * Record the relative position of the dragged element relative to the\n * constraints box and save as a progress value.\n */\n const boxProgress = { x: 0, y: 0 }\n eachAxis((axis) => {\n const axisValue = this.getAxisMotionValue(axis)\n if (axisValue && this.constraints !== false) {\n const latest = axisValue.get()\n boxProgress[axis] = calcOrigin(\n { min: latest, max: latest },\n this.constraints[axis] as Axis\n )\n }\n })\n\n /**\n * Update the layout of this element and resolve the latest drag constraints\n */\n const { transformTemplate } = this.visualElement.getProps()\n this.visualElement.current.style.transform = transformTemplate\n ? transformTemplate({}, \"\")\n : \"none\"\n projection.root && projection.root.updateScroll()\n projection.updateLayout()\n\n /**\n * Reset constraints so resolveConstraints() will recalculate them\n * with the freshly measured layout rather than returning the cached value.\n */\n this.constraints = false\n this.resolveConstraints()\n\n /**\n * For each axis, calculate the current progress of the layout axis\n * within the new constraints.\n */\n eachAxis((axis) => {\n if (!shouldDrag(axis, drag, null)) return\n\n /**\n * Calculate a new transform based on the previous box progress\n */\n const axisValue = this.getAxisMotionValue(axis)\n const { min, max } = (this.constraints as ResolvedConstraints)[\n axis\n ] as Axis\n axisValue.set(mixNumber(min, max, boxProgress[axis]))\n })\n\n /**\n * Flush the updated transform to the DOM synchronously to prevent\n * a visual flash at the element's CSS layout position (0,0) when\n * the transform was stripped for measurement.\n */\n this.visualElement.render()\n }\n\n addListeners() {\n if (!this.visualElement.current) return\n elementDragControls.set(this.visualElement, this)\n const element = this.visualElement.current\n\n /**\n * Attach a pointerdown event listener on this DOM element to initiate drag tracking.\n */\n const stopPointerListener = addPointerEvent(\n element,\n \"pointerdown\",\n (event) => {\n const { drag, dragListener = true } = this.getProps()\n const target = event.target as Element\n\n /**\n * Only block drag if clicking on a text input child element\n * (input, textarea, select, contenteditable) where users might\n * want to select text or interact with the control.\n *\n * Buttons and links don't block drag since they don't have\n * click-and-move actions of their own.\n */\n const isClickingTextInputChild =\n target !== element && isElementTextInput(target)\n\n if (drag && dragListener && !isClickingTextInputChild) {\n this.start(event)\n }\n }\n )\n\n /**\n * If using ref-based constraints, observe both the draggable element\n * and the constraint container for size changes via ResizeObserver.\n * Setup is deferred because dragConstraints.current is null when\n * addListeners first runs (React hasn't committed the ref yet).\n */\n let stopResizeObservers: VoidFunction | undefined\n\n const measureDragConstraints = () => {\n const { dragConstraints } = this.getProps()\n if (isRefObject(dragConstraints) && dragConstraints.current) {\n this.constraints = this.resolveRefConstraints()\n\n if (!stopResizeObservers) {\n stopResizeObservers = startResizeObservers(\n element,\n dragConstraints.current as HTMLElement,\n () => this.scalePositionWithinConstraints()\n )\n }\n }\n }\n\n const { projection } = this.visualElement\n\n const stopMeasureLayoutListener = projection!.addEventListener(\n \"measure\",\n measureDragConstraints\n )\n\n if (projection && !projection!.layout) {\n projection.root && projection.root.updateScroll()\n projection.updateLayout()\n }\n\n frame.read(measureDragConstraints)\n\n /**\n * Attach a window resize listener to scale the draggable target within its defined\n * constraints as the window resizes.\n */\n const stopResizeListener = addDomEvent(window, \"resize\", () =>\n this.scalePositionWithinConstraints()\n )\n\n /**\n * If the element's layout changes, calculate the delta and apply that to\n * the drag gesture's origin point.\n */\n const stopLayoutUpdateListener = projection!.addEventListener(\n \"didUpdate\",\n (({ delta, hasLayoutChanged }: LayoutUpdateData) => {\n if (this.isDragging && hasLayoutChanged) {\n eachAxis((axis) => {\n const motionValue = this.getAxisMotionValue(axis)\n if (!motionValue) return\n\n this.originPoint[axis] += delta[axis].translate\n motionValue.set(\n motionValue.get() + delta[axis].translate\n )\n })\n\n this.visualElement.render()\n }\n }) as any\n )\n\n return () => {\n stopResizeListener()\n stopPointerListener()\n stopMeasureLayoutListener()\n stopLayoutUpdateListener && stopLayoutUpdateListener()\n stopResizeObservers && stopResizeObservers()\n }\n }\n\n getProps(): MotionProps {\n const props = this.visualElement.getProps()\n const {\n drag = false,\n dragDirectionLock = false,\n dragPropagation = false,\n dragConstraints = false,\n dragElastic = defaultElastic,\n dragMomentum = true,\n } = props\n return {\n ...props,\n drag,\n dragDirectionLock,\n dragPropagation,\n dragConstraints,\n dragElastic,\n dragMomentum,\n }\n }\n}\n\nfunction skipFirstCall(callback: VoidFunction): VoidFunction {\n let isFirst = true\n return () => {\n if (isFirst) {\n isFirst = false\n return\n }\n callback()\n }\n}\n\nfunction startResizeObservers(\n element: HTMLElement,\n constraintsElement: HTMLElement,\n onResize: VoidFunction\n): VoidFunction {\n const stopElement = resize(element, skipFirstCall(onResize))\n const stopContainer = resize(constraintsElement, skipFirstCall(onResize))\n return () => {\n stopElement()\n stopContainer()\n }\n}\n\nfunction shouldDrag(\n direction: DragDirection,\n drag: boolean | DragDirection | undefined,\n currentDirection: null | DragDirection\n) {\n return (\n (drag === true || drag === direction) &&\n (currentDirection === null || currentDirection === direction)\n )\n}\n\n/**\n * Based on an x/y offset determine the current drag direction. If both axis' offsets are lower\n * than the provided threshold, return `null`.\n *\n * @param offset - The x/y offset from origin.\n * @param lockThreshold - (Optional) - the minimum absolute offset before we can determine a drag direction.\n */\nfunction getCurrentDirection(\n offset: Point,\n lockThreshold = 10\n): DragDirection | null {\n let direction: DragDirection | null = null\n\n if (Math.abs(offset.y) > lockThreshold) {\n direction = \"y\"\n } else if (Math.abs(offset.x) > lockThreshold) {\n direction = \"x\"\n }\n\n return direction\n}\n\nexport function expectsResolvedDragConstraints({\n dragConstraints,\n onMeasureDragConstraints,\n}: MotionProps) {\n return isRefObject(dragConstraints) && !!onMeasureDragConstraints\n}\n", "import { Feature, type VisualElement } from \"motion-dom\"\nimport { noop } from \"motion-utils\"\nimport { VisualElementDragControls } from \"./VisualElementDragControls\"\n\nexport class DragGesture extends Feature {\n controls: VisualElementDragControls\n\n removeGroupControls: Function = noop\n removeListeners: Function = noop\n\n constructor(node: VisualElement) {\n super(node)\n this.controls = new VisualElementDragControls(node)\n }\n\n mount() {\n // If we've been provided a DragControls for manual control over the drag gesture,\n // subscribe this component to it on mount.\n const { dragControls } = this.node.getProps()\n\n if (dragControls) {\n this.removeGroupControls = dragControls.subscribe(this.controls)\n }\n\n this.removeListeners = this.controls.addListeners() || noop\n }\n\n update() {\n const { dragControls } = this.node.getProps()\n const { dragControls: prevDragControls } = this.node.prevProps || {}\n\n if (dragControls !== prevDragControls) {\n this.removeGroupControls()\n if (dragControls) {\n this.removeGroupControls = dragControls.subscribe(this.controls)\n }\n }\n }\n\n unmount() {\n this.removeGroupControls()\n this.removeListeners()\n /**\n * In React 19, during list reorder reconciliation, components may\n * briefly unmount and remount while the drag is still active. If we're\n * actively dragging, we should NOT end the pan session - it will\n * continue tracking pointer events via its window-level listeners.\n *\n * The pan session will be properly cleaned up when:\n * 1. The drag ends naturally (pointerup/pointercancel)\n * 2. The component is truly removed from the DOM\n */\n if (!this.controls.isDragging) {\n this.controls.endPanSession()\n }\n }\n}\n", "import { Feature, frame, type PanInfo } from \"motion-dom\"\nimport { noop } from \"motion-utils\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { getContextWindow } from \"../../utils/get-context-window\"\nimport { PanSession } from \"./PanSession\"\n\ntype PanEventHandler = (event: PointerEvent, info: PanInfo) => void\nconst asyncHandler =\n (handler?: PanEventHandler) => (event: PointerEvent, info: PanInfo) => {\n if (handler) {\n frame.update(() => handler(event, info), false, true)\n }\n }\n\nexport class PanGesture extends Feature {\n private session?: PanSession\n\n private removePointerDownListener: Function = noop\n\n onPointerDown(pointerDownEvent: PointerEvent) {\n this.session = new PanSession(\n pointerDownEvent,\n this.createPanHandlers(),\n {\n transformPagePoint: this.node.getTransformPagePoint(),\n contextWindow: getContextWindow(this.node),\n }\n )\n }\n\n createPanHandlers() {\n const { onPanSessionStart, onPanStart, onPan, onPanEnd } =\n this.node.getProps()\n\n return {\n onSessionStart: asyncHandler(onPanSessionStart),\n onStart: asyncHandler(onPanStart),\n onMove: asyncHandler(onPan),\n onEnd: (event: PointerEvent, info: PanInfo) => {\n delete this.session\n if (onPanEnd) {\n frame.postRender(() => onPanEnd(event, info))\n }\n },\n }\n }\n\n mount() {\n this.removePointerDownListener = addPointerEvent(\n this.node.current!,\n \"pointerdown\",\n (event: PointerEvent) => this.onPointerDown(event)\n )\n }\n\n update() {\n this.session && this.session.updateHandlers(this.createPanHandlers())\n }\n\n unmount() {\n this.removePointerDownListener()\n this.session && this.session.end()\n }\n}\n", "\"use client\"\n\nimport { frame, microtask, globalProjectionState, type VisualElement } from \"motion-dom\"\nimport { Component, useContext } from \"react\"\nimport { usePresence } from \"../../../components/AnimatePresence/use-presence\"\nimport {\n LayoutGroupContext,\n LayoutGroupContextProps,\n} from \"../../../context/LayoutGroupContext\"\nimport { SwitchLayoutGroupContext } from \"../../../context/SwitchLayoutGroupContext\"\nimport { MotionProps } from \"../../types\"\n\ninterface MeasureContextProps {\n layoutGroup: LayoutGroupContextProps\n switchLayoutGroup?: SwitchLayoutGroupContext\n isPresent: boolean\n safeToRemove?: VoidFunction | null\n}\n\ntype MeasureProps = MotionProps &\n MeasureContextProps & { visualElement: VisualElement }\n\n/**\n * Track whether we've taken any snapshots yet. If not,\n * we can safely skip notification of didUpdate.\n *\n * Difficult to capture in a test but to prevent flickering\n * we must set this to true either on update or unmount.\n * Running `next-env/layout-id` in Safari will show this behaviour if broken.\n */\nlet hasTakenAnySnapshot = false\n\nclass MeasureLayoutWithContext extends Component {\n /**\n * This only mounts projection nodes for components that\n * need measuring, we might want to do it for all components\n * in order to incorporate transforms\n */\n componentDidMount() {\n const { visualElement, layoutGroup, switchLayoutGroup, layoutId } =\n this.props\n const { projection } = visualElement\n\n if (projection) {\n if (layoutGroup.group) layoutGroup.group.add(projection)\n\n if (switchLayoutGroup && switchLayoutGroup.register && layoutId) {\n switchLayoutGroup.register(projection)\n }\n\n if (hasTakenAnySnapshot) {\n projection.root!.didUpdate()\n }\n\n projection.addEventListener(\"animationComplete\", () => {\n this.safeToRemove()\n })\n projection.setOptions({\n ...projection.options,\n layoutDependency: this.props.layoutDependency,\n onExitComplete: () => this.safeToRemove(),\n })\n }\n\n globalProjectionState.hasEverUpdated = true\n }\n\n getSnapshotBeforeUpdate(prevProps: MeasureProps) {\n const { layoutDependency, visualElement, drag, isPresent } = this.props\n const { projection } = visualElement\n\n if (!projection) return null\n\n /**\n * TODO: We use this data in relegate to determine whether to\n * promote a previous element. There's no guarantee its presence data\n * will have updated by this point - if a bug like this arises it will\n * have to be that we markForRelegation and then find a new lead some other way,\n * perhaps in didUpdate\n */\n projection.isPresent = isPresent\n\n if (prevProps.layoutDependency !== layoutDependency) {\n projection.setOptions({\n ...projection.options,\n layoutDependency,\n })\n }\n\n hasTakenAnySnapshot = true\n\n if (\n drag ||\n prevProps.layoutDependency !== layoutDependency ||\n layoutDependency === undefined ||\n prevProps.isPresent !== isPresent\n ) {\n projection.willUpdate()\n } else {\n this.safeToRemove()\n }\n\n if (prevProps.isPresent !== isPresent) {\n if (isPresent) {\n projection.promote()\n } else if (!projection.relegate()) {\n /**\n * If there's another stack member taking over from this one,\n * it's in charge of the exit animation and therefore should\n * be in charge of the safe to remove. Otherwise we call it here.\n */\n frame.postRender(() => {\n const stack = projection.getStack()\n if (!stack || !stack.members.length) {\n this.safeToRemove()\n }\n })\n }\n }\n\n return null\n }\n\n componentDidUpdate() {\n const { visualElement, layoutAnchor } = this.props\n const { projection } = visualElement\n if (projection) {\n projection.options.layoutAnchor = layoutAnchor\n\n projection.root!.didUpdate()\n\n microtask.postRender(() => {\n if (!projection.currentAnimation && projection.isLead()) {\n this.safeToRemove()\n }\n })\n }\n }\n\n componentWillUnmount() {\n const {\n visualElement,\n layoutGroup,\n switchLayoutGroup: promoteContext,\n } = this.props\n const { projection } = visualElement\n\n hasTakenAnySnapshot = true\n\n if (projection) {\n projection.scheduleCheckAfterUnmount()\n if (layoutGroup && layoutGroup.group)\n layoutGroup.group.remove(projection)\n if (promoteContext && promoteContext.deregister)\n promoteContext.deregister(projection)\n }\n }\n\n safeToRemove() {\n const { safeToRemove } = this.props\n safeToRemove && safeToRemove()\n }\n\n render() {\n return null\n }\n}\n\nexport function MeasureLayout(\n props: MotionProps & { visualElement: VisualElement }\n) {\n const [isPresent, safeToRemove] = usePresence()\n const layoutGroup = useContext(LayoutGroupContext)\n\n return (\n \n )\n}\n", "import { DragGesture } from \"../../gestures/drag\"\nimport { PanGesture } from \"../../gestures/pan\"\nimport { HTMLProjectionNode } from \"../../projection\"\nimport { MeasureLayout } from \"./layout/MeasureLayout\"\nimport { FeaturePackages } from \"./types\"\n\nexport const drag: FeaturePackages = {\n pan: {\n Feature: PanGesture,\n },\n drag: {\n Feature: DragGesture,\n ProjectionNode: HTMLProjectionNode,\n MeasureLayout,\n },\n}\n", "import { Feature, frame, hover, type VisualElement } from \"motion-dom\"\nimport { extractEventInfo } from \"../events/event-info\"\n\nfunction handleHoverEvent(\n node: VisualElement,\n event: PointerEvent,\n lifecycle: \"Start\" | \"End\"\n) {\n const { props } = node\n\n if (node.animationState && props.whileHover) {\n node.animationState.setActive(\"whileHover\", lifecycle === \"Start\")\n }\n\n const eventName = (\"onHover\" + lifecycle) as \"onHoverStart\" | \"onHoverEnd\"\n const callback = props[eventName]\n if (callback) {\n frame.postRender(() => callback(event, extractEventInfo(event)))\n }\n}\n\nexport class HoverGesture extends Feature {\n mount() {\n const { current } = this.node\n if (!current) return\n\n this.unmount = hover(current, (_element, startEvent) => {\n handleHoverEvent(this.node, startEvent, \"Start\")\n\n return (endEvent) => handleHoverEvent(this.node, endEvent, \"End\")\n })\n }\n\n unmount() {}\n}\n", "import { Feature, addDomEvent } from \"motion-dom\"\nimport { pipe } from \"motion-utils\"\n\nexport class FocusGesture extends Feature {\n private isActive = false\n\n onFocus() {\n let isFocusVisible = false\n\n /**\n * If this element doesn't match focus-visible then don't\n * apply whileHover. But, if matches throws that focus-visible\n * is not a valid selector then in that browser outline styles will be applied\n * to the element by default and we want to match that behaviour with whileFocus.\n */\n try {\n isFocusVisible = this.node.current!.matches(\":focus-visible\")\n } catch (e) {\n isFocusVisible = true\n }\n\n if (!isFocusVisible || !this.node.animationState) return\n\n this.node.animationState.setActive(\"whileFocus\", true)\n this.isActive = true\n }\n\n onBlur() {\n if (!this.isActive || !this.node.animationState) return\n this.node.animationState.setActive(\"whileFocus\", false)\n this.isActive = false\n }\n\n mount() {\n this.unmount = pipe(\n addDomEvent(this.node.current!, \"focus\", () => this.onFocus()),\n addDomEvent(this.node.current!, \"blur\", () => this.onBlur())\n ) as VoidFunction\n }\n\n unmount() {}\n}\n", "import { Feature, frame, press, type VisualElement } from \"motion-dom\"\nimport { extractEventInfo } from \"../events/event-info\"\n\nfunction handlePressEvent(\n node: VisualElement,\n event: PointerEvent,\n lifecycle: \"Start\" | \"End\" | \"Cancel\"\n) {\n const { props } = node\n\n if (node.current instanceof HTMLButtonElement && node.current.disabled) {\n return\n }\n\n if (node.animationState && props.whileTap) {\n node.animationState.setActive(\"whileTap\", lifecycle === \"Start\")\n }\n\n const eventName = (\"onTap\" + (lifecycle === \"End\" ? \"\" : lifecycle)) as\n | \"onTapStart\"\n | \"onTap\"\n | \"onTapCancel\"\n\n const callback = props[eventName]\n if (callback) {\n frame.postRender(() => callback(event, extractEventInfo(event)))\n }\n}\n\nexport class PressGesture extends Feature {\n mount() {\n const { current } = this.node\n if (!current) return\n\n const { globalTapTarget, propagate } = this.node.props\n\n this.unmount = press(\n current,\n (_element, startEvent) => {\n handlePressEvent(this.node, startEvent, \"Start\")\n\n return (endEvent, { success }) =>\n handlePressEvent(\n this.node,\n endEvent,\n success ? \"End\" : \"Cancel\"\n )\n },\n {\n useGlobalTarget: globalTapTarget,\n stopPropagation: propagate?.tap === false,\n }\n )\n }\n\n unmount() {}\n}\n", "type IntersectionHandler = (entry: IntersectionObserverEntry) => void\n\ninterface ElementIntersectionObservers {\n [key: string]: IntersectionObserver\n}\n\n/**\n * Map an IntersectionHandler callback to an element. We only ever make one handler for one\n * element, so even though these handlers might all be triggered by different\n * observers, we can keep them in the same map.\n */\nconst observerCallbacks = new WeakMap()\n\n/**\n * Multiple observers can be created for multiple element/document roots. Each with\n * different settings. So here we store dictionaries of observers to each root,\n * using serialised settings (threshold/margin) as lookup keys.\n */\nconst observers = new WeakMap<\n Element | Document,\n ElementIntersectionObservers\n>()\n\nconst fireObserverCallback = (entry: IntersectionObserverEntry) => {\n const callback = observerCallbacks.get(entry.target)\n callback && callback(entry)\n}\n\nconst fireAllObserverCallbacks: IntersectionObserverCallback = (entries) => {\n entries.forEach(fireObserverCallback)\n}\n\nfunction initIntersectionObserver({\n root,\n ...options\n}: IntersectionObserverInit): IntersectionObserver {\n const lookupRoot = root || document\n\n /**\n * If we don't have an observer lookup map for this root, create one.\n */\n if (!observers.has(lookupRoot)) {\n observers.set(lookupRoot, {})\n }\n const rootObservers = observers.get(lookupRoot)!\n\n const key = JSON.stringify(options)\n\n /**\n * If we don't have an observer for this combination of root and settings,\n * create one.\n */\n if (!rootObservers[key]) {\n rootObservers[key] = new IntersectionObserver(\n fireAllObserverCallbacks,\n { root, ...options }\n )\n }\n\n return rootObservers[key]\n}\n\nexport function observeIntersection(\n element: Element,\n options: IntersectionObserverInit,\n callback: IntersectionHandler\n) {\n const rootInteresectionObserver = initIntersectionObserver(options)\n\n observerCallbacks.set(element, callback)\n rootInteresectionObserver.observe(element)\n\n return () => {\n observerCallbacks.delete(element)\n rootInteresectionObserver.unobserve(element)\n }\n}\n", "import { Feature } from \"motion-dom\"\nimport { MotionProps } from \"../../types\"\nimport { observeIntersection } from \"./observers\"\n\nconst thresholdNames = {\n some: 0,\n all: 1,\n}\n\nexport class InViewFeature extends Feature {\n private hasEnteredView = false\n\n private isInView = false\n\n private stopObserver?: () => void\n\n private startObserver() {\n this.stopObserver?.()\n\n const { viewport = {} } = this.node.getProps()\n const { root, margin: rootMargin, amount = \"some\", once } = viewport\n\n const options = {\n root: root ? root.current : undefined,\n rootMargin,\n threshold:\n typeof amount === \"number\" ? amount : thresholdNames[amount],\n }\n\n const onIntersectionUpdate = (entry: IntersectionObserverEntry) => {\n const { isIntersecting } = entry\n\n /**\n * If there's been no change in the viewport state, early return.\n */\n if (this.isInView === isIntersecting) return\n\n this.isInView = isIntersecting\n\n /**\n * Handle hasEnteredView. If this is only meant to run once, and\n * element isn't visible, early return. Otherwise set hasEnteredView to true.\n */\n if (once && !isIntersecting && this.hasEnteredView) {\n return\n } else if (isIntersecting) {\n this.hasEnteredView = true\n }\n\n if (this.node.animationState) {\n this.node.animationState.setActive(\n \"whileInView\",\n isIntersecting\n )\n }\n\n /**\n * Use the latest committed props rather than the ones in scope\n * when this observer is created\n */\n const { onViewportEnter, onViewportLeave } = this.node.getProps()\n const callback = isIntersecting ? onViewportEnter : onViewportLeave\n callback && callback(entry)\n }\n\n this.stopObserver = observeIntersection(\n this.node.current!,\n options,\n onIntersectionUpdate\n )\n }\n\n mount() {\n this.startObserver()\n }\n\n update() {\n if (typeof IntersectionObserver === \"undefined\") return\n\n const { props, prevProps } = this.node\n const hasOptionsChanged = [\"amount\", \"margin\", \"root\"].some(\n hasViewportOptionChanged(props, prevProps)\n )\n\n if (hasOptionsChanged) {\n this.startObserver()\n }\n }\n\n unmount() {\n this.stopObserver?.()\n this.hasEnteredView = false\n this.isInView = false\n }\n}\n\nfunction hasViewportOptionChanged(\n { viewport = {} }: MotionProps,\n { viewport: prevViewport = {} }: MotionProps = {}\n) {\n return (name: keyof typeof viewport) =>\n viewport[name] !== prevViewport[name]\n}\n", "import { HoverGesture } from \"../../gestures/hover\"\nimport { FocusGesture } from \"../../gestures/focus\"\nimport { PressGesture } from \"../../gestures/press\"\nimport { InViewFeature } from \"./viewport\"\nimport { FeaturePackages } from \"./types\"\n\nexport const gestureAnimations: FeaturePackages = {\n inView: {\n Feature: InViewFeature,\n },\n tap: {\n Feature: PressGesture,\n },\n focus: {\n Feature: FocusGesture,\n },\n hover: {\n Feature: HoverGesture,\n },\n}\n", "import { HTMLProjectionNode } from \"motion-dom\"\nimport { MeasureLayout } from \"./layout/MeasureLayout\"\nimport { FeaturePackages } from \"./types\"\n\nexport const layout: FeaturePackages = {\n layout: {\n ProjectionNode: HTMLProjectionNode,\n MeasureLayout,\n },\n}\n", "import { animations } from \"../../../motion/features/animations\"\nimport { drag } from \"../../../motion/features/drag\"\nimport { gestureAnimations } from \"../../../motion/features/gestures\"\nimport { layout } from \"../../../motion/features/layout\"\n\nexport const featureBundle = {\n ...animations,\n ...gestureAnimations,\n ...drag,\n ...layout,\n}\n", "import { createDomVisualElement } from \"../../dom/create-visual-element\"\nimport { createMotionProxy } from \"../create-proxy\"\nimport { featureBundle } from \"./feature-bundle\"\n\nexport const motion = /*@__PURE__*/ createMotionProxy(\n featureBundle,\n createDomVisualElement\n)\n", "\"use client\"\n\nimport {\n hasReducedMotionListener,\n initPrefersReducedMotion,\n prefersReducedMotion,\n} from \"motion-dom\"\nimport { warnOnce } from \"motion-utils\"\nimport { useState } from \"react\"\n\n/**\n * A hook that returns `true` if we should be using reduced motion based on the current device's Reduced Motion setting.\n *\n * This can be used to implement changes to your UI based on Reduced Motion. For instance, replacing motion-sickness inducing\n * `x`/`y` animations with `opacity`, disabling the autoplay of background videos, or turning off parallax motion.\n *\n * It will actively respond to changes and re-render your components with the latest setting.\n *\n * ```jsx\n * export function Sidebar({ isOpen }) {\n * const shouldReduceMotion = useReducedMotion()\n * const closedX = shouldReduceMotion ? 0 : \"-100%\"\n *\n * return (\n * \n * )\n * }\n * ```\n *\n * @return boolean\n *\n * @public\n */\nexport function useReducedMotion() {\n /**\n * Lazy initialisation of prefersReducedMotion\n */\n !hasReducedMotionListener.current && initPrefersReducedMotion()\n\n const [shouldReduceMotion] = useState(prefersReducedMotion.current)\n\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n shouldReduceMotion !== true,\n \"You have Reduced Motion enabled on your device. Animations may not appear as expected.\",\n \"reduced-motion-disabled\"\n )\n }\n\n /**\n * TODO See if people miss automatically updating shouldReduceMotion setting\n */\n\n return shouldReduceMotion\n}\n", "export { AnimatePresence } from './components/AnimatePresence/index.mjs';\nexport { PopChild } from './components/AnimatePresence/PopChild.mjs';\nexport { PresenceChild } from './components/AnimatePresence/PresenceChild.mjs';\nexport { LayoutGroup } from './components/LayoutGroup/index.mjs';\nexport { LazyMotion } from './components/LazyMotion/index.mjs';\nexport { MotionConfig } from './components/MotionConfig/index.mjs';\nexport { m } from './render/components/m/proxy.mjs';\nexport { motion } from './render/components/motion/proxy.mjs';\nexport { addPointerEvent } from './events/add-pointer-event.mjs';\nexport { addPointerInfo } from './events/event-info.mjs';\nexport { animations } from './motion/features/animations.mjs';\nexport { makeUseVisualState } from './motion/utils/use-visual-state.mjs';\nexport * from 'motion-dom';\nexport { VisualElement, addScaleCorrector, animateVisualElement, buildTransform, calcLength, createBox, delay, optimizedAppearDataAttribute, resolveMotionValue, visualElementStore } from 'motion-dom';\nexport { filterProps } from './render/dom/utils/filter-props.mjs';\nexport { isBrowser } from './utils/is-browser.mjs';\nexport { useComposedRefs } from './utils/use-composed-ref.mjs';\nexport { useForceUpdate } from './utils/use-force-update.mjs';\nexport { useIsomorphicLayoutEffect } from './utils/use-isomorphic-effect.mjs';\nexport { useUnmountEffect } from './utils/use-unmount-effect.mjs';\nexport { domAnimation } from './render/dom/features-animation.mjs';\nexport { domMax } from './render/dom/features-max.mjs';\nexport { domMin } from './render/dom/features-min.mjs';\nexport { useMotionValueEvent } from './utils/use-motion-value-event.mjs';\nexport { useElementScroll } from './value/scroll/use-element-scroll.mjs';\nexport { useViewportScroll } from './value/scroll/use-viewport-scroll.mjs';\nexport { useMotionTemplate } from './value/use-motion-template.mjs';\nexport { useMotionValue } from './value/use-motion-value.mjs';\nexport { useScroll } from './value/use-scroll.mjs';\nexport { useFollowValue } from './value/use-follow-value.mjs';\nexport { useSpring } from './value/use-spring.mjs';\nexport { useTime } from './value/use-time.mjs';\nexport { useTransform } from './value/use-transform.mjs';\nexport { useVelocity } from './value/use-velocity.mjs';\nexport { useWillChange } from './value/use-will-change/index.mjs';\nexport { WillChangeMotionValue } from './value/use-will-change/WillChangeMotionValue.mjs';\nexport { useReducedMotion } from './utils/reduced-motion/use-reduced-motion.mjs';\nexport { useReducedMotionConfig } from './utils/reduced-motion/use-reduced-motion-config.mjs';\nexport * from 'motion-utils';\nexport { MotionGlobalConfig } from 'motion-utils';\nexport { animationControls } from './animation/hooks/animation-controls.mjs';\nexport { useAnimate } from './animation/hooks/use-animate.mjs';\nexport { useAnimateMini } from './animation/hooks/use-animate-style.mjs';\nexport { useAnimation, useAnimationControls } from './animation/hooks/use-animation.mjs';\nexport { useIsPresent, usePresence } from './components/AnimatePresence/use-presence.mjs';\nexport { usePresenceData } from './components/AnimatePresence/use-presence-data.mjs';\nexport { useDomEvent } from './events/use-dom-event.mjs';\nexport { DragControls, useDragControls } from './gestures/drag/use-drag-controls.mjs';\nexport { isMotionComponent } from './motion/utils/is-motion-component.mjs';\nexport { unwrapMotionComponent } from './motion/utils/unwrap-motion-component.mjs';\nexport { isValidMotionProp } from './motion/utils/valid-prop.mjs';\nexport { useInstantLayoutTransition } from './projection/use-instant-layout-transition.mjs';\nexport { useResetProjection } from './projection/use-reset-projection.mjs';\nexport { useAnimationFrame } from './utils/use-animation-frame.mjs';\nexport { useCycle } from './utils/use-cycle.mjs';\nexport { useInView } from './utils/use-in-view.mjs';\nexport { disableInstantTransitions, useInstantTransition } from './utils/use-instant-transition.mjs';\nexport { usePageInView } from './utils/use-page-in-view.mjs';\nexport { transformViewBoxPoint } from './utils/transform-viewbox-point.mjs';\nexport { correctParentTransform } from './utils/transform-rotated-parent.mjs';\nexport { startOptimizedAppearAnimation } from './animation/optimized-appear/start.mjs';\nexport { LayoutGroupContext } from './context/LayoutGroupContext.mjs';\nexport { MotionConfigContext } from './context/MotionConfigContext.mjs';\nexport { MotionContext } from './context/MotionContext/index.mjs';\nexport { PresenceContext } from './context/PresenceContext.mjs';\nexport { SwitchLayoutGroupContext } from './context/SwitchLayoutGroupContext.mjs';\nexport { useAnimatedState as useDeprecatedAnimatedState } from './animation/hooks/use-animated-state.mjs';\nexport { AnimateSharedLayout } from './components/AnimateSharedLayout.mjs';\nexport { DeprecatedLayoutGroupContext } from './context/DeprecatedLayoutGroupContext.mjs';\nexport { useInvertedScale as useDeprecatedInvertedScale } from './value/use-inverted-scale.mjs';\nimport * as namespace from './components/Reorder/namespace.mjs';\nexport { namespace as Reorder };\nexport { animate, createScopedAnimate } from './animation/animate/index.mjs';\nexport { animateMini } from './animation/animators/waapi/animate-style.mjs';\nexport { distance, distance2D } from './utils/distance.mjs';\nexport { inView } from './render/dom/viewport/index.mjs';\nexport { scroll } from './render/dom/scroll/index.mjs';\nexport { scrollInfo } from './render/dom/scroll/track.mjs';\n//# sourceMappingURL=index.mjs.map\n", "export * from 'framer-motion';\nexport { m, motion } from 'framer-motion';\n", "/**\n * Motion presets \u2014 durations + easings for animations driven by the\n * `motion` library (https://motion.dev). Keep new presets here so all\n * timing values live in one place; reach for the named preset before\n * hand-rolling a transition.\n *\n * Where they're used:\n * - sidepanelExpand \u2192 AppShell.SidePanel `on \u2194 expanded \u2194 off` transitions\n * - indicatorGlide \u2192 SideNav active-indicator pill (motion.div layoutId)\n * - chipEnter \u2192 FolderChipRow chip mount (fade + scale in)\n * - chipExit \u2192 FolderChipRow chip unmount (fade + scale out)\n * - chipLayout \u2192 FolderChipRow sibling reflow when a chip is added/removed\n * - stickyHeaderExpand \u2192 ReaderLayout sticky-header bar mount / unmount\n * (e.g. SearchWithinTranscript open / close)\n * - labelSwap \u2192 sticky speaker label + section-header title content\n * swap (overlapping crossfade between old / new text)\n */\n\ntype TweenTransition = {\n type: \"tween\";\n duration: number;\n ease: [number, number, number, number];\n};\n\ntype SpringTransition = {\n type: \"spring\";\n stiffness: number;\n damping: number;\n};\n\nexport const motion = {\n /**\n * Tween used for the AppShell sidepanel mode transitions. Duration + easing\n * match MUI's \"standard\" transition curve so motion-driven layout changes\n * sit alongside MUI's CSS transitions without feeling out of place.\n */\n sidepanelExpand: {\n type: \"tween\",\n duration: 0.3,\n ease: [0.4, 0, 0.2, 1],\n } satisfies TweenTransition,\n\n /**\n * Tween used for shared-element indicator transitions \u2014 currently the SideNav\n * active-indicator pill gliding between NavItems. A tween (rather than a\n * spring) is intentional: motion's spring is per-axis, so even on a pure\n * vertical move the X-axis spring can pick up sub-pixel residual velocity\n * mid-flight and visually trace a curve. A tween applies one eased duration\n * uniformly to all axes, so the path is always a straight line.\n *\n * Easing matches MUI's emphasized-decelerate curve \u2014 snappy out, gentle in.\n */\n indicatorGlide: {\n type: \"tween\",\n duration: 0.22,\n ease: [0.2, 0.8, 0.2, 1],\n } satisfies TweenTransition,\n\n /**\n * Folder-chip entrance: fade + scale in. Restrained tween (no overshoot)\n * so chips settle into place; pairs with `chipLayout` driving the\n * sibling reflow that happens as the new chip pushes the row.\n */\n chipEnter: {\n type: \"tween\",\n duration: 0.2,\n ease: [0.2, 0.8, 0.2, 1],\n } satisfies TweenTransition,\n\n /**\n * Folder-chip exit: fade + scale out. Slightly quicker than the entrance\n * with an ease-in curve so the removal feels decisive \u2014 the user already\n * acted, the chip just clears out of the way.\n */\n chipExit: {\n type: \"tween\",\n duration: 0.15,\n ease: [0.4, 0, 1, 1],\n } satisfies TweenTransition,\n\n /**\n * Sibling reflow when a chip mounts / unmounts mid-row. Soft spring\n * gives a \"settle into place\" feel without overshoot. Lower stiffness\n * than the indicator pill because we're moving multiple items in\n * parallel \u2014 a tighter spring would feel busy.\n */\n chipLayout: {\n type: \"spring\",\n stiffness: 350,\n damping: 30,\n } satisfies SpringTransition,\n\n /**\n * ReaderLayout sticky-header bar expansion. Used for the\n * SearchWithinTranscript open / close animation; the bar's height\n * grows from 0 to its content height while the contents fade in.\n * Decelerating curve so the bar settles smoothly into place; the\n * mirror exit reads as a quick collapse.\n */\n stickyHeaderExpand: {\n type: \"tween\",\n duration: 0.22,\n ease: [0.2, 0.8, 0.2, 1],\n } satisfies TweenTransition,\n\n /**\n * Mirror of `stickyHeaderExpand` for the close direction \u2014 faster +\n * ease-in so dismissal feels snappy.\n */\n stickyHeaderCollapse: {\n type: \"tween\",\n duration: 0.18,\n ease: [0.4, 0, 1, 1],\n } satisfies TweenTransition,\n\n /**\n * Content swap for the sticky speaker label and the section-header title \u2014\n * an overlapping crossfade: the outgoing and incoming labels occupy the same\n * spot and fade through each other with a slight vertical drift. Symmetric\n * (same curve + duration both directions) on purpose: with both labels\n * animating at once, an uneven in/out would make one side visibly lead. The\n * even overlap is what reads as smooth, versus the sequential exit-then-enter\n * (with a dead gap mid-swap) it replaces.\n */\n labelSwap: {\n type: \"tween\",\n duration: 0.28,\n ease: [0.4, 0, 0.2, 1],\n } satisfies TweenTransition,\n} as const;\n\n/** Format a tween preset as a CSS ` ` pair for use in `transition` rules. */\nexport function motionToCss(preset: TweenTransition): string {\n const ms = Math.round(preset.duration * 1000);\n const easing = `cubic-bezier(${preset.ease.join(\", \")})`;\n return `${ms}ms ${easing}`;\n}\n", "import React, { useRef, useState, useEffect, useCallback } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport Stack from \"@mui/material/Stack\";\nimport Tooltip from \"@mui/material/Tooltip\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport { Folder } from \"lucide-react\";\nimport { BIQChip } from \"./BIQChip\";\nimport { motion as motionPresets } from \"../theme/tokens/motion\";\nimport type { FolderChipData } from \"../../hooks/useSaveToFolder\";\nimport { recordUserEvent } from \"../../api/userEvents\";\n\n/*\n * Motion specs for the chip lifecycle. Restrained fade + scale on\n * enter / exit, plus Motion's `layout` prop on each item so siblings\n * glide into their new positions when a chip is added or removed.\n * Tokens live in theme/tokens/motion.ts (chipEnter / chipExit / chipLayout).\n */\nconst CHIP_INITIAL = { opacity: 0, scale: 0.9 };\nconst CHIP_VISIBLE = { opacity: 1, scale: 1 };\n\nexport interface FolderChipRowProps {\n folders: FolderChipData[];\n onRemove: (folderId: number) => void;\n /**\n * The surface this chip row is rendered on. Threaded into the\n * `folder_chip_removed` analytics event's `source_type` dimension.\n */\n sourceType: \"transcript\" | \"clerk_session\";\n /** Called when the \"+N more\" overflow chip is clicked. */\n onMoreClick?: (event: React.MouseEvent) => void;\n /** Maximum width for a visible folder chip before its label ellipsizes. */\n maxChipWidth?: number | string;\n}\n\nconst CHIP_GAP_PX = 4; // matches Stack spacing={0.5} = 4px\nconst MORE_CHIP_WIDTH_PX = 70;\nconst CHIP_MAX_WIDTH_PX = 180;\n\n// Sentinel handler for the offscreen measurement chips \u2014 they need an\n// onDelete prop so MUI renders the delete icon (and the chip width matches\n// the visible row), but pointer-events: none on the measurement Stack\n// prevents the handler from ever firing.\nconst noop = () => {};\n\n/**\n * How many leading chips fit in `containerWidth` given each chip's width,\n * reserving room for a \"+N more\" chip when the full list doesn't fit.\n *\n * Extracted from the component so it can be unit-tested without jsdom\n * layout. Cumulative-width approach is more robust than right-edge\n * comparisons because children that overflow get rendered outside the\n * container (overflow:hidden clips visually but layout still positions\n * them out there), making right-edge math noisy mid-layout.\n */\nexport function computeVisibleChipCount(containerWidth: number, chipWidths: number[]): number {\n if (chipWidths.length === 0) return 0;\n\n const fit = (reserved: number): number => {\n let cumulative = 0;\n let count = 0;\n for (const w of chipWidths) {\n const next = cumulative + (count === 0 ? w : CHIP_GAP_PX + w);\n if (next + reserved <= containerWidth) {\n cumulative = next;\n count++;\n } else {\n break;\n }\n }\n return count;\n };\n\n const withoutMore = fit(0);\n if (withoutMore === chipWidths.length) return withoutMore;\n\n // Some chips overflow \u2014 re-fit with the more-chip reserved.\n const withMore = fit(MORE_CHIP_WIDTH_PX + CHIP_GAP_PX);\n // Show at least one chip even when the container is extremely narrow.\n return withMore === 0 ? 1 : withMore;\n}\n\ninterface FolderChipProps {\n folder: FolderChipData;\n onClick: (e: React.MouseEvent) => void;\n onDelete: (e: React.MouseEvent) => void;\n sx?: React.ComponentProps[\"sx\"];\n}\n\n/**\n * Single chip wrapper that only renders a Tooltip when the label text is\n * actually truncated by the chip's maxWidth. Avoids the noise of a tooltip\n * appearing on every short folder name.\n *\n * Truncation is checked lazily on mouse enter (not via ResizeObserver) so\n * the chip doesn't re-render on every container resize tick. The Tooltip's\n * own hover detection is suppressed via `disableHoverListener`; we drive\n * `open` manually after the truncation check.\n */\nconst FolderChip: React.FC = ({ folder, onClick, onDelete, sx }) => {\n const chipRef = useRef(null);\n const [tooltipOpen, setTooltipOpen] = useState(false);\n\n /*\n * Truncation-only tooltip \u2014 only opens when the label is clipped by\n * maxWidth. Identical logic for pointer hover and keyboard focus so\n * keyboard users get the same reveal a mouse user does (WCAG 1.4.13 /\n * 2.5.3 compliance). MUI's built-in focus listener fires before the\n * chip is fully styled, so we drive `open` manually via state.\n */\n const revealIfTruncated = () => {\n const labelEl = chipRef.current?.querySelector(\".MuiChip-label\") as HTMLElement | null;\n if (labelEl && labelEl.scrollWidth > labelEl.clientWidth) {\n setTooltipOpen(true);\n }\n };\n const hide = () => setTooltipOpen(false);\n\n return (\n \n \n \n );\n};\n\n/**\n * Single-row horizontal strip of folder chips.\n * Chips that overflow the row are replaced by a \"+N more\" chip.\n */\nexport const FolderChipRow: React.FC = ({\n folders,\n onRemove,\n sourceType,\n onMoreClick,\n maxChipWidth = CHIP_MAX_WIDTH_PX,\n}) => {\n const containerRef = useRef(null);\n /*\n * Offscreen measurement layer (`measureRef`) always renders every chip\n * in `folders`, regardless of `visibleCount`. The visible row contains\n * only the chips that fit + the overflow pill. Measurements always come\n * from the offscreen layer so we have widths for ALL chips \u2014 including\n * the ones currently hidden by overflow. That way we can correctly\n * decide to show more chips when the container has slack space, and\n * shrink when it doesn't.\n *\n * Earlier attempts measured `containerRef.children` directly. Either we\n * counted the \"+N more\" pill as a real chip (oscillation, flashing) or\n * we filtered it out and lost widths for overflowed chips (so the row\n * never re-expanded when there was room). The offscreen layer fixes\n * both: chip widths are always known, the overflow pill is never in\n * the measured set.\n */\n const measureRef = useRef(null);\n const [visibleCount, setVisibleCount] = useState(folders.length);\n const chipMaxWidth = typeof maxChipWidth === \"number\" ? `min(100%, ${maxChipWidth}px)` : maxChipWidth;\n\n const calculateVisibleCount = useCallback(() => {\n const container = containerRef.current;\n const measure = measureRef.current;\n if (!container || !measure) return;\n const measuredChildren = Array.from(measure.children) as HTMLElement[];\n if (measuredChildren.length === 0) return;\n const chipWidths = measuredChildren.map((c) => c.offsetWidth);\n const next = computeVisibleChipCount(container.offsetWidth, chipWidths);\n // Skip the setState when the computed value hasn't actually changed. The\n // container ResizeObserver fires on every panel/drawer resize tick;\n // without this guard each tick schedules a re-render even when the\n // visible-chip count is stable.\n setVisibleCount((prev) => (prev === next ? prev : next));\n }, []);\n\n // Expand-then-measure pattern. `container.children` only contains\n // currently-rendered chips (`folders.slice(0, visibleCount)` + the\n // \"+N more\" chip), so any chip that's currently collapsed into the\n // more-chip can't be measured. When the folders list grows, the\n // container widens (drawer/panel resize), or the row mounts, we first\n // setVisibleCount(folders.length) to render ALL chips so they're in the\n // DOM, then RAF to wait for the render to flush, then measure and set\n // the actual fit count. Two renders per measurement is load-bearing \u2014\n // without the expand step the row stays stuck in its previous\n // (possibly-overflowed) state when chips are added or the container\n // widens.\n const remeasure = useCallback(() => {\n if (folders.length === 0) return;\n setVisibleCount(folders.length);\n requestAnimationFrame(() => calculateVisibleCount());\n }, [folders.length, calculateVisibleCount]);\n\n // Initial measure + folders-change measure + container resize observer.\n useEffect(() => {\n remeasure();\n\n const container = containerRef.current;\n if (!container) return;\n\n const observer = new ResizeObserver(remeasure);\n observer.observe(container);\n return () => observer.disconnect();\n }, [remeasure]);\n\n if (folders.length === 0) return null;\n\n const overflowCount = folders.length - visibleCount;\n const visibleFolders = folders.slice(0, visibleCount);\n const chipSx = {\n maxWidth: chipMaxWidth,\n minWidth: 0,\n height: 24,\n fontSize: \"13px\",\n flexShrink: 0,\n overflow: \"hidden\",\n \"& .MuiChip-icon\": { fontSize: 18, flexShrink: 0 },\n \"& .MuiChip-deleteIcon\": { fontSize: 16, flexShrink: 0 },\n \"& .MuiChip-label\": {\n minWidth: 0,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n px: \"6px\",\n },\n };\n\n const handleChipClick = (folderId: number) => (e: React.MouseEvent) => {\n e.stopPropagation();\n window.open(`/folders/${folderId}?from=chip`, \"_blank\");\n };\n\n const handleDelete = (folderId: number) => (e: React.MouseEvent) => {\n e.stopPropagation();\n void recordUserEvent({\n event_name: \"folder_chip_removed\",\n event_properties: { source_type: sourceType },\n });\n onRemove(folderId);\n };\n\n return (\n /*\n * No top padding \u2014 the chrome row that hosts this chip row (e.g.\n * ReaderTopBar.Container with `gap: 4px` between TopRow and BottomRow,\n * or AppShell.TopBarRight where chips align at flex-row center)\n * owns the spacing. Adding it here would double-pad in the vertical\n * case and push chips out of vertical-center in the horizontal case.\n */\n \n {/*\n * Visible row. Each chip is wrapped in a motion.div so it fades +\n * scales in on mount / out on unmount, with Motion's `layout`\n * prop driving the sibling-reflow spring when a chip is added or\n * removed mid-row. AnimatePresence keeps exiting chips mounted\n * long enough to play their exit animation.\n */}\n \n \n {visibleFolders.map((folder) => (\n \n \n \n ))}\n {overflowCount > 0 && (\n \n \n \n )}\n \n \n {/*\n * Offscreen measurement layer \u2014 always renders all chips so we know\n * each one's natural width. Lightweight (raw BIQChip, no Tooltip /\n * click handlers); visibility:hidden + pointer-events:none keep it\n * invisible and inert, position:absolute removes it from layout\n * flow so it doesn't push the visible row down.\n */}\n \n {folders.map((folder) => (\n /*\n * Offscreen measurement chip must render identically to the\n * visible chip \u2014 same icon, same label, AND the same delete\n * icon. MuiChip only renders the delete X when `onDelete` is\n * present; without it the offscreen chip is ~24px narrower\n * than its visible counterpart, computeVisibleChipCount sees\n * smaller widths than reality, and the visible row ends up\n * overflowing its container by a chip or two. The handler is\n * a no-op (pointer-events: none on the parent suppresses\n * interaction anyway).\n */\n \n ))}\n \n \n );\n};\n\nexport default FolderChipRow;\n", "import { fetchHelper } from \"./fetchHelpers\";\n\nfunction getVapidPublicKey(): string {\n return document.querySelector('meta[name=\"vapid-public-key\"]')?.content || \"\";\n}\n\nexport async function hasActivePushSubscription(): Promise {\n try {\n if (!(\"serviceWorker\" in navigator)) return false;\n const reg = await navigator.serviceWorker.getRegistration();\n if (!reg) return false;\n const sub = await reg.pushManager.getSubscription();\n return sub !== null;\n } catch {\n return false;\n }\n}\n\nexport async function registerAndSubscribe(): Promise {\n try {\n if (!(\"serviceWorker\" in navigator) || !(\"PushManager\" in window)) return false;\n\n const registration = await navigator.serviceWorker.register(\"/service_worker.js\");\n await navigator.serviceWorker.ready;\n\n let subscription = await registration.pushManager.getSubscription();\n if (!subscription) {\n const permission = await Notification.requestPermission();\n if (permission !== \"granted\") return false;\n\n subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: urlBase64ToUint8Array(getVapidPublicKey()),\n });\n }\n\n const response = await fetchHelper(\"/api/push-subscriptions\", {\n method: \"POST\",\n body: {\n endpoint: subscription.endpoint,\n keys: {\n p256dh: arrayBufferToBase64(subscription.getKey(\"p256dh\")),\n auth: arrayBufferToBase64(subscription.getKey(\"auth\")),\n },\n },\n });\n\n if (!response.ok) return false;\n return true;\n } catch {\n return false;\n }\n}\n\nfunction urlBase64ToUint8Array(base64String: string): Uint8Array {\n const padding = \"=\".repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding).replace(/-/g, \"+\").replace(/_/g, \"/\");\n const raw = atob(base64);\n return Uint8Array.from(raw, (char) => char.charCodeAt(0));\n}\n\nfunction arrayBufferToBase64(buffer: ArrayBuffer | null): string {\n if (!buffer) return \"\";\n return btoa(String.fromCharCode(...Array.from(new Uint8Array(buffer))));\n}\n", "import { useInfiniteQuery, type InfiniteData, type QueryClient, type QueryKey } from \"@tanstack/react-query\";\nimport { listSessions } from \"../agentPrototype\";\nimport type { SessionListItem, SessionListResponse } from \"./agentPrototype.types\";\n\nconst clerkRecentsQueryKey = [\"agentPrototypeSessions\", \"infinite\", \"sidenav\"] as const;\n\nexport const agentPrototypeSessionListKey = (projection: \"history\" | \"sidenav\", sortDirection: \"asc\" | \"desc\") =>\n [\"agentPrototypeSessions\", \"infinite\", projection, sortDirection] as const;\n\nconst sessionListOptions = ({\n projection,\n sortDirection,\n enabled = true,\n}: {\n projection: \"history\" | \"sidenav\";\n sortDirection: \"asc\" | \"desc\";\n enabled?: boolean;\n}) => ({\n queryKey: agentPrototypeSessionListKey(projection, sortDirection),\n queryFn: ({ pageParam = 1 }: { pageParam?: number }) =>\n listSessions({ pageParam, sortDirection, pageSize: 20, includeSidenav: projection === \"sidenav\" }),\n initialPageParam: 1,\n getNextPageParam: (lastPage: Awaited>) => lastPage.next_page ?? undefined,\n enabled,\n});\n\nexport const useInfiniteClerkHistory = (sortDirection: \"asc\" | \"desc\" = \"desc\") =>\n useInfiniteQuery({\n ...sessionListOptions({ projection: \"history\", sortDirection }),\n staleTime: 60_000,\n gcTime: 5 * 60_000,\n });\n\nexport const clerkRecentsRefetchInterval = (\n pages: SessionListResponse[] | undefined,\n documentHidden: boolean,\n): number | false => {\n if (documentHidden) return false;\n const hasActive = (pages ?? []).some(\n (page) =>\n page.sidenav_rollup_status === \"working\" ||\n page.sidenav_rollup_status === \"needs_input\" ||\n page.data.some((session) => session.sidenav_status === \"working\" || session.sidenav_status === \"needs_input\"),\n );\n return hasActive ? 5_000 : false;\n};\n\ntype ClerkRecentsData = InfiniteData;\n\nconst updateClerkRecentStatus = (\n data: ClerkRecentsData | undefined,\n token: string,\n update: (status: SessionListItem[\"sidenav_status\"]) => SessionListItem[\"sidenav_status\"],\n): ClerkRecentsData | undefined => {\n if (!data) return data;\n\n let changed = false;\n const pages = data.pages.map((page) => {\n let pageChanged = false;\n const sessions = page.data.map((session) => {\n if (session.token !== token) return session;\n\n const sidenavStatus = update(session.sidenav_status);\n if (sidenavStatus === session.sidenav_status) return session;\n changed = true;\n pageChanged = true;\n return { ...session, sidenav_status: sidenavStatus };\n });\n\n return pageChanged ? { ...page, data: sessions } : page;\n });\n\n return changed ? { ...data, pages } : data;\n};\n\nexport const optimisticallyMarkClerkRecentWorking = (client: QueryClient, token: string): (() => void) => {\n const snapshots: Array<{ queryKey: QueryKey; status: SessionListItem[\"sidenav_status\"] }> = [];\n\n client.getQueriesData({ queryKey: clerkRecentsQueryKey }).forEach(([queryKey, data]) => {\n const session = data?.pages.flatMap((page) => page.data).find((item) => item.token === token);\n if (session) snapshots.push({ queryKey, status: session.sidenav_status });\n });\n\n client.setQueriesData({ queryKey: clerkRecentsQueryKey }, (data) =>\n updateClerkRecentStatus(data, token, () => \"working\"),\n );\n\n return () => {\n snapshots.forEach(({ queryKey, status }) => {\n client.setQueryData(queryKey, (data) =>\n updateClerkRecentStatus(data, token, (currentStatus) => (currentStatus === \"working\" ? status : currentStatus)),\n );\n });\n };\n};\n\nexport const useInfiniteClerkRecents = (enabled: boolean) =>\n useInfiniteQuery({\n ...sessionListOptions({ projection: \"sidenav\", sortDirection: \"desc\", enabled }),\n staleTime: 5_000,\n gcTime: 5 * 60_000,\n refetchOnWindowFocus: true,\n refetchInterval: (query) =>\n clerkRecentsRefetchInterval(query.state.data?.pages, typeof document !== \"undefined\" && document.hidden),\n });\n", "import { useCallback, useEffect, useRef } from \"react\";\nimport { createSessionRun, streamRun } from \"../api/agentPrototype\";\nimport type {\n AgentEvent,\n ClarifyingQuestion,\n AgentPrototypeMessage,\n MessageConsumedEvent,\n AttachedFile,\n CitationData,\n DocketConnectRetrievalRequestPayload,\n ModelConfig,\n PlanningCycle,\n TokenUsage,\n} from \"../api/queries/agentPrototype.types\";\nimport { CLERK_ERROR_COPY } from \"../utils/clerkErrorCopy\";\n\nexport interface StreamCallbacks {\n onMessageQueueUpdated?: (message: AgentPrototypeMessage) => void;\n onMessageConsumed?: (event: MessageConsumedEvent) => void;\n onTextDelta: (content: string) => void;\n onTextReset?: () => void;\n onThinking: (content: string) => void;\n onToolUse: (tool: string, input: Record, delegateId?: string, toolCallId?: string) => void;\n onToolResult: (\n tool: string,\n summary: string,\n delegateId?: string,\n detail?: Record,\n toolCallId?: string,\n ) => void;\n onError: (message: string, fatal?: boolean, errorCode?: string) => void;\n onDone: (usage?: TokenUsage, citations?: CitationData[]) => void;\n onCancelled: () => void;\n onFileReady: (file: { filename: string; sizeBytes?: number; pageCount?: number; url?: string }) => void;\n onClarifyingQuestion?: (\n questionId: string,\n question: string,\n options: ClarifyingQuestion[\"options\"],\n answerTimeoutMs?: number,\n details?: Pick,\n ) => void;\n onDocketConnectRetrievalRequest?: (request: DocketConnectRetrievalRequestPayload) => void;\n onClarifyingQuestionResolved?: (questionId: string) => void;\n onClarifyingQuestionTimeout?: (questionId: string) => void;\n onInputLifecycleChange?: (inputRequestId: string) => void;\n onPlanningOffer?: (cycle: PlanningCycle) => void;\n onAssistantTextReset?: () => void;\n onContentReset?: () => void;\n onStreamBoundary?: () => void;\n onRunStarted?: (runId: string) => void;\n onEventId?: (eventId: number) => void;\n onTransportError?: (error: Error) => void;\n onStreamComplete?: () => void;\n}\n\ntype ActiveStream = {\n controller: AbortController | null;\n};\n\nexport function useAgentPrototypeStream() {\n const activeStreamRef = useRef(null);\n\n useEffect(() => {\n return () => {\n const activeStream = activeStreamRef.current;\n activeStreamRef.current = null;\n activeStream?.controller?.abort();\n };\n }, []);\n\n const processStreamEvent = useCallback((callbacks: StreamCallbacks, rawEvent: unknown, eventId?: number) => {\n const event = rawEvent as AgentEvent;\n if (eventId && callbacks.onEventId) {\n callbacks.onEventId(eventId);\n }\n\n switch (event.type) {\n case \"message_queue_updated\":\n callbacks.onMessageQueueUpdated?.(event.user_message);\n break;\n case \"message_consumed\":\n callbacks.onMessageConsumed?.(event);\n break;\n case \"text_delta\":\n callbacks.onTextDelta(event.content);\n break;\n case \"text_reset\":\n callbacks.onTextReset?.();\n break;\n case \"thinking\":\n callbacks.onThinking(event.content);\n break;\n case \"tool_use\":\n callbacks.onToolUse(event.tool, event.input, event.delegateId, event.toolCallId);\n break;\n case \"tool_result\":\n callbacks.onToolResult(event.tool, event.summary, event.delegateId, event.detail, event.toolCallId);\n break;\n case \"docket_connect_retrieval_request_state\":\n callbacks.onDocketConnectRetrievalRequest?.(event.retrieval_request);\n break;\n case \"error\":\n callbacks.onError(event.message, event.fatal, event.error_code);\n break;\n case \"done\":\n callbacks.onDone(event.usage, event.citations);\n break;\n case \"cancelled\":\n callbacks.onCancelled();\n break;\n case \"file_ready\": {\n const fileEvent = event as {\n type: \"file_ready\";\n filename: string;\n size_bytes?: number;\n page_count?: number;\n url?: string;\n download_url?: string;\n };\n callbacks.onFileReady({\n filename: fileEvent.filename,\n sizeBytes: fileEvent.size_bytes,\n pageCount: fileEvent.page_count,\n url: fileEvent.url || fileEvent.download_url,\n });\n break;\n }\n case \"clarifying_question\": {\n const cqEvent = event as Extract;\n callbacks.onClarifyingQuestion?.(\n cqEvent.question_id,\n cqEvent.question,\n cqEvent.options,\n cqEvent.answer_timeout_ms,\n ...(cqEvent.question_type || cqEvent.input_required !== undefined\n ? [{ questionType: cqEvent.question_type, inputRequired: cqEvent.input_required }]\n : []),\n );\n break;\n }\n case \"clarifying_question_timeout\":\n callbacks.onClarifyingQuestionTimeout?.(\n (event as { type: \"clarifying_question_timeout\"; question_id: string }).question_id,\n );\n break;\n case \"assistant_text_reset\":\n callbacks.onAssistantTextReset?.();\n break;\n case \"clarifying_question_resolved\":\n callbacks.onClarifyingQuestionResolved?.(\n (event as { type: \"clarifying_question_resolved\"; question_id: string }).question_id,\n );\n break;\n case \"input_required\":\n if (event.planning_cycle) callbacks.onPlanningOffer?.(event.planning_cycle);\n callbacks.onInputLifecycleChange?.(event.input_request_id);\n break;\n case \"input_answered\":\n callbacks.onInputLifecycleChange?.(event.input_request_id);\n break;\n case \"content_reset\":\n callbacks.onContentReset?.();\n break;\n case \"stream_boundary\":\n callbacks.onStreamBoundary?.();\n break;\n }\n }, []);\n\n const startRunStream = useCallback(\n (token: string, runId: string, callbacks: StreamCallbacks, lastEventId?: number) => {\n const previousStream = activeStreamRef.current;\n const streamOwner: ActiveStream = { controller: null };\n activeStreamRef.current = streamOwner;\n previousStream?.controller?.abort();\n\n const isCurrentStream = () => activeStreamRef.current === streamOwner;\n try {\n const controller = streamRun(\n token,\n runId,\n (rawEvent, eventId) => {\n if (!isCurrentStream()) return;\n processStreamEvent(callbacks, rawEvent, eventId);\n },\n (error) => {\n if (!isCurrentStream()) return;\n if (callbacks.onTransportError) {\n callbacks.onTransportError(error);\n } else {\n callbacks.onError(error.message, true);\n }\n },\n () => {\n if (!isCurrentStream()) return;\n activeStreamRef.current = null;\n callbacks.onStreamComplete?.();\n },\n lastEventId,\n );\n\n streamOwner.controller = controller;\n if (!isCurrentStream()) controller.abort();\n } catch (error) {\n if (isCurrentStream()) activeStreamRef.current = null;\n throw error;\n }\n },\n [processStreamEvent],\n );\n\n const startStream = useCallback(\n async (\n token: string,\n message: string,\n callbacks: StreamCallbacks,\n files?: AttachedFile[],\n modelConfig?: ModelConfig,\n ) => {\n try {\n const run = await createSessionRun(token, message, files, modelConfig);\n if (!run.run_id) throw new Error(CLERK_ERROR_COPY.genericRetry);\n callbacks.onRunStarted?.(run.run_id);\n startRunStream(token, run.run_id, callbacks);\n } catch (error) {\n const streamError = error instanceof Error ? error : new Error(CLERK_ERROR_COPY.genericRetry);\n if (callbacks.onTransportError) {\n callbacks.onTransportError(streamError);\n } else {\n callbacks.onError(streamError.message, true);\n }\n }\n },\n [startRunStream],\n );\n\n const cancelStream = useCallback(() => {\n const activeStream = activeStreamRef.current;\n activeStreamRef.current = null;\n activeStream?.controller?.abort();\n }, []);\n\n const isStreaming = useCallback(() => {\n return activeStreamRef.current !== null;\n }, []);\n\n return { startStream, startRunStream, cancelStream, isStreaming };\n}\n", "export type ClerkResponseFileSizeBucket = \"lt_100_kb\" | \"100_kb_to_1_mb\" | \"1_mb_to_10_mb\" | \"gte_10_mb\";\n\nexport function normalizeFileExtension(fileName: string): string {\n const dotIndex = fileName.lastIndexOf(\".\");\n if (dotIndex === -1 || dotIndex === fileName.length - 1) {\n return \"unknown\";\n }\n\n return fileName.slice(dotIndex + 1).toLowerCase();\n}\n\nexport function uniqueFileExtensions(files: Array<{ name: string }>): string[] {\n return Array.from(new Set(files.map((file) => normalizeFileExtension(file.name)))).sort();\n}\n\nexport function clerkResponseFileSizeBucket(sizeBytes: number): ClerkResponseFileSizeBucket {\n if (sizeBytes < 100 * 1024) {\n return \"lt_100_kb\";\n }\n if (sizeBytes < 1024 * 1024) {\n return \"100_kb_to_1_mb\";\n }\n if (sizeBytes < 10 * 1024 * 1024) {\n return \"1_mb_to_10_mb\";\n }\n\n return \"gte_10_mb\";\n}\n", "import type { ClarifyingQuestion } from \"../api/queries/agentPrototype.types\";\n\nexport const CLARIFYING_UI_EXPIRY_MARGIN_MS = 5_000;\n\nexport function clarifyingQuestionUiDeadlineMs(question: ClarifyingQuestion): number | null {\n return typeof question.expiresAtMs === \"number\" ? question.expiresAtMs - CLARIFYING_UI_EXPIRY_MARGIN_MS : null;\n}\n\nexport function clarifyingQuestionIsLocallyExpired(question: ClarifyingQuestion, now = Date.now()): boolean {\n const deadline = clarifyingQuestionUiDeadlineMs(question);\n return deadline !== null && now >= deadline;\n}\n", "import React, { createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n checkCreditAgentSpeedBump,\n type CreditAgentSpeedBumpRequest,\n type CreditAgentSpeedBumpRequirement,\n} from \"@/api/agentPrototype\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { CLERK_ERROR_COPY } from \"@/utils/clerkErrorCopy\";\n\ntype ConfirmationResult = string | null | undefined;\n\ninterface PromptState {\n request: CreditAgentSpeedBumpRequest;\n requirement: CreditAgentSpeedBumpRequirement;\n recheckOnConfirm?: boolean;\n resolve: (confirmationToken: ConfirmationResult) => void;\n}\n\ninterface CreditAgentSpeedBumpContextValue {\n prompt: PromptState | null;\n confirming: boolean;\n error: string | null;\n ensureAcknowledged: (request: CreditAgentSpeedBumpRequest) => Promise;\n presentRequired: (\n request: CreditAgentSpeedBumpRequest,\n requirement: CreditAgentSpeedBumpRequirement,\n options?: { recheckOnConfirm?: boolean },\n ) => Promise;\n confirm: () => Promise;\n cancel: () => void;\n}\n\nconst Context = createContext(null);\n\nfunction warningLevel(requirement: CreditAgentSpeedBumpRequirement): number {\n const value = Number(requirement.warningLevelUsd);\n return Number.isFinite(value) ? value : 0;\n}\n\nfunction trackAction(requestKind: CreditAgentSpeedBumpRequest[\"requestKind\"], action: \"continue\" | \"cancel\") {\n void recordUserEvent({\n event_name:\n action === \"continue\"\n ? \"credit_agent_speed_bump_continue_button_clicked\"\n : \"credit_agent_speed_bump_cancel_request_button_clicked\",\n event_properties: { request_kind: requestKind },\n });\n}\n\nexport const CreditAgentSpeedBumpProvider = ({ children }: { children: ReactNode }) => {\n const [prompt, setPrompt] = useState(null);\n const [confirming, setConfirming] = useState(false);\n const [error, setError] = useState(null);\n const pendingRef = useRef(false);\n const pendingResolveRef = useRef(null);\n const mountedRef = useRef(true);\n\n const releasePending = useCallback(() => {\n pendingRef.current = false;\n pendingResolveRef.current = null;\n }, []);\n\n const waitForConfirmation = useCallback(\n (request: CreditAgentSpeedBumpRequest, requirement: CreditAgentSpeedBumpRequirement, recheckOnConfirm = true) =>\n new Promise((resolve) => {\n const finish: PromptState[\"resolve\"] = (confirmationToken) => {\n releasePending();\n resolve(confirmationToken);\n };\n pendingResolveRef.current = finish;\n setError(null);\n setPrompt({ request, requirement, recheckOnConfirm, resolve: finish });\n }),\n [releasePending],\n );\n\n const ensureAcknowledged = useCallback(\n async (request: CreditAgentSpeedBumpRequest): Promise => {\n if (pendingRef.current) return null;\n\n pendingRef.current = true;\n try {\n const requirement = await checkCreditAgentSpeedBump(request);\n if (!mountedRef.current) {\n releasePending();\n return null;\n }\n if (!requirement.required) {\n releasePending();\n return undefined;\n }\n if (!requirement.confirmationToken) {\n throw new Error(CLERK_ERROR_COPY.genericRetry);\n }\n return waitForConfirmation(request, requirement);\n } catch (cause) {\n releasePending();\n throw cause;\n }\n },\n [releasePending, waitForConfirmation],\n );\n\n const presentRequired = useCallback(\n (\n request: CreditAgentSpeedBumpRequest,\n requirement: CreditAgentSpeedBumpRequirement,\n options?: { recheckOnConfirm?: boolean },\n ): Promise => {\n if (pendingRef.current) return Promise.resolve(null);\n\n pendingRef.current = true;\n return waitForConfirmation(request, requirement, options?.recheckOnConfirm);\n },\n [waitForConfirmation],\n );\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n pendingResolveRef.current?.(null);\n };\n }, []);\n\n const confirm = useCallback(async () => {\n if (!prompt || confirming) return;\n\n trackAction(prompt.request.requestKind, \"continue\");\n setConfirming(true);\n setError(null);\n try {\n if (prompt.recheckOnConfirm === false) {\n if (!prompt.requirement.confirmationToken) {\n throw new Error(CLERK_ERROR_COPY.genericRetry);\n }\n prompt.resolve(prompt.requirement.confirmationToken);\n setPrompt(null);\n return;\n }\n\n const result = await checkCreditAgentSpeedBump(prompt.request);\n if (!mountedRef.current) return;\n if (!result.required) {\n prompt.resolve(undefined);\n setPrompt(null);\n return;\n }\n if (!result.confirmationToken) {\n throw new Error(CLERK_ERROR_COPY.genericRetry);\n }\n if (warningLevel(result) > warningLevel(prompt.requirement)) {\n setPrompt((current) => (current ? { ...current, requirement: result } : current));\n return;\n }\n\n prompt.resolve(result.confirmationToken);\n setPrompt(null);\n } catch {\n if (mountedRef.current) {\n setError(CLERK_ERROR_COPY.genericRetry);\n }\n } finally {\n if (mountedRef.current) {\n setConfirming(false);\n }\n }\n }, [confirming, prompt]);\n\n const cancel = useCallback(() => {\n if (confirming || !prompt) return;\n\n trackAction(prompt.request.requestKind, \"cancel\");\n prompt.resolve(null);\n setError(null);\n setPrompt(null);\n }, [confirming, prompt]);\n\n const value = useMemo(\n () => ({\n prompt,\n confirming,\n error,\n ensureAcknowledged,\n presentRequired,\n confirm,\n cancel,\n }),\n [prompt, confirming, error, ensureAcknowledged, presentRequired, confirm, cancel],\n );\n\n return {children};\n};\n\nexport const useOptionalCreditAgentSpeedBump = () => useContext(Context);\n", "import { useState, useCallback, useEffect, useRef, useMemo } from \"react\";\nimport { ConversationDrafts } from \"../components/agent_prototype/conversationDrafts\";\nimport type { NextStepSelection, NextStepSendContext } from \"../components/agent_prototype/nextSteps\";\nimport { queryClient } from \"../api/queryClient\";\nimport { optimisticallyMarkClerkRecentWorking } from \"../api/queries/agentPrototype\";\nimport { DEFAULT_REASONING_EFFORT } from \"../components/agent_prototype/constants\";\nimport {\n createSession,\n steerQueuedMessage,\n resumeQueuedMessage,\n cancelQueuedMessage,\n getMessageDraft,\n forkSessionMessage,\n type MessageDraft,\n createSessionRun,\n AgentAdmissionUncertainError,\n AgentPrototypeApiError,\n getRunStatus,\n getSession,\n updatePlanningMode,\n PlanningModeConflictError,\n ackRun,\n markSessionRead,\n retrySessionRun as apiRetryRun,\n cancelSession as apiCancelSession,\n updateSessionTitle as apiUpdateTitle,\n submitClarifyingAnswer as apiSubmitAnswer,\n submitDocketConnectApproval as apiSubmitDocketConnectApproval,\n cancelDocketConnectApproval as apiCancelDocketConnectApproval,\n acknowledgeClarifyingQuestion as apiAcknowledgeClarifyingQuestion,\n isCreditSpeedBumpRequiredError,\n respondToPlanningOffer as apiRespondToPlanningOffer,\n submitPlanningResponse as apiSubmitPlanningResponse,\n confirmPlanningVersion as apiConfirmPlanningVersion,\n editPlanningVersion as apiEditPlanningVersion,\n cancelPlanningCycle as apiCancelPlanningCycle,\n PlanningActionError,\n type CreditAgentSpeedBumpRequest,\n type DocketConnectContinuationCreditSpeedBump,\n} from \"../api/agentPrototype\";\nimport { recordUserEvent } from \"../api/userEvents\";\nimport { useAgentPrototypeStream, type StreamCallbacks } from \"./useAgentPrototypeStream\";\nimport type {\n ActiveTranscriptContext,\n ActiveTranscriptReference,\n AttachedFile,\n CitationData,\n FileMetadata,\n ModelConfig,\n SessionWithMessages,\n PlanningModeState,\n TokenUsage,\n ToolCallRecord,\n ToolResultRecord,\n ClarifyingQuestion,\n ClarifyingQuestionResponse,\n DocketConnectRetrievalRequestPayload,\n ActiveRun,\n SteerMessageIntent,\n CreatedSessionRunResponse,\n PlanningActionResponse,\n PlanningCycle,\n PlanningQuestionResponse,\n} from \"../api/queries/agentPrototype.types\";\nimport { uniqueFileExtensions } from \"../utils/clerkAnalytics\";\nimport { CLERK_ERROR_COPY, normalizeClerkErrorMessage, type ClerkErrorCopyKey } from \"../utils/clerkErrorCopy\";\nimport { clarifyingQuestionIsLocallyExpired, clarifyingQuestionUiDeadlineMs } from \"../utils/clerkClarifyingQuestion\";\nimport {\n canonicalizeModelConfig,\n canonicalizeOptionalModelConfig,\n preserveRunModelConfig,\n} from \"../components/agent_prototype/modelConfig\";\nimport { useOptionalCreditAgentSpeedBump } from \"../contexts/CreditAgentSpeedBumpContext\";\nimport { featureEnabled } from \"../utils/featureFlags\";\n\nexport interface DownloadFile {\n filename: string;\n pageCount?: number;\n sizeBytes?: number;\n displayFileSize?: boolean;\n url: string;\n}\n\ntype DownloadFilePayload = {\n filename: string;\n size_bytes?: number;\n sizeBytes?: number;\n page_count?: number;\n pageCount?: number;\n url?: string;\n download_url?: string;\n};\n\nexport interface RestoredMessageDraft {\n id: string;\n sessionToken: string;\n text: string;\n files: AttachedFile[];\n}\n\nexport interface ChatMessage {\n createdAt?: string;\n deliveredAt?: string;\n steerRequestedAt?: string;\n steerRunId?: string;\n isSteerSelected?: boolean;\n /** Presentation only; a steered message may still be pending delivery. */\n isSteerAccepted?: boolean;\n /** Presentation only while conversation Stop is being reconciled. */\n isStopAccepted?: boolean;\n canFork?: boolean;\n queueState?: \"pending\" | \"consumed\" | \"cancelled\";\n queuedMessageId?: number;\n clientRequestId?: string;\n isSegmentComplete?: boolean;\n completedWorkLabel?: string;\n id: string;\n role: \"user\" | \"assistant\";\n serverMessageId?: number;\n runId?: string;\n retryableRunId?: string;\n content: string;\n thinking: string[];\n thinkingSinceLastTool: string;\n toolCalls: ToolCallRecord[];\n toolResults: ToolResultRecord[];\n citations: CitationData[];\n files: FileMetadata[];\n downloadFiles: DownloadFile[];\n downloadSelectionExplicit?: boolean;\n downloadLoadState?: \"loading\" | \"error\" | \"retrying\";\n metadata?: Record | null;\n tokenUsage?: TokenUsage;\n clarifyingQuestion?: ClarifyingQuestion;\n clarifyingQuestionId?: string;\n clarifyingMessageRole?: \"question\" | \"answer\";\n isAwaitingUserInput?: boolean;\n isStreaming?: boolean;\n isError?: boolean;\n isTerminalError?: boolean;\n errorMessage?: string;\n isDisplayOnly?: boolean;\n isHistoricalPage?: boolean;\n feedback?: { rating: boolean } | null;\n}\n\nfunction createDisplayMessage(id: string, role: \"user\" | \"assistant\", content: string): ChatMessage {\n return {\n id,\n role,\n content,\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n downloadSelectionExplicit: true,\n isDisplayOnly: true,\n };\n}\n\nfunction safeDirectDownloadUrl(value?: string): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed;\n if (/^\\/(?!\\/)/.test(trimmed)) return trimmed;\n return undefined;\n}\n\nfunction downloadFileUrl(sessionToken: string, file: DownloadFilePayload): string {\n const directUrl = safeDirectDownloadUrl(file.url) ?? safeDirectDownloadUrl(file.download_url);\n if (directUrl) return directUrl;\n return `/api/agent-prototype/sessions/${sessionToken}/files/${encodeURIComponent(file.filename)}`;\n}\n\nfunction mapDownloadFile(sessionToken: string, file: DownloadFilePayload): DownloadFile {\n return {\n filename: file.filename,\n pageCount: file.page_count ?? file.pageCount,\n sizeBytes: file.size_bytes ?? file.sizeBytes,\n displayFileSize: (file.page_count ?? file.pageCount) ? false : undefined,\n url: downloadFileUrl(sessionToken, file),\n };\n}\n\nfunction insertBeforeStreamingOrAppend(messages: ChatMessage[], ...newMsgs: ChatMessage[]): ChatMessage[] {\n const result = [...messages];\n const streamingIdx = result.findIndex((m) => m.isStreaming);\n if (streamingIdx >= 0) {\n result.splice(streamingIdx, 0, ...newMsgs);\n } else {\n result.push(...newMsgs);\n }\n return result;\n}\n\ninterface SessionState {\n freshEmptySession?: boolean;\n branchOrigin?: SessionWithMessages[\"branch_origin\"];\n queueDispatch?: SessionWithMessages[\"queue_dispatch\"];\n serverActiveRun?: ActiveRun | null;\n latestRun?: SessionWithMessages[\"latest_run\"];\n sessionId: number | null;\n token: string | null;\n title: string | null;\n status: \"idle\" | \"creating\" | \"active\" | \"streaming\" | \"error\";\n messages: ChatMessage[];\n hasMoreMessages: boolean;\n nextMessageCursor: string | null;\n oldestServerMessageId: number | null;\n error: string | null;\n pendingClarifyingQuestion: ClarifyingQuestion | null;\n docketConnectRetrievalRequest: DocketConnectRetrievalRequestPayload | null;\n activeTranscript: ActiveTranscriptContext | null;\n activeModelConfig: ModelConfig | null;\n readOnly: boolean;\n clientMatterCode: string | null;\n}\n\ninterface ActiveRunTracker {\n token: string;\n runId: string;\n assistantId: string;\n retrySourceRunId?: string;\n lastEventId: number;\n docketSnapshotEventId: number;\n docketLiveEventId: number;\n lastEventAt: number;\n reconnectAttempts: number;\n terminated: boolean;\n cancelledByUser: boolean;\n shouldHydrateOnStreamComplete?: boolean;\n boundaryReceived: boolean;\n patientPollStartedAt: number | null;\n followUpPollingActive: boolean;\n}\n\ninterface PendingTextDeltaFrame {\n id: number | null;\n}\n\ntype TerminalKind = \"done\" | \"cancelled\" | \"fatal_retryable\" | \"fatal_non_retryable\" | \"recovery_exhausted\";\ntype ClarifyingTimeoutSource = \"local_deadline\" | \"server_event\" | \"stale_ack\";\n\ninterface PendingTerminalHydration {\n token: string;\n runId: string;\n assistantId: string;\n retrySourceRunId?: string;\n terminalKind: TerminalKind;\n generation: number;\n hydrationExhausted?: boolean;\n pendingTextDelta?: string;\n}\n\ninterface HydrateSessionOptions {\n preserveError?: boolean;\n preserveStreaming?: boolean;\n preserveOlderPages?: boolean;\n preserveClarifyingDisplayMessages?: ChatMessage[];\n allowTokenMismatch?: boolean;\n hydrationIsCurrent?: () => boolean;\n pendingTerminalHydration?: PendingTerminalHydration | null;\n pollingActiveRunTail?: Pick | null;\n requireActiveRunMatch?: boolean;\n}\n\ninterface LoadSessionRollbackSnapshot {\n state: SessionState;\n sessionIdRefValue: number | null;\n tokenRefValue: string | null;\n activeRun: ActiveRunTracker | null;\n pendingTerminalHydration: PendingTerminalHydration | null;\n answeredClarifyingQuestionIds: Set;\n resolvedClarifyingQuestionIds: Set;\n acknowledgingClarifyingQuestionIds: Set;\n viewedClarifyingQuestionIds: Set;\n timedOutClarifyingQuestionIds: Set;\n}\n\ninterface PendingSessionLoad {\n generation: number;\n rollbackSnapshot: LoadSessionRollbackSnapshot;\n}\n\ninterface DocketConnectApprovalOperationContext {\n operationId: number;\n generation: number;\n token: string;\n retrievalRequestId: string;\n approvalRequestId: string;\n authorizationVersion: number | undefined;\n requestStatus: string;\n activeSurface: \"limit_approval\" | \"retrieval_approval\";\n}\n\ntype ClerkPromptSource = \"typed\" | \"example_prompt\" | \"transcript_bootstrap\";\nconst MAX_RECONNECT_ATTEMPTS = 10;\nconst SILENT_RECONNECT_THRESHOLD = 5;\nconst RECONNECT_BANNER_DELAY_MS = 8_000;\nconst RECOVERY_EXHAUSTED_MESSAGE = CLERK_ERROR_COPY.genericRetry;\nconst RETRYABLE_RUN_ERROR_CODES = new Set([\n \"stream_terminated\",\n \"shutdown_interrupted\",\n \"deployment_interrupted\",\n \"worker_interrupted\",\n \"missing_tool_output\",\n]);\nconst INTERRUPT_ERROR_CODES = new Set([\"shutdown_interrupted\", \"deployment_interrupted\", \"worker_interrupted\"]);\nconst FOLLOW_UP_POLL_INTERVAL_MS = 3_000;\nconst FOLLOW_UP_POLL_MAX_MS = 120_000;\nconst PATIENT_POLL_INTERVAL_MS = 5_000;\nconst PATIENT_POLL_MAX_MS = 300_000; // 5 min hard timeout from first transport error\nconst ACTIVE_DOCKET_CONNECT_RETRIEVAL_STATUSES = new Set([\"queued\", \"running\", \"retrying\", \"partial\"]);\nconst DOCKET_CONNECT_RETRIEVAL_POLL_INTERVAL_MS = 2_000;\nconst DOCKET_CONNECT_RETRIEVAL_POLL_MAX_BACKOFF_MS = 8_000;\nconst DOCKET_CONNECT_RETRIEVAL_POLL_MAX_FAILURES = 3;\nconst DOCKET_CONNECT_RETRIEVAL_POLL_MAX_MS = 120_000;\nconst DOCKET_CONNECT_RETRIEVAL_POLL_SLOW_INTERVAL_MS = 30_000;\nconst PLANNING_TURN_STALE_AFTER_MS = 55_000;\n\nfunction answeredClarifyingQuestionIdsFromMessages(messages: SessionWithMessages[\"messages\"]): Set {\n return new Set(\n messages.flatMap((msg) => {\n const metadata = msg.metadata as Record | null;\n if (!metadata?.display_only) return [];\n if (metadata.clarifying_message_role !== \"answer\") return [];\n const deliveryStatus = metadata.clarifying_answer_delivery_status;\n if (deliveryStatus && deliveryStatus !== \"accepted\") return [];\n return typeof metadata.clarifying_question_id === \"string\" ? [metadata.clarifying_question_id] : [];\n }),\n );\n}\n\nfunction clerkErrorMessage(\n rawError: string | null | undefined,\n options: { code?: string | null; fallbackKey?: ClerkErrorCopyKey } = {},\n): string {\n return normalizeClerkErrorMessage(rawError, options);\n}\n\nfunction cloneClarifyingQuestion(question: ClarifyingQuestion | null | undefined): ClarifyingQuestion | null {\n if (!question) return null;\n\n return {\n ...question,\n options: question.options.map((option) => ({ ...option })),\n };\n}\n\nfunction cloneDocketConnectRetrievalRequest(\n request: DocketConnectRetrievalRequestPayload | null | undefined,\n): DocketConnectRetrievalRequestPayload | null {\n if (!request) return null;\n\n const cloneItem = (item: DocketConnectRetrievalRequestPayload[\"items\"][number]) => ({ ...item });\n return {\n ...request,\n costs: request.costs ? { ...request.costs } : undefined,\n items: request.items.map(cloneItem),\n reconciliation: {\n new_items: request.reconciliation.new_items.map(cloneItem),\n reused_items: request.reconciliation.reused_items.map(cloneItem),\n joined_items: request.reconciliation.joined_items.map(cloneItem),\n blocked_items: request.reconciliation.blocked_items.map(cloneItem),\n },\n current_approval: request.current_approval ? { ...request.current_approval } : request.current_approval,\n job: request.job ? { ...request.job } : request.job,\n };\n}\n\nfunction hydratedDocketConnectRetrievalRequest(\n session: Pick,\n): DocketConnectRetrievalRequestPayload | null {\n return cloneDocketConnectRetrievalRequest(session.active_docket_connect_retrieval_request);\n}\n\nfunction docketConnectRetrievalRequestFromError(error: unknown): DocketConnectRetrievalRequestPayload | null {\n if (typeof error !== \"object\" || error === null || !(\"retrievalRequest\" in error)) return null;\n return cloneDocketConnectRetrievalRequest(\n (error as { retrievalRequest?: DocketConnectRetrievalRequestPayload }).retrievalRequest,\n );\n}\n\nfunction upsertToolRecord(\n records: T[],\n record: T,\n): T[] {\n const index = record.toolCallId\n ? records.findIndex(\n (existing) =>\n existing.tool === record.tool &&\n existing.delegateId === record.delegateId &&\n existing.toolCallId === record.toolCallId,\n )\n : -1;\n return index < 0 ? [...records, record] : records.map((existing, i) => (i === index ? record : existing));\n}\n\nfunction cloneChatMessage(message: ChatMessage): ChatMessage {\n return {\n ...message,\n thinking: [...message.thinking],\n toolCalls: [...message.toolCalls],\n toolResults: [...message.toolResults],\n citations: [...message.citations],\n files: [...message.files],\n downloadFiles: message.downloadFiles.map((file) => ({ ...file })),\n metadata: message.metadata ? { ...message.metadata } : message.metadata,\n clarifyingQuestion: cloneClarifyingQuestion(message.clarifyingQuestion) || undefined,\n };\n}\n\nfunction shouldClearDocketConnectLimitNoticeOnSend(request: DocketConnectRetrievalRequestPayload | null): boolean {\n return request?.status === \"blocked_limit\" && request.state_reason === \"pacer_spend_limit_increases_exhausted\";\n}\n\nfunction cloneSessionStateValue(sessionState: SessionState): SessionState {\n return {\n ...sessionState,\n messages: sessionState.messages.map((message) => cloneChatMessage(message)),\n pendingClarifyingQuestion: cloneClarifyingQuestion(sessionState.pendingClarifyingQuestion),\n docketConnectRetrievalRequest: cloneDocketConnectRetrievalRequest(sessionState.docketConnectRetrievalRequest),\n activeTranscript: sessionState.activeTranscript ? { ...sessionState.activeTranscript } : null,\n activeModelConfig: sessionState.activeModelConfig ? { ...sessionState.activeModelConfig } : null,\n };\n}\n\nfunction cloneActiveRunTracker(tracker: ActiveRunTracker | null): ActiveRunTracker | null {\n return tracker ? { ...tracker } : null;\n}\n\nfunction clonePendingTerminalHydrationValue(\n pendingTerminalHydration: PendingTerminalHydration | null,\n): PendingTerminalHydration | null {\n return pendingTerminalHydration ? { ...pendingTerminalHydration } : null;\n}\n\nfunction freshestLoadedMessageId(\n loadedMessages: ChatMessage[],\n fallbackOldestMessageId: number | null | undefined,\n): number | null {\n return loadedMessages.reduce((oldest, message) => {\n const id = message.serverMessageId;\n if (typeof id !== \"number\") return oldest;\n return oldest === null ? id : Math.min(oldest, id);\n }, fallbackOldestMessageId || null);\n}\n\nfunction extractPendingTerminalTail(\n previousMessages: ChatMessage[],\n loadedMessages: ChatMessage[],\n pendingTerminalHydration?: PendingTerminalHydration | null,\n): ChatMessage[] {\n if (!pendingTerminalHydration) return [];\n if (loadedMessages.some((message) => message.runId === pendingTerminalHydration.runId)) {\n return [];\n }\n\n const assistantIndex = previousMessages.findIndex((message) => message.id === pendingTerminalHydration.assistantId);\n if (assistantIndex < 0) return [];\n\n const assistantMessage = previousMessages[assistantIndex];\n if (typeof assistantMessage.serverMessageId === \"number\") return [];\n\n // Fallback: if a loaded assistant message matches the pending terminal assistant's\n // content, the server persisted it but hasn't linked it to the run yet. Skip the\n // optimistic tail to avoid showing the response twice.\n if (\n !assistantMessage.runId &&\n assistantMessage.content &&\n loadedMessages.some((m) => m.role === \"assistant\" && !m.isDisplayOnly && m.content === assistantMessage.content)\n ) {\n return [];\n }\n\n const tail: ChatMessage[] = [];\n const previousUserMessage = assistantIndex > 0 ? previousMessages[assistantIndex - 1] : null;\n const latestLoadedUserMessage = [...loadedMessages]\n .reverse()\n .find((message) => message.role === \"user\" && !message.isDisplayOnly);\n\n if (\n previousUserMessage &&\n previousUserMessage.role === \"user\" &&\n !previousUserMessage.isDisplayOnly &&\n typeof previousUserMessage.serverMessageId !== \"number\" &&\n (!latestLoadedUserMessage || latestLoadedUserMessage.content !== previousUserMessage.content)\n ) {\n tail.push(cloneChatMessage(previousUserMessage));\n }\n\n tail.push(cloneChatMessage(assistantMessage));\n return tail;\n}\n\nfunction extractActiveRunPollingTail(\n previousMessages: ChatMessage[],\n loadedMessages: ChatMessage[],\n activeRun?: Pick | null,\n clearAwaitingUserInput = false,\n): ChatMessage[] {\n if (!activeRun) return [];\n\n const assistantIndex = previousMessages.findIndex((message) => message.id === activeRun.assistantId);\n if (assistantIndex < 0) return [];\n const assistantMessage = previousMessages[assistantIndex];\n const tail: ChatMessage[] = [];\n const previousUserMessage = assistantIndex > 0 ? previousMessages[assistantIndex - 1] : null;\n if (\n previousUserMessage?.role === \"user\" &&\n typeof previousUserMessage.serverMessageId !== \"number\" &&\n !loadedMessages.some((message) => message.role === \"user\" && message.content === previousUserMessage.content)\n ) {\n tail.push(cloneChatMessage(previousUserMessage));\n }\n const assistantTail = cloneChatMessage(assistantMessage);\n if (clearAwaitingUserInput) assistantTail.isAwaitingUserInput = false;\n tail.push(assistantTail);\n return tail;\n}\n\n// Segments are persisted at consumption, after the queued message was inserted.\n// Display their completed work before the explicit user-message boundary.\nfunction orderActivitySegments(messages: ChatMessage[]): ChatMessage[] {\n const delivered = messages.filter((message) => message.queueState !== \"pending\" && !!message.deliveredAt);\n delivered.sort(\n (left, right) =>\n Date.parse(left.deliveredAt!) - Date.parse(right.deliveredAt!) ||\n (left.serverMessageId || 0) - (right.serverMessageId || 0),\n );\n let deliveredIndex = 0;\n const ordered = messages.map((message) =>\n message.queueState !== \"pending\" && message.deliveredAt ? delivered[deliveredIndex++] : message,\n );\n for (const segment of messages) {\n const beforeId = segment.metadata?.before_message_id;\n if (!segment.isSegmentComplete || typeof beforeId !== \"number\") continue;\n const index = ordered.findIndex((message) => message.id === segment.id);\n const target = ordered.findIndex((message) => message.serverMessageId === beforeId);\n if (index < 0 || target < 0 || index === target - 1) continue;\n ordered.splice(index, 1);\n ordered.splice(\n ordered.findIndex((message) => message.serverMessageId === beforeId),\n 0,\n segment,\n );\n }\n // Unread input sits below all activity, both live and after a snapshot.\n // Stable partitioning retains submission order within the pending queue.\n const result = [\n ...ordered.filter((message) => message.queueState !== \"pending\"),\n ...ordered.filter((message) => message.queueState === \"pending\"),\n ];\n return result.every((message, index) => message === messages[index]) ? messages : result;\n}\n\nfunction sessionRunIsActive(session: SessionWithMessages): boolean {\n return !!session.active_run && [\"queued\", \"running\", \"waiting_for_input\"].includes(session.active_run.status);\n}\n\nfunction mergeHydratedMessages(\n previousState: SessionState,\n session: SessionWithMessages,\n loadedMessages: ChatMessage[],\n answeredClarifyingQuestionIds: Set,\n options?: Pick<\n HydrateSessionOptions,\n | \"preserveOlderPages\"\n | \"preserveClarifyingDisplayMessages\"\n | \"pendingTerminalHydration\"\n | \"pollingActiveRunTail\"\n | \"requireActiveRunMatch\"\n >,\n): Pick<\n SessionState,\n \"messages\" | \"hasMoreMessages\" | \"nextMessageCursor\" | \"oldestServerMessageId\" | \"pendingClarifyingQuestion\"\n> {\n const oldestLoadedMessageId = freshestLoadedMessageId(loadedMessages, session.oldest_message_id_in_page);\n const loadedMessageIds = new Set(loadedMessages.map((message) => message.id));\n const oldestDelivered = loadedMessages\n .filter((message) => message.deliveredAt && message.queueState !== \"pending\")\n .sort(\n (a, b) =>\n Date.parse(a.deliveredAt!) - Date.parse(b.deliveredAt!) || (a.serverMessageId || 0) - (b.serverMessageId || 0),\n )[0];\n const isBeforeLoadedWindow = (message: ChatMessage) => {\n if (message.queueState === \"pending\") return false;\n if (oldestDelivered?.deliveredAt && message.deliveredAt) {\n const timeDifference = Date.parse(message.deliveredAt) - Date.parse(oldestDelivered.deliveredAt);\n return (\n timeDifference < 0 ||\n (timeDifference === 0 && (message.serverMessageId || 0) < (oldestDelivered.serverMessageId || 0))\n );\n }\n return (\n typeof message.serverMessageId === \"number\" &&\n (oldestLoadedMessageId === null || message.serverMessageId < oldestLoadedMessageId)\n );\n };\n const preservedOlderMessages = options?.preserveOlderPages\n ? previousState.messages.filter(\n (message) => !loadedMessageIds.has(message.id) && (message.isHistoricalPage || isBeforeLoadedWindow(message)),\n )\n : [];\n const optimisticTerminalTail = options?.preserveOlderPages\n ? extractPendingTerminalTail(previousState.messages, loadedMessages, options?.pendingTerminalHydration)\n : [];\n const pollingActiveRunTail =\n options?.pollingActiveRunTail &&\n (!options.requireActiveRunMatch ||\n (sessionRunIsActive(session) && session.active_run?.run_id === options.pollingActiveRunTail.runId))\n ? options.pollingActiveRunTail\n : null;\n const pollingTail = extractActiveRunPollingTail(\n previousState.messages,\n loadedMessages,\n pollingActiveRunTail,\n !!pollingActiveRunTail && session.active_run?.pending_input_request == null,\n );\n const preservedClarifyingMessages = (options?.preserveClarifyingDisplayMessages || []).filter(\n (message) => !loadedMessageIds.has(message.id),\n );\n const hydratedMessages = pollingActiveRunTail\n ? loadedMessages.filter(\n (message) =>\n message.runId !== pollingActiveRunTail.runId || message.isSegmentComplete || message.role === \"user\",\n )\n : loadedMessages;\n const messages = [\n ...preservedOlderMessages,\n ...hydratedMessages,\n ...preservedClarifyingMessages,\n ...optimisticTerminalTail,\n ...pollingTail,\n ...previousState.messages.filter(\n (message) =>\n previousState.token === session.token &&\n message.queueState === \"pending\" &&\n !message.serverMessageId &&\n !loadedMessages.some((loaded) => loaded.clientRequestId === message.clientRequestId),\n ),\n ];\n\n return {\n messages: orderActivitySegments(messages),\n hasMoreMessages: preservedOlderMessages.length > 0 ? previousState.hasMoreMessages : !!session.has_more,\n nextMessageCursor:\n preservedOlderMessages.length > 0 ? previousState.nextMessageCursor : session.next_cursor || null,\n oldestServerMessageId:\n preservedOlderMessages.length > 0\n ? previousState.oldestServerMessageId\n : session.oldest_message_id_in_page || null,\n pendingClarifyingQuestion:\n previousState.pendingClarifyingQuestion &&\n !answeredClarifyingQuestionIds.has(previousState.pendingClarifyingQuestion.questionId)\n ? cloneClarifyingQuestion(previousState.pendingClarifyingQuestion)\n : null,\n };\n}\n\nexport interface PlanningPendingAction {\n kind: \"accept\" | \"decline\" | \"answer\" | \"revision\" | \"confirm\" | \"stop\";\n sessionToken: string;\n operationId: number;\n planToken?: string;\n interactionToken?: string;\n versionToken?: string;\n runToken?: string;\n clientRequestId?: string;\n}\n\nexport function useAgentPrototypeSession() {\n const [conversationDrafts] = useState(() => new ConversationDrafts());\n const [restoreDraft, setRestoreDraft] = useState();\n const [pendingMessageActionId, setPendingMessageActionId] = useState(null);\n const [pendingMessageActionType, setPendingMessageActionType] = useState<\"fork\" | \"steer\" | \"cancel\" | null>(null);\n const [pendingSteerAcceptance, setPendingSteerAcceptance] = useState<{ token: string; messageId: number } | null>(\n null,\n );\n const uncertainStopSessionsRef = useRef(new Set());\n const pendingStopRef = useRef<{ token: string; promise: Promise } | null>(null);\n const [pendingStopAcceptance, setPendingStopAcceptance] = useState<{\n token: string;\n generation: number;\n messageIds: Set;\n } | null>(null);\n const pendingCancellationsRef = useRef(\n new Map; suppress: boolean }>(),\n );\n const unresolvedDraftFilesRef = useRef(new WeakMap Promise>());\n const cancelRestorationsRef = useRef(new Map());\n useEffect(\n () =>\n conversationDrafts.subscribe(() => {\n cancelRestorationsRef.current.forEach((restoration, key) => {\n const draft = conversationDrafts.get(restoration.token);\n if (draft.text === \"\" && draft.files.length === 0) cancelRestorationsRef.current.delete(key);\n });\n }),\n [conversationDrafts],\n );\n const messageActionRef = useRef(null);\n const uncertainQueueRequestsRef = useRef(new Map());\n const presentedQueueCreditBlocksRef = useRef(new Set());\n const [queueCreditPresentationEpoch, setQueueCreditPresentationEpoch] = useState(0);\n const [state, setState] = useState({\n sessionId: null,\n token: null,\n title: null,\n status: \"idle\",\n messages: [],\n hasMoreMessages: false,\n nextMessageCursor: null,\n oldestServerMessageId: null,\n error: null,\n pendingClarifyingQuestion: null,\n docketConnectRetrievalRequest: null,\n activeTranscript: null,\n activeModelConfig: null,\n readOnly: false,\n clientMatterCode: null,\n });\n const stateRef = useRef(state);\n const [planningMode, setPlanningModeValue] = useState(false);\n const [planningModePending, setPlanningModePending] = useState(false);\n const modeRef = useRef({ token: null as string | null, value: false, revision: undefined as number | undefined });\n const modePendingRef = useRef(false);\n const modeUncertainRef = useRef(false);\n const modeOperationRef = useRef(0);\n const modeAdmissionRef = useRef(null);\n const pendingSubmissionsRef = useRef(new Set<{ generation: number; stopped: boolean }>());\n const queuedModeRef = useRef(null);\n const modeAdmissionIntentRef = useRef<{\n token: string | null;\n revision: number | undefined;\n next: boolean | null;\n } | null>(null);\n const [modeAdmissionPending, setModeAdmissionPending] = useState(false);\n const invalidateModeOperation = useCallback(() => {\n if (modePendingRef.current) {\n // If navigation fails, the restored conversation still needs a fresh read.\n modeUncertainRef.current = true;\n setPlanningModeValue(modeRef.current.value);\n }\n modeOperationRef.current += 1;\n modePendingRef.current = false;\n modeAdmissionRef.current = null;\n queuedModeRef.current = null;\n modeAdmissionIntentRef.current = null;\n setPlanningModePending(false);\n setModeAdmissionPending(false);\n }, []);\n const applyPlanningMode = useCallback((payload: PlanningModeState, token: string, force = false) => {\n if (typeof payload.planning_mode !== \"boolean\") return;\n if (!force && modePendingRef.current && modeRef.current.token === token) return;\n if (modeRef.current.token === token && (payload.planning_mode_revision ?? 0) < (modeRef.current.revision ?? 0))\n return;\n modeRef.current = { token, value: payload.planning_mode, revision: payload.planning_mode_revision ?? 0 };\n modeUncertainRef.current = false;\n setPlanningModeValue(queuedModeRef.current ?? payload.planning_mode);\n }, []);\n const [activePlan, setActivePlan] = useState(null);\n const [pendingAction, setPendingAction] = useState(null);\n const planningResponseRetryRef = useRef<{ key: string; id: string } | null>(null);\n const stopInFlightRef = useRef(false);\n const [pendingPlanning, setPendingPlanning] = useState(false);\n const [planningQuestionError, setPlanningQuestionError] = useState<{ code?: string; message: string } | null>(null);\n useEffect(() => {\n setPlanningQuestionError(null);\n }, [activePlan?.active_interaction_token]);\n const speedBump = useOptionalCreditAgentSpeedBump();\n\n const { startRunStream, cancelStream } = useAgentPrototypeStream();\n const messageIdCounter = useRef(0);\n const isMountedRef = useRef(true);\n const sessionIdRef = useRef(null);\n const tokenRef = useRef(null);\n const isCreatingRef = useRef(false);\n const planningActionsInFlightRef = useRef(new Set());\n const planningReconciliationRef = useRef<(() => void) | null>(null);\n const planningReconciliationPendingRef = useRef(false);\n const planningConflictErrorRef = useRef(null);\n const planningRefreshFailedRef = useRef(false);\n const planningActionIdRef = useRef(0);\n const planningActionGenerationRef = useRef(0);\n const planningCancelInFlightRef = useRef(null);\n const planningCancelIdRef = useRef(0);\n const activeRunRef = useRef(null);\n const pendingTerminalHydrationRef = useRef(null);\n const pendingDownloadLoadsRef = useRef(new Map());\n const downloadLoadsInFlightRef = useRef(new Set());\n const sessionViewGenerationRef = useRef(0);\n const pendingSessionLoadRef = useRef(null);\n const hydrationRequestSequenceRef = useRef(0);\n const inputMutationEpochRef = useRef(0);\n const pendingDeltaRef = useRef(\"\");\n const pendingDeltaGenerationRef = useRef(0);\n const pendingDeltaFrameRef = useRef(null);\n const recoveryTimeoutRef = useRef(null);\n const answeredClarifyingQuestionIdsRef = useRef>(new Set());\n const resolvedClarifyingQuestionIdsRef = useRef>(new Set());\n const acknowledgingClarifyingQuestionIdsRef = useRef>(new Set());\n const viewedClarifyingQuestionIdsRef = useRef>(new Set());\n const timedOutClarifyingQuestionIdsRef = useRef>(new Set());\n const docketConnectApprovalOperationIdRef = useRef(0);\n\n const setStateIfMounted = useCallback((updater: SessionState | ((prev: SessionState) => SessionState)) => {\n if (!isMountedRef.current) return;\n setState((prev) => {\n let updated =\n typeof updater === \"function\" ? (updater as (previousState: SessionState) => SessionState)(prev) : updater;\n const cancellation = updated.token ? pendingCancellationsRef.current.get(updated.token) : undefined;\n if (cancellation?.suppress)\n updated = {\n ...updated,\n messages: updated.messages.filter(\n (message) => message.serverMessageId !== cancellation.messageId || message.queueState !== \"pending\",\n ),\n };\n const orderedMessages =\n updated.messages === prev.messages ? updated.messages : orderActivitySegments(updated.messages);\n const next = orderedMessages === updated.messages ? updated : { ...updated, messages: orderedMessages };\n stateRef.current = next;\n return next;\n });\n }, []);\n\n useEffect(() => {\n isMountedRef.current = true;\n\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n const clearRecoveryTimeout = useCallback(() => {\n if (recoveryTimeoutRef.current !== null) {\n clearTimeout(recoveryTimeoutRef.current);\n recoveryTimeoutRef.current = null;\n }\n }, []);\n\n const expireClarifyingQuestionWithSource = useCallback(\n (\n questionId: string,\n source: ClarifyingTimeoutSource,\n options?: {\n runId?: string;\n assistantId?: string;\n expiresAtMs?: number;\n },\n ) => {\n const currentQuestion = stateRef.current.pendingClarifyingQuestion;\n const runId = options?.runId ?? currentQuestion?.runId;\n const expiresAtMs =\n options?.expiresAtMs ??\n (currentQuestion?.questionId === questionId && currentQuestion.runId === runId\n ? currentQuestion.expiresAtMs\n : undefined);\n\n answeredClarifyingQuestionIdsRef.current.add(questionId);\n acknowledgingClarifyingQuestionIdsRef.current.delete(questionId);\n\n if (!timedOutClarifyingQuestionIdsRef.current.has(questionId)) {\n timedOutClarifyingQuestionIdsRef.current.add(questionId);\n if (sessionIdRef.current) {\n void recordUserEvent({\n event_name: \"timeout_clerk_clarifying_question\",\n event_properties: {\n session_id: sessionIdRef.current,\n question_id: questionId,\n source,\n ...(typeof expiresAtMs === \"number\" ? { deadline_delta_ms: Date.now() - expiresAtMs } : {}),\n },\n });\n }\n }\n\n setStateIfMounted((prev) => {\n const matchesPendingQuestion =\n prev.pendingClarifyingQuestion?.questionId === questionId &&\n (runId === undefined || prev.pendingClarifyingQuestion.runId === runId);\n if (!matchesPendingQuestion) return prev;\n\n return {\n ...prev,\n error: null,\n pendingClarifyingQuestion: null,\n messages: prev.messages.map((message) =>\n options?.assistantId && message.id === options.assistantId\n ? { ...message, isAwaitingUserInput: false }\n : message,\n ),\n };\n });\n },\n [setStateIfMounted],\n );\n\n const expireClarifyingQuestion = useCallback(\n (questionId: string) => {\n const question = stateRef.current.pendingClarifyingQuestion;\n if (!question || question.questionId !== questionId || !clarifyingQuestionIsLocallyExpired(question)) {\n return;\n }\n\n const tracker = activeRunRef.current;\n expireClarifyingQuestionWithSource(questionId, \"local_deadline\", {\n runId: question.runId,\n assistantId: tracker?.runId === question.runId ? tracker.assistantId : undefined,\n expiresAtMs: question.expiresAtMs,\n });\n },\n [expireClarifyingQuestionWithSource],\n );\n\n useEffect(() => {\n const question = state.pendingClarifyingQuestion;\n const uiDeadlineMs = question ? clarifyingQuestionUiDeadlineMs(question) : null;\n if (!question || uiDeadlineMs === null) return;\n\n const reconcileExpiry = () => {\n const currentQuestion = stateRef.current.pendingClarifyingQuestion;\n if (\n !currentQuestion ||\n currentQuestion.runId !== question.runId ||\n currentQuestion.questionId !== question.questionId ||\n !clarifyingQuestionIsLocallyExpired(currentQuestion)\n ) {\n return;\n }\n\n const tracker = activeRunRef.current;\n expireClarifyingQuestionWithSource(question.questionId, \"local_deadline\", {\n runId: question.runId,\n assistantId: tracker?.runId === question.runId ? tracker.assistantId : undefined,\n expiresAtMs: currentQuestion.expiresAtMs,\n });\n };\n\n const timeoutId = window.setTimeout(reconcileExpiry, Math.max(0, uiDeadlineMs - Date.now()));\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"visible\") reconcileExpiry();\n };\n window.addEventListener(\"focus\", reconcileExpiry);\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n reconcileExpiry();\n\n return () => {\n window.clearTimeout(timeoutId);\n window.removeEventListener(\"focus\", reconcileExpiry);\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n };\n }, [expireClarifyingQuestionWithSource, state.pendingClarifyingQuestion]);\n\n const generateId = () => {\n messageIdCounter.current += 1;\n return `msg-${messageIdCounter.current}-${Date.now()}`;\n };\n\n const countPromptLines = (message: string) => message.split(/\\r\\n|\\r|\\n/).length;\n\n const previousUserMessageCount = (messages: ChatMessage[]) =>\n messages.filter((message) => message.role === \"user\" && !message.isDisplayOnly).length;\n\n const clearPendingTerminalHydration = useCallback(() => {\n pendingTerminalHydrationRef.current = null;\n }, []);\n\n const revokePendingTextDelta = useCallback((): string => {\n pendingDeltaGenerationRef.current += 1;\n const frame = pendingDeltaFrameRef.current;\n pendingDeltaFrameRef.current = null;\n if (frame?.id != null) {\n cancelAnimationFrame(frame.id);\n }\n const pendingDelta = pendingDeltaRef.current;\n pendingDeltaRef.current = \"\";\n return pendingDelta;\n }, []);\n\n const bumpSessionViewGeneration = useCallback(() => {\n revokePendingTextDelta();\n sessionViewGenerationRef.current += 1;\n pendingSessionLoadRef.current = null;\n pendingDownloadLoadsRef.current.clear();\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.map((message) =>\n message.downloadLoadState === \"loading\" || message.downloadLoadState === \"retrying\"\n ? { ...message, downloadLoadState: \"error\" }\n : message,\n ),\n }));\n setPendingPlanning(false);\n setPendingAction(null);\n stopInFlightRef.current = false;\n planningResponseRetryRef.current = null;\n setPlanningQuestionError(null);\n planningActionGenerationRef.current += 1;\n planningActionsInFlightRef.current.clear();\n planningConflictErrorRef.current = null;\n planningRefreshFailedRef.current = false;\n planningReconciliationPendingRef.current = false;\n planningCancelInFlightRef.current = null;\n clearPendingTerminalHydration();\n }, [clearPendingTerminalHydration, revokePendingTextDelta, setStateIfMounted]);\n\n const restoreRetryability = useCallback((messages: ChatMessage[], retrySourceRunId?: string): ChatMessage[] => {\n if (!retrySourceRunId) return messages;\n\n return messages.map((message) =>\n message.runId === retrySourceRunId ? { ...message, retryableRunId: retrySourceRunId } : message,\n );\n }, []);\n\n const applyTerminalFallback = useCallback(\n (terminal: PendingTerminalHydration) => {\n setStateIfMounted((prev) => {\n const messagesWithPendingDelta = terminal.pendingTextDelta\n ? prev.messages.map((message) =>\n message.id === terminal.assistantId\n ? { ...message, content: message.content + terminal.pendingTextDelta }\n : message,\n )\n : prev.messages;\n const clearedMessages = messagesWithPendingDelta.map((message) => ({\n ...message,\n retryableRunId: undefined,\n }));\n switch (terminal.terminalKind) {\n case \"done\":\n return {\n ...prev,\n status: terminal.hydrationExhausted ? \"error\" : \"active\",\n error: terminal.hydrationExhausted ? CLERK_ERROR_COPY.recoveryHydrationFailure : null,\n pendingClarifyingQuestion: null,\n messages: clearedMessages,\n };\n case \"cancelled\":\n return {\n ...prev,\n status: \"active\",\n error: null,\n pendingClarifyingQuestion: null,\n messages: restoreRetryability(\n clearedMessages.map((message) =>\n message.runId === terminal.runId || message.id === terminal.assistantId\n ? {\n ...message,\n isStreaming: false,\n isAwaitingUserInput: false,\n isError: false,\n isTerminalError: false,\n errorMessage: undefined,\n }\n : message,\n ),\n terminal.retrySourceRunId,\n ),\n };\n case \"fatal_non_retryable\":\n case \"recovery_exhausted\":\n return {\n ...prev,\n status: \"error\",\n error: prev.error || CLERK_ERROR_COPY.genericRetry,\n pendingClarifyingQuestion: null,\n messages: restoreRetryability(\n clearedMessages.map((message) =>\n message.runId === terminal.runId || message.id === terminal.assistantId\n ? {\n ...message,\n isStreaming: false,\n isAwaitingUserInput: false,\n isError: true,\n isTerminalError: true,\n errorMessage: message.errorMessage || CLERK_ERROR_COPY.genericRetry,\n content: message.content || message.errorMessage || CLERK_ERROR_COPY.genericRetry,\n }\n : message,\n ),\n terminal.retrySourceRunId,\n ),\n };\n case \"fatal_retryable\":\n return {\n ...prev,\n status: \"error\",\n error: prev.error || CLERK_ERROR_COPY.genericRetry,\n pendingClarifyingQuestion: null,\n messages: messagesWithPendingDelta.map((message) =>\n message.runId === terminal.runId || message.id === terminal.assistantId\n ? {\n ...message,\n isStreaming: false,\n isAwaitingUserInput: false,\n isError: true,\n isTerminalError: true,\n errorMessage: message.errorMessage || CLERK_ERROR_COPY.genericRetry,\n content: message.content || message.errorMessage || CLERK_ERROR_COPY.genericRetry,\n retryableRunId: terminal.runId,\n }\n : { ...message, retryableRunId: undefined },\n ),\n };\n default:\n return prev;\n }\n });\n },\n [restoreRetryability, setStateIfMounted],\n );\n\n const mapServerMessage = useCallback(\n (sessionToken: string, msg: SessionWithMessages[\"messages\"][number]): ChatMessage => {\n const role = msg.role as \"user\" | \"assistant\";\n const isDisplayOnly = !!(msg.metadata as Record | null)?.display_only || undefined;\n const metadata = msg.metadata as Record | null;\n const clarifyingQuestionId =\n typeof metadata?.clarifying_question_id === \"string\" ? metadata.clarifying_question_id : undefined;\n const clarifyingMessageRole =\n metadata?.clarifying_message_role === \"question\" || metadata?.clarifying_message_role === \"answer\"\n ? metadata.clarifying_message_role\n : undefined;\n const tokenUsage = msg.token_usage || undefined;\n const tokenUsageErrorMessage =\n typeof tokenUsage?.error?.message === \"string\"\n ? clerkErrorMessage(tokenUsage.error.message, {\n code: tokenUsage?.error?.code || null,\n fallbackKey: \"genericRetry\",\n })\n : \"\";\n const hasPersistedAssistantError = role === \"assistant\" && tokenUsageErrorMessage.trim().length > 0;\n const hasPersistedTerminalError = hasPersistedAssistantError && tokenUsage?.error?.fatal === true;\n const content = msg.content?.trim()\n ? msg.content\n : hasPersistedAssistantError\n ? tokenUsageErrorMessage\n : msg.content || \"\";\n\n return {\n id: `loaded-${msg.id}`,\n serverMessageId: msg.id,\n createdAt: msg.created_at,\n deliveredAt: msg.delivered_at || undefined,\n steerRequestedAt: msg.steer_requested_at || undefined,\n steerRunId: msg.steer_run_id || undefined,\n canFork: msg.can_fork,\n queueState: msg.queue_state,\n queuedMessageId: msg.queued_message_id,\n clientRequestId: msg.client_request_id,\n isSegmentComplete: metadata?.is_segment_complete === true,\n completedWorkLabel:\n typeof metadata?.completed_work_label === \"string\" ? metadata.completed_work_label : undefined,\n role,\n runId: msg.run_id || undefined,\n retryableRunId: msg.retryable_run_id || undefined,\n content,\n thinking: msg.thinking ? msg.thinking.split(\"\\n\").filter(Boolean) : [],\n thinkingSinceLastTool: \"\",\n toolCalls: (msg.tool_calls || []).reduce(upsertToolRecord, []),\n toolResults: (msg.tool_results || []).reduce(upsertToolRecord, []),\n citations: msg.citations || [],\n files: msg.files || [],\n downloadFiles: (msg.download_files || []).map((f: DownloadFilePayload) => mapDownloadFile(sessionToken, f)),\n downloadSelectionExplicit: msg.download_selection_explicit === true,\n metadata: msg.metadata,\n tokenUsage,\n isAwaitingUserInput: false,\n isStreaming: false,\n isError: hasPersistedAssistantError || undefined,\n isTerminalError: hasPersistedTerminalError || undefined,\n errorMessage: hasPersistedAssistantError ? tokenUsageErrorMessage : undefined,\n isDisplayOnly,\n clarifyingQuestionId,\n clarifyingMessageRole,\n feedback: msg.feedback || null,\n };\n },\n [],\n );\n\n const snapshotCurrentSessionView = useCallback(\n (): LoadSessionRollbackSnapshot => ({\n state: cloneSessionStateValue(stateRef.current),\n sessionIdRefValue: sessionIdRef.current,\n tokenRefValue: tokenRef.current,\n activeRun: cloneActiveRunTracker(activeRunRef.current),\n pendingTerminalHydration: clonePendingTerminalHydrationValue(pendingTerminalHydrationRef.current),\n answeredClarifyingQuestionIds: new Set(answeredClarifyingQuestionIdsRef.current),\n resolvedClarifyingQuestionIds: new Set(resolvedClarifyingQuestionIdsRef.current),\n acknowledgingClarifyingQuestionIds: new Set(acknowledgingClarifyingQuestionIdsRef.current),\n viewedClarifyingQuestionIds: new Set(viewedClarifyingQuestionIdsRef.current),\n timedOutClarifyingQuestionIds: new Set(timedOutClarifyingQuestionIdsRef.current),\n }),\n [],\n );\n\n const hydrateSession = useCallback(\n async (token: string, options?: HydrateSessionOptions) => {\n const hydrationGeneration = sessionViewGenerationRef.current;\n const hydrationRequestSequence = ++hydrationRequestSequenceRef.current;\n const inputMutationEpoch = inputMutationEpochRef.current;\n const hydrationIsCurrent = options?.hydrationIsCurrent ?? (() => true);\n const session = await getSession(token);\n if (!hydrationIsCurrent()) return null;\n if (!isMountedRef.current) return null;\n if (sessionViewGenerationRef.current !== hydrationGeneration) return null;\n if (hydrationRequestSequenceRef.current !== hydrationRequestSequence) return null;\n if (inputMutationEpochRef.current !== inputMutationEpoch) return null;\n if (!options?.allowTokenMismatch && tokenRef.current && tokenRef.current !== token) return null;\n\n const hydratingCurrentSession = tokenRef.current === session.token;\n const loadedMessages: ChatMessage[] = session.messages\n .filter(\n (msg) => msg.queue_state !== \"cancelled\" && !(msg.metadata as Record | null)?.auto_resumed,\n )\n .map((msg) => mapServerMessage(session.token, msg));\n const answeredClarifyingQuestionIds = answeredClarifyingQuestionIdsFromMessages(session.messages);\n const pendingInput = session.active_run?.pending_input_request;\n const activeRunTracker = activeRunRef.current;\n const preserveNewerLiveDocketRequest =\n !!activeRunTracker &&\n activeRunTracker.runId === session.active_run?.run_id &&\n activeRunTracker.docketLiveEventId > session.active_run.last_event_seq;\n if (activeRunTracker && activeRunTracker.runId === session.active_run?.run_id) {\n activeRunTracker.docketSnapshotEventId = Math.max(\n activeRunTracker.docketSnapshotEventId,\n session.active_run.last_event_seq,\n );\n }\n sessionIdRef.current = session.session_id;\n tokenRef.current = session.token;\n applyPlanningMode(session, session.token);\n setActivePlan(session.active_plan?.active ? session.active_plan : null);\n if (options?.preserveOlderPages || hydratingCurrentSession) {\n answeredClarifyingQuestionIds.forEach((questionId) => {\n answeredClarifyingQuestionIdsRef.current.add(questionId);\n });\n } else {\n answeredClarifyingQuestionIdsRef.current = answeredClarifyingQuestionIds;\n }\n const resolvedClarifyingQuestionIds = new Set(answeredClarifyingQuestionIdsRef.current);\n const hydratedModelConfig = session.active_run?.model_config || session.model_config;\n const preserveActiveRunStreaming =\n !!options?.preserveStreaming && (!options.requireActiveRunMatch || sessionRunIsActive(session));\n setStateIfMounted((prev) => {\n if (!hydrationIsCurrent()) return prev;\n const mergedState = mergeHydratedMessages(prev, session, loadedMessages, resolvedClarifyingQuestionIds, {\n preserveOlderPages: options?.preserveOlderPages,\n preserveClarifyingDisplayMessages: options?.preserveClarifyingDisplayMessages,\n pendingTerminalHydration: options?.pendingTerminalHydration,\n pollingActiveRunTail: options?.pollingActiveRunTail,\n requireActiveRunMatch: options?.requireActiveRunMatch,\n });\n const isAwaitingUserInput =\n session.active_run?.status === \"waiting_for_input\" && !!session.active_run.pending_input_request;\n const hydratedMessages = options?.pollingActiveRunTail\n ? mergedState.messages.map((message) =>\n message.id === options.pollingActiveRunTail?.assistantId ? { ...message, isAwaitingUserInput } : message,\n )\n : mergedState.messages;\n\n return {\n ...prev,\n sessionId: session.session_id,\n token: session.token,\n queueDispatch: session.queue_dispatch || null,\n serverActiveRun: session.active_run || null,\n latestRun: session.latest_run || null,\n freshEmptySession: session.fresh_empty_session === true,\n title: session.title || null,\n branchOrigin: session.branch_origin || null,\n status: preserveActiveRunStreaming ? \"streaming\" : \"active\",\n messages: hydratedMessages,\n hasMoreMessages: mergedState.hasMoreMessages,\n nextMessageCursor: mergedState.nextMessageCursor,\n oldestServerMessageId: mergedState.oldestServerMessageId,\n error: options?.preserveError\n ? prev.error\n : session.queue_dispatch?.block_code &&\n session.queue_dispatch.block_code !== \"agent_conversation_speed_bump_required\"\n ? clerkErrorMessage(null, { code: session.queue_dispatch.block_code, fallbackKey: \"genericRetry\" })\n : null,\n activeTranscript: session.active_transcript || null,\n activeModelConfig: hydratedModelConfig\n ? preserveRunModelConfig(hydratedModelConfig)\n : preserveActiveRunStreaming\n ? prev.activeModelConfig\n : null,\n readOnly: !!session.read_only,\n clientMatterCode: session.client_matter_code || null,\n pendingClarifyingQuestion:\n pendingInput?.kind === \"clarification\" && session.active_run?.run_id\n ? {\n runId: session.active_run.run_id,\n questionId: pendingInput.input_request_id,\n question: pendingInput.prompt,\n options: pendingInput.choices.map((choice) => ({\n title: choice.label,\n })),\n durable: true,\n }\n : prev.pendingClarifyingQuestion?.durable\n ? null\n : mergedState.pendingClarifyingQuestion,\n docketConnectRetrievalRequest: preserveNewerLiveDocketRequest\n ? prev.docketConnectRetrievalRequest\n : hydratedDocketConnectRetrievalRequest(session),\n };\n });\n\n if (!hydrationIsCurrent()) return null;\n if (!session.read_only && session.active_run?.status === \"completed\" && session.active_run?.run_id) {\n void ackRun(session.token, session.active_run.run_id);\n }\n if (!session.read_only && featureEnabled(\"expandable_sidenav\")) {\n void markSessionRead(session.token)\n .then(() => queryClient.invalidateQueries({ queryKey: [\"agentPrototypeSessions\", \"infinite\", \"sidenav\"] }))\n .catch(() => undefined);\n }\n\n return session;\n },\n [mapServerMessage, setStateIfMounted],\n );\n\n useEffect(() => {\n const token = state.token;\n if (!token || state.status === \"creating\") return;\n\n const request = state.docketConnectRetrievalRequest;\n const shouldPollRequest = (candidate: DocketConnectRetrievalRequestPayload | null) =>\n !!candidate &&\n candidate.status !== \"outcome_unknown\" &&\n candidate.poll_required !== false &&\n (candidate.poll_required || ACTIVE_DOCKET_CONNECT_RETRIEVAL_STATUSES.has(candidate.status));\n if (!shouldPollRequest(request)) return;\n\n const generation = sessionViewGenerationRef.current;\n const startedAt = Date.now();\n let cancelled = false;\n let consecutiveFailures = 0;\n let timeoutId: number | null = null;\n\n const currentLoopIsActive = () =>\n !cancelled &&\n isMountedRef.current &&\n sessionViewGenerationRef.current === generation &&\n tokenRef.current === token &&\n stateRef.current.token === token &&\n stateRef.current.status !== \"creating\" &&\n shouldPollRequest(stateRef.current.docketConnectRetrievalRequest);\n\n const schedule = (delayMs: number) => {\n if (!currentLoopIsActive()) return;\n timeoutId = window.setTimeout(poll, delayMs);\n };\n\n const poll = async (): Promise => {\n timeoutId = null;\n if (!currentLoopIsActive()) return;\n\n try {\n const activeRun = activeRunRef.current;\n await hydrateSession(token, {\n preserveStreaming: stateRef.current.status === \"streaming\",\n preserveOlderPages: true,\n pollingActiveRunTail: activeRun ? { runId: activeRun.runId, assistantId: activeRun.assistantId } : null,\n });\n consecutiveFailures = 0;\n } catch {\n consecutiveFailures += 1;\n } finally {\n const shouldPollSlowly =\n Date.now() - startedAt >= DOCKET_CONNECT_RETRIEVAL_POLL_MAX_MS ||\n consecutiveFailures >= DOCKET_CONNECT_RETRIEVAL_POLL_MAX_FAILURES;\n const nextDelayMs = shouldPollSlowly\n ? DOCKET_CONNECT_RETRIEVAL_POLL_SLOW_INTERVAL_MS\n : Math.min(\n DOCKET_CONNECT_RETRIEVAL_POLL_INTERVAL_MS * 2 ** consecutiveFailures,\n DOCKET_CONNECT_RETRIEVAL_POLL_MAX_BACKOFF_MS,\n );\n schedule(nextDelayMs);\n }\n };\n\n schedule(DOCKET_CONNECT_RETRIEVAL_POLL_INTERVAL_MS);\n\n return () => {\n cancelled = true;\n if (timeoutId !== null) window.clearTimeout(timeoutId);\n };\n }, [\n hydrateSession,\n state.docketConnectRetrievalRequest?.poll_required,\n state.docketConnectRetrievalRequest?.retrieval_request_id,\n state.docketConnectRetrievalRequest?.status,\n state.status,\n state.token,\n ]);\n\n const loadCompletedResponse = useCallback(\n async (terminal: PendingTerminalHydration, manual = false): Promise => {\n if (downloadLoadsInFlightRef.current.has(terminal)) return;\n const isCurrent = () =>\n isMountedRef.current &&\n sessionViewGenerationRef.current === terminal.generation &&\n tokenRef.current === terminal.token &&\n pendingDownloadLoadsRef.current.get(terminal.assistantId) === terminal;\n if (!isCurrent()) return;\n\n const markLoadState = (downloadLoadState: ChatMessage[\"downloadLoadState\"]) => {\n if (!isCurrent()) return;\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.map((message) =>\n message.id === terminal.assistantId || message.runId === terminal.runId\n ? { ...message, runId: message.runId || terminal.runId, downloadLoadState }\n : message,\n ),\n }));\n };\n downloadLoadsInFlightRef.current.add(terminal);\n markLoadState(manual ? \"retrying\" : \"loading\");\n try {\n for (const delay of [0, 1000, 3000]) {\n if (delay) await new Promise((resolve) => window.setTimeout(resolve, delay));\n if (!isCurrent()) return;\n const activeTracker = activeRunRef.current;\n try {\n const session = await hydrateSession(terminal.token, {\n preserveOlderPages: true,\n pendingTerminalHydration: terminal,\n preserveStreaming: !!activeTracker && !activeTracker.terminated,\n pollingActiveRunTail: activeTracker\n ? { runId: activeTracker.runId, assistantId: activeTracker.assistantId }\n : null,\n hydrationIsCurrent: () =>\n isMountedRef.current &&\n sessionViewGenerationRef.current === terminal.generation &&\n tokenRef.current === terminal.token &&\n activeRunRef.current === activeTracker,\n });\n if (!isCurrent()) return;\n if (\n session?.messages.some((message) => message.role === \"assistant\" && message.run_id === terminal.runId)\n ) {\n pendingDownloadLoadsRef.current.delete(terminal.assistantId);\n return;\n }\n } catch {\n // Keep the completed answer visible while retrying its saved details.\n }\n }\n markLoadState(\"error\");\n } finally {\n downloadLoadsInFlightRef.current.delete(terminal);\n }\n },\n [hydrateSession, setStateIfMounted],\n );\n\n const retryDownloadLoad = useCallback(\n async (assistantId: string): Promise => {\n const message = stateRef.current.messages.find((entry) => entry.id === assistantId);\n let terminal =\n pendingDownloadLoadsRef.current.get(assistantId) ||\n Array.from(pendingDownloadLoadsRef.current.values()).find((entry) => entry.runId === message?.runId);\n if (!terminal && message?.downloadLoadState && message.runId && tokenRef.current) {\n terminal = {\n token: tokenRef.current,\n runId: message.runId,\n assistantId: message.id,\n terminalKind: \"done\",\n generation: sessionViewGenerationRef.current,\n };\n pendingDownloadLoadsRef.current.set(message.id, terminal);\n }\n if (terminal) await loadCompletedResponse(terminal, true);\n },\n [loadCompletedResponse],\n );\n\n const reconcilePendingTerminalHydration = useCallback(\n (runId: string, token: string): boolean => {\n const tracker = activeRunRef.current;\n const pendingTerminalHydration = pendingTerminalHydrationRef.current;\n if (pendingTerminalHydration?.runId !== runId) return false;\n\n clearPendingTerminalHydration();\n if (tracker && tracker.runId === runId) {\n activeRunRef.current = null;\n }\n if (\n pendingTerminalHydration.generation !== sessionViewGenerationRef.current ||\n tokenRef.current !== pendingTerminalHydration.token\n ) {\n return true;\n }\n\n if (pendingTerminalHydration.terminalKind === \"done\") {\n pendingDownloadLoadsRef.current.set(pendingTerminalHydration.assistantId, pendingTerminalHydration);\n void loadCompletedResponse(pendingTerminalHydration);\n return true;\n }\n\n void (async () => {\n try {\n const hydratedSession = await hydrateSession(token, {\n preserveOlderPages: true,\n pendingTerminalHydration,\n hydrationIsCurrent: () => !activeRunRef.current || activeRunRef.current.runId === runId,\n });\n if (!hydratedSession) return;\n } catch {\n if (!activeRunRef.current || activeRunRef.current.runId === runId)\n applyTerminalFallback(pendingTerminalHydration);\n }\n })();\n\n return true;\n },\n [applyTerminalFallback, clearPendingTerminalHydration, hydrateSession, loadCompletedResponse],\n );\n\n const beginRunStream = useCallback(\n (\n token: string,\n runId: string,\n assistantId: string,\n lastEventId = 0,\n retrySourceRunId?: string,\n docketSnapshotEventId = 0,\n ) => {\n const streamGeneration = sessionViewGenerationRef.current;\n const existingTracker = activeRunRef.current;\n const existingDocketSnapshotEventId =\n existingTracker?.runId === runId ? existingTracker.docketSnapshotEventId : 0;\n const existingDocketLiveEventId = existingTracker?.runId === runId ? existingTracker.docketLiveEventId : 0;\n clearRecoveryTimeout();\n clearPendingTerminalHydration();\n const streamTracker: ActiveRunTracker = {\n token,\n runId,\n assistantId,\n retrySourceRunId,\n lastEventId,\n docketSnapshotEventId: Math.max(existingDocketSnapshotEventId, docketSnapshotEventId),\n docketLiveEventId: existingDocketLiveEventId,\n lastEventAt: Date.now(),\n reconnectAttempts: 0,\n terminated: false,\n cancelledByUser: false,\n shouldHydrateOnStreamComplete: false,\n boundaryReceived: false,\n patientPollStartedAt: null,\n followUpPollingActive: false,\n };\n activeRunRef.current = streamTracker;\n if (featureEnabled(\"clerk_message_queue\"))\n setStateIfMounted((prev) => ({ ...prev, latestRun: { run_id: runId, status: \"running\" } }));\n\n const streamTrackerIsOwned = (tracker: ActiveRunTracker = streamTracker) =>\n isMountedRef.current &&\n sessionViewGenerationRef.current === streamGeneration &&\n tokenRef.current === token &&\n activeRunRef.current === tracker;\n const streamTrackerCanRecover = (tracker: ActiveRunTracker = streamTracker) =>\n streamTrackerIsOwned(tracker) && !tracker.terminated && !tracker.cancelledByUser;\n\n const markPendingTerminalHydration = (terminalKind: TerminalKind, pendingTextDelta = \"\"): void => {\n pendingTerminalHydrationRef.current = {\n token,\n runId,\n assistantId,\n retrySourceRunId,\n terminalKind,\n generation: sessionViewGenerationRef.current,\n ...(pendingTextDelta ? { pendingTextDelta } : {}),\n };\n };\n\n const staleStreamLifecycle = Symbol(\"stale_stream_lifecycle\");\n const retryWithBackoff = async (\n fn: () => Promise,\n maxAttempts: number,\n baseDelayMs: number,\n lifecycleIsCurrent: () => boolean = () => true,\n ): Promise => {\n let lastError: unknown;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (!isMountedRef.current || !lifecycleIsCurrent()) throw staleStreamLifecycle;\n try {\n const result = await fn();\n if (!lifecycleIsCurrent()) throw staleStreamLifecycle;\n return result;\n } catch (err) {\n if (err === staleStreamLifecycle || !lifecycleIsCurrent()) throw staleStreamLifecycle;\n lastError = err;\n if (attempt < maxAttempts - 1) {\n await new Promise((r) => setTimeout(r, baseDelayMs * (attempt + 1)));\n if (!lifecycleIsCurrent()) throw staleStreamLifecycle;\n }\n }\n }\n throw lastError;\n };\n\n // Poll for an auto-resumed follow-up run after an interrupt failure.\n // Used by both patient polling and normal recovery when the run fails\n // with an interruption error code (shutdown/deploy/worker interrupted).\n const startFollowUpPolling = (tracker: ActiveRunTracker) => {\n if (!streamTrackerCanRecover(tracker)) return;\n tracker.followUpPollingActive = true;\n const pollStart = Date.now();\n const poll = async (): Promise => {\n if (!streamTrackerCanRecover(tracker)) return;\n if (Date.now() - pollStart > FOLLOW_UP_POLL_MAX_MS) {\n const pendingTextDelta = revokePendingTextDelta();\n tracker.terminated = true;\n markPendingTerminalHydration(\"fatal_non_retryable\", pendingTextDelta);\n try {\n await retryWithBackoff(\n () =>\n hydrateSession(token, {\n hydrationIsCurrent: () => streamTrackerIsOwned(tracker),\n }),\n 3,\n 1000,\n () => streamTrackerIsOwned(tracker),\n );\n if (!streamTrackerIsOwned(tracker)) return;\n activeRunRef.current = null;\n } catch {\n if (!streamTrackerIsOwned(tracker)) return;\n activeRunRef.current = null;\n const terminal = pendingTerminalHydrationRef.current;\n if (terminal) {\n pendingTerminalHydrationRef.current = { ...terminal, hydrationExhausted: true };\n applyTerminalFallback(pendingTerminalHydrationRef.current);\n }\n }\n return;\n }\n try {\n const session = await getSession(token);\n if (!streamTrackerCanRecover(tracker)) return;\n if (session.active_run && session.active_run.run_id !== runId) {\n // Follow-up run found and still active \u2014 reconnect to its stream\n const newRun = session.active_run;\n if (!streamTrackerCanRecover(tracker)) return;\n beginRunStream(token, newRun.run_id, assistantId, 0, tracker.retrySourceRunId, newRun.last_event_seq);\n return;\n }\n if (!session.active_run && Date.now() - pollStart > FOLLOW_UP_POLL_INTERVAL_MS * 3) {\n // No active run after several polls \u2014 the follow-up run likely\n // already completed (or was never created). Hydrate the session\n // to pick up whatever the latest state is.\n const pendingTextDelta = revokePendingTextDelta();\n tracker.terminated = true;\n markPendingTerminalHydration(\"done\", pendingTextDelta);\n try {\n await retryWithBackoff(\n () =>\n hydrateSession(token, {\n hydrationIsCurrent: () => streamTrackerIsOwned(tracker),\n }),\n 3,\n 1000,\n () => streamTrackerIsOwned(tracker),\n );\n if (!streamTrackerIsOwned(tracker)) return;\n activeRunRef.current = null;\n } catch {\n if (!streamTrackerIsOwned(tracker)) return;\n activeRunRef.current = null;\n const terminal = pendingTerminalHydrationRef.current;\n if (terminal) {\n pendingTerminalHydrationRef.current = { ...terminal, hydrationExhausted: true };\n applyTerminalFallback(pendingTerminalHydrationRef.current);\n }\n }\n return;\n }\n } catch {\n if (!streamTrackerCanRecover(tracker)) return;\n // keep polling\n }\n if (!streamTrackerCanRecover(tracker)) return;\n recoveryTimeoutRef.current = window.setTimeout(poll, FOLLOW_UP_POLL_INTERVAL_MS);\n };\n if (!streamTrackerCanRecover(tracker)) return;\n recoveryTimeoutRef.current = window.setTimeout(poll, FOLLOW_UP_POLL_INTERVAL_MS);\n };\n\n const scheduleRecovery = (silent = false) => {\n const tracker = streamTracker;\n if (!streamTrackerCanRecover(tracker)) return;\n\n clearRecoveryTimeout();\n if (!silent) {\n tracker.reconnectAttempts += 1;\n }\n if (tracker.reconnectAttempts > MAX_RECONNECT_ATTEMPTS) {\n // Before giving up, check if the run is still \"running\" (server may be\n // rebooting during a deploy). If so, enter patient polling mode instead\n // of showing an error \u2014 poll getRunStatus every 5s until the run status\n // changes or the hard timeout (5 min from first error) expires.\n // Store the start time in the tracker so it persists across re-entries\n // (a reconnect attempt from patient poll can trigger another transport\n // error which re-enters scheduleRecovery \u2192 patient poll).\n if (!tracker.patientPollStartedAt) {\n tracker.patientPollStartedAt = Date.now();\n }\n const patientPoll = async (): Promise => {\n const t = tracker;\n if (!streamTrackerCanRecover(t)) return;\n\n if (Date.now() - (t.patientPollStartedAt ?? Date.now()) > PATIENT_POLL_MAX_MS) {\n // Hard timeout \u2014 give up\n const pendingTextDelta = revokePendingTextDelta();\n t.terminated = true;\n activeRunRef.current = null;\n markPendingTerminalHydration(\"recovery_exhausted\");\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"error\",\n error: RECOVERY_EXHAUSTED_MESSAGE,\n pendingClarifyingQuestion: null,\n messages: restoreRetryability(prev.messages, t.retrySourceRunId).map((m) =>\n m.id === assistantId\n ? {\n ...m,\n isStreaming: false,\n isAwaitingUserInput: false,\n isError: true,\n isTerminalError: true,\n errorMessage: RECOVERY_EXHAUSTED_MESSAGE,\n content: m.content + pendingTextDelta || RECOVERY_EXHAUSTED_MESSAGE,\n }\n : m,\n ),\n }));\n return;\n }\n\n try {\n const runStatus = await getRunStatus(token, runId);\n if (!streamTrackerCanRecover(t)) return;\n\n if (\n runStatus.status === \"queued\" ||\n runStatus.status === \"running\" ||\n runStatus.status === \"waiting_for_input\"\n ) {\n // Run still active on the server but we can't reach the agent.\n // Don't try to reconnect the stream (it'll fail and re-enter\n // scheduleRecovery). Just keep polling until the status changes.\n if (!streamTrackerCanRecover(t)) return;\n recoveryTimeoutRef.current = window.setTimeout(patientPoll, PATIENT_POLL_INTERVAL_MS);\n return;\n }\n\n // Run reached a terminal state \u2014 check for interrupt auto-resume\n if (\n runStatus.status === \"failed\" &&\n runStatus.error_code &&\n INTERRUPT_ERROR_CODES.has(runStatus.error_code)\n ) {\n startFollowUpPolling(t);\n return;\n }\n\n // Non-interrupt terminal state \u2014 hydrate and show result\n const terminalKind: TerminalKind =\n runStatus.status === \"completed\"\n ? \"done\"\n : runStatus.status === \"cancelled\"\n ? \"cancelled\"\n : \"fatal_non_retryable\";\n const pendingTextDelta = revokePendingTextDelta();\n t.terminated = true;\n markPendingTerminalHydration(terminalKind, pendingTextDelta);\n try {\n await retryWithBackoff(\n () =>\n hydrateSession(token, {\n hydrationIsCurrent: () => streamTrackerIsOwned(t),\n }),\n 3,\n 1000,\n () => streamTrackerIsOwned(t),\n );\n if (!streamTrackerIsOwned(t)) return;\n activeRunRef.current = null;\n } catch {\n if (!streamTrackerIsOwned(t)) return;\n activeRunRef.current = null;\n const terminal = pendingTerminalHydrationRef.current;\n if (terminal) {\n pendingTerminalHydrationRef.current = { ...terminal, hydrationExhausted: true };\n applyTerminalFallback(pendingTerminalHydrationRef.current);\n }\n }\n } catch {\n if (!streamTrackerCanRecover(t)) return;\n // getRunStatus failed (network down, Rails restarting) \u2014 keep polling\n recoveryTimeoutRef.current = window.setTimeout(patientPoll, PATIENT_POLL_INTERVAL_MS);\n return;\n }\n };\n\n // Show reconnecting banner and start patient polling\n setStateIfMounted((prev) =>\n prev.error === \"Reconnecting\\u2026\" ? prev : { ...prev, status: \"streaming\", error: \"Reconnecting\\u2026\" },\n );\n recoveryTimeoutRef.current = window.setTimeout(patientPoll, PATIENT_POLL_INTERVAL_MS);\n return;\n }\n\n const delayMs = silent ? 0 : Math.min(5000, tracker.reconnectAttempts * 500);\n if (!silent) {\n const msSinceLastEvent = Date.now() - tracker.lastEventAt;\n if (msSinceLastEvent > RECONNECT_BANNER_DELAY_MS && tracker.reconnectAttempts > SILENT_RECONNECT_THRESHOLD) {\n setStateIfMounted((prev) =>\n prev.error === \"Reconnecting\\u2026\"\n ? prev\n : { ...prev, status: \"streaming\", error: \"Reconnecting\\u2026\" },\n );\n }\n }\n\n recoveryTimeoutRef.current = window.setTimeout(async () => {\n recoveryTimeoutRef.current = null;\n const latest = tracker;\n if (!streamTrackerCanRecover(latest)) return;\n\n try {\n const runStatus = await retryWithBackoff(\n () => getRunStatus(token, runId),\n 3,\n 1000,\n () => streamTrackerCanRecover(latest),\n );\n if (!streamTrackerCanRecover(latest)) return;\n if (runStatus.status === \"queued\" || runStatus.status === \"running\") {\n if (!streamTrackerCanRecover(latest)) return;\n startRunStream(token, runId, callbacks, latest.lastEventId > 0 ? latest.lastEventId : undefined);\n return;\n }\n if (runStatus.status === \"waiting_for_input\") {\n if (!streamTrackerCanRecover(latest)) return;\n recoveryTimeoutRef.current = window.setTimeout(scheduleRecovery, PATIENT_POLL_INTERVAL_MS);\n return;\n }\n\n // If the run failed with an interruption code, poll for auto-resumed follow-up\n if (\n runStatus.status === \"failed\" &&\n runStatus.error_code &&\n INTERRUPT_ERROR_CODES.has(runStatus.error_code)\n ) {\n startFollowUpPolling(latest);\n return;\n }\n\n const terminalKind: TerminalKind =\n runStatus.status === \"completed\"\n ? \"done\"\n : runStatus.status === \"cancelled\"\n ? \"cancelled\"\n : \"fatal_non_retryable\";\n\n const pendingTextDelta = revokePendingTextDelta();\n latest.terminated = true;\n markPendingTerminalHydration(terminalKind, pendingTextDelta);\n try {\n await retryWithBackoff(\n () =>\n hydrateSession(token, {\n hydrationIsCurrent: () => streamTrackerIsOwned(latest),\n }),\n 3,\n 1000,\n () => streamTrackerIsOwned(latest),\n );\n if (!streamTrackerIsOwned(latest)) return;\n activeRunRef.current = null;\n } catch {\n if (!streamTrackerIsOwned(latest)) return;\n activeRunRef.current = null;\n const terminal = pendingTerminalHydrationRef.current;\n if (terminal) {\n pendingTerminalHydrationRef.current = { ...terminal, hydrationExhausted: true };\n applyTerminalFallback(pendingTerminalHydrationRef.current);\n }\n }\n } catch {\n if (!streamTrackerCanRecover(latest)) return;\n // getRunStatus failed after retries \u2014 let scheduleRecovery decide\n // whether to schedule another attempt or show the exhaustion error.\n scheduleRecovery();\n }\n }, delayMs);\n };\n\n const consumeBoundaryAndRecover = () => {\n const tracker = streamTracker;\n if (!streamTrackerCanRecover(tracker)) return;\n const silent = tracker?.boundaryReceived ?? false;\n if (tracker) tracker.boundaryReceived = false;\n scheduleRecovery(silent);\n };\n\n const consumedBoundaries = new Set();\n const callbacks: StreamCallbacks = {\n onMessageQueueUpdated: (message) => {\n if (!streamTrackerIsOwned()) return;\n inputMutationEpochRef.current += 1;\n const updated = mapServerMessage(token, message);\n setStateIfMounted((prev) => {\n const matches = (m: ChatMessage) =>\n m.serverMessageId === message.id ||\n (!!message.client_request_id && m.clientRequestId === message.client_request_id);\n if (message.queue_state === \"cancelled\")\n return { ...prev, messages: prev.messages.filter((m) => !matches(m)) };\n // Replay may carry a pending event already superseded in the snapshot.\n if (\n prev.messages.some((m) => matches(m) && m.queueState === \"consumed\") &&\n message.queue_state === \"pending\"\n )\n return prev;\n if (\n message.queue_state === \"consumed\" &&\n !prev.messages.some((m) => matches(m) && m.queueState === \"consumed\")\n ) {\n const messages = prev.messages.filter((m) => !matches(m));\n const activeIndex = messages.findIndex((m) => m.id === assistantId);\n messages.splice(activeIndex < 0 ? messages.length : activeIndex, 0, updated);\n return { ...prev, messages };\n }\n return {\n ...prev,\n messages: prev.messages.some(matches)\n ? prev.messages.map((m) =>\n matches(m)\n ? updated\n : message.steer_requested_at && m.steerRunId === message.steer_run_id\n ? { ...m, steerRequestedAt: undefined, steerRunId: undefined }\n : m,\n )\n : [\n ...prev.messages.map((m) =>\n message.steer_requested_at && m.steerRunId === message.steer_run_id\n ? { ...m, steerRequestedAt: undefined, steerRunId: undefined }\n : m,\n ),\n updated,\n ],\n };\n });\n },\n onMessageConsumed: (event) => {\n if (!streamTrackerIsOwned() || consumedBoundaries.has(event.boundary_id)) return;\n consumedBoundaries.add(event.boundary_id);\n // Reload replays from event zero to rebuild the active segment. Earlier\n // segments are already in the snapshot: discard only their replay tail.\n if (\n stateRef.current.messages.some((m) => m.metadata?.boundary_id === event.boundary_id && m.isSegmentComplete)\n ) {\n revokePendingTextDelta();\n const replayId = assistantId;\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.map((m) =>\n m.id === replayId\n ? { ...createDisplayMessage(replayId, \"assistant\", \"\"), runId, isStreaming: true }\n : m,\n ),\n }));\n return;\n }\n const completedId = assistantId;\n const bufferedText = pendingDeltaRef.current;\n revokePendingTextDelta();\n assistantId = `segment-${event.boundary_id}`;\n streamTracker.assistantId = assistantId;\n const nextAssistantId = assistantId;\n inputMutationEpochRef.current += 1;\n setStateIfMounted((prev) => ({\n ...prev,\n pendingClarifyingQuestion: null,\n messages: [\n ...prev.messages.map((m) =>\n m.id === completedId\n ? event.assistant_message\n ? mapServerMessage(token, event.assistant_message)\n : {\n ...m,\n content: m.content + bufferedText,\n isStreaming: false,\n isAwaitingUserInput: false,\n isSegmentComplete: true,\n serverMessageId: event.assistant_message_id || m.serverMessageId,\n createdAt: event.created_at || m.createdAt,\n }\n : m.serverMessageId === event.message_id ||\n (event.user_message?.client_request_id &&\n m.clientRequestId === event.user_message.client_request_id)\n ? event.user_message\n ? mapServerMessage(token, event.user_message)\n : { ...m, queueState: \"consumed\" as const }\n : m,\n ),\n ...(event.user_message &&\n !prev.messages.some(\n (m) =>\n m.serverMessageId === event.message_id ||\n (!!event.user_message?.client_request_id &&\n m.clientRequestId === event.user_message.client_request_id),\n )\n ? [mapServerMessage(token, event.user_message)]\n : []),\n { ...createDisplayMessage(nextAssistantId, \"assistant\", \"\"), runId, isStreaming: true },\n ],\n }));\n },\n onEventId: (eventId) => {\n if (!streamTrackerIsOwned()) return;\n const tracker = activeRunRef.current;\n if (!tracker || tracker.runId !== runId) return;\n tracker.lastEventId = eventId;\n tracker.lastEventAt = Date.now();\n tracker.reconnectAttempts = 0;\n },\n onTextDelta: (content) => {\n if (!streamTrackerIsOwned() || !streamTrackerCanRecover()) return;\n pendingDeltaRef.current += content;\n\n if (pendingDeltaFrameRef.current === null) {\n const deltaGeneration = pendingDeltaGenerationRef.current;\n const frame: PendingTextDeltaFrame = { id: null };\n pendingDeltaFrameRef.current = frame;\n frame.id = requestAnimationFrame(() => {\n if (\n pendingDeltaFrameRef.current !== frame ||\n pendingDeltaGenerationRef.current !== deltaGeneration ||\n !streamTrackerIsOwned() ||\n !streamTrackerCanRecover()\n ) {\n return;\n }\n\n pendingDeltaFrameRef.current = null;\n const buffered = pendingDeltaRef.current;\n pendingDeltaRef.current = \"\";\n\n if (!buffered) return;\n\n setStateIfMounted((prev) => {\n if (\n pendingDeltaGenerationRef.current !== deltaGeneration ||\n !streamTrackerIsOwned() ||\n !streamTrackerCanRecover()\n ) {\n return prev;\n }\n\n return {\n ...prev,\n status: \"streaming\",\n error: null,\n messages: prev.messages.map((m) =>\n m.id === assistantId ? { ...m, content: m.content + buffered } : m,\n ),\n };\n });\n });\n }\n },\n onTextReset: () => {\n if (!streamTrackerIsOwned()) return;\n revokePendingTextDelta();\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.map((m) => (m.id === assistantId ? { ...m, content: \"\" } : m)),\n }));\n },\n onThinking: (content) => {\n if (!streamTrackerIsOwned()) return;\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n error: null,\n messages: prev.messages.map((m) =>\n m.id === assistantId\n ? { ...m, thinking: [...m.thinking, content], thinkingSinceLastTool: m.thinkingSinceLastTool + content }\n : m,\n ),\n }));\n },\n onToolUse: (tool, input, delegateId, toolCallId) => {\n if (!streamTrackerIsOwned()) return;\n const shouldResetThinking = !tool.startsWith(\"delegate_\") && tool !== \"report_status\";\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n error: null,\n messages: prev.messages.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n toolCalls: upsertToolRecord(m.toolCalls, { tool, input, delegateId, toolCallId }),\n thinkingSinceLastTool: shouldResetThinking ? \"\" : m.thinkingSinceLastTool,\n }\n : m,\n ),\n }));\n },\n onToolResult: (tool, summary, delegateId, detail, toolCallId) => {\n if (!streamTrackerIsOwned()) return;\n const shouldResetThinking = !tool.startsWith(\"delegate_\") && tool !== \"report_status\";\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n error: null,\n messages: prev.messages.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n toolResults: upsertToolRecord(m.toolResults, { tool, summary, detail, delegateId, toolCallId }),\n thinkingSinceLastTool: shouldResetThinking ? \"\" : m.thinkingSinceLastTool,\n }\n : m,\n ),\n }));\n },\n onDocketConnectRetrievalRequest: (request) => {\n if (!streamTrackerIsOwned()) return;\n const tracker = activeRunRef.current;\n if (\n tracker?.runId === runId &&\n tracker.lastEventId > 0 &&\n tracker.lastEventId <= tracker.docketSnapshotEventId\n ) {\n return;\n }\n if (tracker?.runId === runId && tracker.lastEventId > 0) {\n tracker.docketLiveEventId = Math.max(tracker.docketLiveEventId, tracker.lastEventId);\n }\n setStateIfMounted((prev) => ({\n ...prev,\n docketConnectRetrievalRequest: cloneDocketConnectRetrievalRequest(request),\n }));\n },\n onError: (errorMsg, fatal, errorCode) => {\n if (!streamTrackerIsOwned()) return;\n\n // If the error is a deploy/worker interruption, don't show it \u2014 poll\n // for the auto-resumed follow-up run instead. StaleRunRepairer sends\n // this error code through the SSE stream when it finalizes an orphaned\n // run, and the auto-resume follow-up run may already be starting.\n const isInterrupt = Boolean(errorCode && INTERRUPT_ERROR_CODES.has(errorCode));\n const tracker = activeRunRef.current;\n if (isInterrupt && tracker && tracker.runId === runId && !tracker.terminated) {\n revokePendingTextDelta();\n setStateIfMounted((prev) =>\n prev.error === \"Reconnecting\\u2026\"\n ? prev\n : { ...prev, status: \"streaming\", error: \"Reconnecting\\u2026\" },\n );\n startFollowUpPolling(tracker);\n return;\n }\n\n const normalizedErrorMsg = clerkErrorMessage(errorMsg, {\n code:\n errorCode === \"cost_limit\" ||\n errorCode === \"monthly_usage_limit\" ||\n errorCode === \"monthly_usage_unavailable\"\n ? errorCode\n : undefined,\n fallbackKey: \"genericRetry\",\n });\n const isFatal = fatal !== false;\n const isRetryableError = Boolean(errorCode && RETRYABLE_RUN_ERROR_CODES.has(errorCode));\n const remainingDelta = revokePendingTextDelta();\n const retrySourceRunId = tracker && tracker.runId === runId ? tracker.retrySourceRunId : undefined;\n if (isFatal && tracker && tracker.runId === runId) {\n tracker.terminated = true;\n tracker.shouldHydrateOnStreamComplete = true;\n markPendingTerminalHydration(isRetryableError ? \"fatal_retryable\" : \"fatal_non_retryable\");\n }\n if (isFatal) {\n clearRecoveryTimeout();\n }\n setStateIfMounted((prev) => {\n const nextMessages = prev.messages.map((m) => {\n if (m.id !== assistantId) {\n return { ...m, retryableRunId: undefined };\n }\n const contentWithDelta = m.content || remainingDelta ? m.content + remainingDelta : \"\";\n const displayErrorMsg =\n errorCode === \"stream_terminated\" && contentWithDelta\n ? CLERK_ERROR_COPY.streamInterruptedWithContent\n : normalizedErrorMsg;\n return {\n ...m,\n isStreaming: isFatal ? false : m.isStreaming,\n isAwaitingUserInput: isFatal ? false : m.isAwaitingUserInput,\n isError: true,\n isTerminalError: isFatal || m.isTerminalError,\n retryableRunId: isFatal && isRetryableError ? runId : undefined,\n errorMessage: displayErrorMsg,\n content: contentWithDelta || normalizedErrorMsg || CLERK_ERROR_COPY.genericRetry,\n };\n });\n\n return {\n ...prev,\n status: isFatal ? \"error\" : prev.status,\n error: isFatal ? normalizedErrorMsg : prev.error,\n pendingClarifyingQuestion: isFatal ? null : prev.pendingClarifyingQuestion,\n messages:\n isFatal && !isRetryableError ? restoreRetryability(nextMessages, retrySourceRunId) : nextMessages,\n };\n });\n if (isFatal) {\n void ackRun(token, runId)\n .then(() =>\n queryClient.invalidateQueries({ queryKey: [\"agentPrototypeSessions\", \"infinite\", \"sidenav\"] }),\n )\n .catch(() => undefined);\n }\n },\n onDone: (usage, citations) => {\n if (!streamTrackerIsOwned()) return;\n // Don't interfere if follow-up polling is already handling recovery.\n // StaleRunRepairer sends \"error\" then \"done\" events \u2014 onError starts\n // follow-up polling, and this onDone fires immediately after. Without\n // this guard, clearRecoveryTimeout() would kill the polling.\n const trackerForDoneGuard = activeRunRef.current;\n if (trackerForDoneGuard?.followUpPollingActive) return;\n clearRecoveryTimeout();\n const remainingDelta = revokePendingTextDelta();\n const pendingTerminalHydration = pendingTerminalHydrationRef.current;\n const pendingFatalTerminalKind =\n pendingTerminalHydration?.runId === runId &&\n pendingTerminalHydration.token === token &&\n pendingTerminalHydration.assistantId === assistantId &&\n pendingTerminalHydration.generation === sessionViewGenerationRef.current &&\n (pendingTerminalHydration.terminalKind === \"fatal_retryable\" ||\n pendingTerminalHydration.terminalKind === \"fatal_non_retryable\")\n ? pendingTerminalHydration.terminalKind\n : null;\n\n const tracker = activeRunRef.current;\n if (tracker && tracker.runId === runId) {\n tracker.terminated = true;\n tracker.shouldHydrateOnStreamComplete = true;\n markPendingTerminalHydration(pendingFatalTerminalKind || \"done\");\n }\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: null,\n pendingClarifyingQuestion: null,\n messages: prev.messages.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n content: remainingDelta ? m.content + remainingDelta : m.content,\n isAwaitingUserInput: false,\n isStreaming: false,\n retryableRunId: pendingFatalTerminalKind ? m.retryableRunId : undefined,\n downloadSelectionExplicit: true,\n tokenUsage: usage,\n citations: citations || m.citations,\n }\n : {\n ...m,\n retryableRunId: pendingFatalTerminalKind ? m.retryableRunId : undefined,\n },\n ),\n }));\n void ackRun(token, runId);\n },\n onCancelled: () => {\n if (!streamTrackerIsOwned()) return;\n clearRecoveryTimeout();\n const remainingDelta = revokePendingTextDelta();\n\n const tracker = activeRunRef.current;\n const retrySourceRunId = tracker && tracker.runId === runId ? tracker.retrySourceRunId : undefined;\n if (tracker && tracker.runId === runId) {\n tracker.terminated = true;\n tracker.shouldHydrateOnStreamComplete = true;\n markPendingTerminalHydration(\"cancelled\");\n }\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: null,\n pendingClarifyingQuestion: null,\n messages: restoreRetryability(\n prev.messages.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n content: remainingDelta ? m.content + remainingDelta : m.content,\n isAwaitingUserInput: false,\n isStreaming: false,\n isError: false,\n isTerminalError: false,\n retryableRunId: undefined,\n errorMessage: undefined,\n }\n : {\n ...m,\n retryableRunId: undefined,\n },\n ),\n retrySourceRunId,\n ),\n }));\n },\n // File availability is research progress, not a delivery selection. The\n // terminal session hydration loads the agent's saved download selection.\n onFileReady: () => {},\n onPlanningOffer: (cycle) => {\n if (!streamTrackerCanRecover()) return;\n setActivePlan(cycle.active ? cycle : null);\n },\n onInputLifecycleChange: () => {\n if (!streamTrackerCanRecover()) return;\n void hydrateSession(token, {\n preserveStreaming: true,\n preserveOlderPages: true,\n pollingActiveRunTail: { runId, assistantId },\n hydrationIsCurrent: () => streamTrackerCanRecover(),\n });\n },\n onClarifyingQuestion: (questionId, question, options, answerTimeoutMs, details) => {\n if (!streamTrackerIsOwned()) return;\n if (\n answeredClarifyingQuestionIdsRef.current.has(questionId) ||\n timedOutClarifyingQuestionIdsRef.current.has(questionId)\n ) {\n return;\n }\n if (!viewedClarifyingQuestionIdsRef.current.has(questionId) && sessionIdRef.current) {\n viewedClarifyingQuestionIdsRef.current.add(questionId);\n void recordUserEvent({\n event_name: \"view_clerk_clarifying_question\",\n event_properties: {\n session_id: sessionIdRef.current,\n question_id: questionId,\n option_count: options.length,\n },\n });\n }\n setStateIfMounted((prev) => {\n const existingQuestion =\n prev.pendingClarifyingQuestion?.runId === runId &&\n prev.pendingClarifyingQuestion.questionId === questionId\n ? prev.pendingClarifyingQuestion\n : null;\n\n return {\n ...prev,\n pendingClarifyingQuestion: {\n runId,\n questionId,\n question,\n options,\n ...details,\n answerTimeoutMs:\n typeof answerTimeoutMs === \"number\" && answerTimeoutMs > 0\n ? answerTimeoutMs\n : existingQuestion?.answerTimeoutMs,\n expiresAtMs: existingQuestion?.expiresAtMs,\n },\n messages: prev.messages.map((m) => (m.id === assistantId ? { ...m, isAwaitingUserInput: true } : m)),\n };\n });\n\n if (!acknowledgingClarifyingQuestionIdsRef.current.has(questionId)) {\n acknowledgingClarifyingQuestionIdsRef.current.add(questionId);\n void (async () => {\n const acknowledgementStartedAt = Date.now();\n try {\n let result: {\n ok: boolean;\n reason?: \"not_waiting\";\n expires_at_ms?: number;\n } | null = null;\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n result = await apiAcknowledgeClarifyingQuestion(token, runId, questionId);\n break;\n } catch {\n if (attempt === 2) throw new Error(\"clarification acknowledgement failed\");\n await new Promise((resolve) => window.setTimeout(resolve, 250 * (attempt + 1)));\n }\n }\n\n if (\n !result ||\n !streamTrackerIsOwned() ||\n tokenRef.current !== token ||\n activeRunRef.current?.runId !== runId ||\n activeRunRef.current.terminated\n )\n return;\n\n if (result.ok === false) {\n if (answeredClarifyingQuestionIdsRef.current.has(questionId)) {\n acknowledgingClarifyingQuestionIdsRef.current.delete(questionId);\n return;\n }\n const pendingQuestion = stateRef.current.pendingClarifyingQuestion;\n if (\n pendingQuestion &&\n (pendingQuestion.runId !== runId || pendingQuestion.questionId !== questionId)\n ) {\n answeredClarifyingQuestionIdsRef.current.add(questionId);\n acknowledgingClarifyingQuestionIdsRef.current.delete(questionId);\n return;\n }\n expireClarifyingQuestionWithSource(questionId, \"stale_ack\", {\n runId,\n assistantId,\n });\n return;\n }\n\n const authoritativeDeadline =\n typeof result.expires_at_ms === \"number\" &&\n Number.isFinite(result.expires_at_ms) &&\n result.expires_at_ms > 0\n ? result.expires_at_ms\n : null;\n const fallbackDuration =\n typeof answerTimeoutMs === \"number\" && Number.isFinite(answerTimeoutMs) && answerTimeoutMs > 0\n ? answerTimeoutMs\n : null;\n const expiresAtMs =\n authoritativeDeadline ??\n (fallbackDuration === null ? null : acknowledgementStartedAt + fallbackDuration);\n if (expiresAtMs === null) return;\n\n setStateIfMounted((prev) => {\n const pendingQuestion = prev.pendingClarifyingQuestion;\n if (pendingQuestion?.runId !== runId || pendingQuestion.questionId !== questionId) {\n return prev;\n }\n\n return {\n ...prev,\n pendingClarifyingQuestion: {\n ...pendingQuestion,\n expiresAtMs: pendingQuestion.expiresAtMs ?? expiresAtMs,\n },\n };\n });\n } catch {\n // Display is intentionally independent of acknowledgement; an\n // immediate answer can still atomically claim the live waiter.\n acknowledgingClarifyingQuestionIdsRef.current.delete(questionId);\n }\n })();\n }\n },\n onClarifyingQuestionResolved: (questionId) => {\n if (!streamTrackerIsOwned() || tokenRef.current !== token || activeRunRef.current?.runId !== runId) return;\n\n resolvedClarifyingQuestionIdsRef.current.add(questionId);\n answeredClarifyingQuestionIdsRef.current.add(questionId);\n acknowledgingClarifyingQuestionIdsRef.current.delete(questionId);\n setStateIfMounted((prev) => {\n const matchesPendingQuestion =\n prev.pendingClarifyingQuestion?.runId === runId &&\n prev.pendingClarifyingQuestion.questionId === questionId;\n if (!matchesPendingQuestion) return prev;\n\n return {\n ...prev,\n error: prev.error === CLERK_ERROR_COPY.clarifyingAnswerUncertainDelivery ? null : prev.error,\n pendingClarifyingQuestion: null,\n messages: prev.messages.map((message) =>\n message.id === assistantId ? { ...message, isAwaitingUserInput: false } : message,\n ),\n };\n });\n },\n onClarifyingQuestionTimeout: (questionId) => {\n if (!streamTrackerIsOwned()) return;\n const pendingQuestion = stateRef.current.pendingClarifyingQuestion;\n expireClarifyingQuestionWithSource(questionId, \"server_event\", {\n runId,\n assistantId,\n expiresAtMs:\n pendingQuestion?.questionId === questionId && pendingQuestion.runId === runId\n ? pendingQuestion.expiresAtMs\n : undefined,\n });\n },\n onAssistantTextReset: () => {\n if (!streamTrackerIsOwned()) return;\n revokePendingTextDelta();\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.map((m) => (m.id === assistantId ? { ...m, content: \"\" } : m)),\n }));\n },\n onContentReset: () => {\n if (!streamTrackerIsOwned()) return;\n revokePendingTextDelta();\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n content: \"\",\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n downloadFiles: [],\n downloadSelectionExplicit: true,\n }\n : m,\n ),\n }));\n },\n onStreamBoundary: () => {\n if (!streamTrackerIsOwned()) return;\n const tracker = activeRunRef.current;\n if (tracker && tracker.runId === runId) {\n tracker.boundaryReceived = true;\n }\n },\n onTransportError: () => {\n if (!streamTrackerIsOwned()) return;\n if (reconcilePendingTerminalHydration(runId, token)) return;\n // Don't interfere if follow-up polling is already handling recovery\n const tracker = activeRunRef.current;\n if (tracker?.followUpPollingActive) return;\n consumeBoundaryAndRecover();\n },\n onStreamComplete: () => {\n if (!streamTrackerIsOwned()) return;\n if (reconcilePendingTerminalHydration(runId, token)) return;\n\n const tracker = activeRunRef.current;\n if (!tracker || tracker.runId !== runId) return;\n if (tracker.terminated || tracker.cancelledByUser) return;\n // Don't interfere if follow-up polling is already handling recovery\n if (tracker.followUpPollingActive) return;\n consumeBoundaryAndRecover();\n },\n };\n\n revokePendingTextDelta();\n if (!streamTrackerCanRecover()) return;\n startRunStream(token, runId, callbacks, lastEventId > 0 ? lastEventId : undefined);\n },\n [\n clearRecoveryTimeout,\n expireClarifyingQuestionWithSource,\n hydrateSession,\n mapServerMessage,\n reconcilePendingTerminalHydration,\n revokePendingTextDelta,\n restoreRetryability,\n setStateIfMounted,\n startRunStream,\n ],\n );\n\n const activateSavedMessageRun = useCallback(\n async (token: string, run: CreatedSessionRunResponse, isCurrent: () => boolean) => {\n if (!isCurrent()) return;\n const tracker = activeRunRef.current;\n if (![\"queued\", \"running\", \"waiting_for_input\"].includes(run.status)) {\n await hydrateSession(token, {\n preserveOlderPages: true,\n preserveStreaming: !!tracker && !tracker.terminated && !tracker.cancelledByUser,\n pollingActiveRunTail: tracker,\n requireActiveRunMatch: true,\n hydrationIsCurrent: isCurrent,\n });\n return;\n }\n if (tracker?.runId === run.run_id && !tracker.terminated && !tracker.cancelledByUser) return;\n if (tracker && !tracker.terminated && !tracker.cancelledByUser) {\n await hydrateSession(token, {\n preserveStreaming: true,\n preserveOlderPages: true,\n pollingActiveRunTail: tracker,\n requireActiveRunMatch: true,\n hydrationIsCurrent: () => isCurrent() && activeRunRef.current === tracker,\n });\n return;\n }\n const assistantId = `saved-run-${run.run_id}`;\n const assistant = { ...createDisplayMessage(assistantId, \"assistant\", \"\"), runId: run.run_id, isStreaming: true };\n const accepted = run.user_message ? mapServerMessage(token, run.user_message) : undefined;\n inputMutationEpochRef.current += 1;\n setStateIfMounted((prev) => {\n if (!isCurrent()) return prev;\n const messages = prev.messages.map((message) =>\n accepted && message.serverMessageId === accepted.serverMessageId ? accepted : message,\n );\n return {\n ...prev,\n status: \"streaming\",\n error: null,\n queueDispatch: run.queue_dispatch || null,\n messages: messages.some((message) => message.id === assistantId) ? messages : [...messages, assistant],\n };\n });\n beginRunStream(token, run.run_id, assistantId);\n },\n [beginRunStream, hydrateSession, mapServerMessage, setStateIfMounted],\n );\n\n // Queue advancement belongs to the server. Observe completion/dispatch and\n // attach the next run; this poll never sends a message or starts server work.\n const hasPendingMessages = state.messages.some((message) => message.queueState === \"pending\");\n const observedRunId = state.serverActiveRun?.run_id;\n useEffect(() => {\n if (\n !featureEnabled(\"clerk_message_queue\") ||\n !state.token ||\n state.readOnly ||\n state.status === \"streaming\" ||\n state.status === \"creating\"\n )\n return;\n if (\n pendingStopRef.current?.token === state.token ||\n state.queueDispatch?.paused ||\n (!hasPendingMessages && !state.serverActiveRun)\n )\n return;\n const token = state.token;\n const generation = sessionViewGenerationRef.current;\n let cancelled = false;\n let timer: ReturnType | undefined;\n const current = () =>\n !cancelled &&\n isMountedRef.current &&\n tokenRef.current === token &&\n sessionViewGenerationRef.current === generation &&\n !stateRef.current.readOnly;\n const poll = async () => {\n if (!current()) return;\n const tracker = activeRunRef.current;\n if (tracker && !tracker.terminated && !tracker.cancelledByUser) return;\n let attachedTracker: ActiveRunTracker | null = null;\n const snapshotIsCurrent = () =>\n current() &&\n (activeRunRef.current === tracker || (!!attachedTracker && activeRunRef.current === attachedTracker));\n try {\n const session = await hydrateSession(token, {\n preserveOlderPages: true,\n pendingTerminalHydration: pendingTerminalHydrationRef.current,\n hydrationIsCurrent: snapshotIsCurrent,\n });\n if (!current()) return;\n if (!session) {\n timer = setTimeout(poll, 2000);\n return;\n }\n if (!snapshotIsCurrent()) return;\n const run = session.active_run;\n if (run && [\"queued\", \"running\", \"waiting_for_input\"].includes(run.status)) {\n const assistant = {\n ...createDisplayMessage(generateId(), \"assistant\", \"\"),\n runId: run.run_id,\n isStreaming: true,\n isAwaitingUserInput: run.status === \"waiting_for_input\",\n };\n setStateIfMounted((prev) => ({ ...prev, status: \"streaming\", messages: [...prev.messages, assistant] }));\n beginRunStream(token, run.run_id, assistant.id, 0, run.retry_source_run_id || undefined, run.last_event_seq);\n attachedTracker = activeRunRef.current;\n return;\n }\n if (session.queue_dispatch?.paused || !session.messages.some((message) => message.queue_state === \"pending\"))\n return;\n } catch {\n /* A read failure leaves the durable queue untouched. */\n }\n if (current()) timer = setTimeout(poll, 2000);\n };\n timer = setTimeout(poll, 500);\n return () => {\n cancelled = true;\n if (timer) clearTimeout(timer);\n };\n }, [\n state.token,\n state.status,\n state.readOnly,\n state.queueDispatch?.paused,\n hasPendingMessages,\n observedRunId,\n beginRunStream,\n hydrateSession,\n setStateIfMounted,\n ]);\n\n const queueCreditAction = state.queueDispatch?.action;\n const presentQueueCreditRequirement = speedBump?.presentRequired;\n useEffect(() => {\n if (\n !featureEnabled(\"clerk_message_queue\") ||\n state.readOnly ||\n !state.token ||\n state.queueDispatch?.block_code !== \"agent_conversation_speed_bump_required\" ||\n !queueCreditAction ||\n !presentQueueCreditRequirement\n )\n return;\n const token = state.token;\n const generation = sessionViewGenerationRef.current;\n const blockKey = `${token}:${queueCreditAction.message_id}:${queueCreditAction.queue_generation}:${queueCreditAction.confirmation_token}`;\n if (presentedQueueCreditBlocksRef.current.has(blockKey)) return;\n presentedQueueCreditBlocksRef.current.add(blockKey);\n let cancelled = false;\n const current = () =>\n !cancelled &&\n isMountedRef.current &&\n tokenRef.current === token &&\n sessionViewGenerationRef.current === generation;\n void (async () => {\n try {\n const confirmation = await presentQueueCreditRequirement(\n {\n sessionToken: token,\n requestKind: \"message\",\n clientRequestId: queueCreditAction.client_request_id,\n clientMatterCode: queueCreditAction.client_matter_code,\n },\n {\n required: true,\n confirmationToken: queueCreditAction.confirmation_token,\n thresholdUsd: queueCreditAction.threshold_usd,\n warningLevelUsd: queueCreditAction.warning_level_usd,\n nextWarningLevelUsd: queueCreditAction.next_warning_level_usd,\n conversationUsageUsd: queueCreditAction.conversation_usage_usd,\n clientMatterCode: queueCreditAction.client_matter_code,\n },\n { recheckOnConfirm: false },\n );\n if (!current() || confirmation === null) return;\n const run = await resumeQueuedMessage(\n token,\n queueCreditAction.message_id,\n confirmation,\n queueCreditAction.queue_generation,\n );\n if (!current()) return;\n await activateSavedMessageRun(token, run, current);\n } catch (error) {\n if (current())\n setStateIfMounted((prev) => ({\n ...prev,\n error: clerkErrorMessage(error instanceof Error ? error.message : null, { fallbackKey: \"genericRetry\" }),\n }));\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [\n state.token,\n state.readOnly,\n state.queueDispatch?.block_code,\n queueCreditAction?.message_id,\n queueCreditAction?.queue_generation,\n queueCreditAction?.confirmation_token,\n queueCreditPresentationEpoch,\n presentQueueCreditRequirement,\n activateSavedMessageRun,\n setStateIfMounted,\n ]);\n\n const reconnectHydratedActiveRun = useCallback(\n (session: SessionWithMessages, preferredAssistantId?: string): boolean => {\n if (!sessionRunIsActive(session) || !session.active_run) return false;\n\n const run = session.active_run;\n const waitingForInput = run.status === \"waiting_for_input\" && !!run.pending_input_request;\n const tracker = activeRunRef.current;\n const preferredReusableAssistantId =\n preferredAssistantId &&\n stateRef.current.messages.some((message) => message.id === preferredAssistantId && message.role === \"assistant\")\n ? preferredAssistantId\n : null;\n const trackedReusableAssistantId =\n tracker?.runId === run.run_id &&\n stateRef.current.messages.some((message) => message.id === tracker.assistantId && message.role === \"assistant\")\n ? tracker.assistantId\n : null;\n const reusableAssistantId = preferredReusableAssistantId || trackedReusableAssistantId;\n const assistantId = reusableAssistantId || generateId();\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n error: null,\n docketConnectRetrievalRequest: hydratedDocketConnectRetrievalRequest(session),\n messages: reusableAssistantId\n ? prev.messages.map((message) =>\n message.id === reusableAssistantId\n ? {\n ...message,\n isStreaming: true,\n isAwaitingUserInput: waitingForInput,\n isError: false,\n errorMessage: undefined,\n }\n : message,\n )\n : [\n ...prev.messages,\n {\n id: assistantId,\n role: \"assistant\",\n content: \"\",\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n downloadSelectionExplicit: true,\n isAwaitingUserInput: waitingForInput,\n isStreaming: true,\n },\n ],\n }));\n beginRunStream(\n session.token,\n run.run_id,\n assistantId,\n tracker?.runId === run.run_id ? tracker.lastEventId : 0,\n tracker?.runId === run.run_id ? tracker.retrySourceRunId : run.retry_source_run_id || undefined,\n run.last_event_seq,\n );\n return true;\n },\n [beginRunStream, setStateIfMounted],\n );\n\n const resumeRunAfterDurableInput = useCallback(\n async (token: string, resolvedInputRequestId: string, preserveClarifyingDisplayMessages: ChatMessage[] = []) => {\n const generation = sessionViewGenerationRef.current;\n const activeRun = activeRunRef.current;\n const session = await hydrateSession(token, {\n preserveStreaming: true,\n preserveOlderPages: true,\n preserveClarifyingDisplayMessages,\n pollingActiveRunTail: activeRun ? { runId: activeRun.runId, assistantId: activeRun.assistantId } : null,\n requireActiveRunMatch: true,\n });\n if (\n !session ||\n !isMountedRef.current ||\n sessionViewGenerationRef.current !== generation ||\n tokenRef.current !== token\n ) {\n return;\n }\n\n if (!sessionRunIsActive(session) || !session.active_run) {\n if (activeRun && activeRunRef.current === activeRun) {\n activeRun.terminated = true;\n bumpSessionViewGeneration();\n clearRecoveryTimeout();\n cancelStream();\n activeRunRef.current = null;\n }\n return;\n }\n\n const run = session.active_run;\n const pendingInput = run.pending_input_request;\n if (pendingInput && pendingInput.input_request_id !== resolvedInputRequestId) {\n return;\n }\n\n const waitingForInput = run.status === \"waiting_for_input\" && !!pendingInput;\n const tracker = activeRunRef.current;\n const reusableAssistantId =\n tracker?.runId === run.run_id &&\n stateRef.current.messages.some((message) => message.id === tracker.assistantId && message.role === \"assistant\")\n ? tracker.assistantId\n : null;\n const assistantId = reusableAssistantId || generateId();\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n error: null,\n pendingClarifyingQuestion: null,\n docketConnectRetrievalRequest: hydratedDocketConnectRetrievalRequest(session),\n messages: reusableAssistantId\n ? prev.messages.map((message) =>\n message.id === reusableAssistantId\n ? {\n ...message,\n isStreaming: true,\n isAwaitingUserInput: waitingForInput,\n isError: false,\n isTerminalError: false,\n errorMessage: undefined,\n }\n : message,\n )\n : [\n ...prev.messages,\n {\n id: assistantId,\n role: \"assistant\",\n content: \"\",\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n downloadSelectionExplicit: true,\n isAwaitingUserInput: waitingForInput,\n isStreaming: true,\n },\n ],\n }));\n beginRunStream(\n token,\n run.run_id,\n assistantId,\n tracker?.runId === run.run_id ? tracker.lastEventId : 0,\n tracker?.runId === run.run_id ? tracker.retrySourceRunId : undefined,\n run.last_event_seq,\n );\n },\n [beginRunStream, bumpSessionViewGeneration, cancelStream, clearRecoveryTimeout, hydrateSession, setStateIfMounted],\n );\n\n const restoreSessionView = useCallback(\n (\n snapshot: LoadSessionRollbackSnapshot,\n options?: {\n error?: string | null;\n reconnectActiveRun?: boolean;\n },\n ) => {\n sessionIdRef.current = snapshot.sessionIdRefValue;\n tokenRef.current = snapshot.tokenRefValue;\n answeredClarifyingQuestionIdsRef.current = new Set(snapshot.answeredClarifyingQuestionIds);\n resolvedClarifyingQuestionIdsRef.current = new Set(snapshot.resolvedClarifyingQuestionIds);\n acknowledgingClarifyingQuestionIdsRef.current = new Set(snapshot.acknowledgingClarifyingQuestionIds);\n viewedClarifyingQuestionIdsRef.current = new Set(snapshot.viewedClarifyingQuestionIds);\n timedOutClarifyingQuestionIdsRef.current = new Set(snapshot.timedOutClarifyingQuestionIds);\n pendingTerminalHydrationRef.current = clonePendingTerminalHydrationValue(snapshot.pendingTerminalHydration);\n\n const restoredState = cloneSessionStateValue(snapshot.state);\n // Switching invalidated these download requests, so restored messages\n // must offer recovery instead of waiting for a request that no longer owns them.\n restoredState.messages = restoredState.messages.map((message) =>\n message.downloadLoadState === \"loading\" || message.downloadLoadState === \"retrying\"\n ? { ...message, downloadLoadState: \"error\" }\n : message,\n );\n if (options?.error !== undefined) {\n restoredState.error = options.error;\n }\n setStateIfMounted(restoredState);\n\n if (options?.reconnectActiveRun && snapshot.activeRun) {\n activeRunRef.current = null;\n beginRunStream(\n snapshot.activeRun.token,\n snapshot.activeRun.runId,\n snapshot.activeRun.assistantId,\n snapshot.activeRun.lastEventId,\n snapshot.activeRun.retrySourceRunId,\n snapshot.activeRun.docketSnapshotEventId,\n );\n return;\n }\n\n activeRunRef.current = cloneActiveRunTracker(snapshot.activeRun);\n },\n [beginRunStream, setStateIfMounted],\n );\n\n const setPlanningMode = useCallback(\n async (next: boolean, ownedAdmission?: number) => {\n if (stateRef.current.readOnly || modePendingRef.current) return false;\n if (modeAdmissionRef.current !== null && modeAdmissionRef.current !== ownedAdmission) {\n queuedModeRef.current = next;\n if (modeAdmissionIntentRef.current) modeAdmissionIntentRef.current.next = next;\n setPlanningModeValue(next);\n return true;\n }\n const token = tokenRef.current;\n const previous = { ...modeRef.current };\n if (!token) {\n modeRef.current = { token: null, value: next, revision: undefined };\n setPlanningModeValue(next);\n return true;\n }\n const operation = ownedAdmission ?? ++modeOperationRef.current;\n const isCurrent = () =>\n isMountedRef.current && modeOperationRef.current === operation && tokenRef.current === token;\n modePendingRef.current = true;\n setPlanningModePending(true);\n setPlanningModeValue(next);\n try {\n const result = await updatePlanningMode(token, next, previous.revision ?? 0);\n if (!isCurrent()) return false;\n applyPlanningMode(result, token, true);\n return true;\n } catch (error) {\n if (!isCurrent()) return false;\n if (error instanceof PlanningModeConflictError) {\n applyPlanningMode(error.mode, token, true);\n } else {\n modeUncertainRef.current = true;\n setPlanningModeValue(previous.value);\n try {\n const session = await getSession(token);\n if (isCurrent()) applyPlanningMode(session, token, true);\n } catch {\n /* Sending stays blocked until a successful authoritative read. */\n }\n }\n if (!isCurrent()) return false;\n setStateIfMounted((prev) => ({\n ...prev,\n error: \"Could not confirm the mode change. Check the selected mode before sending again.\",\n }));\n return false;\n } finally {\n if (modeOperationRef.current === operation) {\n modePendingRef.current = false;\n if (isMountedRef.current) setPlanningModePending(false);\n }\n }\n },\n [applyPlanningMode, setStateIfMounted],\n );\n\n const releaseStoppedModeAdmission = useCallback(async () => {\n if (modeAdmissionRef.current === null) return;\n const nextMode = queuedModeRef.current;\n // Retire this intent before releasing admission: the original HTTP request\n // may finish later, after a new send has acquired its own admission.\n if (modeAdmissionIntentRef.current) modeAdmissionIntentRef.current.next = null;\n modeAdmissionRef.current = null;\n modeAdmissionIntentRef.current = null;\n queuedModeRef.current = null;\n setModeAdmissionPending(false);\n if (nextMode !== null) await setPlanningMode(nextMode);\n }, [setPlanningMode]);\n\n const sendMessage = useCallback(\n async (\n message: string,\n files?: AttachedFile[],\n modelConfig?: ModelConfig,\n activeTranscript?: ActiveTranscriptReference,\n promptSource?: \"typed\" | \"example_prompt\",\n creditRequest?: { clientRequestId: string; clientMatterCode: string },\n requestedPlanningMode = false,\n nextStepSelection?: NextStepSelection,\n nextStepContext?: NextStepSendContext,\n ) => {\n const stop = pendingStopRef.current;\n if (stop?.token === tokenRef.current) {\n const generation = sessionViewGenerationRef.current;\n if (\n !(await stop.promise) ||\n !isMountedRef.current ||\n tokenRef.current !== stop.token ||\n sessionViewGenerationRef.current !== generation\n )\n return false;\n }\n let reconciledStopSession: SessionWithMessages | null = null;\n if (tokenRef.current && uncertainStopSessionsRef.current.has(tokenRef.current)) {\n const token = tokenRef.current;\n const generation = sessionViewGenerationRef.current;\n const isCurrent = () =>\n isMountedRef.current && tokenRef.current === token && sessionViewGenerationRef.current === generation;\n const session = await hydrateSession(token, { preserveOlderPages: true, hydrationIsCurrent: isCurrent }).catch(\n () => null,\n );\n if (!session || !isCurrent()) return false;\n uncertainStopSessionsRef.current.delete(token);\n reconciledStopSession = session;\n if (sessionRunIsActive(session)) reconnectHydratedActiveRun(session);\n else {\n if (activeRunRef.current) activeRunRef.current.cancelledByUser = true;\n clearRecoveryTimeout();\n cancelStream();\n activeRunRef.current = null;\n pendingTerminalHydrationRef.current = null;\n // Send can advance the generation before the hydration update renders.\n // Preserve confirmed admission independently of that hydration guard.\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n queueDispatch: session.queue_dispatch,\n messages: prev.messages.map((message) => {\n const confirmed = session.messages.find((entry) => entry.id === message.serverMessageId);\n return confirmed\n ? mapServerMessage(token, confirmed)\n : { ...message, isStreaming: false, isAwaitingUserInput: false };\n }),\n }));\n }\n }\n if (modePendingRef.current || modeUncertainRef.current || modeAdmissionRef.current !== null) return false;\n let planningMode =\n modeRef.current.revision !== undefined || !tokenRef.current\n ? modeRef.current.value || (!tokenRef.current && requestedPlanningMode)\n : requestedPlanningMode;\n let expectedModeRevision = modeRef.current.revision;\n if (stateRef.current.readOnly || (!tokenRef.current && isCreatingRef.current)) return false;\n const submissionToken = tokenRef.current;\n const cancellationViewGeneration = sessionViewGenerationRef.current;\n const cancellation = submissionToken ? pendingCancellationsRef.current.get(submissionToken) : undefined;\n if (cancellation) {\n const cancelled = await cancellation.promise;\n if (\n !cancelled ||\n !isMountedRef.current ||\n tokenRef.current !== submissionToken ||\n sessionViewGenerationRef.current !== cancellationViewGeneration\n )\n return false;\n }\n // Retry unavailable attachment bytes before sending a previously restored draft.\n const loaders = new Set((files || []).map((file) => unresolvedDraftFilesRef.current.get(file)).filter(Boolean));\n if (loaders.size) await Promise.all(Array.from(loaders).map((load) => load!().catch(() => undefined)));\n if (tokenRef.current !== submissionToken || sessionViewGenerationRef.current !== cancellationViewGeneration)\n return false;\n if (files?.some((file) => unresolvedDraftFilesRef.current.has(file))) {\n setStateIfMounted((prev) => ({ ...prev, error: \"Could not cancel this message. Please try again.\" }));\n return false;\n }\n // Suggested steps have their own idempotent admission and must not enter the generic message queue.\n const queueEnabled = !nextStepSelection && !planningMode && featureEnabled(\"clerk_message_queue\");\n // Bind this submission to the work the user saw when pressing Send.\n // Keep the value captured through attachment processing, retries and Stop.\n const submittedWhileStreaming = reconciledStopSession\n ? sessionRunIsActive(reconciledStopSession)\n : stateRef.current.status === \"streaming\";\n const queueRunId = submittedWhileStreaming ? activeRunRef.current?.runId : undefined;\n // Exact structured request identity survives a restored draft retry after\n // uncertain delivery. Clear it only once the server confirms acceptance.\n const requestKey = JSON.stringify({\n token: tokenRef.current,\n message,\n files,\n modelConfig,\n activeTranscript,\n clientMatterCode: creditRequest?.clientMatterCode,\n });\n const queueClientRequestId = queueEnabled\n ? uncertainQueueRequestsRef.current.get(requestKey) || creditRequest?.clientRequestId || crypto.randomUUID()\n : undefined;\n if (queueClientRequestId) uncertainQueueRequestsRef.current.set(requestKey, queueClientRequestId);\n\n if (tokenRef.current && submittedWhileStreaming) {\n if (!queueEnabled) return false;\n const queueToken = tokenRef.current;\n const generation = sessionViewGenerationRef.current;\n const clientRequestId = queueClientRequestId!;\n const optimistic: ChatMessage = {\n ...createDisplayMessage(`queued-${clientRequestId}`, \"user\", message),\n queueState: \"pending\",\n clientRequestId,\n files: (files || []).map(({ name, size, type }) => ({ name, size, type })),\n };\n inputMutationEpochRef.current += 1;\n setStateIfMounted((prev) => ({ ...prev, messages: [...prev.messages, optimistic], error: null }));\n const isCurrent = () => isMountedRef.current && tokenRef.current === queueToken;\n try {\n const request = {\n clientRequestId,\n clientMatterCode: creditRequest?.clientMatterCode || stateRef.current.clientMatterCode || \"\",\n queue: true,\n queueRunId,\n };\n let confirmation: string | undefined;\n let run;\n let transportRetried = false;\n while (true) {\n try {\n run = await createSessionRun(\n queueToken,\n message,\n files,\n canonicalizeOptionalModelConfig(modelConfig),\n activeTranscript,\n { ...request, speedBumpConfirmationToken: confirmation },\n );\n break;\n } catch (err) {\n if (!speedBump || !isCreditSpeedBumpRequiredError(err) || !err.speedBumpRequirement) {\n const status =\n typeof err === \"object\" && err !== null && \"status\" in err\n ? (err as { status?: number }).status\n : undefined;\n if (status === undefined || status >= 500) {\n if (!transportRetried && isCurrent()) {\n transportRetried = true;\n continue;\n }\n if (isCurrent()) {\n const snapshot = await getSession(queueToken).catch(() => null);\n const accepted = snapshot?.messages.find(\n (candidate) => candidate.client_request_id === clientRequestId,\n );\n if (accepted) {\n run = {\n run_id: snapshot?.active_run?.run_id || \"\",\n status: snapshot?.active_run?.status || (\"completed\" as const),\n user_message: accepted,\n queued: true,\n };\n break;\n }\n }\n }\n throw err;\n }\n const approved = await speedBump.presentRequired(\n {\n sessionToken: queueToken,\n requestKind: \"message\",\n ...request,\n message,\n files,\n modelConfig,\n activeTranscript,\n },\n err.speedBumpRequirement,\n );\n // Confirmation has not submitted the message. Let the composer\n // restore its originating draft if navigation prevents submission.\n if (!isCurrent()) return false;\n if (approved === null) {\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.filter((m) => m.id !== optimistic.id),\n }));\n return false;\n }\n confirmation = approved;\n }\n }\n uncertainQueueRequestsRef.current.delete(requestKey);\n if (!isCurrent()) return true;\n inputMutationEpochRef.current += 1;\n const accepted = run.user_message ? mapServerMessage(queueToken, run.user_message) : optimistic;\n if (run.queue_dispatch !== undefined)\n setStateIfMounted((prev) => ({ ...prev, queueDispatch: run.queue_dispatch }));\n setStateIfMounted((prev) => {\n const alreadyConsumed = prev.messages.find(\n (m) => m.serverMessageId === accepted.serverMessageId && m.queueState === \"consumed\",\n );\n if (alreadyConsumed) return { ...prev, messages: prev.messages.filter((m) => m.id !== optimistic.id) };\n return {\n ...prev,\n messages: prev.messages.map((m) =>\n m.id === optimistic.id || (accepted.serverMessageId && m.serverMessageId === accepted.serverMessageId)\n ? accepted\n : m,\n ),\n };\n });\n // A send racing terminalization may have started a successor run.\n if (\n run.run_id &&\n [\"queued\", \"running\", \"waiting_for_input\"].includes(run.status) &&\n sessionViewGenerationRef.current === generation &&\n (activeRunRef.current?.runId !== run.run_id || activeRunRef.current?.terminated)\n ) {\n const assistant = { ...createDisplayMessage(generateId(), \"assistant\", \"\"), isStreaming: true };\n setStateIfMounted((prev) => ({ ...prev, status: \"streaming\", messages: [...prev.messages, assistant] }));\n beginRunStream(queueToken, run.run_id, assistant.id);\n }\n return true;\n } catch (err) {\n if (isCurrent())\n setStateIfMounted((prev) => ({\n ...prev,\n error: clerkErrorMessage(err instanceof Error ? err.message : null, { fallbackKey: \"genericRetry\" }),\n messages: prev.messages.filter((m) => m.id !== optimistic.id),\n }));\n return false;\n }\n }\n\n if (nextStepContext && !nextStepContext.isCurrent()) return false;\n const admission = ++modeOperationRef.current;\n const admissionIntent = { token: tokenRef.current, revision: expectedModeRevision, next: null as boolean | null };\n modeAdmissionIntentRef.current = admissionIntent;\n modeAdmissionRef.current = admission;\n setModeAdmissionPending(true);\n const submission = { generation: -1, stopped: false };\n const supersededResult = () => (submission.stopped ? (\"stopped\" as const) : false);\n pendingSubmissionsRef.current.add(submission);\n try {\n bumpSessionViewGeneration();\n submission.generation = sessionViewGenerationRef.current;\n const submissionGeneration = sessionViewGenerationRef.current;\n let selectionSubmitted = false;\n const submissionIsCurrent = () =>\n isMountedRef.current &&\n (!planningMode || sessionViewGenerationRef.current === submissionGeneration) &&\n (selectionSubmitted || !nextStepContext || nextStepContext.isCurrent());\n const clearPendingPlanning = () => {\n if (isMountedRef.current && sessionViewGenerationRef.current === submissionGeneration) {\n setPendingPlanning(false);\n }\n };\n setPendingPlanning(planningMode);\n const canonicalModelConfig = canonicalizeOptionalModelConfig(modelConfig);\n const startedWithoutSession = !tokenRef.current;\n const refreshSidenavRecents = () => {\n void queryClient.invalidateQueries({ queryKey: [\"agentPrototypeSessions\", \"infinite\", \"sidenav\"] });\n };\n let token = tokenRef.current;\n let sessionId = sessionIdRef.current;\n\n // Create session if we don't have one\n if (!token) {\n isCreatingRef.current = true;\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"creating\",\n activeModelConfig: canonicalModelConfig || null,\n }));\n try {\n const session = await createSession(canonicalModelConfig, activeTranscript);\n if (!submissionIsCurrent()) return supersededResult();\n sessionId = session.session_id;\n sessionIdRef.current = sessionId;\n token = session.token;\n admissionIntent.token = token;\n tokenRef.current = token;\n refreshSidenavRecents();\n // Don't setState here \u2014 token + messages are set together below\n // to avoid a render where token exists but messages are empty.\n } catch (err) {\n if (!submissionIsCurrent()) return supersededResult();\n clearPendingPlanning();\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"error\",\n error: clerkErrorMessage(err instanceof Error ? err.message : null, { fallbackKey: \"genericRetry\" }),\n }));\n return false;\n } finally {\n isCreatingRef.current = false;\n }\n }\n\n const speedBumpRequest: CreditAgentSpeedBumpRequest | null =\n creditRequest && speedBump\n ? {\n sessionToken: token,\n requestKind: \"message\",\n clientRequestId: queueClientRequestId || creditRequest.clientRequestId,\n message,\n modelConfig: canonicalModelConfig,\n activeTranscript,\n files,\n clientMatterCode: creditRequest.clientMatterCode,\n }\n : null;\n let speedBumpConfirmationToken: string | undefined;\n if (speedBumpRequest && speedBump) {\n try {\n const confirmation = await speedBump.ensureAcknowledged(speedBumpRequest);\n if (!submissionIsCurrent()) return supersededResult();\n if (confirmation === null) {\n clearPendingPlanning();\n setStateIfMounted((prev) => ({\n ...prev,\n sessionId,\n token,\n status: \"active\",\n activeModelConfig: canonicalModelConfig || null,\n error: null,\n }));\n refreshSidenavRecents();\n return false;\n }\n speedBumpConfirmationToken = confirmation;\n } catch (err) {\n if (!submissionIsCurrent()) return supersededResult();\n clearPendingPlanning();\n setStateIfMounted((prev) => ({\n ...prev,\n sessionId,\n token,\n status: \"error\",\n error: clerkErrorMessage(err instanceof Error ? err.message : null, { fallbackKey: \"genericRetry\" }),\n }));\n refreshSidenavRecents();\n return false;\n }\n }\n\n // A chip may opt into planning only after the user accepts matter/credit prompts.\n // Persist through the same revision-aware transition used by the mode toggle.\n let chipEnabledModeRevision: number | undefined;\n if (nextStepContext?.startInPlanningMode) {\n if (!submissionIsCurrent() || queuedModeRef.current !== null) return supersededResult();\n if (!modeRef.current.value) {\n if (!(await setPlanningMode(true, admission))) return false;\n chipEnabledModeRevision = modeRef.current.revision;\n }\n if (!submissionIsCurrent() || queuedModeRef.current !== null || !modeRef.current.value) return false;\n planningMode = true;\n expectedModeRevision = modeRef.current.revision;\n admissionIntent.revision = expectedModeRevision;\n setPendingPlanning(true);\n }\n\n if (!submissionIsCurrent()) return supersededResult();\n selectionSubmitted = true;\n const rollbackOptimisticSidenavStatus = optimisticallyMarkClerkRecentWorking(queryClient, token);\n\n // Add user message\n const fileMetadata: FileMetadata[] = (files || []).map((f) => ({\n name: f.name,\n size: f.size,\n type: f.type,\n }));\n const normalizedPromptSource: ClerkPromptSource =\n activeTranscript && previousUserMessageCount(state.messages) === 0\n ? \"transcript_bootstrap\"\n : promptSource || \"typed\";\n\n if (sessionId) {\n void recordUserEvent({\n event_name: \"start_clerk_run\",\n event_properties: {\n session_id: sessionId,\n prompt_length_chars: message.length,\n prompt_line_count: countPromptLines(message),\n has_files: fileMetadata.length > 0,\n file_count: fileMetadata.length,\n file_extensions: uniqueFileExtensions(fileMetadata).join(\",\"),\n has_active_transcript: Boolean(activeTranscript),\n active_transcript_id: activeTranscript?.transcript_id,\n model: canonicalModelConfig?.model || \"unknown\",\n reasoning_effort: canonicalModelConfig?.reasoning_effort || DEFAULT_REASONING_EFFORT,\n prompt_source: normalizedPromptSource,\n },\n });\n }\n const userMessage: ChatMessage = {\n id: generateId(),\n role: \"user\",\n content: message,\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: fileMetadata,\n downloadFiles: [],\n downloadSelectionExplicit: true,\n };\n\n // Add placeholder assistant message\n const assistantId = generateId();\n const assistantMessage: ChatMessage = {\n id: assistantId,\n role: \"assistant\",\n content: \"\",\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n downloadSelectionExplicit: true,\n isAwaitingUserInput: false,\n isStreaming: true,\n };\n\n setStateIfMounted((prev) => ({\n ...prev,\n sessionId,\n token: startedWithoutSession ? prev.token : token,\n // Stop needs the durable run identity; restricted planning discovers\n // that run while its synchronous HTTP request remains in flight.\n status: planningMode ? \"creating\" : \"streaming\",\n activeModelConfig: canonicalModelConfig || null,\n messages: [...prev.messages, userMessage, assistantMessage],\n docketConnectRetrievalRequest: shouldClearDocketConnectLimitNoticeOnSend(prev.docketConnectRetrievalRequest)\n ? null\n : prev.docketConnectRetrievalRequest,\n error: null,\n }));\n\n try {\n let run;\n let uncertainAdmissionRetries = 0;\n while (true) {\n try {\n const credit =\n creditRequest || queueEnabled\n ? {\n clientRequestId: queueClientRequestId || creditRequest!.clientRequestId,\n clientMatterCode: creditRequest?.clientMatterCode || stateRef.current.clientMatterCode || \"\",\n ...(queueEnabled ? { queue: true } : {}),\n speedBumpConfirmationToken,\n }\n : undefined;\n run = nextStepSelection\n ? await createSessionRun(\n token,\n message,\n files,\n canonicalModelConfig,\n activeTranscript,\n credit,\n planningMode,\n expectedModeRevision,\n nextStepSelection,\n )\n : expectedModeRevision !== undefined\n ? await createSessionRun(\n token,\n message,\n files,\n canonicalModelConfig,\n activeTranscript,\n credit,\n planningMode,\n expectedModeRevision,\n )\n : planningMode\n ? await createSessionRun(\n token,\n message,\n files,\n canonicalModelConfig,\n activeTranscript,\n credit,\n true,\n )\n : credit\n ? await createSessionRun(token, message, files, canonicalModelConfig, activeTranscript, credit)\n : await createSessionRun(token, message, files, canonicalModelConfig, activeTranscript);\n break;\n } catch (err) {\n if (nextStepSelection && err instanceof AgentAdmissionUncertainError && uncertainAdmissionRetries < 2) {\n if (!submissionIsCurrent() || submission.stopped) return supersededResult();\n uncertainAdmissionRetries += 1;\n // Retry only uncertain delivery, retaining all admission/credit identity.\n // The server resolves an already committed selection before admitting work.\n continue;\n }\n if (\n !speedBumpRequest ||\n !speedBump ||\n !isCreditSpeedBumpRequiredError(err) ||\n !err.speedBumpRequirement\n ) {\n throw err;\n }\n\n const confirmation = await speedBump.presentRequired(speedBumpRequest, err.speedBumpRequirement);\n if (!submissionIsCurrent()) {\n rollbackOptimisticSidenavStatus();\n return supersededResult();\n }\n if (confirmation === null) {\n // Admission can discover a new credit prompt after preflight. Undo\n // only this chip's mode change; newer local or remote choices win.\n if (\n chipEnabledModeRevision !== undefined &&\n modeRef.current.revision === chipEnabledModeRevision &&\n modeRef.current.value &&\n queuedModeRef.current === null &&\n tokenRef.current === token &&\n modeAdmissionRef.current === admission\n ) {\n await setPlanningMode(false, admission);\n admissionIntent.revision = modeRef.current.revision;\n }\n if (!submissionIsCurrent()) return supersededResult();\n rollbackOptimisticSidenavStatus();\n setStateIfMounted((prev) => ({\n ...prev,\n sessionId,\n token,\n status: \"active\",\n error: null,\n messages: prev.messages.filter((item) => item.id !== userMessage.id && item.id !== assistantId),\n }));\n return false;\n }\n speedBumpConfirmationToken = confirmation;\n }\n }\n uncertainQueueRequestsRef.current.delete(requestKey);\n admissionIntent.revision = run.planning_mode_revision ?? admissionIntent.revision;\n if (!submissionIsCurrent()) return supersededResult();\n // A pre-admission snapshot must not restore the superseded plan or\n // replace the newly accepted user message after this response.\n inputMutationEpochRef.current += 1;\n\n if (tokenRef.current === token && modeAdmissionRef.current === admission) applyPlanningMode(run, token);\n const runModelConfig = run.model_config;\n if (runModelConfig) {\n setStateIfMounted((prev) => ({\n ...prev,\n activeModelConfig: preserveRunModelConfig(runModelConfig),\n }));\n }\n\n if (run.user_message) {\n const persistedUserMessage = mapServerMessage(token, run.user_message);\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.map((m) => (m.id === userMessage.id ? persistedUserMessage : m)),\n }));\n }\n\n if (run.planning_cycle && !run.run_id) {\n clearPendingPlanning();\n setActivePlan(run.planning_cycle.active ? run.planning_cycle : null);\n setStateIfMounted((prev) => ({\n ...prev,\n sessionId: startedWithoutSession ? sessionId : prev.sessionId,\n token: startedWithoutSession ? token : prev.token,\n status: \"active\",\n error: null,\n clientMatterCode: run.client_matter_code || prev.clientMatterCode,\n messages: prev.messages.filter((item) => item.id !== assistantId),\n }));\n const session = await hydrateSession(token, { hydrationIsCurrent: submissionIsCurrent });\n if (!submissionIsCurrent()) return supersededResult();\n if (session) reconnectHydratedActiveRun(session);\n return true;\n }\n if (!run.run_id) throw new Error(CLERK_ERROR_COPY.genericRetry);\n if (run.queued && ![\"queued\", \"running\", \"waiting_for_input\"].includes(run.status)) {\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n queueDispatch: run.queue_dispatch || null,\n messages: prev.messages.filter((m) => m.id !== assistantId),\n }));\n return true;\n }\n if (\n !planningMode &&\n tokenRef.current === token &&\n sessionViewGenerationRef.current === submissionGeneration\n ) {\n // Accepted research supersedes the unfinished plan on the server.\n // Drop its interactive projection before the research stream renders.\n setActivePlan(null);\n }\n\n setStateIfMounted((prev) => ({\n ...prev,\n sessionId: startedWithoutSession ? sessionId : prev.sessionId,\n token: startedWithoutSession ? token : prev.token,\n status: \"streaming\",\n error: null,\n clientMatterCode: run.client_matter_code || prev.clientMatterCode,\n }));\n setStateIfMounted((prev) => ({\n ...prev,\n queueDispatch: run.queue_dispatch === undefined ? prev.queueDispatch : run.queue_dispatch,\n }));\n beginRunStream(token, run.run_id, assistantId);\n } catch (err) {\n if (!submissionIsCurrent()) return supersededResult();\n if (err instanceof PlanningModeConflictError) {\n applyPlanningMode(err.mode, token, true);\n clearPendingPlanning();\n rollbackOptimisticSidenavStatus();\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: err.message,\n messages: prev.messages.filter((item) => item.id !== assistantId && item.id !== userMessage.id),\n }));\n return false;\n }\n if (err instanceof AgentPrototypeApiError && err.code === \"active_run_in_progress\") {\n // Nothing was admitted: drop the optimistic turn so the composer restores the draft.\n rollbackOptimisticSidenavStatus();\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: CLERK_ERROR_COPY.activeRunInProgress,\n messages: prev.messages.filter((item) => item.id !== assistantId && item.id !== userMessage.id),\n }));\n return false;\n }\n if (err instanceof PlanningActionError && err.planningCycle) {\n clearPendingPlanning();\n setActivePlan(err.planningCycle.active ? err.planningCycle : null);\n try {\n const hydratedSession = await hydrateSession(token, { hydrationIsCurrent: submissionIsCurrent });\n if (!submissionIsCurrent()) return supersededResult();\n if (hydratedSession && reconnectHydratedActiveRun(hydratedSession, assistantId)) {\n return true;\n }\n } catch {\n // Fall through to the normal error state when authoritative\n // session recovery is unavailable.\n }\n }\n rollbackOptimisticSidenavStatus();\n const errorMsg = clerkErrorMessage(err instanceof Error ? err.message : null, {\n fallbackKey: \"genericRetry\",\n });\n setStateIfMounted((prev) => ({\n ...prev,\n sessionId,\n token,\n status: \"error\",\n error: errorMsg,\n messages: prev.messages.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n isStreaming: false,\n isError: true,\n isTerminalError: true,\n errorMessage: errorMsg,\n content: m.content || errorMsg || CLERK_ERROR_COPY.genericRetry,\n }\n : m,\n ),\n }));\n } finally {\n clearPendingPlanning();\n refreshSidenavRecents();\n }\n return true;\n } finally {\n pendingSubmissionsRef.current.delete(submission);\n if (modeAdmissionRef.current === admission) {\n modeAdmissionRef.current = null;\n const nextMode = queuedModeRef.current;\n queuedModeRef.current = null;\n modeAdmissionIntentRef.current = null;\n if (isMountedRef.current) {\n setModeAdmissionPending(false);\n if (nextMode !== null) await setPlanningMode(nextMode);\n }\n } else if (admissionIntent.next !== null && admissionIntent.token) {\n // The preference belongs to the original conversation even after navigation.\n // Its response must never mutate the currently displayed conversation.\n try {\n const revision =\n admissionIntent.revision ?? (await getSession(admissionIntent.token)).planning_mode_revision ?? 0;\n await updatePlanningMode(admissionIntent.token, admissionIntent.next, revision);\n } catch {\n // A newer choice wins on conflict; normal hydration reconciles on return.\n }\n }\n }\n },\n [\n beginRunStream,\n bumpSessionViewGeneration,\n cancelStream,\n clearRecoveryTimeout,\n hydrateSession,\n mapServerMessage,\n reconnectHydratedActiveRun,\n setStateIfMounted,\n speedBump,\n setPlanningMode,\n state.messages,\n ],\n );\n\n const consumeRestoredDraft = useCallback((id: string) => {\n setRestoreDraft((draft) => {\n if (draft?.id !== id) return draft;\n return undefined;\n });\n }, []);\n\n const steeringRunId = activeRunRef.current?.runId;\n const activeSteerAvailable =\n state.status === \"streaming\" &&\n !!steeringRunId &&\n !activeRunRef.current?.terminated &&\n !activeRunRef.current?.cancelledByUser;\n const restartAvailable =\n state.status !== \"streaming\" &&\n state.status !== \"creating\" &&\n !!state.latestRun &&\n [\"cancelled\", \"failed\", \"completed\"].includes(state.latestRun.status) &&\n typeof state.queueDispatch?.generation === \"number\" &&\n (!state.serverActiveRun || [\"cancelled\", \"failed\", \"completed\"].includes(state.serverActiveRun.status));\n const renderedSteerIntent = useMemo(\n () =>\n activeSteerAvailable\n ? { intent: \"steer\", expectedRunId: steeringRunId! }\n : restartAvailable\n ? {\n intent: \"restart\",\n expectedRunId: state.latestRun!.run_id,\n queueGeneration: state.queueDispatch!.generation!,\n }\n : undefined,\n [activeSteerAvailable, steeringRunId, restartAvailable, state.latestRun?.run_id, state.queueDispatch?.generation],\n );\n const performMessageAction = useCallback(\n async (message: ChatMessage, action: \"steer\" | \"cancel\" | \"fork\", steerIntent?: SteerMessageIntent) => {\n const token = tokenRef.current;\n if (\n !token ||\n stateRef.current.readOnly ||\n !featureEnabled(\"clerk_message_queue\") ||\n !message.serverMessageId ||\n messageActionRef.current ||\n pendingStopRef.current?.token === token\n )\n return;\n if (!stateRef.current.messages.some((m) => m.id === message.id)) return;\n const generation = sessionViewGenerationRef.current;\n const isCurrent = () =>\n isMountedRef.current && tokenRef.current === token && sessionViewGenerationRef.current === generation;\n messageActionRef.current = message.id;\n setPendingMessageActionId(message.id);\n setPendingMessageActionType(action);\n let resolveCancellation: ((success: boolean) => void) | undefined;\n let cancellationSucceeded = false;\n const restoredFiles: AttachedFile[] = [];\n const fillRestoredFiles = (draft: MessageDraft) => {\n restoredFiles.forEach((file, index) => {\n const full = draft.files[index];\n if (full) {\n Object.assign(file, full);\n unresolvedDraftFilesRef.current.delete(file);\n }\n });\n conversationDrafts.update(token, (draft) => ({ ...draft, files: [...draft.files] }));\n };\n const loadRestoredFiles = async () => {\n fillRestoredFiles(await getMessageDraft(token, message.serverMessageId!));\n };\n if (action === \"cancel\") {\n if (message.queueState !== \"pending\") {\n messageActionRef.current = null;\n setPendingMessageActionId(null);\n setPendingMessageActionType(null);\n return;\n }\n const promise = new Promise((resolve) => {\n resolveCancellation = resolve;\n });\n pendingCancellationsRef.current.set(token, { messageId: message.serverMessageId, promise, suppress: true });\n const restorationKey = JSON.stringify([token, message.serverMessageId]);\n const previousRestoration = cancelRestorationsRef.current.get(restorationKey);\n if (previousRestoration) {\n // A failed attempt still has an editable draft. Reuse its attachment identities\n // without appending the original text or reintroducing removed attachments.\n restoredFiles.push(...previousRestoration.files);\n } else {\n restoredFiles.push(...message.files.map((file) => ({ ...file, data: \"\" })));\n restoredFiles.forEach((file) => unresolvedDraftFilesRef.current.set(file, loadRestoredFiles));\n const draft = { text: message.content, files: restoredFiles };\n const id = `cancel-${message.serverMessageId}-${crypto.randomUUID()}`;\n cancelRestorationsRef.current.set(restorationKey, { token, id, files: restoredFiles });\n conversationDrafts.restore(token, id, draft);\n setRestoreDraft({ id, sessionToken: token, ...draft });\n }\n inputMutationEpochRef.current += 1;\n setStateIfMounted((prev) => ({ ...prev, messages: prev.messages.filter((item) => item.id !== message.id) }));\n }\n try {\n if (action === \"fork\") {\n const result = await forkSessionMessage(token, message.serverMessageId);\n // The caller owns a separate tab; source navigation must not discard its destination.\n return result;\n }\n if (action === \"steer\") {\n if (!steerIntent || message.queueState !== \"pending\") return;\n if (steerIntent.intent === \"steer\") {\n if (\n activeRunRef.current?.runId !== steerIntent.expectedRunId ||\n activeRunRef.current?.terminated ||\n activeRunRef.current?.cancelledByUser ||\n stateRef.current.status !== \"streaming\"\n )\n return;\n } else {\n const current = stateRef.current;\n if (\n current.status === \"streaming\" ||\n current.status === \"creating\" ||\n current.latestRun?.run_id !== steerIntent.expectedRunId ||\n current.queueDispatch?.generation !== steerIntent.queueGeneration ||\n ![\"completed\", \"failed\", \"cancelled\"].includes(current.latestRun?.status || \"\") ||\n (current.serverActiveRun &&\n [\"queued\", \"running\", \"waiting_for_input\"].includes(current.serverActiveRun.status))\n )\n return;\n }\n setPendingSteerAcceptance({ token, messageId: message.serverMessageId });\n }\n const result =\n action === \"cancel\"\n ? await cancelQueuedMessage(token, message.serverMessageId)\n : await steerQueuedMessage(token, message.serverMessageId, steerIntent!);\n if (!result) return;\n if (\"draft\" in result) {\n // Fill the same objects used by the draft and any already-captured Send.\n // Do not append again: the user may have edited text or removed attachments.\n fillRestoredFiles(result.draft);\n cancellationSucceeded = true;\n }\n if (!isCurrent()) return;\n inputMutationEpochRef.current += 1;\n if (result.user_message) {\n const accepted = mapServerMessage(token, result.user_message);\n setStateIfMounted((prev) => ({\n ...prev,\n error: null,\n messages:\n action === \"cancel\"\n ? prev.messages.filter((m) => m.id !== message.id)\n : prev.messages.map((m) => {\n if (m.id !== message.id) return { ...m, steerRequestedAt: undefined, steerRunId: undefined };\n // Consumption can arrive over the stream before the pending Steer acknowledgement.\n return m.queueState === \"consumed\" ? m : accepted;\n }),\n }));\n }\n if (\"intent\" in result && result.intent === \"restart\") await activateSavedMessageRun(token, result, isCurrent);\n } catch (err) {\n // Allow the authoritative failed-cancellation snapshot to restore the original.\n if (action === \"cancel\") {\n const cancellation = pendingCancellationsRef.current.get(token);\n if (cancellation) cancellation.suppress = false;\n // This read is allowed even when consumption made cancellation impossible.\n if (restoredFiles.length) await loadRestoredFiles().catch(() => undefined);\n }\n if (isCurrent()) {\n if (steerIntent?.intent === \"restart\" && isCreditSpeedBumpRequiredError(err) && err.queueDispatch) {\n const creditAction = err.queueDispatch.action;\n if (creditAction)\n presentedQueueCreditBlocksRef.current.delete(\n `${token}:${creditAction.message_id}:${creditAction.queue_generation}:${creditAction.confirmation_token}`,\n );\n setQueueCreditPresentationEpoch((value) => value + 1);\n setStateIfMounted((prev) => ({ ...prev, queueDispatch: err.queueDispatch, error: null }));\n return;\n }\n const session = await hydrateSession(token, {\n preserveStreaming: stateRef.current.status === \"streaming\",\n preserveOlderPages: true,\n pollingActiveRunTail: activeRunRef.current,\n }).catch(() => null);\n if (\n steerIntent?.intent === \"restart\" &&\n isCreditSpeedBumpRequiredError(err) &&\n session?.queue_dispatch?.action\n )\n return;\n if (isCurrent()) {\n if (action === \"cancel\") {\n if (!session)\n setStateIfMounted((prev) =>\n prev.messages.some((item) => item.serverMessageId === message.serverMessageId)\n ? prev\n : { ...prev, messages: [...prev.messages, message] },\n );\n const consumed = session?.messages.some(\n (item) => item.id === message.serverMessageId && item.queue_state === \"consumed\",\n );\n throw new Error(\n consumed\n ? \"Could not cancel this message because it was already read.\"\n : \"Could not cancel this message. Please try again.\",\n );\n }\n throw err;\n }\n }\n } finally {\n if (action === \"cancel\") {\n pendingCancellationsRef.current.delete(token);\n resolveCancellation?.(cancellationSucceeded);\n }\n messageActionRef.current = null;\n if (isMountedRef.current) {\n if (action === \"steer\") setPendingSteerAcceptance(null);\n setPendingMessageActionId(null);\n setPendingMessageActionType(null);\n }\n }\n },\n [activateSavedMessageRun, hydrateSession, mapServerMessage, setStateIfMounted],\n );\n const steerMessage = useCallback(\n (message: ChatMessage) => performMessageAction(message, \"steer\", renderedSteerIntent),\n [performMessageAction, renderedSteerIntent],\n );\n const cancelAndEditMessage = useCallback(\n (message: ChatMessage) => performMessageAction(message, \"cancel\"),\n [performMessageAction],\n );\n const forkMessage = useCallback(\n (message: ChatMessage) => performMessageAction(message, \"fork\"),\n [performMessageAction],\n );\n\n const beginPlanningExecution = useCallback(\n (response: PlanningActionResponse) => {\n const token = tokenRef.current;\n if (!token || !response.run_id) return false;\n const activeRun = activeRunRef.current;\n if (activeRun?.token === token && activeRun.runId === response.run_id && !activeRun.terminated) return true;\n const assistantId = generateId();\n setActivePlan(null);\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n error: null,\n activeModelConfig: response.model_config\n ? preserveRunModelConfig(response.model_config)\n : prev.activeModelConfig,\n clientMatterCode: response.client_matter_code || prev.clientMatterCode,\n messages: [\n ...prev.messages,\n {\n id: assistantId,\n role: \"assistant\",\n content: \"\",\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n downloadSelectionExplicit: true,\n isStreaming: true,\n },\n ],\n }));\n beginRunStream(token, response.run_id, assistantId);\n return true;\n },\n [beginRunStream, setStateIfMounted],\n );\n\n const runPlanningAction = useCallback(\n async (\n action: () => Promise,\n options?: {\n allowConcurrent?: boolean;\n supersedeOnSuccess?: boolean;\n executionSatisfiesAction?: boolean;\n pending?: Omit;\n },\n ) => {\n if (stateRef.current.readOnly) return false;\n if (!options?.allowConcurrent && planningActionsInFlightRef.current.size > 0) return false;\n let operationGeneration = options?.supersedeOnSuccess\n ? planningActionGenerationRef.current\n : ++planningActionGenerationRef.current;\n const operationId = ++planningActionIdRef.current;\n planningActionsInFlightRef.current.add(operationId);\n if (options?.pending) setPendingAction({ ...options.pending, operationId });\n planningConflictErrorRef.current = null;\n planningRefreshFailedRef.current = false;\n setStateIfMounted((prev) => ({ ...prev, status: \"creating\", error: null }));\n const submission = { generation: sessionViewGenerationRef.current, stopped: false };\n const supersededResult = () => (submission.stopped ? (\"stopped\" as const) : false);\n pendingSubmissionsRef.current.add(submission);\n try {\n const response = await action();\n if (options?.supersedeOnSuccess) {\n if (operationGeneration !== planningActionGenerationRef.current) return supersededResult();\n operationGeneration = ++planningActionGenerationRef.current;\n }\n if (!isMountedRef.current || operationGeneration !== planningActionGenerationRef.current)\n return supersededResult();\n if (!response) {\n setStateIfMounted((prev) => ({ ...prev, status: \"active\", error: null }));\n return false;\n }\n if (tokenRef.current) applyPlanningMode(response, tokenRef.current);\n if (response.run_id) {\n const token = tokenRef.current;\n const activeRun = activeRunRef.current;\n if (activeRun?.token === token && activeRun.runId === response.run_id && !activeRun.terminated) {\n setActivePlan(response.planning_cycle.active ? response.planning_cycle : null);\n try {\n const session = await hydrateSession(activeRun.token, {\n preserveStreaming: true,\n preserveOlderPages: true,\n pollingActiveRunTail: { runId: activeRun.runId, assistantId: activeRun.assistantId },\n hydrationIsCurrent: () => operationGeneration === planningActionGenerationRef.current,\n });\n if (!session || operationGeneration !== planningActionGenerationRef.current) return supersededResult();\n reconnectHydratedActiveRun(session, activeRun.assistantId);\n } catch {\n if (!isMountedRef.current || operationGeneration !== planningActionGenerationRef.current)\n return supersededResult();\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n error: null,\n messages: prev.messages.map((message) =>\n message.id === activeRun.assistantId ? { ...message, isAwaitingUserInput: false } : message,\n ),\n }));\n beginRunStream(activeRun.token, activeRun.runId, activeRun.assistantId, activeRun.lastEventId);\n }\n return true;\n }\n if (!token) return false;\n // Planning replies can commit a new user question before creating the\n // execution run. Load that transcript before adding its live answer.\n let session;\n try {\n session = await hydrateSession(token, {\n hydrationIsCurrent: () => operationGeneration === planningActionGenerationRef.current,\n });\n } catch {\n // The action already started research. A transcript refresh failure\n // must not discard that execution or require another submission.\n if (\n !isMountedRef.current ||\n tokenRef.current !== token ||\n operationGeneration !== planningActionGenerationRef.current\n )\n return supersededResult();\n if (response.user_message) {\n const userMessage = mapServerMessage(token, response.user_message);\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.some((message) => message.serverMessageId === userMessage.serverMessageId)\n ? prev.messages\n : [...prev.messages, userMessage],\n }));\n }\n return beginPlanningExecution(response);\n }\n if (!session || operationGeneration !== planningActionGenerationRef.current) return supersededResult();\n if (session.active_run?.run_id === response.run_id && !sessionRunIsActive(session)) return true;\n return beginPlanningExecution(response);\n }\n setActivePlan(response.planning_cycle.active ? response.planning_cycle : null);\n const token = tokenRef.current;\n if (token) {\n try {\n const session = await hydrateSession(token, {\n hydrationIsCurrent: () => operationGeneration === planningActionGenerationRef.current,\n });\n if (session && operationGeneration === planningActionGenerationRef.current) {\n reconnectHydratedActiveRun(session);\n }\n } catch {\n // The mutation succeeded; a failed read must not invite a duplicate submission.\n if (operationGeneration === planningActionGenerationRef.current) {\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: CLERK_ERROR_COPY.conversationLoadFailure,\n }));\n }\n }\n }\n return operationGeneration === planningActionGenerationRef.current ? true : supersededResult();\n } catch (error) {\n if (operationGeneration !== planningActionGenerationRef.current) return supersededResult();\n let reconnectedToRun = false;\n let reconciledConflict = false;\n const isStateConflict = error instanceof PlanningActionError && error.code === \"planning_state_conflict\";\n if (isStateConflict) planningConflictErrorRef.current = error;\n {\n if (error instanceof PlanningActionError && error.planningCycle)\n setActivePlan(error.planningCycle.active ? error.planningCycle : null);\n const token = tokenRef.current;\n if (token) {\n try {\n const hydratedSession = await hydrateSession(token, {\n hydrationIsCurrent: () => operationGeneration === planningActionGenerationRef.current,\n });\n if (operationGeneration !== planningActionGenerationRef.current) return supersededResult();\n if (hydratedSession) {\n reconciledConflict = isStateConflict;\n reconnectedToRun = reconnectHydratedActiveRun(hydratedSession);\n // A lost HTTP response can follow a committed transition. Resolve\n // from saved interaction identity before offering the same action again.\n const pending = options?.pending;\n const saved = hydratedSession.active_plan;\n if (\n pending &&\n !isStateConflict &&\n ((pending.kind === \"accept\" &&\n saved &&\n saved.plan_token === pending.planToken &&\n saved.status !== \"offered\") ||\n ((pending.kind === \"answer\" || pending.kind === \"revision\") &&\n hydratedSession.messages.some(\n (message) => message.metadata?.planning_client_request_id === pending.clientRequestId,\n )))\n )\n return true;\n }\n } catch {\n // The conflict response still carries the authoritative Plan\n // projection, so keep it even if transcript hydration fails.\n }\n }\n }\n if (!isMountedRef.current || operationGeneration !== planningActionGenerationRef.current)\n return supersededResult();\n if (reconciledConflict) planningConflictErrorRef.current = null;\n if (reconnectedToRun) return options?.executionSatisfiesAction === true;\n if (reconciledConflict) return false;\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: clerkErrorMessage(error instanceof Error ? error.message : null, { fallbackKey: \"genericRetry\" }),\n }));\n return false;\n } finally {\n pendingSubmissionsRef.current.delete(submission);\n planningActionsInFlightRef.current.delete(operationId);\n if (isMountedRef.current)\n setPendingAction((current) => (current?.operationId === operationId ? null : current));\n if (planningActionsInFlightRef.current.size === 0 && planningReconciliationPendingRef.current) {\n planningReconciliationPendingRef.current = false;\n planningReconciliationRef.current?.();\n }\n void queryClient.invalidateQueries({ queryKey: [\"agentPrototypeSessions\", \"infinite\", \"sidenav\"] });\n }\n },\n [\n beginPlanningExecution,\n beginRunStream,\n hydrateSession,\n mapServerMessage,\n reconnectHydratedActiveRun,\n setStateIfMounted,\n ],\n );\n\n const respondToPlanningOffer = useCallback(\n (decision: \"accept\" | \"execute_without_plan\") => {\n const token = tokenRef.current;\n const plan = activePlan;\n if (!token || !plan) return Promise.resolve(false);\n return runPlanningAction(() => apiRespondToPlanningOffer(token, plan.plan_token, decision), {\n executionSatisfiesAction: true,\n pending: {\n kind: decision === \"accept\" ? \"accept\" : \"decline\",\n sessionToken: token,\n planToken: plan.plan_token,\n },\n });\n },\n [activePlan, runPlanningAction],\n );\n\n const submitPlanningResponse = useCallback(\n (message: string, files?: AttachedFile[], questionResponse?: PlanningQuestionResponse) => {\n const token = tokenRef.current;\n const plan = activePlan;\n if (\n modePendingRef.current ||\n modeUncertainRef.current ||\n (modeRef.current.revision !== undefined && !modeRef.current.value)\n )\n return Promise.resolve(false);\n if (!token || !plan?.active_interaction_token || planningActionsInFlightRef.current.size > 0)\n return Promise.resolve(false);\n setPlanningQuestionError(null);\n const retryKey = JSON.stringify([\n token,\n plan.plan_token,\n plan.active_interaction_token,\n message,\n files,\n questionResponse,\n ]);\n const clientRequestId =\n planningResponseRetryRef.current?.key === retryKey ? planningResponseRetryRef.current.id : crypto.randomUUID();\n planningResponseRetryRef.current = { key: retryKey, id: clientRequestId };\n const optimisticId = `planning-response-${clientRequestId}`;\n return runPlanningAction(\n async () => {\n {\n setStateIfMounted((prev) => ({\n ...prev,\n messages: [\n ...prev.messages,\n {\n ...createDisplayMessage(optimisticId, \"user\", message),\n files: files ?? [],\n },\n ],\n }));\n }\n const generation = planningActionGenerationRef.current;\n const isCurrent = () => isMountedRef.current && generation === planningActionGenerationRef.current;\n let confirmationToken: string | undefined;\n while (isCurrent()) {\n try {\n return await apiSubmitPlanningResponse(\n token,\n plan.plan_token,\n plan.active_interaction_token!,\n message,\n files,\n clientRequestId,\n confirmationToken,\n ...((modeRef.current.revision !== undefined\n ? [questionResponse, modeRef.current.revision]\n : questionResponse\n ? [questionResponse]\n : []) as [PlanningQuestionResponse?, number?]),\n );\n } catch (error) {\n if (!isCurrent()) return null;\n if (error instanceof PlanningActionError && error.code === \"file_unreadable\") {\n setPlanningQuestionError({ code: error.code, message: error.message });\n return null;\n }\n if (\n !(error instanceof PlanningActionError) ||\n !error.newQuestion ||\n !error.speedBumpRequirement ||\n !speedBump\n ) {\n throw error;\n }\n if (error.planningCycle) setActivePlan(error.planningCycle.active ? error.planningCycle : null);\n const candidate = error.newQuestion;\n const confirmation = await speedBump.presentRequired(\n {\n sessionToken: token,\n requestKind: \"message\",\n clientRequestId: candidate.client_request_id,\n message: candidate.message,\n files: candidate.files,\n modelConfig: candidate.model_config ? canonicalizeModelConfig(candidate.model_config) : undefined,\n clientMatterCode: candidate.client_matter_code,\n },\n error.speedBumpRequirement,\n { recheckOnConfirm: false },\n );\n if (!isCurrent() || confirmation === null) return null;\n if (!confirmation) throw new Error(CLERK_ERROR_COPY.genericRetry);\n confirmationToken = confirmation;\n }\n }\n return null;\n },\n {\n pending: {\n kind:\n plan.interaction.kind === \"question\" || plan.interaction.kind === \"scope_decision\"\n ? \"answer\"\n : \"revision\",\n sessionToken: token,\n planToken: plan.plan_token,\n interactionToken: plan.active_interaction_token,\n clientRequestId,\n },\n },\n )\n .then((success) => {\n if (success && planningResponseRetryRef.current?.id === clientRequestId)\n planningResponseRetryRef.current = null;\n return success;\n })\n .finally(() => {\n setStateIfMounted((prev) => ({\n ...prev,\n messages: prev.messages.filter((entry) => entry.id !== optimisticId),\n }));\n });\n },\n [activePlan, runPlanningAction, speedBump, setStateIfMounted],\n );\n\n const editPlan = useCallback(() => {\n const token = tokenRef.current;\n const plan = activePlan;\n const versionToken = plan?.current_version?.version_token;\n if (!token || !plan || !versionToken) return Promise.resolve(false);\n return runPlanningAction(() => apiEditPlanningVersion(token, plan.plan_token, versionToken));\n }, [activePlan, runPlanningAction]);\n\n const confirmPlan = useCallback(() => {\n const token = tokenRef.current;\n const plan = activePlan;\n const versionToken = plan?.current_version?.version_token;\n if (!token || !plan || !versionToken) return Promise.resolve(false);\n return runPlanningAction(() => apiConfirmPlanningVersion(token, plan.plan_token, versionToken), {\n executionSatisfiesAction: true,\n pending: { kind: \"confirm\", sessionToken: token, planToken: plan.plan_token, versionToken },\n });\n }, [activePlan, runPlanningAction]);\n\n const cancelPlan = useCallback(async () => {\n const token = tokenRef.current;\n const plan = activePlan;\n if (!token || !plan || planningCancelInFlightRef.current !== null) return false;\n const cancelId = ++planningCancelIdRef.current;\n planningCancelInFlightRef.current = cancelId;\n try {\n return await runPlanningAction(() => apiCancelPlanningCycle(token, plan.plan_token), {\n allowConcurrent: true,\n supersedeOnSuccess: true,\n });\n } finally {\n if (planningCancelInFlightRef.current === cancelId) planningCancelInFlightRef.current = null;\n }\n }, [activePlan, runPlanningAction]);\n\n const retryRun = useCallback(\n async (failedRunId: string) => {\n if (stateRef.current.readOnly) return;\n\n bumpSessionViewGeneration();\n const token = tokenRef.current;\n const sessionId = sessionIdRef.current;\n if (!token || !failedRunId) return;\n\n const clientRequestId = window.currentAccount?.billing_type === \"credit\" ? crypto.randomUUID() : undefined;\n const speedBumpRequest: CreditAgentSpeedBumpRequest | null =\n clientRequestId && speedBump\n ? {\n sessionToken: token,\n requestKind: \"retry\",\n clientRequestId,\n parentRunToken: failedRunId,\n }\n : null;\n let speedBumpConfirmationToken: string | undefined;\n if (speedBumpRequest && speedBump) {\n try {\n const confirmation = await speedBump.ensureAcknowledged(speedBumpRequest);\n if (!isMountedRef.current) return;\n if (confirmation === null) return;\n speedBumpConfirmationToken = confirmation;\n } catch (err) {\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"error\",\n error: clerkErrorMessage(err instanceof Error ? err.message : null, { fallbackKey: \"genericRetry\" }),\n }));\n return;\n }\n }\n\n const rollbackOptimisticSidenavStatus = optimisticallyMarkClerkRecentWorking(queryClient, token);\n\n const assistantId = generateId();\n const assistantMessage: ChatMessage = {\n id: assistantId,\n role: \"assistant\",\n content: \"\",\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n downloadSelectionExplicit: true,\n isAwaitingUserInput: false,\n isStreaming: true,\n };\n\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n error: null,\n messages: [...prev.messages.map((m) => ({ ...m, retryableRunId: undefined })), assistantMessage],\n }));\n\n try {\n let run;\n while (true) {\n try {\n run = clientRequestId\n ? await apiRetryRun(token, failedRunId, clientRequestId, speedBumpConfirmationToken)\n : await apiRetryRun(token, failedRunId);\n break;\n } catch (err) {\n if (!speedBumpRequest || !speedBump || !isCreditSpeedBumpRequiredError(err) || !err.speedBumpRequirement) {\n throw err;\n }\n\n const confirmation = await speedBump.presentRequired(speedBumpRequest, err.speedBumpRequirement);\n if (!isMountedRef.current) {\n rollbackOptimisticSidenavStatus();\n return;\n }\n if (confirmation === null) {\n rollbackOptimisticSidenavStatus();\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: null,\n messages: restoreRetryability(\n prev.messages.filter((item) => item.id !== assistantId),\n failedRunId,\n ),\n }));\n return;\n }\n speedBumpConfirmationToken = confirmation;\n }\n }\n if (!isMountedRef.current) return;\n\n if (sessionId) {\n void recordUserEvent({\n event_name: \"retry_clerk_run\",\n event_properties: {\n session_id: sessionId,\n failed_run_id: failedRunId,\n retry_run_id: run.run_id,\n },\n });\n }\n\n setStateIfMounted((prev) => ({\n ...prev,\n activeModelConfig: run.model_config ? preserveRunModelConfig(run.model_config) : prev.activeModelConfig,\n messages: prev.messages.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n runId: run.run_id,\n }\n : m,\n ),\n }));\n beginRunStream(token, run.run_id, assistantId, 0, failedRunId);\n } catch (err) {\n rollbackOptimisticSidenavStatus();\n const errorMsg = clerkErrorMessage(err instanceof Error ? err.message : null, { fallbackKey: \"genericRetry\" });\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"error\",\n error: errorMsg,\n messages: restoreRetryability(\n prev.messages.map((m) =>\n m.id === assistantId\n ? {\n ...m,\n isStreaming: false,\n isError: true,\n isTerminalError: true,\n errorMessage: errorMsg,\n content: m.content || errorMsg || CLERK_ERROR_COPY.genericRetry,\n }\n : {\n ...m,\n retryableRunId: undefined,\n },\n ),\n failedRunId,\n ),\n }));\n } finally {\n void queryClient.invalidateQueries({ queryKey: [\"agentPrototypeSessions\", \"infinite\", \"sidenav\"] });\n }\n },\n [beginRunStream, bumpSessionViewGeneration, restoreRetryability, setStateIfMounted, speedBump],\n );\n\n const cancel = useCallback(async () => {\n const tracker = activeRunRef.current;\n const token = tokenRef.current;\n if (featureEnabled(\"clerk_message_queue\") && !pendingPlanning && !activePlan?.active) {\n if (stateRef.current.readOnly || !token || pendingStopRef.current?.token === token) return;\n let resolveStop!: (success: boolean) => void;\n const operation = {\n token,\n promise: new Promise((resolve) => {\n resolveStop = resolve;\n }),\n };\n pendingStopRef.current = operation;\n const messageIds = new Set(\n stateRef.current.messages\n .filter((message) => message.queueState === \"pending\" && message.serverMessageId !== undefined)\n .map((message) => message.serverMessageId!),\n );\n if (tracker) tracker.cancelledByUser = true;\n bumpSessionViewGeneration();\n const stoppedGeneration = sessionViewGenerationRef.current;\n const isCurrent = () =>\n isMountedRef.current && tokenRef.current === token && sessionViewGenerationRef.current === stoppedGeneration;\n setPendingStopAcceptance({ token, generation: stoppedGeneration, messageIds });\n inputMutationEpochRef.current += 1;\n clearRecoveryTimeout();\n cancelStream();\n activeRunRef.current = null;\n pendingTerminalHydrationRef.current = null;\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: null,\n pendingClarifyingQuestion: null,\n messages: prev.messages.map((m) =>\n m.isStreaming ? { ...m, isAwaitingUserInput: false, isStreaming: false } : m,\n ),\n }));\n let succeeded = false;\n try {\n const response = tracker?.runId\n ? await apiCancelSession(token, tracker.runId, \"queue\")\n : await apiCancelSession(token);\n if (!isCurrent()) return;\n const mergeAccepted = () => {\n if (!isCurrent() || !response) return;\n inputMutationEpochRef.current += 1;\n setStateIfMounted((prev) => {\n const accepted = new Map(\n (response.user_messages || []).map((message) => [message.id, mapServerMessage(token, message)]),\n );\n const messages = prev.messages.map((message) => {\n const replacement =\n message.serverMessageId !== undefined ? accepted.get(message.serverMessageId) : undefined;\n if (replacement) accepted.delete(message.serverMessageId!);\n return replacement || message;\n });\n return {\n ...prev,\n messages: [...messages, ...Array.from(accepted.values())],\n queueDispatch: response.queue_dispatch === undefined ? prev.queueDispatch : response.queue_dispatch,\n };\n });\n };\n mergeAccepted();\n await hydrateSession(token, { preserveOlderPages: true, hydrationIsCurrent: isCurrent }).catch(() => null);\n // A snapshot begun before cancellation can still contain the old queue rows.\n // The cancellation response is authoritative for the IDs it admitted.\n mergeAccepted();\n succeeded = isCurrent();\n if (succeeded) uncertainStopSessionsRef.current.delete(token);\n } catch (error) {\n if (!isCurrent()) return;\n const session = await hydrateSession(token, {\n preserveOlderPages: true,\n hydrationIsCurrent: isCurrent,\n }).catch(() => null);\n if (!isCurrent()) return;\n if (session) uncertainStopSessionsRef.current.delete(token);\n else uncertainStopSessionsRef.current.add(token);\n // A lost response may still have committed Stop. Require an authoritative\n // paused, idle snapshot before allowing an already waiting Send to continue.\n succeeded =\n !!session &&\n !sessionRunIsActive(session) &&\n session.queue_dispatch?.paused === true &&\n Array.from(messageIds).every((id) =>\n session.messages.some((message) => message.id === id && message.queue_state !== \"pending\"),\n );\n if (succeeded && session) {\n // An already waiting Send can advance the view generation before React\n // applies hydration. Retain the confirmed message admission separately.\n setStateIfMounted((prev) => ({\n ...prev,\n queueDispatch: session.queue_dispatch,\n messages: prev.messages.map((message) => {\n const confirmed = session.messages.find((entry) => entry.id === message.serverMessageId);\n return confirmed && messageIds.has(confirmed.id) ? mapServerMessage(token, confirmed) : message;\n }),\n }));\n }\n if (session && sessionRunIsActive(session)) reconnectHydratedActiveRun(session);\n if (!session && tracker) {\n // Neither transport established cancellation. Resume observation of the\n // same run so its eventual terminal event can reconcile the conversation.\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"streaming\",\n messages: prev.messages.map((message) =>\n message.id === tracker.assistantId ? { ...message, isStreaming: true } : message,\n ),\n }));\n beginRunStream(token, tracker.runId, tracker.assistantId, tracker.lastEventId, tracker.retrySourceRunId);\n }\n if (!succeeded)\n setStateIfMounted((prev) => ({\n ...prev,\n error: clerkErrorMessage(error instanceof Error ? error.message : null, { fallbackKey: \"genericRetry\" }),\n }));\n } finally {\n if (pendingStopRef.current === operation) pendingStopRef.current = null;\n setPendingStopAcceptance((current) =>\n current?.token === token && current.generation === stoppedGeneration ? null : current,\n );\n resolveStop(succeeded);\n }\n return;\n }\n if (stateRef.current.readOnly || stopInFlightRef.current || !token || !tracker) return;\n // Keep stream callbacks and transport recovery valid while cancellation is\n // unconfirmed. A failed request and failed refresh must not strand the run.\n const generation = sessionViewGenerationRef.current;\n const operationId = ++planningActionIdRef.current;\n stopInFlightRef.current = true;\n setPendingAction({ kind: \"stop\", sessionToken: token, runToken: tracker.runId, operationId });\n const isCurrent = () =>\n isMountedRef.current && tokenRef.current === token && sessionViewGenerationRef.current === generation;\n try {\n await apiCancelSession(token, tracker.runId);\n if (!isCurrent() || (activeRunRef.current && activeRunRef.current.runId !== tracker.runId)) return;\n if (activeRunRef.current) activeRunRef.current.cancelledByUser = true;\n pendingSubmissionsRef.current.forEach((submission) => {\n if (submission.generation === generation) submission.stopped = true;\n });\n bumpSessionViewGeneration();\n clearRecoveryTimeout();\n cancelStream();\n activeRunRef.current = null;\n pendingTerminalHydrationRef.current = null;\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n error: null,\n pendingClarifyingQuestion: null,\n messages: prev.messages.map((m) =>\n m.isStreaming ? { ...m, isAwaitingUserInput: false, isStreaming: false } : m,\n ),\n }));\n await releaseStoppedModeAdmission();\n } catch (error) {\n if (!isCurrent()) return;\n // Keep the original stream alive until the server establishes the result.\n // In particular, a stale tab must never cancel the replacement run.\n const currentTracker = activeRunRef.current;\n if (!currentTracker || currentTracker.runId !== tracker.runId || currentTracker.terminated) return;\n const streamEventId = currentTracker.lastEventId;\n const reconciliationIsCurrent = () =>\n isCurrent() &&\n activeRunRef.current === currentTracker &&\n !currentTracker.terminated &&\n currentTracker.lastEventId === streamEventId;\n try {\n const session = await hydrateSession(token, {\n preserveOlderPages: true,\n preserveStreaming: true,\n requireActiveRunMatch: true,\n pollingActiveRunTail: { runId: currentTracker.runId, assistantId: currentTracker.assistantId },\n hydrationIsCurrent: reconciliationIsCurrent,\n });\n if (!isCurrent() || !session) return;\n if (!sessionRunIsActive(session)) {\n currentTracker.cancelledByUser = true;\n pendingSubmissionsRef.current.forEach((submission) => {\n if (submission.generation === generation) submission.stopped = true;\n });\n bumpSessionViewGeneration();\n clearRecoveryTimeout();\n cancelStream();\n activeRunRef.current = null;\n await releaseStoppedModeAdmission();\n return;\n }\n reconnectHydratedActiveRun(session);\n } catch {\n if (!reconciliationIsCurrent()) return;\n }\n setStateIfMounted((prev) => ({\n ...prev,\n error: clerkErrorMessage(error instanceof Error ? error.message : null, { fallbackKey: \"genericRetry\" }),\n }));\n } finally {\n if (isCurrent()) {\n stopInFlightRef.current = false;\n setPendingAction((current) => (current?.operationId === operationId ? null : current));\n }\n }\n }, [\n activePlan?.active,\n beginRunStream,\n pendingPlanning,\n bumpSessionViewGeneration,\n cancelStream,\n clearRecoveryTimeout,\n hydrateSession,\n reconnectHydratedActiveRun,\n releaseStoppedModeAdmission,\n setStateIfMounted,\n ]);\n\n const reset = useCallback(() => {\n setRestoreDraft(undefined);\n invalidateModeOperation();\n bumpSessionViewGeneration();\n clearRecoveryTimeout();\n cancelStream();\n activeRunRef.current = null;\n clearPendingTerminalHydration();\n sessionIdRef.current = null;\n tokenRef.current = null;\n modeRef.current = { token: null, value: false, revision: undefined };\n modeUncertainRef.current = false;\n setPlanningModeValue(false);\n answeredClarifyingQuestionIdsRef.current = new Set();\n resolvedClarifyingQuestionIdsRef.current = new Set();\n acknowledgingClarifyingQuestionIdsRef.current = new Set();\n viewedClarifyingQuestionIdsRef.current = new Set();\n timedOutClarifyingQuestionIdsRef.current = new Set();\n setActivePlan(null);\n setStateIfMounted({\n sessionId: null,\n token: null,\n title: null,\n status: \"idle\",\n messages: [],\n hasMoreMessages: false,\n nextMessageCursor: null,\n oldestServerMessageId: null,\n error: null,\n pendingClarifyingQuestion: null,\n docketConnectRetrievalRequest: null,\n activeTranscript: null,\n activeModelConfig: null,\n readOnly: false,\n clientMatterCode: null,\n });\n }, [bumpSessionViewGeneration, cancelStream, clearPendingTerminalHydration, clearRecoveryTimeout, setStateIfMounted]);\n\n // Restricted planning requests wait for the model before returning their HTTP\n // response. Discover the durable run meanwhile so the existing Stop control\n // works without hydrating over the user's optimistic answer or draft.\n useEffect(() => {\n const pendingTurn = pendingAction && [\"answer\", \"revision\", \"accept\"].includes(pendingAction.kind);\n if (!pendingPlanning && !pendingTurn) return;\n let disposed = false;\n let inFlight = false;\n const generation = sessionViewGenerationRef.current;\n const actionGeneration = planningActionGenerationRef.current;\n const discoverRun = async () => {\n const token = tokenRef.current;\n if (disposed || inFlight || !token || (activeRunRef.current && !activeRunRef.current.terminated)) return;\n inFlight = true;\n try {\n const session = await getSession(token);\n if (\n disposed ||\n !isMountedRef.current ||\n tokenRef.current !== token ||\n session.token !== token ||\n generation !== sessionViewGenerationRef.current ||\n actionGeneration !== planningActionGenerationRef.current ||\n (activeRunRef.current && !activeRunRef.current.terminated) ||\n session.active_plan?.interaction.kind !== \"loading\" ||\n (pendingTurn && session.active_plan.plan_token !== pendingAction.planToken) ||\n !sessionRunIsActive(session) ||\n session.active_run?.pending_input_request\n )\n return;\n applyPlanningMode(session, token);\n setStateIfMounted((prev) => ({ ...prev, token, sessionId: session.session_id }));\n const placeholder = [...stateRef.current.messages]\n .reverse()\n .find((message) => message.role === \"assistant\" && message.isStreaming && !message.runId);\n reconnectHydratedActiveRun(session, placeholder?.id);\n } catch {\n // The pending mutation still owns success/error recovery. Retry discovery\n // without turning a transient read failure into a failed submission.\n } finally {\n inFlight = false;\n }\n };\n void discoverRun();\n const interval = window.setInterval(() => void discoverRun(), 1_500);\n return () => {\n disposed = true;\n window.clearInterval(interval);\n };\n }, [pendingPlanning, pendingAction, state.status, applyPlanningMode, reconnectHydratedActiveRun, setStateIfMounted]);\n\n const loadSession = useCallback(\n async (token: string) => {\n const pendingLoad = pendingSessionLoadRef.current;\n const rollbackSnapshot =\n pendingLoad?.generation === sessionViewGenerationRef.current\n ? pendingLoad.rollbackSnapshot\n : snapshotCurrentSessionView();\n invalidateModeOperation();\n bumpSessionViewGeneration();\n const operation: PendingSessionLoad = {\n generation: sessionViewGenerationRef.current,\n rollbackSnapshot,\n };\n pendingSessionLoadRef.current = operation;\n const loadIsCurrent = () => isMountedRef.current && sessionViewGenerationRef.current === operation.generation;\n clearRecoveryTimeout();\n if (activeRunRef.current) {\n activeRunRef.current.cancelledByUser = true;\n }\n cancelStream();\n activeRunRef.current = null;\n clearPendingTerminalHydration();\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"creating\",\n error: null,\n pendingClarifyingQuestion: null,\n }));\n try {\n const session = await hydrateSession(token, { allowTokenMismatch: true, hydrationIsCurrent: loadIsCurrent });\n if (!loadIsCurrent() || !session) return null;\n setRestoreDraft(undefined);\n\n acknowledgingClarifyingQuestionIdsRef.current = new Set();\n resolvedClarifyingQuestionIdsRef.current = new Set();\n viewedClarifyingQuestionIdsRef.current = new Set();\n timedOutClarifyingQuestionIdsRef.current = new Set();\n\n reconnectHydratedActiveRun(session);\n return session;\n } catch {\n if (!loadIsCurrent()) return null;\n restoreSessionView(rollbackSnapshot, {\n error: CLERK_ERROR_COPY.conversationLoadFailure,\n reconnectActiveRun: rollbackSnapshot.state.status === \"streaming\" && rollbackSnapshot.activeRun !== null,\n });\n return null;\n } finally {\n if (pendingSessionLoadRef.current === operation) {\n pendingSessionLoadRef.current = null;\n }\n }\n },\n [\n bumpSessionViewGeneration,\n cancelStream,\n clearPendingTerminalHydration,\n clearRecoveryTimeout,\n hydrateSession,\n reconnectHydratedActiveRun,\n restoreSessionView,\n setStateIfMounted,\n snapshotCurrentSessionView,\n ],\n );\n\n useEffect(() => {\n if (\n !state.token ||\n state.readOnly ||\n state.status === \"creating\" ||\n (!activePlan && modeRef.current.revision === undefined)\n )\n return;\n let inFlight = false;\n let disposed = false;\n const reconcile = async () => {\n if (disposed || stateRef.current.status === \"creating\" || document.visibilityState !== \"visible\" || inFlight)\n return;\n if (modePendingRef.current || modeAdmissionRef.current !== null) return;\n if (planningActionsInFlightRef.current.size > 0) {\n planningReconciliationPendingRef.current = true;\n return;\n }\n // A live run already owns its stream and authoritative progress updates.\n if (activeRunRef.current && !activeRunRef.current.terminated && activePlan?.status !== \"offered\") {\n if (modeRef.current.revision === undefined) return;\n inFlight = true;\n try {\n const session = await getSession(state.token!);\n if (!disposed && tokenRef.current === state.token) applyPlanningMode(session, state.token!);\n } catch {\n /* The active run owns connection recovery. */\n } finally {\n inFlight = false;\n }\n return;\n }\n const token = state.token!;\n const generation = planningActionGenerationRef.current;\n const previousError = stateRef.current.error;\n const staleError = planningConflictErrorRef.current;\n const recoveringRefresh = planningRefreshFailedRef.current;\n const requestSequence = hydrationRequestSequenceRef.current + 1;\n const isCurrent = () =>\n !disposed &&\n isMountedRef.current &&\n tokenRef.current === token &&\n generation === planningActionGenerationRef.current &&\n hydrationRequestSequenceRef.current === requestSequence;\n inFlight = true;\n try {\n const tracker = activeRunRef.current;\n const streamEventId = tracker?.lastEventId;\n const session = await hydrateSession(token, {\n preserveOlderPages: true,\n preserveStreaming: !!tracker,\n ...(tracker ? { pollingActiveRunTail: { runId: tracker.runId, assistantId: tracker.assistantId } } : {}),\n preserveError: !staleError && !recoveringRefresh,\n hydrationIsCurrent: () =>\n !disposed &&\n generation === planningActionGenerationRef.current &&\n activeRunRef.current === tracker &&\n tracker?.lastEventId === streamEventId,\n });\n if (!session) return;\n if (tracker && !sessionRunIsActive(session)) {\n tracker.cancelledByUser = true;\n cancelStream();\n activeRunRef.current = null;\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"active\",\n messages: prev.messages.map((message) => ({ ...message, isStreaming: false, isAwaitingUserInput: false })),\n }));\n } else if (\n !(\n tracker?.runId === session.active_run?.run_id &&\n session.active_run?.pending_input_request?.kind === \"planning_offer\"\n )\n ) {\n reconnectHydratedActiveRun(session);\n }\n if (staleError === planningConflictErrorRef.current) planningConflictErrorRef.current = null;\n planningRefreshFailedRef.current = false;\n if (previousError && !staleError && !recoveringRefresh) {\n setStateIfMounted((prev) => ({ ...prev, error: previousError }));\n }\n } catch {\n if (isCurrent() && !stateRef.current.error) {\n planningRefreshFailedRef.current = true;\n setStateIfMounted((prev) =>\n isCurrent() && !prev.error ? { ...prev, error: CLERK_ERROR_COPY.conversationLoadFailure } : prev,\n );\n }\n } finally {\n inFlight = false;\n }\n };\n const onReturn = () => void reconcile();\n planningReconciliationRef.current = onReturn;\n // Only an active cycle advances server-side while this tab watches. Mode\n // changes from another tab sync on focus, and stale sends are rejected by\n // the mode revision check. Without a cycle, the tick only retries an\n // uncertain mode change (which blocks sending) or a failed refresh (which\n // shows a load error) until one read succeeds.\n const intervalId = window.setInterval(() => {\n if (activePlan || modeUncertainRef.current || planningRefreshFailedRef.current) onReturn();\n }, 1_500);\n window.addEventListener(\"focus\", onReturn);\n document.addEventListener(\"visibilitychange\", onReturn);\n return () => {\n disposed = true;\n window.clearInterval(intervalId);\n if (planningReconciliationRef.current === onReturn) planningReconciliationRef.current = null;\n window.removeEventListener(\"focus\", onReturn);\n document.removeEventListener(\"visibilitychange\", onReturn);\n };\n }, [\n activePlan,\n state.status,\n state.token,\n hydrateSession,\n reconnectHydratedActiveRun,\n setStateIfMounted,\n cancelStream,\n ]);\n\n useEffect(() => {\n if (activePlan?.status !== \"offered\" || !activePlan.offer_expires_at) return;\n const token = tokenRef.current;\n if (!token) return;\n const remaining = new Date(activePlan.offer_expires_at).getTime() - Date.now();\n const timeoutId = window.setTimeout(() => planningReconciliationRef.current?.(), Math.max(1_000, remaining + 500));\n return () => window.clearTimeout(timeoutId);\n }, [activePlan, loadSession]);\n\n useEffect(() => {\n if (activePlan?.interaction.kind !== \"loading\" || !activePlan.updated_at) return;\n const token = tokenRef.current;\n if (!token) return;\n const remaining = new Date(activePlan.updated_at).getTime() + PLANNING_TURN_STALE_AFTER_MS - Date.now();\n const timeoutId = window.setTimeout(() => planningReconciliationRef.current?.(), Math.max(1_000, remaining + 500));\n return () => window.clearTimeout(timeoutId);\n }, [activePlan, loadSession]);\n\n const bootstrapSession = useCallback(\n async (activeTranscript: ActiveTranscriptReference, modelConfig?: ModelConfig) => {\n const canonicalModelConfig = canonicalizeOptionalModelConfig(modelConfig);\n if (isCreatingRef.current) return;\n\n bumpSessionViewGeneration();\n clearRecoveryTimeout();\n cancelStream();\n activeRunRef.current = null;\n clearPendingTerminalHydration();\n sessionIdRef.current = null;\n tokenRef.current = null;\n answeredClarifyingQuestionIdsRef.current = new Set();\n resolvedClarifyingQuestionIdsRef.current = new Set();\n acknowledgingClarifyingQuestionIdsRef.current = new Set();\n viewedClarifyingQuestionIdsRef.current = new Set();\n timedOutClarifyingQuestionIdsRef.current = new Set();\n isCreatingRef.current = true;\n setStateIfMounted({\n sessionId: null,\n token: null,\n title: null,\n status: \"creating\",\n messages: [],\n hasMoreMessages: false,\n nextMessageCursor: null,\n oldestServerMessageId: null,\n error: null,\n pendingClarifyingQuestion: null,\n docketConnectRetrievalRequest: null,\n activeTranscript: null,\n activeModelConfig: canonicalModelConfig || null,\n readOnly: false,\n clientMatterCode: null,\n });\n\n try {\n const session = await createSession(canonicalModelConfig, activeTranscript);\n if (!isMountedRef.current) return null;\n return await hydrateSession(session.token);\n } catch (err) {\n setStateIfMounted((prev) => ({\n ...prev,\n status: \"error\",\n error: clerkErrorMessage(err instanceof Error ? err.message : null, { fallbackKey: \"genericRetry\" }),\n }));\n return null;\n } finally {\n isCreatingRef.current = false;\n }\n },\n [\n bumpSessionViewGeneration,\n cancelStream,\n clearPendingTerminalHydration,\n clearRecoveryTimeout,\n hydrateSession,\n setStateIfMounted,\n ],\n );\n\n const loadOlderMessages = useCallback(async () => {\n const token = tokenRef.current;\n const cursor = state.nextMessageCursor;\n const beforeMessageId = state.oldestServerMessageId;\n if (!token || !state.hasMoreMessages || (!cursor && !beforeMessageId)) return;\n\n try {\n const session = await getSession(\n token,\n cursor\n ? {\n cursor,\n limit: 50,\n }\n : {\n beforeMessageId: beforeMessageId!,\n limit: 50,\n },\n );\n if (tokenRef.current !== token) return;\n\n const olderMessages: ChatMessage[] = session.messages\n .filter(\n (msg) => msg.queue_state !== \"cancelled\" && !(msg.metadata as Record | null)?.auto_resumed,\n )\n .map((msg) => ({ ...mapServerMessage(session.token, msg), isHistoricalPage: true }));\n const answeredClarifyingQuestionIds = answeredClarifyingQuestionIdsFromMessages(session.messages);\n answeredClarifyingQuestionIds.forEach((questionId) => {\n answeredClarifyingQuestionIdsRef.current.add(questionId);\n });\n\n setStateIfMounted((prev) => {\n if (tokenRef.current !== token || prev.token !== token) return prev;\n\n const existingIds = new Set(prev.messages.map((message) => message.id));\n const dedupedOlderMessages = olderMessages.filter((message) => !existingIds.has(message.id));\n\n return {\n ...prev,\n messages: [...dedupedOlderMessages, ...prev.messages],\n hasMoreMessages: !!session.has_more,\n nextMessageCursor: session.next_cursor || null,\n oldestServerMessageId: session.oldest_message_id_in_page || prev.oldestServerMessageId,\n error: null,\n };\n });\n } catch (err) {\n setStateIfMounted((prev) => ({\n ...prev,\n error: clerkErrorMessage(err instanceof Error ? err.message : null, { fallbackKey: \"conversationLoadFailure\" }),\n }));\n }\n }, [\n mapServerMessage,\n setStateIfMounted,\n state.hasMoreMessages,\n state.nextMessageCursor,\n state.oldestServerMessageId,\n ]);\n\n const submitClarifyingAnswer = useCallback(\n async (\n questionId: string,\n answer: string,\n interactionStartedAtMs?: number,\n response?: ClarifyingQuestionResponse,\n files?: AttachedFile[],\n ) => {\n const token = tokenRef.current;\n if (stateRef.current.readOnly) return;\n if (!token) return;\n\n const question = stateRef.current.pendingClarifyingQuestion;\n if (!question || question.questionId !== questionId) return;\n const submissionStartedAtMs =\n typeof interactionStartedAtMs === \"number\" && Number.isFinite(interactionStartedAtMs)\n ? interactionStartedAtMs\n : Date.now();\n if (clarifyingQuestionIsLocallyExpired(question, submissionStartedAtMs)) {\n expireClarifyingQuestion(questionId);\n return;\n }\n if (answeredClarifyingQuestionIdsRef.current.has(questionId)) return;\n answeredClarifyingQuestionIdsRef.current.add(questionId);\n const submissionGeneration = sessionViewGenerationRef.current;\n const existingQuestionMessage = stateRef.current.messages.find(\n (message) => message.clarifyingQuestionId === questionId && message.clarifyingMessageRole === \"question\",\n );\n const existingAnswerMessage = stateRef.current.messages.find(\n (message) => message.clarifyingQuestionId === questionId && message.clarifyingMessageRole === \"answer\",\n );\n const legacyQuestionMessage = {\n ...(existingQuestionMessage || createDisplayMessage(generateId(), \"assistant\", question.question)),\n content: question.question,\n clarifyingQuestionId: questionId,\n clarifyingMessageRole: \"question\" as const,\n };\n const legacyAnswerMessage = {\n ...(existingAnswerMessage || createDisplayMessage(generateId(), \"user\", answer)),\n content: answer,\n files: files?.map(({ name, size, type }) => ({ name, size, type })) ?? existingAnswerMessage?.files ?? [],\n clarifyingQuestionId: questionId,\n clarifyingMessageRole: \"answer\" as const,\n };\n\n setStateIfMounted((prev) => {\n const updatedMessages = prev.messages.map((message) => {\n if (message.id === legacyQuestionMessage.id) return legacyQuestionMessage;\n if (message.id === legacyAnswerMessage.id) return legacyAnswerMessage;\n return message.isStreaming ? { ...message, isAwaitingUserInput: false } : message;\n });\n const existingIds = new Set(updatedMessages.map((message) => message.id));\n const missingLegacyMessages: ChatMessage[] = [];\n if (!existingIds.has(legacyQuestionMessage.id)) {\n missingLegacyMessages.push(legacyQuestionMessage);\n }\n if (!existingIds.has(legacyAnswerMessage.id)) {\n missingLegacyMessages.push(legacyAnswerMessage);\n }\n return {\n ...prev,\n error: null,\n pendingClarifyingQuestion: null,\n messages: insertBeforeStreamingOrAppend(updatedMessages, ...missingLegacyMessages),\n };\n });\n\n try {\n const result =\n response || files\n ? await apiSubmitAnswer(token, question.runId, questionId, answer, question.question, response, files)\n : await apiSubmitAnswer(token, question.runId, questionId, answer, question.question);\n if (sessionViewGenerationRef.current !== submissionGeneration || tokenRef.current !== token) {\n return;\n }\n let acceptedDisplayMessages = [legacyQuestionMessage, legacyAnswerMessage];\n if (result.display_messages?.length) {\n inputMutationEpochRef.current += 1;\n const displayMessages = result.display_messages\n .filter(\n (\n message,\n ): message is {\n id: number;\n role: \"user\" | \"assistant\";\n content: string;\n files?: FileMetadata[] | null;\n } => message.role === \"user\" || message.role === \"assistant\",\n )\n .map((message, index) => ({\n ...createDisplayMessage(`loaded-${message.id}`, message.role, message.content),\n serverMessageId: message.id,\n files: message.files ?? [],\n clarifyingQuestionId: questionId,\n clarifyingMessageRole: (index === 0 ? \"question\" : \"answer\") as \"question\" | \"answer\",\n }));\n acceptedDisplayMessages = displayMessages;\n const displayMessageIds = new Set(displayMessages.map((message) => message.id));\n setStateIfMounted((prev) => ({\n ...prev,\n messages: insertBeforeStreamingOrAppend(\n prev.messages.filter(\n (message) =>\n !displayMessageIds.has(message.id) &&\n !(\n message.clarifyingQuestionId === questionId &&\n (message.clarifyingMessageRole === \"question\" || message.clarifyingMessageRole === \"answer\")\n ),\n ),\n ...displayMessages,\n ),\n }));\n }\n if (result.ok !== true) {\n const discardOptimisticAnswer = result.reason === \"not_waiting\" && !result.display_messages?.length;\n // A definitive rejection must not leave an uploaded file visible after\n // Rails has discarded its answer and attachment. Fence older hydration.\n if (discardOptimisticAnswer) inputMutationEpochRef.current += 1;\n if (result.reason === \"conflict\") {\n await hydrateSession(token, {\n preserveStreaming: stateRef.current.status === \"streaming\",\n preserveOlderPages: true,\n pollingActiveRunTail: activeRunRef.current\n ? {\n runId: activeRunRef.current.runId,\n assistantId: activeRunRef.current.assistantId,\n }\n : null,\n });\n }\n setStateIfMounted((prev) => ({\n ...prev,\n error:\n result.reason === \"conflict\"\n ? CLERK_ERROR_COPY.clarifyingAnswerConflict\n : CLERK_ERROR_COPY.clarifyingAnswerNoLongerAccepted,\n messages: discardOptimisticAnswer\n ? prev.messages.filter((message) => message.clarifyingQuestionId !== questionId)\n : prev.messages,\n }));\n return;\n }\n if (question.durable) {\n if (!result.display_messages?.length) inputMutationEpochRef.current += 1;\n await resumeRunAfterDurableInput(token, result.input_request_id || questionId, acceptedDisplayMessages);\n }\n } catch (error) {\n if (resolvedClarifyingQuestionIdsRef.current.has(questionId)) return;\n\n const responseStatus =\n typeof error === \"object\" && error !== null && \"status\" in error\n ? (error as { status?: unknown }).status\n : null;\n const status = typeof responseStatus === \"number\" ? responseStatus : null;\n const canRetry =\n (status === null || status >= 500 || status === 422) &&\n sessionViewGenerationRef.current === submissionGeneration &&\n tokenRef.current === token &&\n !resolvedClarifyingQuestionIdsRef.current.has(questionId) &&\n !timedOutClarifyingQuestionIdsRef.current.has(questionId);\n if (canRetry) {\n answeredClarifyingQuestionIdsRef.current.delete(questionId);\n }\n setStateIfMounted((prev) => ({\n ...prev,\n error:\n status === 422 && error instanceof Error\n ? error.message\n : status !== null && status < 500\n ? CLERK_ERROR_COPY.clarifyingAnswerSubmitFailure\n : CLERK_ERROR_COPY.clarifyingAnswerUncertainDelivery,\n pendingClarifyingQuestion:\n canRetry && (!prev.pendingClarifyingQuestion || prev.pendingClarifyingQuestion.questionId === questionId)\n ? cloneClarifyingQuestion(question)\n : prev.pendingClarifyingQuestion,\n messages: canRetry\n ? prev.messages\n .filter((message) => status !== 422 || message.clarifyingQuestionId !== questionId)\n .map((message) =>\n message.runId === question.runId || message.isStreaming\n ? { ...message, isAwaitingUserInput: true }\n : message,\n )\n : prev.messages,\n }));\n }\n },\n [\n expireClarifyingQuestion,\n hydrateSession,\n resumeRunAfterDurableInput,\n setStateIfMounted,\n state.pendingClarifyingQuestion,\n ],\n );\n\n const beginDocketConnectApprovalOperation = useCallback(\n (approvalRequestId: string | number): DocketConnectApprovalOperationContext | null => {\n const token = tokenRef.current;\n const currentState = stateRef.current;\n const request = currentState.docketConnectRetrievalRequest;\n const approval = request?.current_approval;\n const activeSurface = request?.active_surface;\n if (\n !token ||\n currentState.token !== token ||\n !request ||\n !approval ||\n String(approval.id) !== String(approvalRequestId) ||\n approval.status !== \"pending\" ||\n (activeSurface !== \"limit_approval\" && activeSurface !== \"retrieval_approval\")\n ) {\n return null;\n }\n\n docketConnectApprovalOperationIdRef.current += 1;\n return {\n operationId: docketConnectApprovalOperationIdRef.current,\n generation: sessionViewGenerationRef.current,\n token,\n retrievalRequestId: String(request.retrieval_request_id),\n approvalRequestId: String(approvalRequestId),\n authorizationVersion: approval.authorization_version,\n requestStatus: request.status,\n activeSurface,\n };\n },\n [],\n );\n\n const docketConnectApprovalOperationIsStillOwned = useCallback(\n (operation: DocketConnectApprovalOperationContext, candidateState: SessionState = stateRef.current) => {\n const request = candidateState.docketConnectRetrievalRequest;\n return (\n isMountedRef.current &&\n docketConnectApprovalOperationIdRef.current === operation.operationId &&\n sessionViewGenerationRef.current === operation.generation &&\n tokenRef.current === operation.token &&\n candidateState.token === operation.token &&\n String(request?.retrieval_request_id) === operation.retrievalRequestId\n );\n },\n [],\n );\n\n const docketConnectApprovalOperationIsCurrent = useCallback(\n (operation: DocketConnectApprovalOperationContext, candidateState: SessionState = stateRef.current) => {\n const request = candidateState.docketConnectRetrievalRequest;\n const approval = request?.current_approval;\n return (\n docketConnectApprovalOperationIsStillOwned(operation, candidateState) &&\n request?.status === operation.requestStatus &&\n request?.active_surface === operation.activeSurface &&\n String(approval?.id) === operation.approvalRequestId &&\n approval?.status === \"pending\" &&\n approval?.authorization_version === operation.authorizationVersion\n );\n },\n [docketConnectApprovalOperationIsStillOwned],\n );\n\n const docketConnectRequestMatchesApprovalOperation = useCallback(\n (\n request: DocketConnectRetrievalRequestPayload | null,\n operation: DocketConnectApprovalOperationContext,\n ): request is DocketConnectRetrievalRequestPayload =>\n !!request && String(request.retrieval_request_id) === operation.retrievalRequestId,\n [],\n );\n\n const attachDocketConnectContinuationRun = useCallback(\n (operation: DocketConnectApprovalOperationContext, run: ActiveRun | null | undefined) => {\n if (!run || (run.status !== \"queued\" && run.status !== \"running\")) return;\n if (!docketConnectApprovalOperationIsStillOwned(operation)) return;\n\n const activeTracker = activeRunRef.current;\n if (activeTracker?.runId === run.run_id) return;\n if (activeTracker && !activeTracker.terminated) return;\n\n const assistantId = generateId();\n setStateIfMounted((prev) => {\n if (!docketConnectApprovalOperationIsStillOwned(operation, prev)) return prev;\n\n return {\n ...prev,\n status: \"streaming\",\n activeModelConfig: run.model_config ? preserveRunModelConfig(run.model_config) : prev.activeModelConfig,\n messages: [\n ...prev.messages,\n {\n id: assistantId,\n role: \"assistant\",\n content: \"\",\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n downloadSelectionExplicit: true,\n isAwaitingUserInput: false,\n isStreaming: true,\n },\n ],\n error: null,\n };\n });\n beginRunStream(operation.token, run.run_id, assistantId, 0, run.retry_source_run_id || undefined);\n },\n [beginRunStream, docketConnectApprovalOperationIsStillOwned, setStateIfMounted],\n );\n\n const confirmDocketConnectContinuation = useCallback(\n async (operation: DocketConnectApprovalOperationContext, requirement: DocketConnectContinuationCreditSpeedBump) => {\n if (!speedBump || !docketConnectApprovalOperationIsStillOwned(operation)) return null;\n\n return speedBump.presentRequired(\n {\n sessionToken: operation.token,\n requestKind: requirement.requestKind,\n clientRequestId: requirement.clientRequestId,\n clientMatterCode: requirement.clientMatterCode,\n },\n requirement,\n { recheckOnConfirm: false },\n );\n },\n [docketConnectApprovalOperationIsStillOwned, speedBump],\n );\n\n const approveDocketConnectApproval = useCallback(\n async (approvalRequestId: string | number) => {\n const operation = beginDocketConnectApprovalOperation(approvalRequestId);\n if (!operation) return false;\n\n let decisionApplied = false;\n let speedBumpConfirmationToken: string | undefined;\n try {\n while (true) {\n const result = await apiSubmitDocketConnectApproval(\n operation.token,\n approvalRequestId,\n speedBumpConfirmationToken,\n );\n const request = cloneDocketConnectRetrievalRequest(result.retrieval_request);\n if (!docketConnectRequestMatchesApprovalOperation(request, operation)) return false;\n const operationStillOwned = docketConnectApprovalOperationIsStillOwned(operation);\n if (!operationStillOwned) return false;\n\n if (!decisionApplied) {\n if (!docketConnectApprovalOperationIsCurrent(operation)) {\n attachDocketConnectContinuationRun(operation, result.continuation_run);\n return operation.activeSurface === \"limit_approval\";\n }\n const continuationError = result.continuation_error\n ? clerkErrorMessage(result.continuation_error, { fallbackKey: \"genericRetry\" })\n : null;\n setStateIfMounted((prev) =>\n docketConnectApprovalOperationIsCurrent(operation, prev)\n ? {\n ...prev,\n docketConnectRetrievalRequest: request,\n error: continuationError,\n }\n : prev,\n );\n decisionApplied = true;\n }\n\n attachDocketConnectContinuationRun(operation, result.continuation_run);\n const creditRequirement = result.continuationCreditSpeedBump;\n if (!creditRequirement) return true;\n\n const confirmation = await confirmDocketConnectContinuation(operation, creditRequirement);\n if (!isMountedRef.current || !docketConnectApprovalOperationIsStillOwned(operation)) return false;\n if (confirmation === null) return true;\n speedBumpConfirmationToken = confirmation;\n }\n } catch (err) {\n const request = docketConnectRetrievalRequestFromError(err);\n if (request) {\n if (\n docketConnectApprovalOperationIsCurrent(operation) &&\n docketConnectRequestMatchesApprovalOperation(request, operation)\n ) {\n setStateIfMounted((prev) =>\n docketConnectApprovalOperationIsCurrent(operation, prev)\n ? { ...prev, docketConnectRetrievalRequest: request, error: null }\n : prev,\n );\n }\n return false;\n }\n if (\n !decisionApplied &&\n (!docketConnectApprovalOperationIsCurrent(operation) ||\n !docketConnectApprovalOperationIsStillOwned(operation))\n ) {\n return false;\n }\n const rawErrorMessage = err instanceof Error ? err.message : null;\n setStateIfMounted((prev) =>\n docketConnectApprovalOperationIsStillOwned(operation, prev)\n ? {\n ...prev,\n error: clerkErrorMessage(rawErrorMessage, { fallbackKey: \"genericRetry\" }),\n }\n : prev,\n );\n return false;\n }\n },\n [\n beginDocketConnectApprovalOperation,\n attachDocketConnectContinuationRun,\n confirmDocketConnectContinuation,\n docketConnectApprovalOperationIsCurrent,\n docketConnectApprovalOperationIsStillOwned,\n docketConnectRequestMatchesApprovalOperation,\n setStateIfMounted,\n ],\n );\n\n const cancelDocketConnectApproval = useCallback(\n async (approvalRequestId: string | number) => {\n const operation = beginDocketConnectApprovalOperation(approvalRequestId);\n if (!operation) return;\n\n let decisionApplied = false;\n let speedBumpConfirmationToken: string | undefined;\n try {\n while (true) {\n const result = await apiCancelDocketConnectApproval(\n operation.token,\n approvalRequestId,\n speedBumpConfirmationToken,\n );\n const request = cloneDocketConnectRetrievalRequest(result.retrieval_request);\n if (!docketConnectRequestMatchesApprovalOperation(request, operation)) return;\n if (!docketConnectApprovalOperationIsStillOwned(operation)) return;\n\n if (!decisionApplied) {\n if (!docketConnectApprovalOperationIsCurrent(operation)) return;\n const continuationError = result.continuation_error\n ? clerkErrorMessage(result.continuation_error, { fallbackKey: \"genericRetry\" })\n : null;\n setStateIfMounted((prev) =>\n docketConnectApprovalOperationIsCurrent(operation, prev)\n ? {\n ...prev,\n docketConnectRetrievalRequest: request,\n error: continuationError,\n }\n : prev,\n );\n decisionApplied = true;\n }\n\n attachDocketConnectContinuationRun(operation, result.continuation_run);\n const creditRequirement = result.continuationCreditSpeedBump;\n if (!creditRequirement) return;\n\n const confirmation = await confirmDocketConnectContinuation(operation, creditRequirement);\n if (!isMountedRef.current || !docketConnectApprovalOperationIsStillOwned(operation)) return;\n if (confirmation === null) return;\n speedBumpConfirmationToken = confirmation;\n }\n } catch (err) {\n const request = docketConnectRetrievalRequestFromError(err);\n if (request) {\n if (\n docketConnectApprovalOperationIsCurrent(operation) &&\n docketConnectRequestMatchesApprovalOperation(request, operation)\n ) {\n setStateIfMounted((prev) =>\n docketConnectApprovalOperationIsCurrent(operation, prev)\n ? { ...prev, docketConnectRetrievalRequest: request, error: null }\n : prev,\n );\n }\n return;\n }\n if (\n !decisionApplied &&\n (!docketConnectApprovalOperationIsCurrent(operation) ||\n !docketConnectApprovalOperationIsStillOwned(operation))\n ) {\n return;\n }\n const rawErrorMessage = err instanceof Error ? err.message : null;\n setStateIfMounted((prev) =>\n docketConnectApprovalOperationIsStillOwned(operation, prev)\n ? {\n ...prev,\n error: clerkErrorMessage(rawErrorMessage, { fallbackKey: \"genericRetry\" }),\n }\n : prev,\n );\n }\n },\n [\n beginDocketConnectApprovalOperation,\n attachDocketConnectContinuationRun,\n confirmDocketConnectContinuation,\n docketConnectApprovalOperationIsCurrent,\n docketConnectApprovalOperationIsStillOwned,\n docketConnectRequestMatchesApprovalOperation,\n setStateIfMounted,\n ],\n );\n\n const injectRequestJudgeMessages = useCallback(\n (judgeName: string) => {\n const userMsg = createDisplayMessage(generateId(), \"user\", `Requested: ${judgeName}`);\n const assistantMsg = createDisplayMessage(\n generateId(),\n \"assistant\",\n `Request submitted for ${judgeName}. We'll add them within 24\u201348 hours and notify you when their transcripts become available. In the meantime, would you like to search for a different judge?`,\n );\n\n setStateIfMounted((prev) => ({\n ...prev,\n messages: insertBeforeStreamingOrAppend(prev.messages, userMsg, assistantMsg),\n }));\n },\n [setStateIfMounted, generateId],\n );\n\n const updateTitle = useCallback(\n async (newTitle: string) => {\n if (!tokenRef.current) return;\n if (stateRef.current.readOnly) return;\n setStateIfMounted((prev) => ({ ...prev, title: newTitle }));\n try {\n await apiUpdateTitle(tokenRef.current, newTitle);\n } catch {\n // Best-effort \u2014 title is already updated locally\n }\n },\n [setStateIfMounted],\n );\n\n useEffect(() => {\n return () => {\n isMountedRef.current = false;\n clearRecoveryTimeout();\n cancelStream();\n activeRunRef.current = null;\n revokePendingTextDelta();\n };\n }, [cancelStream, clearRecoveryTimeout, revokePendingTextDelta]);\n\n const canSteer = featureEnabled(\"clerk_message_queue\") && !!renderedSteerIntent && !state.readOnly;\n const displayedMessages = useMemo(\n () =>\n state.messages.map((message) => ({\n ...message,\n isStopAccepted:\n message.queueState === \"pending\" &&\n pendingStopAcceptance?.token === state.token &&\n pendingStopAcceptance.generation === sessionViewGenerationRef.current &&\n message.serverMessageId !== undefined &&\n pendingStopAcceptance.messageIds.has(message.serverMessageId),\n isSteerAccepted:\n message.queueState === \"pending\" &&\n (!!message.steerRequestedAt ||\n (pendingSteerAcceptance?.token === state.token &&\n pendingSteerAcceptance?.messageId === message.serverMessageId)),\n isSteerSelected:\n canSteer &&\n message.queueState === \"pending\" &&\n !!message.steerRequestedAt &&\n message.steerRunId === steeringRunId,\n })),\n [state.messages, state.token, canSteer, steeringRunId, pendingSteerAcceptance, pendingStopAcceptance],\n );\n\n return {\n ...(state.freshEmptySession === true &&\n state.status === \"active\" &&\n !state.error &&\n !state.readOnly &&\n state.messages.length === 0 &&\n !state.serverActiveRun &&\n !state.latestRun &&\n !activePlan?.active &&\n !pendingPlanning\n ? { isFreshEmptySession: true }\n : {}),\n pendingAction,\n sessionId: state.sessionId,\n token: state.token,\n title: state.title,\n branchOrigin: state.branchOrigin || null,\n status: state.status,\n messages: displayedMessages,\n error: state.error,\n hasMoreMessages: state.hasMoreMessages,\n sendMessage,\n steerMessage,\n canSteer,\n queueDispatchBlockCode: state.queueDispatch?.block_code || null,\n cancelAndEditMessage,\n forkMessage,\n pendingMessageActionId,\n pendingMessageActionType,\n conversationDrafts,\n restoreDraft,\n consumeRestoredDraft,\n retryRun,\n retryDownloadLoad,\n cancel,\n reset,\n loadSession,\n bootstrapSession,\n loadOlderMessages,\n updateTitle,\n submitClarifyingAnswer,\n expireClarifyingQuestion,\n approveDocketConnectApproval,\n cancelDocketConnectApproval,\n injectRequestJudgeMessages,\n pendingClarifyingQuestion: state.pendingClarifyingQuestion,\n docketConnectRetrievalRequest: cloneDocketConnectRetrievalRequest(state.docketConnectRetrievalRequest),\n activeTranscript: state.activeTranscript,\n activeModelConfig: state.activeModelConfig,\n readOnly: state.readOnly,\n clientMatterCode: state.clientMatterCode,\n activePlan,\n pendingPlanning,\n planningMode,\n planningModePending: planningModePending || modeAdmissionPending,\n planningModeTogglePending: planningModePending,\n setPlanningMode,\n planningQuestionError,\n respondToPlanningOffer,\n submitPlanningResponse,\n editPlan,\n confirmPlan,\n cancelPlan,\n isStreaming: state.status === \"streaming\",\n };\n}\n", "import { recordPlanningEvent } from \"./planningAnalytics\";\nimport React, { useEffect, useState } from \"react\";\nimport { Box, Skeleton, Stack, Typography } from \"@mui/material\";\nimport { Check, ChevronRight, ListChecks } from \"lucide-react\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQChip } from \"@/components/atoms/BIQChip\";\nimport { Icon } from \"@/components/icons\";\nimport { spacing } from \"@/components/theme/tokens/spacing\";\nimport { layout } from \"@/components/theme/tokens/layout\";\nimport type { PlanningCycle, PlanningVersion } from \"../../api/queries/agentPrototype.types\";\n\ninterface Props {\n plan: PlanningCycle;\n loading: boolean;\n onOfferDecision: (decision: \"accept\" | \"execute_without_plan\") => void;\n onAnswer: (answer: string) => void;\n onConfirm: () => void;\n onComposerFocus: () => void;\n completed?: boolean;\n inactive?: boolean;\n editing?: boolean;\n version?: PlanningVersion;\n}\n\nconst AgentPrototypePlanningCard: React.FC = ({\n plan,\n loading,\n onOfferDecision,\n onConfirm,\n onComposerFocus,\n completed = false,\n inactive = false,\n editing = false,\n version: displayedVersion,\n}) => {\n const interaction = plan.interaction;\n const version = displayedVersion ?? (interaction.kind === \"review\" ? plan.current_version : undefined);\n const disabled = loading || inactive || editing || !plan.active;\n const [now, setNow] = useState(Date.now);\n useEffect(() => {\n if (interaction.kind !== \"offer\" || !plan.offer_expires_at || inactive) return;\n setNow(Date.now());\n const timer = window.setInterval(() => setNow(Date.now()), 1000);\n return () => window.clearInterval(timer);\n }, [interaction.kind, plan.offer_expires_at, inactive]);\n const expiresAt = plan.offer_expires_at ? Date.parse(plan.offer_expires_at) : NaN;\n const secondsRemaining = Number.isFinite(expiresAt) ? Math.max(0, Math.ceil((expiresAt - now) / 1000)) : null;\n const stage =\n interaction.kind === \"offer\"\n ? `Wait ${secondsRemaining ?? 60}s, then proceeds on manual mode...`\n : (interaction.kind === \"loading\" && interaction.stage === \"clarifying\") ||\n interaction.kind === \"question\" ||\n interaction.kind === \"scope_decision\"\n ? \"Clarifying intent and scope\"\n : interaction.kind === \"review\"\n ? \"Waiting for confirmation...\"\n : interaction.kind === \"loading\" && interaction.stage === \"writing\"\n ? \"Writing the plan\"\n : (interaction.kind === \"loading\" && interaction.stage === \"rewriting\") || plan.versions.length > 0\n ? \"Rewriting the plan\"\n : \"Writing the plan\";\n const showStage =\n !completed &&\n !inactive &&\n !editing &&\n [\"offer\", \"question\", \"scope_decision\", \"loading\", \"review\"].includes(interaction.kind);\n\n const statusOnly =\n interaction.kind === \"loading\" &&\n (interaction.stage === \"rewriting\" || (!interaction.stage && plan.versions.length > 0)) &&\n !displayedVersion;\n\n if (interaction.kind === \"error\") return null;\n\n return (\n \n {showStage && (\n \n \n {stage}\n {interaction.kind !== \"offer\" && interaction.kind !== \"review\" ? \"\u2026\" : \"\"}\n \n \n \n )}\n {!statusOnly && (\n ({\n border: `1px solid ${theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n backgroundColor: \"background.paper\",\n p: `${spacing[4] - 1}px`,\n })}\n >\n \n \n \n \n Plan\n \n {completed && }\n \n {version ? (\n <>\n \n {version.title}\n \n \n {version.prompt}\n \n {!completed && (\n \n {\n recordPlanningEvent({\n event_name: \"click_edit_clerk_plan\",\n event_properties: {\n plan_token: plan.plan_token,\n version_token: version.version_token,\n version_sequence: version.sequence,\n },\n });\n onComposerFocus();\n }}\n >\n Edit\n \n \n Confirm\n \n \n )}\n \n ) : interaction.kind === \"offer\" ? (\n <>\n \n Want to use Planning Mode?\n \n \n I\u2019ll ask a few questions, then draft the request for you to review before I run it.\n \n \n onOfferDecision(\"accept\")}\n >\n Use Planning Mode\n \n onOfferDecision(\"execute_without_plan\")}\n >\n Just answer it\n \n \n \n ) : interaction.kind === \"unsupported\" ? (\n {interaction.explanation}\n ) : (\n <>\n \n {plan.current_version?.title || \"Preparing your plan\u2026\"}\n \n \n {[\"100%\", \"67%\", \"82%\"].map((width) => (\n \n ))}\n \n \n )}\n \n \n )}\n \n );\n};\n\nexport default AgentPrototypePlanningCard;\n", "import React, { useLayoutEffect, useRef, useState } from \"react\";\nimport { Tooltip } from \"@mui/material\";\n\n/** Add the existing tooltip interaction to a control without adding another focus target. */\nexport function OverflowTooltip({\n children,\n focusableText = false,\n}: {\n children: React.ReactElement;\n focusableText?: boolean;\n}) {\n const ref = useRef(null);\n const [fullText, setFullText] = useState(\"\");\n useLayoutEffect(() => {\n const root = ref.current;\n if (!root) return;\n const elements = root.matches(\"[data-overflow-text]\")\n ? [root]\n : Array.from(root.querySelectorAll(\"[data-overflow-text]\"));\n let active = true;\n const measure = () => {\n if (!active) return;\n const truncated = elements.some((element) => {\n // Allow fractional line-box ink without mistaking it for another line.\n const lineHeight = parseFloat(getComputedStyle(element).lineHeight) || 20;\n return (\n element.scrollWidth > element.clientWidth + 1 || element.scrollHeight > element.clientHeight + lineHeight / 2\n );\n });\n setFullText(truncated ? elements.map((element) => element.textContent).join(\"\\n\") : \"\");\n };\n measure();\n const observer = new ResizeObserver(measure);\n elements.forEach((element) => observer.observe(element));\n document.fonts?.addEventListener(\"loadingdone\", measure);\n void document.fonts?.ready.then(measure);\n return () => {\n active = false;\n observer.disconnect();\n document.fonts?.removeEventListener(\"loadingdone\", measure);\n };\n }, [children]);\n return (\n \n {React.cloneElement(children, {\n ref,\n ...(focusableText ? { tabIndex: fullText ? 0 : undefined } : {}),\n })}\n \n );\n}\n\n/** Layout behavior only: typography and tooltip appearance remain theme-owned. */\nexport const questionTextClamp = {\n display: \"-webkit-box\",\n WebkitBoxOrient: \"vertical\",\n WebkitLineClamp: 3,\n overflow: \"hidden\",\n overflowWrap: \"anywhere\",\n} as const;\n\nexport const optionTitleClamp = {\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n} as const;\n", "import React from \"react\";\nimport { Badge, Box, ButtonBase, Tooltip, Typography } from \"@mui/material\";\nimport { X as CloseIcon, ArrowUp as SendIcon, ArrowRight } from \"lucide-react\";\nimport { colors } from \"@/components/theme/tokens/colors\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { Icon } from \"@/components/icons\";\nimport { BIQInputField } from \"@/components/atoms/BIQInputField\";\n\nimport { OverflowTooltip, optionTitleClamp, questionTextClamp } from \"./OverflowTooltip\";\n\ninterface ClarifyingQuestionCardProps {\n title: string;\n options: Array<{ title: string; description?: string }>;\n customText: string;\n onCustomTextChange: (value: string) => void;\n onCustomSubmit: () => void;\n onOptionSelect: (index: number) => void;\n onDismiss: () => void;\n disabled?: boolean;\n busy?: boolean;\n dismissLabel?: string;\n dismissTooltip?: string;\n sendLabel?: string;\n customPlaceholder?: string;\n showCustomSubmitButton?: boolean;\n dataComponent?: string;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n scrollOptionsOnly?: boolean;\n textColor?: string;\n}\n\n/** Shared presentation for manual and planning clarification; callers own lifecycle and analytics. */\nexport function ClarifyingQuestionCard({\n title,\n options,\n customText,\n onCustomTextChange,\n onCustomSubmit,\n onOptionSelect,\n onDismiss,\n disabled = false,\n busy = false,\n dismissLabel = \"Dismiss\",\n dismissTooltip,\n sendLabel = \"Send\",\n customPlaceholder = \"Something else...\",\n showCustomSubmitButton = true,\n dataComponent,\n children,\n footer,\n scrollOptionsOnly = true,\n textColor = colors.black,\n}: ClarifyingQuestionCardProps) {\n const dismissButton = (\n \n );\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n onCustomSubmit();\n }\n };\n return (\n ({\n bgcolor: \"background.paper\",\n color: textColor,\n \"& .MuiTypography-body1, & .MuiTypography-body2\": { letterSpacing: 0 },\n \"& .MuiOutlinedInput-root:not(:hover):not(.Mui-focused):not(.Mui-disabled) .MuiOutlinedInput-notchedOutline\": {\n borderColor: theme.palette.grey[300],\n },\n border: 1,\n borderColor: theme.palette.grey[300],\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n boxShadow: theme.tokens.shadows.lg,\n p: `${theme.tokens.spacing[6] - 1}px`,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n width: \"100%\",\n boxSizing: \"border-box\",\n maxHeight: scrollOptionsOnly ? \"calc(100dvh - 112px)\" : \"65vh\",\n minHeight: 0,\n overflowY: scrollOptionsOnly ? \"hidden\" : \"auto\",\n })}\n aria-busy={busy}\n data-component={dataComponent}\n >\n {/* Title row */}\n \n \n \n {title}\n \n \n {dismissTooltip ? (\n \n {dismissButton}\n \n ) : (\n dismissButton\n )}\n \n\n {children ?? (\n \n \n {options.map((option, index) => {\n return (\n \n onOptionSelect(index)}\n disabled={disabled}\n focusVisibleClassName=\"Mui-focusVisible\"\n sx={(theme) => ({\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-start\",\n textAlign: \"left\",\n gap: 1,\n p: 1.5,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n cursor: \"pointer\",\n bgcolor: \"background.paper\",\n transition: theme.transitions.create(\"background-color\", {\n duration: theme.transitions.duration.shortest,\n }),\n \"&:hover\": {\n bgcolor: theme.palette.secondary._states.hover,\n },\n \"&.Mui-focusVisible\": {\n bgcolor: theme.palette.secondary._states.hover,\n outline: `2px solid ${theme.palette.primary.main}`,\n outlineOffset: 2,\n },\n \"&.Mui-disabled\": {\n cursor: \"default\",\n opacity: 0.6,\n },\n \"& .choice-action\": {\n opacity: 0,\n },\n \"&:hover .choice-action, &.Mui-focusVisible .choice-action\": {\n opacity: 1,\n },\n })}\n >\n ({\n \"& .MuiBadge-badge\": {\n position: \"static\",\n transform: \"none\",\n bgcolor: colors.taupe[200],\n color: colors.black,\n fontSize: 12,\n fontFamily: '\"Roboto\", sans-serif',\n lineHeight: \"20px\",\n letterSpacing: \"0.14px\",\n fontWeight: 500,\n minWidth: 20,\n height: 20,\n borderRadius: `${theme.tokens.radii.fullRadius}px`,\n },\n })}\n />\n \n \n {option.title}\n \n {option.description && (\n \n {option.description}\n \n )}\n \n ({\n display: \"flex\",\n alignItems: \"center\",\n gap: 0.5,\n px: 0.5,\n py: 0.25,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n flexShrink: 0,\n transition: theme.transitions.create(\"opacity\", {\n duration: theme.transitions.duration.shortest,\n }),\n })}\n >\n \n \n Select\n \n \n \n \n );\n })}\n \n {/* Custom text input */}\n {\n event.preventDefault();\n onCustomSubmit();\n }}\n sx={{\n mt: 0,\n p: 1.5,\n flexShrink: 0,\n \"& .MuiOutlinedInput-root\": { minHeight: 56 },\n \"& .MuiInputBase-input\": { fontSize: 16, lineHeight: \"24px\", letterSpacing: \"0.15px\" },\n }}\n >\n onCustomTextChange(e.target.value)}\n onKeyDown={handleKeyDown}\n endIcon={\n showCustomSubmitButton && customText.trim() ? (\n \n ) : undefined\n }\n />\n \n \n )}\n {footer && {footer}}\n \n );\n}\n", "import { planningSubmitSx } from \"./planningSubmitSx\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { Box, Checkbox, FormControlLabel, Link, Typography } from \"@mui/material\";\nimport { Icon } from \"@/components/icons\";\nimport { colors } from \"@/components/theme/tokens/colors\";\nimport { ArrowUp, ArrowRight, FileText, FileUp, X } from \"lucide-react\";\nimport { BenchAlert } from \"@/components/atoms/BenchAlert\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { BIQInputField } from \"@/components/atoms/BIQInputField\";\nimport { ClarifyingQuestionCard } from \"@/components/molecules/ClarifyingQuestionCard\";\nimport { OverflowTooltip, optionTitleClamp, questionTextClamp } from \"@/components/molecules/OverflowTooltip\";\nimport type {\n AttachedFile,\n PlanningQuestionResponse,\n ClarifyingQuestion,\n} from \"../../api/queries/agentPrototype.types\";\n\ninterface Props {\n question: string;\n questionType: ClarifyingQuestion[\"questionType\"];\n options: ClarifyingQuestion[\"options\"];\n loading: boolean;\n disabled?: boolean;\n customAnswer: string;\n onCustomAnswerChange: (answer: string) => void;\n onAnswer: (answer: string, files?: AttachedFile[], response?: PlanningQuestionResponse) => void;\n onOptionSelect?: (index: number) => void;\n onDismiss?: () => void;\n onDismissDefault?: () => void;\n dismissTooltip?: string;\n dismissLabel?: string;\n error?: { code?: string; message: string };\n dataComponent?: string;\n showCustomSubmitButton?: boolean;\n}\n\n/** Shared controls; the planning and research adapters own submission and lifecycle. */\nexport default function AgentQuestionControls({\n question: prompt,\n questionType,\n options,\n loading,\n disabled: inactive = false,\n customAnswer,\n onCustomAnswerChange,\n onAnswer,\n onOptionSelect,\n onDismiss,\n onDismissDefault,\n dismissTooltip,\n dismissLabel,\n error,\n dataComponent,\n showCustomSubmitButton = true,\n}: Props) {\n const submitted = useRef(false);\n const [selected, setSelected] = useState([]);\n const [file, setFile] = useState(null);\n const [localError, setLocalError] = useState(null);\n const [reading, setReading] = useState(false);\n const [replacedError, setReplacedError] = useState();\n const fileInput = useRef(null);\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n useEffect(() => {\n if (!loading) submitted.current = false;\n }, [loading]);\n const disabled = loading || inactive;\n const answer = (value: string) => {\n if (disabled || submitted.current || !value.trim()) return;\n submitted.current = true;\n onAnswer(value.trim());\n };\n\n const multi = questionType === \"multi_select\";\n const upload = questionType === \"file_upload\";\n const busy = disabled || reading;\n const visibleError = error !== replacedError ? error : undefined;\n const chooseFile = (files: FileList | null) => {\n if (busy || !files?.length) return;\n if (files.length !== 1) {\n setLocalError(\"Choose one PDF or DOCX file.\");\n return;\n }\n const candidate = files[0];\n const extension = candidate.name.slice(candidate.name.lastIndexOf(\".\")).toLowerCase();\n if (![\".pdf\", \".docx\"].includes(extension)) {\n setLocalError(\"Choose a PDF or DOCX file.\");\n return;\n }\n if (candidate.size > 10 * 1024 * 1024) {\n setLocalError(\"Choose a file up to 10 MB.\");\n return;\n }\n setFile(candidate);\n setLocalError(null);\n setReplacedError(error);\n };\n const submitFile = async () => {\n if (busy || submitted.current || !file) return;\n submitted.current = true;\n setReading(true);\n setLocalError(null);\n try {\n const data = await new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(String(reader.result).split(\",\")[1] || \"\");\n reader.onerror = () => reject(new Error(\"unreadable\"));\n reader.readAsDataURL(file);\n });\n if (mounted.current)\n onAnswer(`Uploaded ${file.name}`, [{ name: file.name, type: file.type, size: file.size, data }], {\n kind: \"file_upload\",\n action: \"upload\",\n });\n } catch {\n if (mounted.current) {\n setLocalError(\"This file couldn\u2019t be opened. Replace it or continue without it.\");\n submitted.current = false;\n }\n } finally {\n if (mounted.current) setReading(false);\n }\n };\n const submitMulti = () => {\n if (busy || submitted.current || (!selected.length && !customAnswer.trim())) return;\n submitted.current = true;\n const indexes = [...selected].sort((a, b) => a - b);\n onAnswer(\n [...indexes.map((index) => options?.[index].title), customAnswer.trim()].filter(Boolean).join(\"; \"),\n undefined,\n { kind: \"multi_select\", selected_option_indexes: indexes, custom_text: customAnswer.trim() },\n );\n };\n if (multi || upload)\n return (\n void submitFile()}\n onOptionSelect={() => undefined}\n disabled={busy}\n busy={loading || reading}\n onDismiss={() => {\n if (busy || submitted.current) return;\n if (!onDismiss) onDismissDefault?.();\n if (onDismiss) {\n submitted.current = true;\n onDismiss();\n } else if (upload) {\n submitted.current = true;\n onAnswer(\"Continue without a file\", undefined, { kind: \"file_upload\", action: \"continue_without_file\" });\n } else {\n submitted.current = true;\n onAnswer(\"Use your best judgment\", undefined, {\n kind: \"multi_select\",\n selected_option_indexes: [],\n custom_text: \"Use your best judgment\",\n });\n }\n }}\n dismissTooltip={dismissTooltip}\n dismissLabel={dismissLabel ?? (upload ? \"Continue without a file\" : \"Use your best judgment\")}\n dataComponent={dataComponent}\n footer={\n \n void submitFile() : submitMulti}\n />\n \n }\n >\n \n {(localError || visibleError) && (\n \n {localError\n ? localError\n : visibleError?.code === \"file_unreadable\"\n ? \"This file couldn\u2019t be opened. Replace it or continue without it.\"\n : visibleError?.message}\n \n )}\n {multi ? (\n <>\n \n {options?.map((option, index) => (\n \n ({\n display: \"flex\",\n m: 0,\n p: 1.5,\n gap: 1,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n \"& .MuiCheckbox-root\": {\n p: 1.5,\n \"& [data-biq-cb]\": { width: 18, height: 18, borderRadius: \"1px\" },\n \"& [data-biq-cb=unchecked]\": { borderColor: theme.palette.action.active },\n },\n \"& .MuiFormControlLabel-label\": {\n flex: 1,\n minWidth: 0,\n overflowWrap: \"anywhere\",\n whiteSpace: \"normal\",\n },\n \"& .choice-action\": { opacity: 0 },\n \"&:hover\": { bgcolor: theme.palette.secondary._states.hover },\n \"&:focus-within\": {\n outline: `2px solid ${theme.palette.primary.main}`,\n outlineOffset: 2,\n bgcolor: theme.palette.secondary._states.hover,\n },\n \"&:hover .choice-action, &:focus-within .choice-action\": { opacity: 1 },\n })}\n control={\n \n setSelected((values) =>\n checked ? [...values, index] : values.filter((value) => value !== index),\n )\n }\n />\n }\n label={\n \n \n \n {option.title}\n \n {option.description && (\n \n {option.description}\n \n )}\n \n \n \n Select\n \n \n }\n />\n \n ))}\n \n onCustomAnswerChange(event.target.value)}\n />\n \n ) : (\n <>\n {\n chooseFile(event.target.files);\n event.target.value = \"\";\n }}\n />\n {file ? (\n ({\n display: \"flex\",\n alignItems: \"center\",\n gap: 0.5,\n minWidth: 0,\n p: `${theme.tokens.spacing[3] - 1}px`,\n bgcolor: colors.taupe[50],\n border: `1px solid ${theme.border.light}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n })}\n >\n \n \n {file.name}\n \n {(localError || visibleError) && (\n fileInput.current?.click()}\n >\n Replace\n \n )}\n {!(localError || visibleError) && (\n {\n setFile(null);\n setLocalError(null);\n setReplacedError(error);\n }}\n />\n )}\n \n ) : (\n event.preventDefault()}\n onDrop={(event) => {\n event.preventDefault();\n chooseFile(event.dataTransfer.files);\n }}\n sx={(theme) => ({\n border: `1px dashed ${theme.palette.secondary.main}`,\n bgcolor: colors.taupe[50],\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n p: `${theme.tokens.spacing[12] - 1}px`,\n minHeight: 191,\n boxSizing: \"border-box\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gap: 3,\n textAlign: \"center\",\n })}\n >\n \n \n \n Drag a file here or,{\" \"}\n fileInput.current?.click()}\n >\n browse\n \n \n \n PDF or DOCX \u00B7 up to 10 MB\n \n \n \n )}\n \n )}\n \n \n );\n return (\n answer(customAnswer)}\n onOptionSelect={(index) => {\n const option = options?.[index];\n if (option) {\n if (onOptionSelect) onOptionSelect(index);\n else answer(option.title);\n }\n }}\n onDismiss={\n onDismiss ??\n (() => {\n if (disabled || submitted.current) return;\n onDismissDefault?.();\n answer(\"Use your best judgment\");\n })\n }\n dismissTooltip={dismissTooltip}\n disabled={disabled}\n busy={loading}\n dismissLabel={dismissLabel ?? \"Use your best judgment\"}\n showCustomSubmitButton={showCustomSubmitButton}\n dataComponent={dataComponent}\n />\n );\n}\n", "import React from \"react\";\nimport { recordPlanningEvent } from \"./planningAnalytics\";\nimport type { AttachedFile, PlanningCycle, PlanningQuestionResponse } from \"../../api/queries/agentPrototype.types\";\nimport AgentQuestionControls from \"./AgentQuestionControls\";\n\ninterface Props {\n plan: PlanningCycle;\n loading: boolean;\n customAnswer: string;\n onCustomAnswerChange: (answer: string) => void;\n onAnswer: (answer: string, files?: AttachedFile[], response?: PlanningQuestionResponse) => void;\n error?: { code?: string; message: string };\n}\n\nexport default function AgentPrototypePlanningQuestion({ plan, ...props }: Props) {\n const interaction = plan.interaction;\n if (interaction.kind !== \"question\" && interaction.kind !== \"scope_decision\") return null;\n const questionType = interaction.kind === \"question\" ? interaction.question_type : \"single_select\";\n return (\n \n recordPlanningEvent({\n event_name: \"dismiss_clerk_planning_question\",\n event_properties: {\n plan_token: plan.plan_token,\n interaction_token: plan.active_interaction_token!,\n question_type: questionType,\n },\n })\n }\n showCustomSubmitButton={false}\n dataComponent=\"AgentPrototypePlanningQuestion\"\n />\n );\n}\n", "import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\ninterface UseSidepanelResizeArgs {\n enabled: boolean;\n currentWidth: number;\n minWidth: number;\n maxWidth: number;\n /** Fires on every pointermove with the new clamped width \u2014 drives live resize. */\n onResize: (px: number) => void;\n /**\n * Fires once on pointerup with the final width (or pointercancel). Useful\n * for one-shot side effects: analytics emit (\"user committed to width N\"),\n * persistence write, focus restore, etc. Optional \u2014 most callers wire only\n * `onResize` and rely on its last emit being the final width.\n */\n onDragEnd?: (px: number) => void;\n}\n\n/**\n * Pointer-driven resize for the sidepanel's left edge.\n *\n * Drag math: handle sits on the left edge of Column 3, so dragging the\n * pointer left increases sidepanel width. `newWidth = startWidth + (startX - clientX)`.\n *\n * Bounds are clamped continuously; if the pointer keeps moving past a bound,\n * width stays clamped but drag-state remains active until pointer release.\n */\nexport function useSidepanelResize({\n enabled,\n currentWidth,\n minWidth,\n maxWidth,\n onResize,\n onDragEnd,\n}: UseSidepanelResizeArgs) {\n const [isDragging, setIsDragging] = useState(false);\n const dragRef = useRef<{ startX: number; startWidth: number; lastWidth: number } | null>(null);\n\n // Stash live values in refs so the pointer-event callbacks keep stable\n // identities across pointermove ticks. Without this, every tick mutates\n // currentWidth, which would regenerate the useCallback handlers and force\n // React to re-bind events on the handle each frame.\n const enabledRef = useRef(enabled);\n enabledRef.current = enabled;\n const currentWidthRef = useRef(currentWidth);\n currentWidthRef.current = currentWidth;\n const minWidthRef = useRef(minWidth);\n minWidthRef.current = minWidth;\n const maxWidthRef = useRef(maxWidth);\n maxWidthRef.current = maxWidth;\n const onResizeRef = useRef(onResize);\n onResizeRef.current = onResize;\n const onDragEndRef = useRef(onDragEnd);\n onDragEndRef.current = onDragEnd;\n\n const onPointerDown = useCallback((event: React.PointerEvent) => {\n if (!enabledRef.current) return;\n event.preventDefault();\n (event.currentTarget as HTMLDivElement).setPointerCapture(event.pointerId);\n const width = currentWidthRef.current;\n dragRef.current = { startX: event.clientX, startWidth: width, lastWidth: width };\n setIsDragging(true);\n }, []);\n\n const onPointerMove = useCallback((event: React.PointerEvent) => {\n if (!dragRef.current) return;\n const { startX, startWidth } = dragRef.current;\n const delta = startX - event.clientX;\n const next = Math.max(minWidthRef.current, Math.min(maxWidthRef.current, startWidth + delta));\n dragRef.current.lastWidth = next;\n onResizeRef.current(next);\n }, []);\n\n const endDrag = useCallback((event: React.PointerEvent) => {\n if (!dragRef.current) return;\n (event.currentTarget as HTMLDivElement).releasePointerCapture(event.pointerId);\n // Use the last width emitted during the drag \u2014 not the prop, which goes\n // stale across mid-drag prop updates.\n const finalWidth = dragRef.current.lastWidth;\n dragRef.current = null;\n setIsDragging(false);\n onDragEndRef.current?.(finalWidth);\n }, []);\n\n // Global cursor lock during drag so the cursor stays col-resize even when the\n // pointer leaves the handle's hit zone.\n useEffect(() => {\n if (!isDragging) return;\n const previous = document.body.style.cursor;\n document.body.style.cursor = \"col-resize\";\n return () => {\n document.body.style.cursor = previous;\n };\n }, [isDragging]);\n\n const handleProps = useMemo(\n () => ({ onPointerDown, onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag }),\n [onPointerDown, onPointerMove, endDrag],\n );\n\n return { isDragging, handleProps };\n}\n", "import { useCallback, useEffect, useRef } from \"react\";\n\nimport type { ColumnThreeMode } from \"./AppShell\";\n\n/**\n * The decision the auto-fullscreen logic makes on each measurement:\n * - none: leave the panel as it is\n * - snap: paneled panel no longer fits \u2192 go fullscreen, remembering `rememberWidth`\n * - restore: an auto-snapped panel has room again \u2192 return to paneled, *aiming for*\n * `targetWidth`. The caller passes this through AppShell's width clamp,\n * so the panel comes back as wide as currently fits, capped at\n * `targetWidth` \u2014 exact only when there's genuinely room (see the hook\n * doc and the restore-buffer note for why it's usually narrower).\n */\nexport type AutoFullscreenAction =\n | { type: \"none\" }\n | { type: \"snap\"; rememberWidth: number }\n | { type: \"restore\"; targetWidth: number };\n\ninterface ComputeAutoFullscreenActionArgs {\n /** Current panel mode. */\n columnThree: ColumnThreeMode;\n /** Width available to the panel (the AppArea's inner width). */\n availableWidth: number;\n /** Current paneled width of the reader. */\n panelWidth: number;\n /** Pre-snap width to aim for on restore (the caller clamps it to what fits); set only while an auto-snap is active, null otherwise. */\n rememberedWidth: number | null;\n /** Hysteresis: how far past `panelWidth` the window must grow before restoring. */\n restoreBuffer: number;\n}\n\n/**\n * Pure decision function for {@link useAutoFullscreenOnNarrow}.\n *\n * Two thresholds with a hysteresis gap between them so resizing across the\n * boundary doesn't flip-flop:\n * - snap when a paneled panel would consume the whole available width\n * (`availableWidth <= panelWidth`) \u2014 the point at which its top-left\n * controls clip off-screen.\n * - restore only once the window clears `rememberedWidth + restoreBuffer`.\n */\nexport function computeAutoFullscreenAction({\n columnThree,\n availableWidth,\n panelWidth,\n rememberedWidth,\n restoreBuffer,\n}: ComputeAutoFullscreenActionArgs): AutoFullscreenAction {\n // No measurement yet (initial render / detached node). Never act on a 0 width,\n // which would otherwise read as \"narrower than the panel\" and false-snap.\n if (availableWidth <= 0) return { type: \"none\" };\n\n if (columnThree === \"on\") {\n if (availableWidth <= panelWidth) {\n return { type: \"snap\", rememberWidth: panelWidth };\n }\n return { type: \"none\" };\n }\n\n if (columnThree === \"expanded\") {\n // Only auto-restore an auto-snap (rememberedWidth set). A manual expand has\n // no remembered width and stays fullscreen until the user collapses it.\n //\n // Floor the buffer at 1: rememberedWidth === panelWidth at snap, so a buffer\n // of 0 (or less) would make the restore boundary coincide with the snap\n // boundary and oscillate every tick. No caller passes <= 0 today; this just\n // hardens the param against future misuse.\n const buffer = Math.max(1, restoreBuffer);\n if (rememberedWidth != null && availableWidth >= rememberedWidth + buffer) {\n return { type: \"restore\", targetWidth: rememberedWidth };\n }\n }\n\n return { type: \"none\" };\n}\n\n/**\n * Default hysteresis between the snap and restore thresholds, in px. The window\n * must grow this far past the remembered width before the panel pops back to\n * paneled \u2014 small enough to feel responsive, large enough to never flicker at\n * the boundary.\n *\n * Deliberately smaller than AppShell's appAreaMin (460). A buffer >= appAreaMin\n * would guarantee the panel restores at its *exact* pre-snap width (there'd be\n * room for the panel + the min main area before pop-back) \u2014 but only by keeping\n * it fullscreen ~340px longer as the window widens, which feels sticky and\n * unresponsive. We prefer the snappy pop-back and accept \"restore as wide as\n * currently fits\" instead: with a 120px buffer the pop-back usually fires before\n * there's room for the full remembered width, so the panel comes back narrower\n * (down to its min for modest widths; trimmed by ~340px for large ones), and is\n * exact only when the window grows in a large jump. That's an intentional\n * trade-off \u2014 there's no UX convention requiring exact-width restore, and the\n * snappy behavior tests well.\n */\nexport const DEFAULT_AUTO_FULLSCREEN_RESTORE_BUFFER = 120;\n\ninterface UseAutoFullscreenOnNarrowArgs {\n enabled?: boolean;\n /** Element whose inner width is the space available to the panel (the AppArea). */\n containerRef: React.RefObject;\n /** Current panel mode. */\n columnThree: ColumnThreeMode;\n /** Current paneled width of the reader. */\n panelWidth: number;\n /** Switch panel mode (paneled \u2194 fullscreen). */\n setColumnThree: (mode: ColumnThreeMode) => void;\n /** Set the paneled width; clamps to what currently fits. Used on restore to re-apply the width bound. */\n setPanelWidth: (px: number) => void;\n /** Override the restore hysteresis; defaults to {@link DEFAULT_AUTO_FULLSCREEN_RESTORE_BUFFER}. */\n restoreBuffer?: number;\n}\n\n/**\n * Auto-snaps a paneled reader to fullscreen when the window gets too narrow to\n * fit it (its top-left close/expand controls would otherwise clip off-screen),\n * and pops it back to paneled once there's room again. On pop-back it aims for\n * the width it had, but AppShell's width clamp caps that to what currently fits,\n * so it returns \"as wide as fits\" rather than guaranteed-exact (intentional \u2014\n * see DEFAULT_AUTO_FULLSCREEN_RESTORE_BUFFER for the snappy-vs-exact rationale).\n *\n * The remembered width lives in a ref and is the single source of \"this was an\n * automatic snap\". It's set only on snap and cleared on restore; the reconcile\n * step (`columnThree === \"on\"` \u21D2 clear) guarantees a manual expand never\n * inherits a stale remembered width and auto-restores against the user's wish.\n *\n * The latest measured width and the current props are stashed in refs (the same\n * pattern as useSidepanelResize) so the ResizeObserver callback is registered\n * once and reads current values without re-subscribing \u2014 and, critically, so a\n * window-resize tick does NOT re-render AppShell. Only an actual snap/restore\n * (which changes columnThree/width state) triggers a render. `evaluate` is run\n * from two places: the observer (on resize) and an effect keyed on the mode\n * (so a manual collapse/expand re-evaluates even without an intervening resize).\n *\n * NOTE: AppShell also derives a \"does the panel fit\" bound via the non-reactive\n * computeMaxWidth() (window.innerWidth \u2212 rail \u2212 appAreaMin). This hook is a\n * second, reactive width source measured off the AppArea element. Unifying the\n * two onto one observed width (and making the drag clamp reactive too) is a\n * worthwhile follow-up, tracked separately \u2014 out of scope for this fix.\n */\nexport function useAutoFullscreenOnNarrow({\n enabled = true,\n containerRef,\n columnThree,\n panelWidth,\n setColumnThree,\n setPanelWidth,\n restoreBuffer = DEFAULT_AUTO_FULLSCREEN_RESTORE_BUFFER,\n}: UseAutoFullscreenOnNarrowArgs): void {\n const rememberedWidthRef = useRef(null);\n const availableWidthRef = useRef(0);\n\n // Stash live props in refs so `evaluate` (and the resize callback that calls\n // it) stays stable and always reads current values \u2014 no re-subscribe per tick.\n const columnThreeRef = useRef(columnThree);\n columnThreeRef.current = columnThree;\n const panelWidthRef = useRef(panelWidth);\n panelWidthRef.current = panelWidth;\n const restoreBufferRef = useRef(restoreBuffer);\n restoreBufferRef.current = restoreBuffer;\n const setColumnThreeRef = useRef(setColumnThree);\n setColumnThreeRef.current = setColumnThree;\n const setPanelWidthRef = useRef(setPanelWidth);\n setPanelWidthRef.current = setPanelWidth;\n\n const evaluate = useCallback(() => {\n const mode = columnThreeRef.current;\n // Reconcile: a paneled panel can have no pending restore. Clearing here is\n // what stops a later manual expand from auto-restoring a stale width.\n if (mode === \"on\") {\n rememberedWidthRef.current = null;\n }\n\n const action = computeAutoFullscreenAction({\n columnThree: mode,\n availableWidth: availableWidthRef.current,\n panelWidth: panelWidthRef.current,\n rememberedWidth: rememberedWidthRef.current,\n restoreBuffer: restoreBufferRef.current,\n });\n\n if (action.type === \"snap\") {\n rememberedWidthRef.current = action.rememberWidth;\n setColumnThreeRef.current(\"expanded\");\n } else if (action.type === \"restore\") {\n rememberedWidthRef.current = null;\n // setPanelWidth re-applies AppShell's width clamp (computeMaxWidth), so this\n // is \"aim for the pre-snap width, take what currently fits\" \u2014 not a guaranteed\n // exact restore. See DEFAULT_AUTO_FULLSCREEN_RESTORE_BUFFER for why.\n setPanelWidthRef.current(action.targetWidth);\n setColumnThreeRef.current(\"on\");\n }\n }, []);\n\n // Observe the AppArea's width. It changes on window/layout resize, not on\n // panel drag (dragging the panel doesn't resize its container), so this stays\n // quiet during normal resizing of the panel itself. Writes to a ref (not\n // state), so a resize tick re-evaluates without re-rendering AppShell.\n useEffect(() => {\n if (!enabled) return;\n const el = containerRef.current;\n if (!el) return;\n availableWidthRef.current = el.getBoundingClientRect().width;\n evaluate();\n const observer = new ResizeObserver(([entry]) => {\n if (!entry) return;\n availableWidthRef.current = entry.contentRect.width;\n evaluate();\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [containerRef, enabled, evaluate]);\n\n // Re-evaluate when the mode (or paneled width) changes without a resize \u2014 e.g.\n // a manual collapse while the window is still narrow should re-snap.\n useEffect(() => {\n if (!enabled) return;\n evaluate();\n }, [columnThree, enabled, panelWidth, evaluate]);\n}\n", "import React, { createContext, useContext } from \"react\";\nimport type { FC, ReactNode } from \"react\";\nimport { layout } from \"../theme/tokens/layout\";\n\nconst EffectiveRailWidthContext = createContext(layout.railWidth);\n\nexport const EffectiveRailWidthProvider: FC<{ value: number; children: ReactNode }> = ({ value, children }) => (\n {children}\n);\n\n/** Numeric rail reservation used by app content and React/MUI portals. */\nexport const useEffectiveRailWidth = (): number => useContext(EffectiveRailWidthContext);\n", "import { layout } from \"../theme/tokens/layout\";\n\nexport type SidenavPriority = \"reader\" | \"nav\";\n\nexport interface SidenavLayoutInput {\n containerWidth: number;\n pinned: boolean;\n hovering: boolean;\n readerOpen: boolean;\n /** The current paneled reader width, not merely its minimum. */\n readerWidth?: number;\n priority: SidenavPriority;\n}\n\nexport interface SidenavLayout {\n reader: \"shown\" | \"hidden\" | \"full\";\n nav: \"rail\" | \"push\" | \"overlay\";\n}\n\nexport const SIDENAV_LAYOUT = {\n RAIL: layout.expandableRailCollapsedWidth,\n EXPANDED: layout.railExpandedWidth,\n MAIN_MIN: layout.appAreaMin,\n READER_MIN: layout.readerLayoutMinWidth,\n RESTORE_HYSTERESIS: 120,\n} as const;\n\n/** Pure \u201Clast action wins\u201D resolver shared by the nav and reader shell. */\nfunction resolveWithoutHysteresis(input: SidenavLayoutInput): SidenavLayout {\n const { RAIL, EXPANDED, MAIN_MIN, READER_MIN } = SIDENAV_LAYOUT;\n const { containerWidth: width, pinned, hovering, readerOpen, priority } = input;\n const readerWidth = Math.max(READER_MIN, input.readerWidth ?? READER_MIN);\n const navAsserting = pinned && priority === \"nav\";\n\n if (readerOpen && width < RAIL + readerWidth && !navAsserting) {\n return { reader: \"full\", nav: hovering ? \"overlay\" : \"rail\" };\n }\n\n if (!pinned && !hovering) return { reader: readerOpen ? \"shown\" : \"hidden\", nav: \"rail\" };\n if (!pinned) return { reader: readerOpen ? \"shown\" : \"hidden\", nav: \"overlay\" };\n if (!readerOpen) return { reader: \"hidden\", nav: \"push\" };\n\n if (width >= EXPANDED + MAIN_MIN + readerWidth) return { reader: \"shown\", nav: \"push\" };\n\n return priority === \"reader\"\n ? { reader: \"shown\", nav: hovering ? \"overlay\" : \"rail\" }\n : { reader: \"hidden\", nav: \"push\" };\n}\n\n/**\n * Resolve the requested layout and, when supplied, use the last effective\n * layout to keep responsive restoration 120px away from its collapse\n * boundary. Explicit reader/nav actions still take effect immediately; the\n * buffer applies only while restoring a layout that width arbitration forced.\n */\nexport function resolveSidenavLayout(input: SidenavLayoutInput, previous?: SidenavLayout): SidenavLayout {\n const next = resolveWithoutHysteresis(input);\n if (!previous || !input.readerOpen || input.containerWidth <= 0) return next;\n\n const { RAIL, EXPANDED, MAIN_MIN, READER_MIN, RESTORE_HYSTERESIS } = SIDENAV_LAYOUT;\n const readerWidth = Math.max(READER_MIN, input.readerWidth ?? READER_MIN);\n const fullReaderRestoreAt = RAIL + readerWidth + RESTORE_HYSTERESIS;\n const sideBySideRestoreAt = EXPANDED + MAIN_MIN + readerWidth + RESTORE_HYSTERESIS;\n\n if (\n previous.reader === \"full\" &&\n next.reader === \"shown\" &&\n input.priority === \"reader\" &&\n input.containerWidth < fullReaderRestoreAt\n ) {\n return { reader: \"full\", nav: input.hovering ? \"overlay\" : \"rail\" };\n }\n\n if (\n previous.reader === \"shown\" &&\n previous.nav !== \"push\" &&\n next.reader === \"shown\" &&\n next.nav === \"push\" &&\n input.pinned &&\n input.priority === \"reader\" &&\n input.containerWidth < sideBySideRestoreAt\n ) {\n return { reader: \"shown\", nav: input.hovering ? \"overlay\" : \"rail\" };\n }\n\n if (\n previous.reader === \"hidden\" &&\n previous.nav === \"push\" &&\n next.reader === \"shown\" &&\n next.nav === \"push\" &&\n input.pinned &&\n input.priority === \"nav\" &&\n input.containerWidth < sideBySideRestoreAt\n ) {\n return previous;\n }\n\n return next;\n}\n", "import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport const SIDENAV_HOVER_OPEN_DELAY = 40;\nexport const SIDENAV_HOVER_CLOSE_DELAY = 140;\n\n/** Hover/focus-only interaction state used by the first feature release. */\nexport const useExpandableSideNavOverlay = () => {\n const [expanded, setExpanded] = useState(false);\n const pointerInsideRef = useRef(false);\n const focusInsideRef = useRef(false);\n const touchOpenRef = useRef(false);\n const surfaceOpenRef = useRef(false);\n const openTimerRef = useRef | null>(null);\n const closeTimerRef = useRef | null>(null);\n\n const clearTimers = useCallback(() => {\n if (openTimerRef.current) clearTimeout(openTimerRef.current);\n if (closeTimerRef.current) clearTimeout(closeTimerRef.current);\n openTimerRef.current = null;\n closeTimerRef.current = null;\n }, []);\n\n useEffect(() => clearTimers, [clearTimers]);\n\n const closeIfIdle = useCallback(() => {\n if (!pointerInsideRef.current && !focusInsideRef.current && !touchOpenRef.current && !surfaceOpenRef.current) {\n setExpanded(false);\n }\n }, []);\n\n const onPointerEnter = useCallback(\n (event: React.PointerEvent) => {\n if (event.pointerType === \"touch\") return;\n pointerInsideRef.current = true;\n clearTimers();\n openTimerRef.current = setTimeout(() => setExpanded(true), SIDENAV_HOVER_OPEN_DELAY);\n },\n [clearTimers],\n );\n\n const onPointerLeave = useCallback(\n (event: React.PointerEvent) => {\n if (event.pointerType === \"touch\") return;\n pointerInsideRef.current = false;\n clearTimers();\n closeTimerRef.current = setTimeout(closeIfIdle, SIDENAV_HOVER_CLOSE_DELAY);\n },\n [clearTimers, closeIfIdle],\n );\n\n const onFocusCapture = useCallback(() => {\n focusInsideRef.current = true;\n clearTimers();\n setExpanded(true);\n }, [clearTimers]);\n\n const onClickCapture = useCallback((event: React.MouseEvent) => {\n // Pointer clicks move focus to the activated nav button before `click`\n // fires. If that focus remains after navigation, mouse-leave treats it as\n // keyboard focus and keeps the unpinned overlay open indefinitely. Drop\n // pointer-created focus here; keyboard-generated clicks have detail=0 and\n // deliberately keep focus so keyboard navigation remains expanded.\n if (event.detail === 0) return;\n\n const activeElement = event.currentTarget.ownerDocument.activeElement;\n if (activeElement instanceof HTMLElement && event.currentTarget.contains(activeElement)) {\n activeElement.blur();\n }\n }, []);\n\n const onBlurCapture = useCallback(\n (event: React.FocusEvent) => {\n if (event.currentTarget.contains(event.relatedTarget as Node | null)) return;\n focusInsideRef.current = false;\n clearTimers();\n closeTimerRef.current = setTimeout(closeIfIdle, SIDENAV_HOVER_CLOSE_DELAY);\n },\n [clearTimers, closeIfIdle],\n );\n\n const onPointerDown = useCallback(\n (event: React.PointerEvent) => {\n // Some older touch WebViews omit pointerType; treating the missing value\n // as coarse keeps the navigation operable instead of hover-only.\n if (event.pointerType && event.pointerType !== \"touch\") return;\n touchOpenRef.current = !expanded;\n setExpanded((current) => !current);\n },\n [expanded],\n );\n\n const setTransientSurfaceOpen = useCallback(\n (open: boolean) => {\n surfaceOpenRef.current = open;\n clearTimers();\n if (open) {\n setExpanded(true);\n } else {\n closeTimerRef.current = setTimeout(closeIfIdle, SIDENAV_HOVER_CLOSE_DELAY);\n }\n },\n [clearTimers, closeIfIdle],\n );\n\n return {\n expanded,\n setExpanded,\n rootProps: { onPointerEnter, onPointerLeave, onFocusCapture, onBlurCapture, onPointerDown, onClickCapture },\n setTransientSurfaceOpen,\n };\n};\n", "import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { resolveSidenavLayout, type SidenavLayout, type SidenavPriority } from \"./resolveSidenavLayout\";\nimport { useExpandableSideNavOverlay } from \"./useExpandableSideNavOverlay\";\n\ninterface UseSidenavLayoutArgs {\n containerWidth: number;\n readerOpen: boolean;\n readerWidth: number;\n pinned: boolean;\n onPinnedChange: (pinned: boolean) => void;\n}\n\nexport const useSidenavLayout = ({\n containerWidth,\n readerOpen,\n readerWidth,\n pinned,\n onPinnedChange,\n}: UseSidenavLayoutArgs) => {\n const overlay = useExpandableSideNavOverlay();\n const [priority, setPriority] = useState(readerOpen ? \"reader\" : \"nav\");\n\n const previousLayoutRef = useRef();\n const resolvedLayout = useMemo(() => {\n return resolveSidenavLayout(\n {\n containerWidth,\n pinned,\n hovering: overlay.expanded,\n readerOpen,\n readerWidth,\n priority,\n },\n previousLayoutRef.current,\n );\n }, [containerWidth, overlay.expanded, pinned, priority, readerOpen, readerWidth]);\n useEffect(() => {\n previousLayoutRef.current = resolvedLayout;\n }, [resolvedLayout]);\n\n const pinnedOpen = resolvedLayout.nav === \"push\";\n\n const togglePin = useCallback(() => {\n setPriority(\"nav\");\n onPinnedChange(!pinnedOpen);\n }, [onPinnedChange, pinnedOpen]);\n const expandAndPin = useCallback(() => {\n setPriority(\"nav\");\n onPinnedChange(true);\n }, [onPinnedChange]);\n const noteReaderAction = useCallback(() => {\n setPriority(\"reader\");\n overlay.setExpanded(false);\n }, [overlay.setExpanded]);\n\n return {\n layout: resolvedLayout,\n expanded: resolvedLayout.nav !== \"rail\",\n pinnedOpen,\n togglePin,\n expandAndPin,\n noteReaderAction,\n rootProps: overlay.rootProps,\n setTransientSurfaceOpen: overlay.setTransientSurfaceOpen,\n };\n};\n", "import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { FC, ReactNode } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport Tooltip from \"@mui/material/Tooltip\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport { styled } from \"@/utils/styled\";\nimport { layout } from \"../theme/tokens/layout\";\nimport { motion as motionPresets, motionToCss } from \"../theme/tokens/motion\";\nimport { useSidepanelResize } from \"./useSidepanelResize\";\nimport { useAutoFullscreenOnNarrow } from \"./useAutoFullscreenOnNarrow\";\nimport { useEffectiveRailWidth } from \"./EffectiveRailWidthContext\";\nimport { useSidenavLayout } from \"../SideNav/useSidenavLayout\";\n\nexport type ColumnThreeMode = \"off\" | \"on\" | \"expanded\";\n\n/*\n * Split into two contexts so high-frequency width updates (60+/sec during a\n * drag) don't force every mode consumer (every reader-hosting page) to re-\n * render. Page-level consumers read mode via useAppShell / useAppShellOptional;\n * only the panel + resize handle JSX (inside AppShell itself) reads width via\n * useSidePanelWidth.\n */\ninterface AppShellModeContextValue {\n /** Effective visibility / expansion state after responsive layout arbitration. */\n columnThree: ColumnThreeMode;\n /** Reader-requested state, preserved while responsive arbitration temporarily hides it. */\n requestedColumnThree: ColumnThreeMode;\n setColumnThree: (mode: ColumnThreeMode) => void;\n}\n\ninterface SidePanelWidthContextValue {\n /**\n * Current width of Column 3 in px when columnThree === \"on\". Owned by AppShell;\n * NOT persisted across opens \u2014 every off \u2192 on/expanded transition resets to the\n * slot's effective min width so opening from a click lands predictably at the floor.\n */\n sidePanelWidth: number;\n setSidePanelWidth: (px: number) => void;\n}\n\nconst AppShellContext = createContext(null);\nconst SidePanelWidthContext = createContext(null);\n\ninterface ExpandableRailContextValue {\n expanded: boolean;\n pinnedOpen: boolean;\n visibleWidth: number;\n togglePin: () => void;\n expandAndPin: () => void;\n interactionProps: React.HTMLAttributes;\n setTransientSurfaceOpen: (open: boolean) => void;\n}\n\nconst ExpandableRailContext = createContext(null);\n\nexport const useExpandableRail = (): ExpandableRailContextValue => {\n const context = useContext(ExpandableRailContext);\n if (!context) throw new Error(\"useExpandableRail must be used inside an expandable \");\n return context;\n};\n\nexport const useExpandableRailOptional = (): ExpandableRailContextValue | null => useContext(ExpandableRailContext);\n\nexport const useAppShell = (): AppShellModeContextValue => {\n const ctx = useContext(AppShellContext);\n if (!ctx) {\n throw new Error(\"useAppShell must be used inside \");\n }\n return ctx;\n};\n\n/*\n * Test-friendly variant \u2014 returns null instead of throwing when rendered\n * outside an AppShell provider. Consumed by `useReaderPanelState` so reader-\n * hosting pages can be rendered in isolation in unit tests without setting up\n * a full AppShell wrapper. Production paths always have the provider in\n * place (AppShellLayout always wraps the route element).\n */\nexport const useAppShellOptional = (): AppShellModeContextValue | null => {\n return useContext(AppShellContext);\n};\n\nexport const useSidePanelWidth = (): SidePanelWidthContextValue => {\n const ctx = useContext(SidePanelWidthContext);\n if (!ctx) {\n throw new Error(\"useSidePanelWidth must be used inside \");\n }\n return ctx;\n};\n\n/**\n * Test- and legacy-friendly variant for components that can render either\n * inside the AppShell sidepanel or in the older standalone reader layout.\n */\nexport const useSidePanelWidthOptional = (): SidePanelWidthContextValue | null => {\n return useContext(SidePanelWidthContext);\n};\n\ninterface AppShellProps {\n /** Page content \u2014 renders inside ContentArea (the `LayoutSlot`). */\n children?: ReactNode;\n /** SideNav content (Column 1). Typically / . */\n rail?: ReactNode;\n /** TopBar TopBarLeft content \u2014 typically . */\n topBarLeft?: ReactNode;\n /**\n * TopBar TopBarRight content \u2014 typically .\n */\n topBarRight?: ReactNode;\n /**\n * SidePanel content (Column 3). Rendered only when columnThree is \"on\" or \"expanded\".\n *\n * Two ways to populate the sidepanel:\n * 1. Pass `sidePanel` as a prop at the top level (used by Storybook\n * stories and simple cases where the page knows its sidepanel up\n * front).\n * 2. Render `{content}`\n * anywhere inside the AppShell tree. The compound registers its\n * children via context \u2014 useful for route-driven pages where the\n * sidepanel content is owned deep in the React tree (e.g. NotesPage\n * renders a ReaderLayout inside Sidepanel when a transcript opens).\n *\n * Registered content from the compound takes precedence over the\n * `sidePanel` prop when both are present.\n */\n sidePanel?: ReactNode;\n /** Initial Column-Three state. */\n initialColumnThree?: ColumnThreeMode;\n /** Initial SidePanel width on first mount. Defaults to the effective minimum. */\n initialSidePanelWidth?: number;\n /**\n * Minimum SidePanel width declared by the slotted layout (e.g. `ReaderLayout.minWidth`).\n * The effective panel min is `max(this, layout.sidepanelStructuralMin)`.\n * When the `` compound is used, its `minWidth` prop\n * overrides this value.\n */\n sidePanelMinWidth?: number;\n /**\n * Lets simple, single-column routes shrink below the shell's normal 460px\n * application-area floor. Reader and workspace routes retain the wide\n * horizontal-scroll fallback.\n */\n allowNarrowAppArea?: boolean;\n /** Defaults to EffectiveRailWidthContext; exposed for isolated stories/tests. */\n effectiveRailWidth?: number;\n expandableRail?: boolean;\n navPinned?: boolean;\n onNavPinnedChange?: (pinned: boolean) => void;\n onEffectiveRailWidthChange?: (width: number) => void;\n}\n\ninterface SidepanelSlotRegistration {\n content: ReactNode;\n minWidth?: number;\n}\n\ninterface SidepanelSlotContextValue {\n setSlot: React.Dispatch>;\n}\n\nconst SidepanelSlotContext = createContext(null);\n\n/*\n * Page-driven topbar slot overrides. AppShellLayout sets defaults via the\n * `topBarLeft` / `topBarRight` props, and pages can REPLACE them by rendering\n * `` / `` from deep in the route tree.\n * Useful when a route owns its own session chrome (e.g. AgentPrototype's\n * conversation: folder chips + session actions) that should live inside the\n * AppShell topbar instead of duplicating below it.\n */\ninterface TopBarSlotsContextValue {\n setTopBarLeft: React.Dispatch>;\n setTopBarRight: React.Dispatch>;\n}\n\nconst TopBarSlotsContext = createContext(null);\n\n/*\n * Page-driven banner slot. Lives inside ContentArea, ABOVE LayoutSlot, so\n * pages that need a full-bleed banner (currently: the locked-Clerk surfaces\n * showing \"Clerk is disabled\u2026\") can place it within column 2's natural\n * padding without having to render the banner from inside LayoutSlot. Same\n * registration model as the TopBar / SidePanel slots \u2014 see ``.\n */\ninterface ContentBannerSlotContextValue {\n setSlot: React.Dispatch>;\n}\nconst ContentBannerSlotContext = createContext(null);\n\n/**\n * AppShell \u2014 three-column application shell (Figma node 74-440).\n *\n * AppShell (flex row)\n * \u251C\u2500\u2500 SideNav (rail, 56px fixed, border-right)\n * \u2514\u2500\u2500 AppArea (flex-1)\n * \u251C\u2500\u2500 columnThree=\"off\"\n * \u2502 \u2514\u2500\u2500 MainArea (column 2) \u2014 wraps TopBar + ContentArea\n * \u2502 \u251C\u2500\u2500 TopBar (sticky, justify-between, 12/16 padding) \u2014 TopBarLeft + TopBarRight\n * \u2502 \u2514\u2500\u2500 ContentArea (centered, 16px horizontal padding) \u2014 LayoutSlot accepts EntryLayout / IndexLayout / ChatLayout via children\n * \u251C\u2500\u2500 columnThree=\"on\"\n * \u2502 \u251C\u2500\u2500 MainArea (flex-1, vertical)\n * \u2502 \u2502 \u251C\u2500\u2500 TopBar\n * \u2502 \u2502 \u2514\u2500\u2500 ContentArea > LayoutSlot (children)\n * \u2502 \u2514\u2500\u2500 SidePanel (resizable, paper bg, left border, shadow/lg)\n * \u2514\u2500\u2500 columnThree=\"expanded\"\n * \u251C\u2500\u2500 MainArea (STAYS MOUNTED underneath, opacity 1)\n * \u2514\u2500\u2500 SidePanel (overlays MainArea via z-index \u2014 flex-1, fills AppArea width)\n *\n * Horizontal-scroll fallback: when window < rail + appArea-min + sidepanel.min,\n * ShellRoot scrolls horizontally. Rail is NOT sticky during horizontal scroll \u2014\n * it travels with the page (per Figma notes).\n *\n * Sidepanel transitions (on \u2194 expanded \u2194 off) animate via `motion` using the\n * `sidepanelExpand` preset; mount / unmount goes through ``.\n */\n\nconst ShellRoot = styled(Box)`\n display: flex;\n align-items: stretch;\n width: 100%;\n height: 100vh;\n overflow-x: auto;\n overflow-y: hidden;\n background: ${({ theme }) => theme.palette.background.default};\n position: relative;\n`;\n\nconst RailSlot = styled(Box)<{ $railWidth: number; $legacy: boolean }>`\n position: relative;\n flex: 0 0 ${({ $railWidth }) => $railWidth}px;\n width: ${({ $railWidth }) => $railWidth}px;\n height: 100%;\n background: ${({ theme }) => theme.palette.background.default};\n border-right: ${({ $legacy, theme }) => ($legacy ? `1px solid ${theme.border.default}` : \"none\")};\n overflow: visible;\n display: flex;\n flex-direction: column;\n z-index: ${({ theme }) => theme.tokens.zIndex.topBar};\n`;\n\nconst AppAreaWrapper = styled(Box)<{ $allowNarrowAppArea: boolean }>`\n flex: 1 1 auto;\n min-width: ${({ $allowNarrowAppArea }) => ($allowNarrowAppArea ? 0 : layout.appAreaMin)}px;\n height: 100%;\n display: flex;\n flex-direction: row;\n align-items: stretch;\n /*\n * overflow: clip instead of hidden. Both clip visual overflow, but\n * hidden still creates a scroll container that can be scrolled\n * PROGRAMMATICALLY. When TranscriptReader's highlight-navigation calls\n * scrollIntoView on a highlight inside the panel, the browser scrolls\n * every scrollable ancestor \u2014 including AppAreaWrapper, since its\n * children (MainArea + placeholder) overflow it at narrow viewports.\n * Result: AppAreaWrapper.scrollLeft becomes nonzero and the absolutely\n * positioned sidepanel child shifts left visually, leaving a gap\n * between its right edge and the viewport. clip prevents AppAreaWrapper\n * from being a scroll container at all, so scrollIntoView walks up to\n * the next scroll container (ShellRoot) instead.\n */\n overflow: clip;\n min-height: 0;\n position: relative;\n`;\n\nconst MainArea = styled(Box)<{ $allowNarrowAppArea: boolean }>`\n flex: 1 1 auto;\n /*\n * Hard floor at appAreaMin (460px). Without this, the flex children\n * inside AppAreaWrapper (MainArea + sidepanel-placeholder) collapse\n * MainArea to whatever space remains after the placeholder takes its\n * fixed width, which can drop to 0 below a narrow viewport \u2014 content\n * inside MainArea (e.g. the AgentPrototype input bar) ends up too small\n * for its buttons. With this floor, AppAreaWrapper's intrinsic min\n * becomes appAreaMin + sidePanelWidth, which exceeds the viewport when\n * squeezed \u2192 ShellRoot's overflow-x: auto kicks in and the page scrolls\n * horizontally (matches the Figma \"wide spreadsheet\" fallback).\n */\n min-width: ${({ $allowNarrowAppArea }) => ($allowNarrowAppArea ? 0 : layout.appAreaMin)}px;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n overflow-x: hidden;\n /*\n * Contain MainArea's stacking context so the SidePanel-expanded overlay\n * (sibling, z-index 1) reliably covers everything inside MainArea \u2014 most\n * importantly the sticky TopBar. Without this, the sticky TopBar's\n * z-index leaks into AppAreaWrapper's stacking context and shows through\n * the expanded overlay.\n */\n isolation: isolate;\n`;\n\nconst TopBar = styled(Box)`\n display: flex;\n // align-items: center keeps icons coplanar with ReaderTopBar's centered icons.\n align-items: center;\n justify-content: space-between;\n width: 100%;\n // Fixed height matches ReaderTopBar \u2014 don't substitute min-height, children would grow the row.\n height: ${layout.appShellTopBarHeight}px;\n padding: ${layout.topBarPaddingY}px ${layout.topBarPaddingX}px;\n box-sizing: border-box;\n position: sticky;\n top: 0;\n z-index: ${({ theme }) => theme.tokens.zIndex.topBar};\n background: ${({ theme }) => theme.palette.background.default};\n overflow: hidden;\n flex: 0 0 auto;\n gap: ${({ theme }) => theme.spacing(2)};\n`;\n\nconst TopBarSideSlot = styled(Box)`\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.spacing(1)};\n min-width: 0;\n`;\n\nconst ContentArea = styled(Box)`\n flex: 1 1 auto;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 0 ${layout.contentAreaPaddingX}px;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n`;\n\n/*\n * Wrapper around the page-registered `` content.\n * Acts as a Figma-style \"autolayout, fit container\" frame: full width of\n * ContentArea's content box, flex column so any number of children stack\n * vertically, and `flex-shrink: 0` so the banner keeps its natural height\n * instead of being squeezed by LayoutSlot's vertical growth.\n *\n * Without this wrapper the registered content would inherit ContentArea's\n * `align-items: center` and shrink to its content width, leaving the\n * banner floating mid-column. The wrapper short-circuits that by claiming\n * the full cross-axis width.\n */\nconst ContentBannerSlot = styled(Box)`\n width: 100%;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n`;\n\nconst LayoutSlot = styled(Box)`\n flex: 1 1 auto;\n width: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n`;\n\n// Hoisted so the styled template's `$dragging` interpolation doesn't recompute\n// the CSS string on every drag tick.\nconst SIDEPANEL_EXPAND_CSS = motionToCss(motionPresets.sidepanelExpand);\n\nconst SidePanelMotion = styled(motion.div)<{ $expanded: boolean; $dragging: boolean }>`\n /* Always position: absolute \u2014 the panel overlays the right portion of\n AppArea regardless of mode. MainArea behind it keeps its full width,\n so its contents never reflow when the panel opens / expands. Critical\n for the transition: there's no position-type snap to animate around,\n and width changes drive a natural per-frame DOM re-layout (browser\n reflows contents at each width) instead of CSS transforms that would\n visually stretch text and chrome. */\n position: absolute;\n top: 0;\n bottom: 0;\n right: 0;\n z-index: ${({ theme }) => theme.tokens.zIndex.raised};\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: ${({ theme }) => theme.palette.background.paper};\n /* In \"on\" mode the panel's left edge sits inside AppArea \u2014 its border-left\n is the visual divider. In \"expanded\" mode the panel covers the entire\n AppArea and its left edge meets the Rail's right edge; dropping the\n border-left there avoids a doubled-up 2px line against the Rail. */\n border-left: ${({ $expanded, theme }) => ($expanded ? \"none\" : `1px solid ${theme.border.default}`)};\n box-shadow: ${({ theme }) => theme.tokens.shadows.lg};\n overflow: hidden;\n min-width: 0;\n /*\n * Width transition for on \u2194 expanded smoothness. Disabled during drag so\n * the panel tracks the pointer 1:1. CSS-only \u2014 no motion.layout, no\n * transforms, so contents reflow naturally per frame and don't visually\n * scale during the transition. Duration / easing come from the\n * sidepanelExpand motion preset via motionToCss(); keeps this transition\n * in sync with the AnimatePresence translateX that runs alongside.\n */\n transition: ${({ $dragging }) => ($dragging ? \"none\" : `width ${SIDEPANEL_EXPAND_CSS}`)};\n`;\n\n/*\n * Lives in AppAreaWrapper as a sibling of SidePanelMotion (NOT inside the\n * panel) so the handle can straddle the panel/MainArea boundary without its\n * hover-visible hairline being clipped by SidePanelMotion's overflow: hidden.\n * Position is driven by an inline `right` style that the parent sets to\n * `sidePanelWidth - handleWidth/2` so the handle is centered on the panel's\n * left edge.\n */\nconst ResizeHandle = styled(Box)`\n position: absolute;\n top: 0;\n bottom: 0;\n width: ${layout.sidepanelResizeHandleWidth}px;\n cursor: col-resize;\n z-index: ${({ theme }) => theme.tokens.zIndex.raisedAbove};\n touch-action: none;\n user-select: none;\n\n // Hover/drag affordance \u2014 visible only on interaction; stays during drag so it doesn't flicker mid-interaction.\n &::after {\n content: \"\";\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 3px;\n height: 60px;\n border-radius: 2px;\n background: ${({ theme }) => theme.palette.secondary.dark};\n opacity: 0;\n pointer-events: none;\n transition: opacity ${motionToCss(motionPresets.stickyHeaderExpand)};\n }\n &:hover::after,\n &[data-dragging=\"true\"]::after {\n opacity: 1;\n }\n`;\n\nfunction clampWidth(width: number, min: number, max: number): number {\n if (!Number.isFinite(width)) return min;\n return Math.max(min, Math.min(max, width));\n}\n\nconst AppShellComponent: FC = ({\n children,\n rail,\n topBarLeft,\n topBarRight,\n sidePanel,\n initialColumnThree = \"off\",\n initialSidePanelWidth,\n sidePanelMinWidth = 0,\n allowNarrowAppArea = false,\n effectiveRailWidth: effectiveRailWidthProp,\n expandableRail = false,\n navPinned = false,\n onNavPinnedChange = () => undefined,\n onEffectiveRailWidthChange,\n}) => {\n const contextRailWidth = useEffectiveRailWidth();\n const effectiveRailWidth = effectiveRailWidthProp ?? contextRailWidth;\n /*\n * Registered sidepanel slot from the `` compound, when\n * present. Takes precedence over the `sidePanel` prop. The compound's\n * `minWidth` prop also overrides `sidePanelMinWidth`, since slot-fill\n * children are closer to the layout-component contract (e.g. ReaderLayout\n * declares its own minWidth via the compound).\n */\n const [registeredSlot, setRegisteredSlot] = useState(null);\n const slotContextValue = useMemo(() => ({ setSlot: setRegisteredSlot }), []);\n\n const effectiveSidePanel = registeredSlot ? registeredSlot.content : sidePanel;\n const effectiveSlotMinWidth = registeredSlot?.minWidth ?? sidePanelMinWidth;\n\n // Page-driven topbar slot overrides from / .\n const [registeredTopBarLeft, setRegisteredTopBarLeft] = useState(null);\n const [registeredTopBarRight, setRegisteredTopBarRight] = useState(null);\n const topBarSlotsContextValue = useMemo(\n () => ({ setTopBarLeft: setRegisteredTopBarLeft, setTopBarRight: setRegisteredTopBarRight }),\n [],\n );\n const effectiveTopBarLeft = registeredTopBarLeft ?? topBarLeft;\n const effectiveTopBarRight = registeredTopBarRight ?? topBarRight;\n\n // Page-driven ContentArea banner slot from .\n const [registeredContentBanner, setRegisteredContentBanner] = useState(null);\n const contentBannerSlotsContextValue = useMemo(\n () => ({ setSlot: setRegisteredContentBanner }),\n [],\n );\n\n /*\n * Effective min = max(slot's declared min, shell structural floor).\n *\n * Deliberate deviation from the original plan, which had no structural\n * floor and let the slot fully own its bounds. The 320px floor was\n * restored during the AppShell fidelity sweep as a safety net: a panel\n * narrower than ~320px stops being a panel (the conventional minimum\n * mobile viewport width). Without the floor, a future slot that\n * declares `minWidth: 80` could silently break the resize UX.\n *\n * Today this is a no-op for the one consumer (`ReaderLayout.minWidth =\n * 772`). If a future caller legitimately needs a smaller panel, add an\n * opt-out (e.g. `disableStructuralFloor` on ``)\n * rather than relaxing the floor for everyone.\n */\n const effectiveMin = Math.max(effectiveSlotMinWidth, layout.sidepanelStructuralMin);\n\n // Computed dynamically from window for the max; recomputed on resize.\n const computeMaxWidth = useCallback(() => {\n if (typeof window === \"undefined\") return effectiveMin;\n return Math.max(effectiveMin, window.innerWidth - effectiveRailWidth - layout.appAreaMin);\n }, [effectiveMin, effectiveRailWidth]);\n\n const [columnThree, setColumnThree] = useState(initialColumnThree);\n /*\n * The sidepanel always opens at its minimum width (effectiveMin = the\n * slot's declared minWidth, e.g. ReaderLayout.minWidth). Users can drag\n * wider mid-session; closing and reopening resets to min. We intentionally\n * do NOT persist drag state across opens \u2014 opening from a click should\n * land predictably at the floor, not at whatever the user happened to drag\n * to last time.\n */\n const [sidePanelWidth, setSidePanelWidthState] = useState(() =>\n clampWidth(initialSidePanelWidth ?? effectiveMin, effectiveMin, computeMaxWidth()),\n );\n\n const shellRootRef = useRef(null);\n const [containerWidth, setContainerWidth] = useState(() => (typeof window === \"undefined\" ? 0 : window.innerWidth));\n useEffect(() => {\n if (!expandableRail || !shellRootRef.current) return;\n const element = shellRootRef.current;\n const measure = () => setContainerWidth(element.getBoundingClientRect().width || window.innerWidth);\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [expandableRail]);\n\n const sidenavLayout = useSidenavLayout({\n containerWidth,\n readerOpen: columnThree !== \"off\",\n readerWidth: sidePanelWidth,\n pinned: navPinned,\n onPinnedChange: onNavPinnedChange,\n });\n const resolvedRailWidth = expandableRail\n ? sidenavLayout.layout.nav === \"push\"\n ? layout.railExpandedWidth\n : layout.expandableRailCollapsedWidth\n : effectiveRailWidth;\n const effectiveColumnThree: ColumnThreeMode = !expandableRail\n ? columnThree\n : sidenavLayout.layout.reader === \"full\"\n ? \"expanded\"\n : sidenavLayout.layout.reader === \"hidden\"\n ? \"off\"\n : columnThree;\n const setColumnThreeWithPriority = useCallback(\n (mode: ColumnThreeMode) => {\n if (expandableRail && mode !== \"off\") sidenavLayout.noteReaderAction();\n setColumnThree(mode);\n },\n [expandableRail, sidenavLayout.noteReaderAction],\n );\n\n useEffect(() => {\n if (expandableRail) onEffectiveRailWidthChange?.(resolvedRailWidth);\n }, [expandableRail, onEffectiveRailWidthChange, resolvedRailWidth]);\n\n const setSidePanelWidth = useCallback(\n (px: number) => {\n setSidePanelWidthState(clampWidth(px, effectiveMin, computeMaxWidth()));\n },\n [effectiveMin, computeMaxWidth],\n );\n\n // Reset to the slot's minimum on every off \u2192 on/expanded transition.\n const previousColumnThreeRef = useRef(initialColumnThree);\n useEffect(() => {\n if (previousColumnThreeRef.current === \"off\" && columnThree !== \"off\") {\n setSidePanelWidthState(clampWidth(effectiveMin, effectiveMin, computeMaxWidth()));\n }\n previousColumnThreeRef.current = columnThree;\n }, [columnThree, effectiveMin, computeMaxWidth]);\n\n const modeContextValue = useMemo(\n () => ({\n columnThree: effectiveColumnThree,\n requestedColumnThree: columnThree,\n setColumnThree: setColumnThreeWithPriority,\n }),\n [columnThree, effectiveColumnThree, setColumnThreeWithPriority],\n );\n const widthContextValue = useMemo(\n () => ({ sidePanelWidth, setSidePanelWidth }),\n [sidePanelWidth, setSidePanelWidth],\n );\n\n const expanded = effectiveColumnThree === \"expanded\";\n\n const { isDragging, handleProps } = useSidepanelResize({\n enabled: effectiveColumnThree === \"on\",\n currentWidth: sidePanelWidth,\n minWidth: effectiveMin,\n maxWidth: computeMaxWidth(),\n onResize: setSidePanelWidth,\n // No onDragEnd today \u2014 onResize's last emit is the committed width.\n // Future analytics / persistence side effects can hook here.\n });\n\n // When the window narrows enough that the paneled sidepanel no longer fits\n // (its top-left controls would clip off-screen), snap it to fullscreen; when\n // there's room again, pop it back to paneled (re-clamped to what currently\n // fits, not necessarily the exact pre-snap width). See useAutoFullscreenOnNarrow.\n const appAreaRef = useRef(null);\n useAutoFullscreenOnNarrow({\n containerRef: appAreaRef,\n columnThree: effectiveColumnThree,\n panelWidth: sidePanelWidth,\n setColumnThree: setColumnThreeWithPriority,\n setPanelWidth: setSidePanelWidth,\n enabled: !expandableRail,\n });\n\n const expandableRailContextValue = useMemo(\n () => ({\n expanded: sidenavLayout.expanded,\n pinnedOpen: sidenavLayout.pinnedOpen,\n visibleWidth: expandableRail\n ? sidenavLayout.expanded\n ? layout.railExpandedWidth\n : layout.expandableRailCollapsedWidth\n : effectiveRailWidth,\n togglePin: sidenavLayout.togglePin,\n expandAndPin: sidenavLayout.expandAndPin,\n interactionProps: sidenavLayout.rootProps,\n setTransientSurfaceOpen: sidenavLayout.setTransientSurfaceOpen,\n }),\n [effectiveRailWidth, expandableRail, sidenavLayout],\n );\n\n // MainArea is ALWAYS rendered when sidepanel content exists \u2014 even in\n // expanded mode where the SidePanel overlays it. This preserves page state\n // (scroll positions, form drafts, etc.) when toggling between modes.\n //\n // In expanded mode, mark MainArea `inert` + `aria-hidden` so the overlay\n // behaves like a modal: keyboard Tab can't reach the underlying content\n // (otherwise focus would silently leak behind the visible overlay), and\n // screen readers don't announce two layers. `inert` is passed via spread\n // because React 18.2 types don't yet include it as a prop; the DOM\n // attribute is widely supported (Chrome 102+, Firefox 112+, Safari 15.5+).\n const mainArea = (\n \n \n {effectiveTopBarLeft}\n {effectiveTopBarRight}\n \n \n {/* Optional banner slot \u2014 registered via \n from inside a page. The slot is an autolayout (full width of\n ContentArea's content box, column flex) so any registered\n content fills column 2 edge-to-edge regardless of its own\n intrinsic width. */}\n {registeredContentBanner != null && {registeredContentBanner}}\n {children}\n \n \n );\n\n const showSidePanel = effectiveColumnThree !== \"off\";\n\n return (\n \n \n \n \n \n \n \n \n {rail}\n \n \n {mainArea}\n {/*\n * Invisible flex placeholder that pushes MainArea over to make\n * room for the absolute-positioned SidePanel.\n *\n * - off: placeholder unmounted \u2192 MainArea full width\n * - on: placeholder = sidePanelWidth \u2192 MainArea shrinks\n * - expanded: placeholder = sidePanelWidth (UNCHANGED) \u2192\n * MainArea stays at its on-mode width. SidePanel\n * grows to 100% and overlays MainArea; MainArea\n * content is hidden under the overlay but does\n * NOT reflow or animate (it stays mounted at the\n * same width across the on \u2194 expanded toggle).\n *\n * During drag, transition is disabled so the placeholder tracks\n * the pointer 1:1 along with the panel.\n */}\n {showSidePanel && (\n \n )}\n \n {showSidePanel && (\n \n {effectiveSidePanel}\n \n )}\n \n {/*\n * Resize handle lives OUTSIDE the panel (sibling, not child)\n * so its hover-visible hairline can straddle the panel's left\n * edge without being clipped by SidePanelMotion's overflow:\n * hidden. Positioned right: sidePanelWidth - handleWidth/2 so\n * the 8px hit zone is centered on the panel boundary.\n */}\n {effectiveColumnThree === \"on\" && (\n \n \n \n )}\n \n \n \n \n \n \n \n \n );\n};\n\n/*\n * `` compound \u2014 declarative way to put content into the\n * AppShell sidepanel slot from anywhere in the React tree. Registers its\n * children with the parent AppShell via context on mount; unregisters on\n * unmount (so navigating away clears the sidepanel automatically).\n *\n * @example\n * function NotesPage() {\n * const { isReaderOpen } = useReaderPanelState({ ... });\n * return (\n * <>\n * \n * {isReaderOpen && (\n * \n * {transcriptContent}\n * \n * )}\n * \n * );\n * }\n */\ninterface SidePanelProps {\n /** Content to render inside the AppShell sidepanel slot. */\n children: ReactNode;\n /**\n * Minimum width the slot child can shrink to. Typically the layout\n * component's static minWidth (e.g. `ReaderLayout.minWidth = 772`). Overrides\n * the AppShell's `sidePanelMinWidth` prop when both are set.\n */\n minWidth?: number;\n}\n\nconst SidePanel: FC = ({ children, minWidth }) => {\n /*\n * When rendered inside an AppShell: register children with the slot\n * registry (renders inside the shell's sidepanel column). When rendered\n * OUTSIDE an AppShell (unit tests / Storybook in isolation): render\n * children inline at this position so the page's interactions remain\n * reachable instead of disappearing entirely. Production paths always have\n * the provider, so this fallback only matters in test environments.\n */\n const ctx = useContext(SidepanelSlotContext);\n const setSlot = ctx?.setSlot;\n /*\n * Identity-guarded cleanup: capture the registration this instance wrote\n * and only clear it on unmount if it's still the one in the registry.\n * Protects against the next-mount-runs-before-this-unmount transition\n * sequence (concurrent rendering, route swaps), where an unconditional\n * `setSlot(null)` would clobber the new page's registration.\n */\n const registrationRef = useRef(null);\n useEffect(() => {\n if (!setSlot) return;\n const registration: SidepanelSlotRegistration = { content: children, minWidth };\n registrationRef.current = registration;\n setSlot(registration);\n return () => {\n setSlot((prev) => (prev === registrationRef.current ? null : prev));\n };\n }, [children, minWidth, setSlot]);\n if (!setSlot) return <>{children};\n return null;\n};\n\n/*\n * `` / `` compounds \u2014 declarative\n * page-level overrides for the AppShell topbar. When mounted, replaces\n * AppShellLayout's default topBarLeft / topBarRight content. Unmounting clears\n * the override so the default reappears.\n *\n * @example\n * // AgentPrototypeConversation injects session actions + folder chips:\n * \n * } folderChipRow={} />\n * \n */\ninterface TopBarSlotProps {\n children: ReactNode;\n}\n\nconst TopBarLeft: FC = ({ children }) => {\n // Renders inline as fallback when outside an AppShell (see comment).\n const ctx = useContext(TopBarSlotsContext);\n const setTopBarLeft = ctx?.setTopBarLeft;\n const registrationRef = useRef(null);\n useEffect(() => {\n if (!setTopBarLeft) return;\n registrationRef.current = children;\n setTopBarLeft(children);\n // Identity-guarded cleanup \u2014 see .\n return () => {\n setTopBarLeft((prev) => (prev === registrationRef.current ? null : prev));\n };\n }, [children, setTopBarLeft]);\n if (!setTopBarLeft) return <>{children};\n return null;\n};\n\nconst TopBarRight: FC = ({ children }) => {\n // Renders inline as fallback when outside an AppShell (see comment).\n const ctx = useContext(TopBarSlotsContext);\n const setTopBarRight = ctx?.setTopBarRight;\n const registrationRef = useRef(null);\n useEffect(() => {\n if (!setTopBarRight) return;\n registrationRef.current = children;\n setTopBarRight(children);\n // Identity-guarded cleanup \u2014 see .\n return () => {\n setTopBarRight((prev) => (prev === registrationRef.current ? null : prev));\n };\n }, [children, setTopBarRight]);\n if (!setTopBarRight) return <>{children};\n return null;\n};\n\n/*\n * `` compound \u2014 declarative way to inject a banner\n * above LayoutSlot, inside ContentArea. Used by the locked-Clerk pages to\n * show the \"Clerk is disabled\" info banner at the top of column 2 without\n * coupling the AppShell to that specific feature.\n *\n * @example\n * function LockedClerkLanding() {\n * return (\n * <>\n * \n * \n * \n * \n * \n * );\n * }\n */\nconst ContentBanner: FC = ({ children }) => {\n // Same render-inline-as-fallback semantics as the other compound slots\n // (see comment) so storybook / unit tests outside an\n // AppShell still see the banner content.\n const ctx = useContext(ContentBannerSlotContext);\n const setSlot = ctx?.setSlot;\n const registrationRef = useRef(null);\n useEffect(() => {\n if (!setSlot) return;\n registrationRef.current = children;\n setSlot(children);\n // Identity-guarded cleanup \u2014 see .\n return () => {\n setSlot((prev) => (prev === registrationRef.current ? null : prev));\n };\n }, [children, setSlot]);\n if (!setSlot) return <>{children};\n return null;\n};\n\ntype AppShellComponentType = FC & {\n SidePanel: FC;\n TopBarLeft: FC;\n TopBarRight: FC;\n ContentBanner: FC;\n};\n\nexport const AppShell = AppShellComponent as AppShellComponentType;\nAppShell.SidePanel = SidePanel;\nAppShell.TopBarLeft = TopBarLeft;\nAppShell.TopBarRight = TopBarRight;\nAppShell.ContentBanner = ContentBanner;\n", "import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAppShellOptional, type ColumnThreeMode } from \"./AppShell\";\n\n/*\n * Legacy reader-expansion modes used by `TranscriptReader` /\n * `TranscriptReaderWithDrawers`. Kept as a string-literal union here so this\n * module doesn't import from `molecules/` (which would create a circular\n * design-system layering between `AppShell/` and `molecules/`). Source of\n * truth lives in `molecules/TranscriptReader.tsx`; mirrored here so the\n * mapping helper can return the right shape without a heavy import.\n */\ntype ExpandedModes = \"collapsed\" | \"expandedButPaneled\" | \"expanded\";\n\ninterface UseReaderPanelStateInput {\n /**\n * The page's source of truth for whether a transcript / reader is currently\n * open. Typically derived from a `selectedTranscriptId` (or similar) page\n * state: `isReaderOpen: !!selectedTranscriptId`.\n */\n isReaderOpen: boolean;\n /**\n * Called when the user clicks the reader's close (X) affordance. The hook\n * sets the AppShell sidepanel mode to `\"off\"` itself; this callback is for\n * the PAGE to clear its own \"which transcript is selected\" state so the\n * next render's `isReaderOpen` is false.\n */\n onClose: () => void;\n /**\n * AppShell sidepanel mode to use when the reader transitions from closed \u2192\n * open. Defaults to `\"on\"` (panel sits next to AppArea). Pass `\"expanded\"`\n * if the page wants the reader to open in fullscreen-overlay mode.\n */\n defaultMode?: Exclude;\n /**\n * Changes whenever the user explicitly asks to open a transcript, including\n * clicking the transcript that is already selected. This lets the reader\n * reassert layout priority after a pinned sidenav force-collapsed it without\n * clearing either the selected transcript or the stored pin preference.\n */\n openRequestKey?: unknown;\n}\n\nexport interface UseReaderPanelStateReturn {\n /**\n * AppShell's current sidepanel mode, mapped onto `TranscriptReader` /\n * `TranscriptReaderWithDrawers`'s `ExpandedModes` enum. Pass this to the\n * wrapper's `expandedModeExternal` prop so its internal state machine sits\n * downstream of the AppShell sidepanel mode.\n *\n * `\"off\"` \u2192 `\"collapsed\"`\n * `\"on\"` \u2192 `\"expandedButPaneled\"`\n * `\"expanded\"` \u2192 `\"expanded\"`\n *\n * If a consumer needs AppShell's raw column-three mode (\"off\" / \"on\" /\n * \"expanded\"), call `useAppShell()` directly \u2014 this hook only exposes the\n * ExpandedModes-shaped translation that page-level consumers actually need.\n */\n expandedMode: ExpandedModes;\n /**\n * Wire to the reader's close (X) icon button. Sets the AppShell sidepanel\n * mode to `\"off\"` AND invokes the page's `onClose` callback to clear its\n * selected-transcript state.\n */\n handleClose: () => void;\n /**\n * Wire to the reader's fullscreen (Expand) icon button. Toggles between\n * `\"on\"` and `\"expanded\"` modes. No-op when the reader is closed.\n */\n handleToggleExpand: () => void;\n /**\n * Wire to `TranscriptReaderWithDrawers`' `onExpandedModeChange` callback.\n * Translates a wrapper-emitted ExpandedModes value (e.g. when the user\n * opens the in-transcript search drawer and the wrapper would normally\n * flip to `\"expandedButPaneled\"`) back into the right AppShell sidepanel\n * mode. Use:\n *\n * ``\n */\n handleExpandedModeChange: (next: ExpandedModes) => void;\n}\n\n/**\n * Map an AppShell sidepanel mode \u2192 a legacy reader ExpandedModes value.\n * Exposed both inside the hook return AND as a standalone export so callsites\n * that need the mapping without consuming the whole hook can use it directly.\n */\nexport function columnThreeModeToExpandedMode(mode: ColumnThreeMode): ExpandedModes {\n if (mode === \"off\") return \"collapsed\";\n if (mode === \"expanded\") return \"expanded\";\n return \"expandedButPaneled\";\n}\n\nfunction expandedModeToColumnThreeMode(mode: ExpandedModes): ColumnThreeMode {\n if (mode === \"collapsed\") return \"off\";\n if (mode === \"expanded\") return \"expanded\";\n return \"on\";\n}\n\n/**\n * useReaderPanelState \u2014 bridge between a page's transcript-selection state\n * and the AppShell sidepanel mode.\n *\n * Pages that host a reader (Notes, Starred, FolderDetail, QueryResults,\n * AgentPrototype conversation) own a piece of local state for \"which\n * transcript is currently open\". This hook lifts that state up to the\n * AppShell sidepanel \u2014 when a transcript is selected, the sidepanel opens;\n * when it's deselected (or the user closes the reader), the sidepanel\n * closes. The fullscreen handler toggles between the `\"on\"` (split) and\n * `\"expanded\"` (overlay) modes.\n *\n * MUST be called inside an `` provider (it consumes the AppShell\n * context via `useAppShell()`).\n *\n * @example\n * const [selectedTranscriptId, setSelectedTranscriptId] = useState(null);\n *\n * const panel = useReaderPanelState({\n * isReaderOpen: !!selectedTranscriptId,\n * onClose: () => setSelectedTranscriptId(null),\n * });\n *\n * // Then pass the whole `panel` object to (the\n * // canonical reader-in-sidepanel wrapper); destructure handlers if wiring\n * // chrome directly.\n * \n */\nexport function useReaderPanelState({\n isReaderOpen,\n onClose,\n defaultMode = \"on\",\n openRequestKey,\n}: UseReaderPanelStateInput): UseReaderPanelStateReturn {\n /*\n * Optional \u2014 when rendered inside an AppShell (production path), drive the\n * shell's column-three state directly. When rendered outside (unit tests\n * that mount a page in isolation), fall back to local state so the hook\n * doesn't throw. The sidepanel doesn't render in that environment, so\n * mode state has no UI consequence \u2014 it's just kept consistent for the\n * callbacks the page wires up.\n */\n const ctx = useAppShellOptional();\n const localState = useState(\"off\");\n const columnThree = ctx ? ctx.columnThree : localState[0];\n const requestedColumnThree = ctx ? ctx.requestedColumnThree : localState[0];\n const setColumnThree = ctx ? ctx.setColumnThree : localState[1];\n\n /*\n * Sync sidepanel mode with `isReaderOpen`. Transitions to handle:\n * - closed \u2192 open: panel was \"off\", reader is now open \u2192 set to defaultMode\n * - open \u2192 closed: reader is no longer open but panel is still \"on\" /\n * \"expanded\" \u2192 set to \"off\"\n * - explicit reopen: the reader is still selected but a new open request\n * arrived after responsive arbitration hid it \u2192 reassert defaultMode\n * The intermediate \"on\" \u2194 \"expanded\" transitions (driven by handleToggleExpand)\n * don't touch `isReaderOpen`, so this effect is a no-op for those.\n */\n const previousOpenRequestKeyRef = useRef(openRequestKey);\n useEffect(() => {\n const hasNewOpenRequest =\n openRequestKey !== undefined && !Object.is(previousOpenRequestKeyRef.current, openRequestKey);\n previousOpenRequestKeyRef.current = openRequestKey;\n\n if (isReaderOpen && (requestedColumnThree === \"off\" || hasNewOpenRequest)) {\n setColumnThree(defaultMode);\n } else if (!isReaderOpen && requestedColumnThree !== \"off\") {\n setColumnThree(\"off\");\n }\n }, [isReaderOpen, openRequestKey, requestedColumnThree, defaultMode, setColumnThree]);\n\n /*\n * Reset the sidepanel to \"off\" when this hook unmounts. AppShellLayout\n * (the wrapper that owns the AppShell context) doesn't itself unmount\n * across page navigations \u2014 only the page inside the changes \u2014\n * so `columnThree` persists. Without this cleanup, navigating from a\n * page that opened the reader (e.g. /starred with a transcript open) to\n * a page that doesn't use a reader (e.g. /history) leaves the sidepanel\n * column rendered but empty (the slot's content unregisters, the mode\n * stays \"on\"). Forcing \"off\" here keeps state consistent with the\n * AppShell semantics: no `useReaderPanelState` consumer in the route \u2192\n * no open sidepanel.\n *\n * Capture setColumnThree in a ref so the cleanup fires exactly once on\n * unmount; depending on the setter directly would re-fire the cleanup if\n * the AppShell context's setter identity ever changes mid-life.\n */\n const setColumnThreeRef = useRef(setColumnThree);\n setColumnThreeRef.current = setColumnThree;\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n useEffect(() => {\n return () => {\n setColumnThreeRef.current(\"off\");\n };\n }, []);\n\n /*\n * Focus management. When the reader transitions from closed \u2192 open\n * (the click that opens a transcript), capture the element that was\n * focused at that moment. When the reader closes via `handleClose`,\n * restore focus to that element so keyboard users land back where they\n * started instead of on . Uses requestAnimationFrame so the\n * restore happens after the panel-exit reflow finishes and the\n * previously-focused element is back in the DOM.\n */\n const previouslyFocusedRef = useRef(null);\n useEffect(() => {\n if (isReaderOpen) {\n previouslyFocusedRef.current = (document.activeElement as HTMLElement) ?? null;\n }\n }, [isReaderOpen]);\n\n const handleClose = useCallback(() => {\n const toRestore = previouslyFocusedRef.current;\n setColumnThreeRef.current(\"off\");\n onCloseRef.current();\n if (toRestore && document.contains(toRestore)) {\n requestAnimationFrame(() => {\n toRestore.focus({ preventScroll: true });\n });\n }\n }, []);\n\n const handleToggleExpand = useCallback(() => {\n setColumnThreeRef.current(columnThree === \"expanded\" ? \"on\" : \"expanded\");\n }, [columnThree]);\n\n const handleExpandedModeChange = useCallback((next: ExpandedModes) => {\n const nextColumnThree = expandedModeToColumnThreeMode(next);\n /*\n * If the wrapper wants to transition to \"collapsed\", that means the\n * close button was clicked from inside its UI \u2014 fire `onClose` too so\n * the page's selected-transcript state clears (otherwise the next\n * render would reopen the panel from `isReaderOpen=true`).\n */\n if (next === \"collapsed\") {\n onCloseRef.current();\n }\n setColumnThreeRef.current(nextColumnThree);\n }, []);\n\n // Memoize the return so consumers that pass the whole `panel` object as a\n // prop (e.g. SidepanelTranscriptReader) keep a stable identity across\n // renders that don't actually change anything observable.\n return useMemo(\n () => ({\n expandedMode: columnThreeModeToExpandedMode(columnThree),\n handleClose,\n handleToggleExpand,\n handleExpandedModeChange,\n }),\n [columnThree, handleClose, handleToggleExpand, handleExpandedModeChange],\n );\n}\n", "export {\n AppShell,\n useAppShell,\n useAppShellOptional,\n useExpandableRail,\n useExpandableRailOptional,\n useSidePanelWidth,\n useSidePanelWidthOptional,\n} from \"./AppShell\";\nexport type { ColumnThreeMode } from \"./AppShell\";\nexport { useReaderPanelState } from \"./useReaderPanelState\";\nexport { EffectiveRailWidthProvider, useEffectiveRailWidth } from \"./EffectiveRailWidthContext\";\n", "import React from \"react\";\nimport { Alert } from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { AGENT_HELP_CENTER_URL } from \"./constants\";\n\n/**\n * Shared \"Clerk is disabled\" info banner shown at the top of every locked\n * Clerk surface (landing, example session, and the locked /history page).\n *\n * Visual reference: Figma 6054-26452 (and identical instances on 6056-5925\n * / 6056-6154). Uses MUI Alert's default `severity=\"info\"` palette \u2014 the\n * resolved tokens match the Figma export exactly:\n * bg = #e5f6fd (_components/alert/info/background)\n * color = #014361 (_components/alert/info/color)\n *\n * The only override is the corner radius \u2014 designer wants the same 10px\n * `standardRadius` used everywhere else, not MUI's default 4px.\n *\n * The \"Learn more\" action opens the Clerk-101 help article in Intercom\n * \u2014 the same article the homepage's \"Try an example\" info icon and the\n * locked-landing's section-header tooltip point at. URL lives in the\n * shared `constants` module so all four surfaces stay in sync.\n */\nconst BANNER_COPY = \"Bench IQ's agent is disabled for your organization. Contact your admin to upgrade.\";\n\nconst ClerkDisabledBanner: React.FC = () => (\n ({\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n width: \"100%\",\n // MUI Alert defaults to `box-sizing: content-box`, so without this\n // its 16px horizontal padding adds OUTSIDE the declared 100% width,\n // making the Alert 32px wider than its parent and clipping at the\n // right. Forcing border-box keeps `width: 100%` honest.\n boxSizing: \"border-box\",\n })}\n action={\n \n Learn more\n \n }\n >\n {BANNER_COPY}\n \n);\n\nexport default ClerkDisabledBanner;\n", "import React from \"react\";\nimport { Box } from \"@mui/material\";\nimport { AppShell } from \"@/components/AppShell\";\nimport ClerkDisabledBanner from \"./ClerkDisabledBanner\";\n\n/**\n * Convenience wrapper that registers `` into\n * AppShell's `ContentBanner` slot with the standard 4px horizontal inset +\n * 8px bottom gap below it. All three locked-Clerk surfaces (landing,\n * example session, live locked session) use the identical wrapper, so it\n * lives here to keep the slot wiring DRY and prevent the inset from\n * drifting between callsites.\n */\nconst ClerkDisabledBannerSlot: React.FC = () => (\n \n \n \n \n \n);\n\nexport default ClerkDisabledBannerSlot;\n", "import React, { useState } from \"react\";\nimport { ClarifyingQuestionCard } from \"@/components/molecules/ClarifyingQuestionCard\";\nimport type {\n AttachedFile,\n ClarifyingQuestion,\n ClarifyingQuestionResponse,\n} from \"../../api/queries/agentPrototype.types\";\nimport AgentQuestionControls from \"./AgentQuestionControls\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { clarifyingQuestionIsLocallyExpired } from \"../../utils/clerkClarifyingQuestion\";\n\ninterface AgentPrototypeClarifyingQuestionProps {\n question: ClarifyingQuestion;\n sessionId?: number | null;\n onAnswer: (\n questionId: string,\n answer: string,\n interactionStartedAtMs?: number,\n response?: ClarifyingQuestionResponse,\n files?: AttachedFile[],\n ) => void;\n isSubmitting?: boolean;\n onExpire?: (questionId: string) => void;\n}\n\nexport default function AgentPrototypeClarifyingQuestion({\n question,\n sessionId,\n onAnswer,\n isSubmitting = false,\n onExpire,\n}: AgentPrototypeClarifyingQuestionProps) {\n const [customText, setCustomText] = useState(\"\");\n\n const rejectExpiredInteraction = (interactionStartedAtMs: number) => {\n if (!clarifyingQuestionIsLocallyExpired(question, interactionStartedAtMs)) return false;\n\n onExpire?.(question.questionId);\n return true;\n };\n\n const handleOptionClick = (index: number) => {\n if (isSubmitting) return;\n const interactionStartedAtMs = Date.now();\n if (rejectExpiredInteraction(interactionStartedAtMs)) return;\n const option = question.options[index];\n if (sessionId) {\n void recordUserEvent({\n event_name: \"select_clerk_clarifying_question_option\",\n event_properties: {\n session_id: sessionId,\n question_id: question.questionId,\n option_index: index,\n },\n });\n }\n if (question.questionType || option.behavior) {\n onAnswer(question.questionId, option.title, interactionStartedAtMs, {\n kind: \"single_select\",\n selected_option_index: index,\n });\n } else {\n onAnswer(question.questionId, option.title, interactionStartedAtMs);\n }\n };\n\n const handleCustomSubmit = () => {\n if (isSubmitting || !customText.trim()) return;\n const interactionStartedAtMs = Date.now();\n if (rejectExpiredInteraction(interactionStartedAtMs)) return;\n if (sessionId) {\n void recordUserEvent({\n event_name: \"submit_clerk_clarifying_question_custom_answer\",\n event_properties: {\n session_id: sessionId,\n question_id: question.questionId,\n answer_length_chars: customText.trim().length,\n },\n });\n }\n if (question.questionType) {\n onAnswer(question.questionId, customText.trim(), interactionStartedAtMs, {\n kind: \"free_text\",\n text: customText.trim(),\n });\n } else {\n onAnswer(question.questionId, customText.trim(), interactionStartedAtMs);\n }\n };\n\n const handleDismiss = () => {\n if (isSubmitting) return;\n const interactionStartedAtMs = Date.now();\n if (rejectExpiredInteraction(interactionStartedAtMs)) return;\n if (sessionId) {\n void recordUserEvent({\n event_name: \"dismiss_clerk_clarifying_question\",\n event_properties: {\n session_id: sessionId,\n question_id: question.questionId,\n },\n });\n }\n if (question.questionType === \"file_upload\" && !question.inputRequired) {\n onAnswer(question.questionId, \"Continue without a file\", interactionStartedAtMs, {\n kind: \"file_upload\",\n action: \"continue_without_file\",\n });\n return;\n }\n if (question.questionType || question.inputRequired) {\n onAnswer(\n question.questionId,\n question.inputRequired ? \"I cannot provide this information now.\" : \"Use your best judgment\",\n interactionStartedAtMs,\n { kind: \"dismiss\" },\n );\n return;\n }\n onAnswer(\n question.questionId,\n \"User dismissed the question \u2014 proceed with your best judgment.\",\n interactionStartedAtMs,\n );\n };\n\n if (question.questionType)\n return (\n {\n const startedAt = Date.now();\n if (rejectExpiredInteraction(startedAt)) return;\n onAnswer(question.questionId, answer, startedAt, response ?? { kind: \"free_text\", text: answer }, files);\n }}\n />\n );\n\n return (\n \n );\n}\n", "import React from \"react\";\nimport { Box, Paper, Stack, Typography } from \"@mui/material\";\nimport { AlertTriangle, Info, X } from \"lucide-react\";\n\nimport { BenchAlert } from \"@/components/atoms/BenchAlert\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\n\nexport type DocketConnectApprovalMode = \"cached\" | \"free\" | \"limit-increase\";\nexport type DocketConnectApprovalType =\n | \"court_artifact_retrieval\"\n | \"party_report_retrieval\"\n | \"pacer_spend_limit_increase\"\n | string;\n\nexport type DocketConnectDocument = {\n title: string;\n description?: string;\n};\n\ntype Props = {\n open: boolean;\n mode: DocketConnectApprovalMode;\n approvalType?: DocketConnectApprovalType;\n documents: DocketConnectDocument[];\n submitting?: boolean;\n onCancel: () => void;\n onClose: () => void;\n onRetrieveDocuments: () => void;\n};\n\nconst includedPreviewCopy = \"Bench IQ can now retrieve PACER documents, included at no cost during early preview.\";\nconst partyReportPreviewCopy =\n \"Bench IQ can retrieve the latest party report, included at no cost during early preview.\";\nconst limitIncreaseCopy =\n \"You\u2019ve reached your PACER retrieval limit. Request an increase to continue retrieving these documents at no cost during the early preview.\";\n\nexport function DocketConnectApprovalSurface({\n open,\n mode,\n approvalType,\n documents,\n submitting = false,\n onCancel,\n onClose,\n onRetrieveDocuments,\n}: Props) {\n const limitIncrease = mode === \"limit-increase\";\n const partyReportApproval = approvalType === \"party_report_retrieval\";\n const singleDocumentApproval = !partyReportApproval && documents.length === 1;\n const singleDocument = singleDocumentApproval ? documents[0] : undefined;\n const alertCopy = limitIncrease\n ? limitIncreaseCopy\n : partyReportApproval\n ? partyReportPreviewCopy\n : includedPreviewCopy;\n const promptCopy = limitIncrease\n ? \"Would you like me to request an increase?\"\n : partyReportApproval\n ? \"Do I have your permission to retrieve the latest party report?\"\n : singleDocumentApproval\n ? \"Do I have your permission to retrieve this document?\"\n : \"Do I have your permission to retrieve these documents?\";\n const retrieveCopy = limitIncrease\n ? \"Request increase\"\n : partyReportApproval\n ? \"Retrieve party report\"\n : singleDocumentApproval\n ? \"Retrieve document\"\n : \"Retrieve documents\";\n\n if (!open) return null;\n\n return (\n ({\n width: \"100%\",\n maxWidth: \"100%\",\n boxSizing: \"border-box\",\n boxShadow: theme.tokens.shadows.lg,\n border: `1px solid ${theme.border.light}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n overflow: \"hidden\",\n pointerEvents: \"auto\",\n p: 3,\n })}\n >\n \n \n {alertCopy}\n \n \n \n {promptCopy}\n \n \n \n ({\n maxHeight: 280,\n overflow: \"auto\",\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n bgcolor: \"background.default\",\n p: 2,\n })}\n >\n {partyReportApproval ? (\n \n {documents.map((document, index) => (\n \n {!document.description ? (\n \n {document.title}\n \n ) : null}\n {document.description ? (\n \n {document.description}\n \n ) : null}\n \n ))}\n \n ) : singleDocument ? (\n \n \n {singleDocument.title}\n \n {singleDocument.description ? (\n \n {singleDocument.description}\n \n ) : null}\n \n ) : (\n \n {documents.map((document, index) => (\n

  • \n \n {document.title}\n \n {document.description ? (\n \n {document.description}\n \n ) : null}\n
  • \n ))}\n \n )}\n \n \n \n \n Cancel\n \n \n {retrieveCopy}\n \n \n \n );\n}\n", "import React from \"react\";\nimport { Alert, Box } from \"@mui/material\";\n\nimport type { DocketConnectRetrievalRequestPayload } from \"../../../api/queries/agentPrototype.types\";\nimport { DocketConnectApprovalSurface } from \"./DocketConnectApprovalDialog\";\n\ntype Props = {\n request: DocketConnectRetrievalRequestPayload;\n onApprove: (approvalRequestId: string | number) => boolean | void | Promise;\n onCancel: (approvalRequestId: string | number) => void | Promise;\n submitting?: boolean;\n \"data-testid\"?: string;\n};\n\nexport function DocketConnectRequestSurface({\n request,\n onApprove,\n onCancel,\n submitting = false,\n \"data-testid\": testId = \"docket-connect-request-surface\",\n}: Props) {\n const activeSurface = request.active_surface;\n const approval = request.current_approval;\n const identityError = request.identity_error;\n const hasValidIdentityRestart =\n identityError?.code === \"ambiguous_court_case_identity\" &&\n identityError.restart_after === \"separately_approved_external_data_resolution\";\n\n if (\n activeSurface === \"blocked\" &&\n request.next_action === \"do_not_retry\" &&\n identityError?.action === \"do_not_retry\" &&\n hasValidIdentityRestart &&\n request.status_message\n ) {\n return (\n \n {request.status_message}\n \n );\n }\n\n if (activeSurface !== \"limit_approval\" && activeSurface !== \"retrieval_approval\") return null;\n\n const documents = request.reconciliation.new_items.map((item) => ({\n title: item.title,\n description: item.description ?? undefined,\n }));\n\n return (\n \n approval && onCancel(approval.id)}\n onClose={() => approval && onCancel(approval.id)}\n onRetrieveDocuments={() => approval && onApprove(approval.id)}\n />\n \n );\n}\n", "import { styled } from \"@/utils/styled\";\n\nconst allowedProps = new Set([\"children\", \"className\", \"style\", \"id\", \"title\", \"role\", \"tabIndex\"]);\nconst isEvent = (p: string) => /^on[A-Z]/.test(p);\n\nconst SafeSpan = styled(\"span\", {\n shouldForwardProp: (prop) => {\n if (typeof prop !== \"string\") return false;\n if (prop === \"sx\" || prop === \"as\" || prop === \"theme\" || prop === \"ownerState\" || prop === \"css\") return false;\n if (allowedProps.has(prop)) return true;\n if (prop.startsWith(\"aria-\") || prop.startsWith(\"data-\") || isEvent(prop)) return true;\n return false;\n },\n})({});\n\nexport default SafeSpan;\n", "/**\n * Format `date_of_hearing` (ISO yyyy-mm-dd) for the reader title bar.\n * Returns \"\" for null/invalid input. Appends \"T00:00:00\" so the date\n * parses as local time, matching QueryResultCard etc.\n */\nexport const formatTranscriptDateForDisplay = (dateString: string | null | undefined): string => {\n if (!dateString) return \"\";\n const date = new Date(`${dateString}T00:00:00`);\n if (isNaN(date.valueOf())) return \"\";\n\n const monthNames = [\"Jan.\", \"Feb.\", \"Mar.\", \"Apr.\", \"May\", \"Jun.\", \"Jul.\", \"Aug.\", \"Sep.\", \"Oct.\", \"Nov.\", \"Dec.\"];\n return `${monthNames[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;\n};\n\n/**\n * Reader-title-bar display string: \"Jun. 21, 2024: Case Name (Court)\".\n * Strips a trailing \" (Mon. dd, yyyy)\" off the citation when present so\n * the date isn't duplicated. Returns \"\" when citation is empty.\n */\nexport const formatTranscriptDisplayTitle = (\n citation: string | null | undefined,\n dateOfHearing: string | null | undefined,\n): string => {\n if (!citation) return \"\";\n\n const formattedDate = formatTranscriptDateForDisplay(dateOfHearing);\n if (!formattedDate) return citation;\n\n const citationWithoutDate = citation.replace(/\\s*\\([A-Za-z]{3}\\.?\\s+\\d{1,2},\\s+\\d{4}\\)$/, \"\");\n return `${formattedDate}: ${citationWithoutDate}`;\n};\n", "import { useQueryTranscriptsAPIShow } from \"../api/documents\";\nimport { formatTranscriptDisplayTitle } from \"../utils/formatTranscriptDisplayTitle\";\n\n/**\n * useTranscriptDisplayTitle \u2014 returns the reader-title-bar display string for\n * a given transcript id (e.g. \"Jun. 21, 2024: Smith v. Jones (Bankr. D. Del.)\").\n *\n * Subscribes to the transcript-show query under the bare `[id]` key. For a\n * normal reader open this shares the reader's own cache entry (just an extra\n * subscription, no extra request); for an anchored open \u2014 where the reader\n * fetches under `[id, { targetAnchorIds }]` \u2014 it's a separate cache entry, so\n * the title resolves via its own request. Either way the title (citation +\n * date) is correct. Returns \"\" while loading or for a null transcript id.\n */\nexport const useTranscriptDisplayTitle = (transcriptId: number | string | null): string => {\n const id = transcriptId == null ? null : transcriptId.toString();\n const { data } = useQueryTranscriptsAPIShow(id);\n const transcript = data?.transcript;\n if (!transcript) return \"\";\n return formatTranscriptDisplayTitle(transcript.citation, transcript.date_of_hearing);\n};\n", "/**\n * @license\n * Lodash \n * Copyright OpenJS Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n;(function() {\n\n /** Used as a safe reference for `undefined` in pre-ES5 environments. */\n var undefined;\n\n /** Used as the semantic version number. */\n var VERSION = '4.18.1';\n\n /** Used as the size to enable large array optimizations. */\n var LARGE_ARRAY_SIZE = 200;\n\n /** Error message constants. */\n var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',\n FUNC_ERROR_TEXT = 'Expected a function',\n INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`',\n INVALID_TEMPL_IMPORTS_ERROR_TEXT = 'Invalid `imports` option passed into `_.template`';\n\n /** Used to stand-in for `undefined` hash values. */\n var HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n /** Used as the maximum memoize cache size. */\n var MAX_MEMOIZE_SIZE = 500;\n\n /** Used as the internal argument placeholder. */\n var PLACEHOLDER = '__lodash_placeholder__';\n\n /** Used to compose bitmasks for cloning. */\n var CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n /** Used to compose bitmasks for value comparisons. */\n var COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n /** Used to compose bitmasks for function metadata. */\n var WRAP_BIND_FLAG = 1,\n WRAP_BIND_KEY_FLAG = 2,\n WRAP_CURRY_BOUND_FLAG = 4,\n WRAP_CURRY_FLAG = 8,\n WRAP_CURRY_RIGHT_FLAG = 16,\n WRAP_PARTIAL_FLAG = 32,\n WRAP_PARTIAL_RIGHT_FLAG = 64,\n WRAP_ARY_FLAG = 128,\n WRAP_REARG_FLAG = 256,\n WRAP_FLIP_FLAG = 512;\n\n /** Used as default options for `_.truncate`. */\n var DEFAULT_TRUNC_LENGTH = 30,\n DEFAULT_TRUNC_OMISSION = '...';\n\n /** Used to detect hot functions by number of calls within a span of milliseconds. */\n var HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n /** Used to indicate the type of lazy iteratees. */\n var LAZY_FILTER_FLAG = 1,\n LAZY_MAP_FLAG = 2,\n LAZY_WHILE_FLAG = 3;\n\n /** Used as references for various `Number` constants. */\n var INFINITY = 1 / 0,\n MAX_SAFE_INTEGER = 9007199254740991,\n MAX_INTEGER = 1.7976931348623157e+308,\n NAN = 0 / 0;\n\n /** Used as references for the maximum length and index of an array. */\n var MAX_ARRAY_LENGTH = 4294967295,\n MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,\n HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\n\n /** Used to associate wrap methods with their bit flags. */\n var wrapFlags = [\n ['ary', WRAP_ARY_FLAG],\n ['bind', WRAP_BIND_FLAG],\n ['bindKey', WRAP_BIND_KEY_FLAG],\n ['curry', WRAP_CURRY_FLAG],\n ['curryRight', WRAP_CURRY_RIGHT_FLAG],\n ['flip', WRAP_FLIP_FLAG],\n ['partial', WRAP_PARTIAL_FLAG],\n ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],\n ['rearg', WRAP_REARG_FLAG]\n ];\n\n /** `Object#toString` result references. */\n var argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n asyncTag = '[object AsyncFunction]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n domExcTag = '[object DOMException]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n nullTag = '[object Null]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n proxyTag = '[object Proxy]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n undefinedTag = '[object Undefined]',\n weakMapTag = '[object WeakMap]',\n weakSetTag = '[object WeakSet]';\n\n var arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n /** Used to match empty string literals in compiled template source. */\n var reEmptyStringLeading = /\\b__p \\+= '';/g,\n reEmptyStringMiddle = /\\b(__p \\+=) '' \\+/g,\n reEmptyStringTrailing = /(__e\\(.*?\\)|\\b__t\\)) \\+\\n'';/g;\n\n /** Used to match HTML entities and HTML characters. */\n var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,\n reUnescapedHtml = /[&<>\"']/g,\n reHasEscapedHtml = RegExp(reEscapedHtml.source),\n reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n\n /** Used to match template delimiters. */\n var reEscape = /<%-([\\s\\S]+?)%>/g,\n reEvaluate = /<%([\\s\\S]+?)%>/g,\n reInterpolate = /<%=([\\s\\S]+?)%>/g;\n\n /** Used to match property names within property paths. */\n var reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/,\n rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n /**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\n var reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g,\n reHasRegExpChar = RegExp(reRegExpChar.source);\n\n /** Used to match leading whitespace. */\n var reTrimStart = /^\\s+/;\n\n /** Used to match a single whitespace character. */\n var reWhitespace = /\\s/;\n\n /** Used to match wrap detail comments. */\n var reWrapComment = /\\{(?:\\n\\/\\* \\[wrapped with .+\\] \\*\\/)?\\n?/,\n reWrapDetails = /\\{\\n\\/\\* \\[wrapped with (.+)\\] \\*/,\n reSplitDetails = /,? & /;\n\n /** Used to match words composed of alphanumeric characters. */\n var reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n /**\n * Used to validate the `validate` option in `_.template` variable.\n *\n * Forbids characters which could potentially change the meaning of the function argument definition:\n * - \"(),\" (modification of function parameters)\n * - \"=\" (default value)\n * - \"[]{}\" (destructuring of function parameters)\n * - \"/\" (beginning of a comment)\n * - whitespace\n */\n var reForbiddenIdentifierChars = /[()=,{}\\[\\]\\/\\s]/;\n\n /** Used to match backslashes in property paths. */\n var reEscapeChar = /\\\\(\\\\)?/g;\n\n /**\n * Used to match\n * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).\n */\n var reEsTemplate = /\\$\\{([^\\\\}]*(?:\\\\.[^\\\\}]*)*)\\}/g;\n\n /** Used to match `RegExp` flags from their coerced string values. */\n var reFlags = /\\w*$/;\n\n /** Used to detect bad signed hexadecimal string values. */\n var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n /** Used to detect binary string values. */\n var reIsBinary = /^0b[01]+$/i;\n\n /** Used to detect host constructors (Safari). */\n var reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n /** Used to detect octal string values. */\n var reIsOctal = /^0o[0-7]+$/i;\n\n /** Used to detect unsigned integer values. */\n var reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n /** Used to match Latin Unicode letters (excluding mathematical operators). */\n var reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n /** Used to ensure capturing order of template delimiters. */\n var reNoMatch = /($^)/;\n\n /** Used to match unescaped characters in compiled string literals. */\n var reUnescapedString = /['\\n\\r\\u2028\\u2029\\\\]/g;\n\n /** Used to compose unicode character classes. */\n var rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsDingbatRange = '\\\\u2700-\\\\u27bf',\n rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n rsPunctuationRange = '\\\\u2000-\\\\u206f',\n rsSpaceRange = ' \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000',\n rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n rsVarRange = '\\\\ufe0e\\\\ufe0f',\n rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n /** Used to compose unicode capture groups. */\n var rsApos = \"['\\u2019]\",\n rsAstral = '[' + rsAstralRange + ']',\n rsBreak = '[' + rsBreakRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsDigits = '\\\\d+',\n rsDingbat = '[' + rsDingbatRange + ']',\n rsLower = '[' + rsLowerRange + ']',\n rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsUpper = '[' + rsUpperRange + ']',\n rsZWJ = '\\\\u200d';\n\n /** Used to compose unicode regexes. */\n var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',\n rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',\n rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsOrdLower = '\\\\d*(?:1st|2nd|3rd|(?![123])\\\\dth)(?=\\\\b|[A-Z_])',\n rsOrdUpper = '\\\\d*(?:1ST|2ND|3RD|(?![123])\\\\dTH)(?=\\\\b|[a-z_])',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n /** Used to match apostrophes. */\n var reApos = RegExp(rsApos, 'g');\n\n /**\n * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n */\n var reComboMark = RegExp(rsCombo, 'g');\n\n /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\n var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n /** Used to match complex or compound words. */\n var reUnicodeWord = RegExp([\n rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',\n rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,\n rsUpper + '+' + rsOptContrUpper,\n rsOrdUpper,\n rsOrdLower,\n rsDigits,\n rsEmoji\n ].join('|'), 'g');\n\n /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\n var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n /** Used to detect strings that need a more robust regexp to match words. */\n var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n /** Used to assign default `context` object properties. */\n var contextProps = [\n 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',\n 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',\n 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',\n 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',\n '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'\n ];\n\n /** Used to make template sourceURLs easier to identify. */\n var templateCounter = -1;\n\n /** Used to identify `toStringTag` values of typed arrays. */\n var typedArrayTags = {};\n typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n typedArrayTags[uint32Tag] = true;\n typedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\n typedArrayTags[errorTag] = typedArrayTags[funcTag] =\n typedArrayTags[mapTag] = typedArrayTags[numberTag] =\n typedArrayTags[objectTag] = typedArrayTags[regexpTag] =\n typedArrayTags[setTag] = typedArrayTags[stringTag] =\n typedArrayTags[weakMapTag] = false;\n\n /** Used to identify `toStringTag` values supported by `_.clone`. */\n var cloneableTags = {};\n cloneableTags[argsTag] = cloneableTags[arrayTag] =\n cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\n cloneableTags[boolTag] = cloneableTags[dateTag] =\n cloneableTags[float32Tag] = cloneableTags[float64Tag] =\n cloneableTags[int8Tag] = cloneableTags[int16Tag] =\n cloneableTags[int32Tag] = cloneableTags[mapTag] =\n cloneableTags[numberTag] = cloneableTags[objectTag] =\n cloneableTags[regexpTag] = cloneableTags[setTag] =\n cloneableTags[stringTag] = cloneableTags[symbolTag] =\n cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\n cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\n cloneableTags[errorTag] = cloneableTags[funcTag] =\n cloneableTags[weakMapTag] = false;\n\n /** Used to map Latin Unicode letters to basic Latin letters. */\n var deburredLetters = {\n // Latin-1 Supplement block.\n '\\xc0': 'A', '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n '\\xe0': 'a', '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n '\\xc7': 'C', '\\xe7': 'c',\n '\\xd0': 'D', '\\xf0': 'd',\n '\\xc8': 'E', '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n '\\xe8': 'e', '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n '\\xcc': 'I', '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n '\\xec': 'i', '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n '\\xd1': 'N', '\\xf1': 'n',\n '\\xd2': 'O', '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n '\\xf2': 'o', '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n '\\xd9': 'U', '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n '\\xf9': 'u', '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n '\\xdd': 'Y', '\\xfd': 'y', '\\xff': 'y',\n '\\xc6': 'Ae', '\\xe6': 'ae',\n '\\xde': 'Th', '\\xfe': 'th',\n '\\xdf': 'ss',\n // Latin Extended-A block.\n '\\u0100': 'A', '\\u0102': 'A', '\\u0104': 'A',\n '\\u0101': 'a', '\\u0103': 'a', '\\u0105': 'a',\n '\\u0106': 'C', '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n '\\u0107': 'c', '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n '\\u010e': 'D', '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n '\\u0112': 'E', '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n '\\u0113': 'e', '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n '\\u011c': 'G', '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n '\\u011d': 'g', '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n '\\u0124': 'H', '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n '\\u0128': 'I', '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n '\\u0129': 'i', '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n '\\u0134': 'J', '\\u0135': 'j',\n '\\u0136': 'K', '\\u0137': 'k', '\\u0138': 'k',\n '\\u0139': 'L', '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n '\\u013a': 'l', '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n '\\u0143': 'N', '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n '\\u0144': 'n', '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n '\\u014c': 'O', '\\u014e': 'O', '\\u0150': 'O',\n '\\u014d': 'o', '\\u014f': 'o', '\\u0151': 'o',\n '\\u0154': 'R', '\\u0156': 'R', '\\u0158': 'R',\n '\\u0155': 'r', '\\u0157': 'r', '\\u0159': 'r',\n '\\u015a': 'S', '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n '\\u015b': 's', '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n '\\u0162': 'T', '\\u0164': 'T', '\\u0166': 'T',\n '\\u0163': 't', '\\u0165': 't', '\\u0167': 't',\n '\\u0168': 'U', '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n '\\u0169': 'u', '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n '\\u0174': 'W', '\\u0175': 'w',\n '\\u0176': 'Y', '\\u0177': 'y', '\\u0178': 'Y',\n '\\u0179': 'Z', '\\u017b': 'Z', '\\u017d': 'Z',\n '\\u017a': 'z', '\\u017c': 'z', '\\u017e': 'z',\n '\\u0132': 'IJ', '\\u0133': 'ij',\n '\\u0152': 'Oe', '\\u0153': 'oe',\n '\\u0149': \"'n\", '\\u017f': 's'\n };\n\n /** Used to map characters to HTML entities. */\n var htmlEscapes = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n };\n\n /** Used to map HTML entities to characters. */\n var htmlUnescapes = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\"\n };\n\n /** Used to escape characters for inclusion in compiled string literals. */\n var stringEscapes = {\n '\\\\': '\\\\',\n \"'\": \"'\",\n '\\n': 'n',\n '\\r': 'r',\n '\\u2028': 'u2028',\n '\\u2029': 'u2029'\n };\n\n /** Built-in method references without a dependency on `root`. */\n var freeParseFloat = parseFloat,\n freeParseInt = parseInt;\n\n /** Detect free variable `global` from Node.js. */\n var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n /** Detect free variable `self`. */\n var freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n /** Used as a reference to the global object. */\n var root = freeGlobal || freeSelf || Function('return this')();\n\n /** Detect free variable `exports`. */\n var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n /** Detect free variable `module`. */\n var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n /** Detect the popular CommonJS extension `module.exports`. */\n var moduleExports = freeModule && freeModule.exports === freeExports;\n\n /** Detect free variable `process` from Node.js. */\n var freeProcess = moduleExports && freeGlobal.process;\n\n /** Used to access faster Node.js helpers. */\n var nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n }());\n\n /* Node.js helper references. */\n var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,\n nodeIsDate = nodeUtil && nodeUtil.isDate,\n nodeIsMap = nodeUtil && nodeUtil.isMap,\n nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,\n nodeIsSet = nodeUtil && nodeUtil.isSet,\n nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n /*--------------------------------------------------------------------------*/\n\n /**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\n function apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n }\n\n /**\n * A specialized version of `baseAggregator` for arrays.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform keys.\n * @param {Object} accumulator The initial aggregated object.\n * @returns {Function} Returns `accumulator`.\n */\n function arrayAggregator(array, setter, iteratee, accumulator) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n var value = array[index];\n setter(accumulator, value, iteratee(value), array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\n function arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n }\n\n /**\n * A specialized version of `_.forEachRight` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\n function arrayEachRight(array, iteratee) {\n var length = array == null ? 0 : array.length;\n\n while (length--) {\n if (iteratee(array[length], length, array) === false) {\n break;\n }\n }\n return array;\n }\n\n /**\n * A specialized version of `_.every` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`.\n */\n function arrayEvery(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (!predicate(array[index], index, array)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\n function arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `_.includes` for arrays without support for\n * specifying an index to search from.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\n function arrayIncludes(array, value) {\n var length = array == null ? 0 : array.length;\n return !!length && baseIndexOf(array, value, 0) > -1;\n }\n\n /**\n * This function is like `arrayIncludes` except that it accepts a comparator.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\n function arrayIncludesWith(array, value, comparator) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (comparator(value, array[index])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\n function arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n }\n\n /**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\n function arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n }\n\n /**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\n function arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.reduceRight` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the last element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\n function arrayReduceRight(array, iteratee, accumulator, initAccum) {\n var length = array == null ? 0 : array.length;\n if (initAccum && length) {\n accumulator = array[--length];\n }\n while (length--) {\n accumulator = iteratee(accumulator, array[length], length, array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\n function arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Gets the size of an ASCII `string`.\n *\n * @private\n * @param {string} string The string inspect.\n * @returns {number} Returns the string size.\n */\n var asciiSize = baseProperty('length');\n\n /**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function asciiToArray(string) {\n return string.split('');\n }\n\n /**\n * Splits an ASCII `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\n function asciiWords(string) {\n return string.match(reAsciiWord) || [];\n }\n\n /**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\n function baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n }\n\n /**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseIndexOf(array, value, fromIndex) {\n return value === value\n ? strictIndexOf(array, value, fromIndex)\n : baseFindIndex(array, baseIsNaN, fromIndex);\n }\n\n /**\n * This function is like `baseIndexOf` except that it accepts a comparator.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseIndexOfWith(array, value, fromIndex, comparator) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (comparator(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\n function baseIsNaN(value) {\n return value !== value;\n }\n\n /**\n * The base implementation of `_.mean` and `_.meanBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the mean.\n */\n function baseMean(array, iteratee) {\n var length = array == null ? 0 : array.length;\n return length ? (baseSum(array, iteratee) / length) : NAN;\n }\n\n /**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\n function baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n }\n\n /**\n * The base implementation of `_.propertyOf` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Function} Returns the new accessor function.\n */\n function basePropertyOf(object) {\n return function(key) {\n return object == null ? undefined : object[key];\n };\n }\n\n /**\n * The base implementation of `_.reduce` and `_.reduceRight`, without support\n * for iteratee shorthands, which iterates over `collection` using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} accumulator The initial value.\n * @param {boolean} initAccum Specify using the first or last element of\n * `collection` as the initial value.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the accumulated value.\n */\n function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {\n eachFunc(collection, function(value, index, collection) {\n accumulator = initAccum\n ? (initAccum = false, value)\n : iteratee(accumulator, value, index, collection);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.sortBy` which uses `comparer` to define the\n * sort order of `array` and replaces criteria objects with their corresponding\n * values.\n *\n * @private\n * @param {Array} array The array to sort.\n * @param {Function} comparer The function to define sort order.\n * @returns {Array} Returns `array`.\n */\n function baseSortBy(array, comparer) {\n var length = array.length;\n\n array.sort(comparer);\n while (length--) {\n array[length] = array[length].value;\n }\n return array;\n }\n\n /**\n * The base implementation of `_.sum` and `_.sumBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the sum.\n */\n function baseSum(array, iteratee) {\n var result,\n index = -1,\n length = array.length;\n\n while (++index < length) {\n var current = iteratee(array[index]);\n if (current !== undefined) {\n result = result === undefined ? current : (result + current);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\n function baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n }\n\n /**\n * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array\n * of key-value pairs for `object` corresponding to the property names of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the key-value pairs.\n */\n function baseToPairs(object, props) {\n return arrayMap(props, function(key) {\n return [key, object[key]];\n });\n }\n\n /**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\n function baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n }\n\n /**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\n function baseUnary(func) {\n return function(value) {\n return func(value);\n };\n }\n\n /**\n * The base implementation of `_.values` and `_.valuesIn` which creates an\n * array of `object` property values corresponding to the property names\n * of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the array of property values.\n */\n function baseValues(object, props) {\n return arrayMap(props, function(key) {\n return object[key];\n });\n }\n\n /**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function cacheHas(cache, key) {\n return cache.has(key);\n }\n\n /**\n * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol\n * that is not found in the character symbols.\n *\n * @private\n * @param {Array} strSymbols The string symbols to inspect.\n * @param {Array} chrSymbols The character symbols to find.\n * @returns {number} Returns the index of the first unmatched string symbol.\n */\n function charsStartIndex(strSymbols, chrSymbols) {\n var index = -1,\n length = strSymbols.length;\n\n while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n return index;\n }\n\n /**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol\n * that is not found in the character symbols.\n *\n * @private\n * @param {Array} strSymbols The string symbols to inspect.\n * @param {Array} chrSymbols The character symbols to find.\n * @returns {number} Returns the index of the last unmatched string symbol.\n */\n function charsEndIndex(strSymbols, chrSymbols) {\n var index = strSymbols.length;\n\n while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n return index;\n }\n\n /**\n * Gets the number of `placeholder` occurrences in `array`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} placeholder The placeholder to search for.\n * @returns {number} Returns the placeholder count.\n */\n function countHolders(array, placeholder) {\n var length = array.length,\n result = 0;\n\n while (length--) {\n if (array[length] === placeholder) {\n ++result;\n }\n }\n return result;\n }\n\n /**\n * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n * letters to basic Latin letters.\n *\n * @private\n * @param {string} letter The matched letter to deburr.\n * @returns {string} Returns the deburred letter.\n */\n var deburrLetter = basePropertyOf(deburredLetters);\n\n /**\n * Used by `_.escape` to convert characters to HTML entities.\n *\n * @private\n * @param {string} chr The matched character to escape.\n * @returns {string} Returns the escaped character.\n */\n var escapeHtmlChar = basePropertyOf(htmlEscapes);\n\n /**\n * Used by `_.template` to escape characters for inclusion in compiled string literals.\n *\n * @private\n * @param {string} chr The matched character to escape.\n * @returns {string} Returns the escaped character.\n */\n function escapeStringChar(chr) {\n return '\\\\' + stringEscapes[chr];\n }\n\n /**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\n function getValue(object, key) {\n return object == null ? undefined : object[key];\n }\n\n /**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\n function hasUnicode(string) {\n return reHasUnicode.test(string);\n }\n\n /**\n * Checks if `string` contains a word composed of Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a word is found, else `false`.\n */\n function hasUnicodeWord(string) {\n return reHasUnicodeWord.test(string);\n }\n\n /**\n * Converts `iterator` to an array.\n *\n * @private\n * @param {Object} iterator The iterator to convert.\n * @returns {Array} Returns the converted array.\n */\n function iteratorToArray(iterator) {\n var data,\n result = [];\n\n while (!(data = iterator.next()).done) {\n result.push(data.value);\n }\n return result;\n }\n\n /**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\n function mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n }\n\n /**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\n function overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n }\n\n /**\n * Replaces all `placeholder` elements in `array` with an internal placeholder\n * and returns an array of their indexes.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {*} placeholder The placeholder to replace.\n * @returns {Array} Returns the new array of placeholder indexes.\n */\n function replaceHolders(array, placeholder) {\n var index = -1,\n length = array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (value === placeholder || value === PLACEHOLDER) {\n array[index] = PLACEHOLDER;\n result[resIndex++] = index;\n }\n }\n return result;\n }\n\n /**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\n function setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n }\n\n /**\n * Converts `set` to its value-value pairs.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the value-value pairs.\n */\n function setToPairs(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = [value, value];\n });\n return result;\n }\n\n /**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * A specialized version of `_.lastIndexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function strictLastIndexOf(array, value, fromIndex) {\n var index = fromIndex + 1;\n while (index--) {\n if (array[index] === value) {\n return index;\n }\n }\n return index;\n }\n\n /**\n * Gets the number of symbols in `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the string size.\n */\n function stringSize(string) {\n return hasUnicode(string)\n ? unicodeSize(string)\n : asciiSize(string);\n }\n\n /**\n * Converts `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function stringToArray(string) {\n return hasUnicode(string)\n ? unicodeToArray(string)\n : asciiToArray(string);\n }\n\n /**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\n function trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n }\n\n /**\n * Used by `_.unescape` to convert HTML entities to characters.\n *\n * @private\n * @param {string} chr The matched character to unescape.\n * @returns {string} Returns the unescaped character.\n */\n var unescapeHtmlChar = basePropertyOf(htmlUnescapes);\n\n /**\n * Gets the size of a Unicode `string`.\n *\n * @private\n * @param {string} string The string inspect.\n * @returns {number} Returns the string size.\n */\n function unicodeSize(string) {\n var result = reUnicode.lastIndex = 0;\n while (reUnicode.test(string)) {\n ++result;\n }\n return result;\n }\n\n /**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function unicodeToArray(string) {\n return string.match(reUnicode) || [];\n }\n\n /**\n * Splits a Unicode `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\n function unicodeWords(string) {\n return string.match(reUnicodeWord) || [];\n }\n\n /*--------------------------------------------------------------------------*/\n\n /**\n * Create a new pristine `lodash` function using the `context` object.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Util\n * @param {Object} [context=root] The context object.\n * @returns {Function} Returns a new `lodash` function.\n * @example\n *\n * _.mixin({ 'foo': _.constant('foo') });\n *\n * var lodash = _.runInContext();\n * lodash.mixin({ 'bar': lodash.constant('bar') });\n *\n * _.isFunction(_.foo);\n * // => true\n * _.isFunction(_.bar);\n * // => false\n *\n * lodash.isFunction(lodash.foo);\n * // => false\n * lodash.isFunction(lodash.bar);\n * // => true\n *\n * // Create a suped-up `defer` in Node.js.\n * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;\n */\n var runInContext = (function runInContext(context) {\n context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));\n\n /** Built-in constructor references. */\n var Array = context.Array,\n Date = context.Date,\n Error = context.Error,\n Function = context.Function,\n Math = context.Math,\n Object = context.Object,\n RegExp = context.RegExp,\n String = context.String,\n TypeError = context.TypeError;\n\n /** Used for built-in method references. */\n var arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n /** Used to detect overreaching core-js shims. */\n var coreJsData = context['__core-js_shared__'];\n\n /** Used to resolve the decompiled source of functions. */\n var funcToString = funcProto.toString;\n\n /** Used to check objects for own properties. */\n var hasOwnProperty = objectProto.hasOwnProperty;\n\n /** Used to generate unique IDs. */\n var idCounter = 0;\n\n /** Used to detect methods masquerading as native. */\n var maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n }());\n\n /**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\n var nativeObjectToString = objectProto.toString;\n\n /** Used to infer the `Object` constructor. */\n var objectCtorString = funcToString.call(Object);\n\n /** Used to restore the original `_` reference in `_.noConflict`. */\n var oldDash = root._;\n\n /** Used to detect if a method is native. */\n var reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n );\n\n /** Built-in value references. */\n var Buffer = moduleExports ? context.Buffer : undefined,\n Symbol = context.Symbol,\n Uint8Array = context.Uint8Array,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,\n getPrototype = overArg(Object.getPrototypeOf, Object),\n objectCreate = Object.create,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice,\n spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,\n symIterator = Symbol ? Symbol.iterator : undefined,\n symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n var defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n }());\n\n /** Mocked built-ins. */\n var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,\n ctxNow = Date && Date.now !== root.Date.now && Date.now,\n ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;\n\n /* Built-in method references for those with the same name as other `lodash` methods. */\n var nativeCeil = Math.ceil,\n nativeFloor = Math.floor,\n nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeIsFinite = context.isFinite,\n nativeJoin = arrayProto.join,\n nativeKeys = overArg(Object.keys, Object),\n nativeMax = Math.max,\n nativeMin = Math.min,\n nativeNow = Date.now,\n nativeParseInt = context.parseInt,\n nativeRandom = Math.random,\n nativeReverse = arrayProto.reverse;\n\n /* Built-in method references that are verified to be native. */\n var DataView = getNative(context, 'DataView'),\n Map = getNative(context, 'Map'),\n Promise = getNative(context, 'Promise'),\n Set = getNative(context, 'Set'),\n WeakMap = getNative(context, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n /** Used to store function metadata. */\n var metaMap = WeakMap && new WeakMap;\n\n /** Used to lookup unminified function names. */\n var realNames = {};\n\n /** Used to detect maps, sets, and weakmaps. */\n var dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n /** Used to convert symbols to primitives and strings. */\n var symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a `lodash` object which wraps `value` to enable implicit method\n * chain sequences. Methods that operate on and return arrays, collections,\n * and functions can be chained together. Methods that retrieve a single value\n * or may return a primitive value will automatically end the chain sequence\n * and return the unwrapped value. Otherwise, the value must be unwrapped\n * with `_#value`.\n *\n * Explicit chain sequences, which must be unwrapped with `_#value`, may be\n * enabled using `_.chain`.\n *\n * The execution of chained methods is lazy, that is, it's deferred until\n * `_#value` is implicitly or explicitly called.\n *\n * Lazy evaluation allows several methods to support shortcut fusion.\n * Shortcut fusion is an optimization to merge iteratee calls; this avoids\n * the creation of intermediate arrays and can greatly reduce the number of\n * iteratee executions. Sections of a chain sequence qualify for shortcut\n * fusion if the section is applied to an array and iteratees accept only\n * one argument. The heuristic for whether a section qualifies for shortcut\n * fusion is subject to change.\n *\n * Chaining is supported in custom builds as long as the `_#value` method is\n * directly or indirectly included in the build.\n *\n * In addition to lodash methods, wrappers have `Array` and `String` methods.\n *\n * The wrapper `Array` methods are:\n * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`\n *\n * The wrapper `String` methods are:\n * `replace` and `split`\n *\n * The wrapper methods that support shortcut fusion are:\n * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,\n * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,\n * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`\n *\n * The chainable wrapper methods are:\n * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,\n * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,\n * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,\n * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,\n * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,\n * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,\n * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,\n * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,\n * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,\n * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,\n * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,\n * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,\n * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,\n * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,\n * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,\n * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,\n * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,\n * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,\n * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,\n * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,\n * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,\n * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,\n * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,\n * `zipObject`, `zipObjectDeep`, and `zipWith`\n *\n * The wrapper methods that are **not** chainable by default are:\n * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,\n * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,\n * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,\n * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,\n * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,\n * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,\n * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,\n * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,\n * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,\n * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,\n * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,\n * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,\n * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,\n * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,\n * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,\n * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,\n * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,\n * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,\n * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,\n * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,\n * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,\n * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,\n * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,\n * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,\n * `upperFirst`, `value`, and `words`\n *\n * @name _\n * @constructor\n * @category Seq\n * @param {*} value The value to wrap in a `lodash` instance.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var wrapped = _([1, 2, 3]);\n *\n * // Returns an unwrapped value.\n * wrapped.reduce(_.add);\n * // => 6\n *\n * // Returns a wrapped value.\n * var squares = wrapped.map(square);\n *\n * _.isArray(squares);\n * // => false\n *\n * _.isArray(squares.value());\n * // => true\n */\n function lodash(value) {\n if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\n if (value instanceof LodashWrapper) {\n return value;\n }\n if (hasOwnProperty.call(value, '__wrapped__')) {\n return wrapperClone(value);\n }\n }\n return new LodashWrapper(value);\n }\n\n /**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\n var baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n }());\n\n /**\n * The function whose prototype chain sequence wrappers inherit from.\n *\n * @private\n */\n function baseLodash() {\n // No operation performed.\n }\n\n /**\n * The base constructor for creating `lodash` wrapper objects.\n *\n * @private\n * @param {*} value The value to wrap.\n * @param {boolean} [chainAll] Enable explicit method chain sequences.\n */\n function LodashWrapper(value, chainAll) {\n this.__wrapped__ = value;\n this.__actions__ = [];\n this.__chain__ = !!chainAll;\n this.__index__ = 0;\n this.__values__ = undefined;\n }\n\n /**\n * By default, the template delimiters used by lodash are like those in\n * embedded Ruby (ERB) as well as ES2015 template strings. Change the\n * following template settings to use alternative delimiters.\n *\n * **Security:** See\n * [threat model](https://github.com/lodash/lodash/blob/main/threat-model.md)\n * \u2014 `_.template` is insecure and will be removed in v5.\n *\n * @static\n * @memberOf _\n * @type {Object}\n */\n lodash.templateSettings = {\n\n /**\n * Used to detect `data` property values to be HTML-escaped.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'escape': reEscape,\n\n /**\n * Used to detect code to be evaluated.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'evaluate': reEvaluate,\n\n /**\n * Used to detect `data` property values to inject.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'interpolate': reInterpolate,\n\n /**\n * Used to reference the data object in the template text.\n *\n * @memberOf _.templateSettings\n * @type {string}\n */\n 'variable': '',\n\n /**\n * Used to import variables into the compiled template.\n *\n * @memberOf _.templateSettings\n * @type {Object}\n */\n 'imports': {\n\n /**\n * A reference to the `lodash` function.\n *\n * @memberOf _.templateSettings.imports\n * @type {Function}\n */\n '_': lodash\n }\n };\n\n // Ensure wrappers are instances of `baseLodash`.\n lodash.prototype = baseLodash.prototype;\n lodash.prototype.constructor = lodash;\n\n LodashWrapper.prototype = baseCreate(baseLodash.prototype);\n LodashWrapper.prototype.constructor = LodashWrapper;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\n *\n * @private\n * @constructor\n * @param {*} value The value to wrap.\n */\n function LazyWrapper(value) {\n this.__wrapped__ = value;\n this.__actions__ = [];\n this.__dir__ = 1;\n this.__filtered__ = false;\n this.__iteratees__ = [];\n this.__takeCount__ = MAX_ARRAY_LENGTH;\n this.__views__ = [];\n }\n\n /**\n * Creates a clone of the lazy wrapper object.\n *\n * @private\n * @name clone\n * @memberOf LazyWrapper\n * @returns {Object} Returns the cloned `LazyWrapper` object.\n */\n function lazyClone() {\n var result = new LazyWrapper(this.__wrapped__);\n result.__actions__ = copyArray(this.__actions__);\n result.__dir__ = this.__dir__;\n result.__filtered__ = this.__filtered__;\n result.__iteratees__ = copyArray(this.__iteratees__);\n result.__takeCount__ = this.__takeCount__;\n result.__views__ = copyArray(this.__views__);\n return result;\n }\n\n /**\n * Reverses the direction of lazy iteration.\n *\n * @private\n * @name reverse\n * @memberOf LazyWrapper\n * @returns {Object} Returns the new reversed `LazyWrapper` object.\n */\n function lazyReverse() {\n if (this.__filtered__) {\n var result = new LazyWrapper(this);\n result.__dir__ = -1;\n result.__filtered__ = true;\n } else {\n result = this.clone();\n result.__dir__ *= -1;\n }\n return result;\n }\n\n /**\n * Extracts the unwrapped value from its lazy wrapper.\n *\n * @private\n * @name value\n * @memberOf LazyWrapper\n * @returns {*} Returns the unwrapped value.\n */\n function lazyValue() {\n var array = this.__wrapped__.value(),\n dir = this.__dir__,\n isArr = isArray(array),\n isRight = dir < 0,\n arrLength = isArr ? array.length : 0,\n view = getView(0, arrLength, this.__views__),\n start = view.start,\n end = view.end,\n length = end - start,\n index = isRight ? end : (start - 1),\n iteratees = this.__iteratees__,\n iterLength = iteratees.length,\n resIndex = 0,\n takeCount = nativeMin(length, this.__takeCount__);\n\n if (!isArr || (!isRight && arrLength == length && takeCount == length)) {\n return baseWrapperValue(array, this.__actions__);\n }\n var result = [];\n\n outer:\n while (length-- && resIndex < takeCount) {\n index += dir;\n\n var iterIndex = -1,\n value = array[index];\n\n while (++iterIndex < iterLength) {\n var data = iteratees[iterIndex],\n iteratee = data.iteratee,\n type = data.type,\n computed = iteratee(value);\n\n if (type == LAZY_MAP_FLAG) {\n value = computed;\n } else if (!computed) {\n if (type == LAZY_FILTER_FLAG) {\n continue outer;\n } else {\n break outer;\n }\n }\n }\n result[resIndex++] = value;\n }\n return result;\n }\n\n // Ensure `LazyWrapper` is an instance of `baseLodash`.\n LazyWrapper.prototype = baseCreate(baseLodash.prototype);\n LazyWrapper.prototype.constructor = LazyWrapper;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\n function hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n }\n\n /**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n }\n\n /**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n }\n\n /**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\n function hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n }\n\n // Add methods to `Hash`.\n Hash.prototype.clear = hashClear;\n Hash.prototype['delete'] = hashDelete;\n Hash.prototype.get = hashGet;\n Hash.prototype.has = hashHas;\n Hash.prototype.set = hashSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\n function listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n }\n\n /**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n }\n\n /**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n }\n\n /**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\n function listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n }\n\n // Add methods to `ListCache`.\n ListCache.prototype.clear = listCacheClear;\n ListCache.prototype['delete'] = listCacheDelete;\n ListCache.prototype.get = listCacheGet;\n ListCache.prototype.has = listCacheHas;\n ListCache.prototype.set = listCacheSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\n function mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n }\n\n /**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n }\n\n /**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function mapCacheGet(key) {\n return getMapData(this, key).get(key);\n }\n\n /**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function mapCacheHas(key) {\n return getMapData(this, key).has(key);\n }\n\n /**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\n function mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n }\n\n // Add methods to `MapCache`.\n MapCache.prototype.clear = mapCacheClear;\n MapCache.prototype['delete'] = mapCacheDelete;\n MapCache.prototype.get = mapCacheGet;\n MapCache.prototype.has = mapCacheHas;\n MapCache.prototype.set = mapCacheSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\n function SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n }\n\n /**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\n function setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n }\n\n /**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {boolean} Returns `true` if `value` is found, else `false`.\n */\n function setCacheHas(value) {\n return this.__data__.has(value);\n }\n\n // Add methods to `SetCache`.\n SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\n SetCache.prototype.has = setCacheHas;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n }\n\n /**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\n function stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n }\n\n /**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function stackGet(key) {\n return this.__data__.get(key);\n }\n\n /**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function stackHas(key) {\n return this.__data__.has(key);\n }\n\n /**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\n function stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n }\n\n // Add methods to `Stack`.\n Stack.prototype.clear = stackClear;\n Stack.prototype['delete'] = stackDelete;\n Stack.prototype.get = stackGet;\n Stack.prototype.has = stackHas;\n Stack.prototype.set = stackSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\n function arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `_.sample` for arrays.\n *\n * @private\n * @param {Array} array The array to sample.\n * @returns {*} Returns the random element.\n */\n function arraySample(array) {\n var length = array.length;\n return length ? array[baseRandom(0, length - 1)] : undefined;\n }\n\n /**\n * A specialized version of `_.sampleSize` for arrays.\n *\n * @private\n * @param {Array} array The array to sample.\n * @param {number} n The number of elements to sample.\n * @returns {Array} Returns the random elements.\n */\n function arraySampleSize(array, n) {\n return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));\n }\n\n /**\n * A specialized version of `_.shuffle` for arrays.\n *\n * @private\n * @param {Array} array The array to shuffle.\n * @returns {Array} Returns the new shuffled array.\n */\n function arrayShuffle(array) {\n return shuffleSelf(copyArray(array));\n }\n\n /**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function assignMergeValue(object, key, value) {\n if ((value !== undefined && !eq(object[key], value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n }\n\n /**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n }\n\n /**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n }\n\n /**\n * Aggregates elements of `collection` on `accumulator` with keys transformed\n * by `iteratee` and values set by `setter`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform keys.\n * @param {Object} accumulator The initial aggregated object.\n * @returns {Function} Returns `accumulator`.\n */\n function baseAggregator(collection, setter, iteratee, accumulator) {\n baseEach(collection, function(value, key, collection) {\n setter(accumulator, value, iteratee(value), collection);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\n function baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n }\n\n /**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\n function baseAssignIn(object, source) {\n return object && copyObject(source, keysIn(source), object);\n }\n\n /**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n }\n\n /**\n * The base implementation of `_.at` without support for individual paths.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {string[]} paths The property paths to pick.\n * @returns {Array} Returns the picked elements.\n */\n function baseAt(object, paths) {\n var index = -1,\n length = paths.length,\n result = Array(length),\n skip = object == null;\n\n while (++index < length) {\n result[index] = skip ? undefined : get(object, paths[index]);\n }\n return result;\n }\n\n /**\n * The base implementation of `_.clamp` which doesn't coerce arguments.\n *\n * @private\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n */\n function baseClamp(number, lower, upper) {\n if (number === number) {\n if (upper !== undefined) {\n number = number <= upper ? number : upper;\n }\n if (lower !== undefined) {\n number = number >= lower ? number : lower;\n }\n }\n return number;\n }\n\n /**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\n function baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (isSet(value)) {\n value.forEach(function(subValue) {\n result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n });\n } else if (isMap(value)) {\n value.forEach(function(subValue, key) {\n result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n }\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n }\n\n /**\n * The base implementation of `_.conforms` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property predicates to conform to.\n * @returns {Function} Returns the new spec function.\n */\n function baseConforms(source) {\n var props = keys(source);\n return function(object) {\n return baseConformsTo(object, source, props);\n };\n }\n\n /**\n * The base implementation of `_.conformsTo` which accepts `props` to check.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property predicates to conform to.\n * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n */\n function baseConformsTo(object, source, props) {\n var length = props.length;\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (length--) {\n var key = props[length],\n predicate = source[key],\n value = object[key];\n\n if ((value === undefined && !(key in object)) || !predicate(value)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * The base implementation of `_.delay` and `_.defer` which accepts `args`\n * to provide to `func`.\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {Array} args The arguments to provide to `func`.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\n function baseDelay(func, wait, args) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return setTimeout(function() { func.apply(undefined, args); }, wait);\n }\n\n /**\n * The base implementation of methods like `_.difference` without support\n * for excluding multiple arrays or iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Array} values The values to exclude.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n */\n function baseDifference(array, values, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n isCommon = true,\n length = array.length,\n result = [],\n valuesLength = values.length;\n\n if (!length) {\n return result;\n }\n if (iteratee) {\n values = arrayMap(values, baseUnary(iteratee));\n }\n if (comparator) {\n includes = arrayIncludesWith;\n isCommon = false;\n }\n else if (values.length >= LARGE_ARRAY_SIZE) {\n includes = cacheHas;\n isCommon = false;\n values = new SetCache(values);\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee == null ? value : iteratee(value);\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var valuesIndex = valuesLength;\n while (valuesIndex--) {\n if (values[valuesIndex] === computed) {\n continue outer;\n }\n }\n result.push(value);\n }\n else if (!includes(values, computed, comparator)) {\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.forEach` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\n var baseEach = createBaseEach(baseForOwn);\n\n /**\n * The base implementation of `_.forEachRight` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\n var baseEachRight = createBaseEach(baseForOwnRight, true);\n\n /**\n * The base implementation of `_.every` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`\n */\n function baseEvery(collection, predicate) {\n var result = true;\n baseEach(collection, function(value, index, collection) {\n result = !!predicate(value, index, collection);\n return result;\n });\n return result;\n }\n\n /**\n * The base implementation of methods like `_.max` and `_.min` which accepts a\n * `comparator` to determine the extremum value.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The iteratee invoked per iteration.\n * @param {Function} comparator The comparator used to compare values.\n * @returns {*} Returns the extremum value.\n */\n function baseExtremum(array, iteratee, comparator) {\n var index = -1,\n length = array.length;\n\n while (++index < length) {\n var value = array[index],\n current = iteratee(value);\n\n if (current != null && (computed === undefined\n ? (current === current && !isSymbol(current))\n : comparator(current, computed)\n )) {\n var computed = current,\n result = value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.fill` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to fill.\n * @param {*} value The value to fill `array` with.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns `array`.\n */\n function baseFill(array, value, start, end) {\n var length = array.length;\n\n start = toInteger(start);\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = (end === undefined || end > length) ? length : toInteger(end);\n if (end < 0) {\n end += length;\n }\n end = start > end ? 0 : toLength(end);\n while (start < end) {\n array[start++] = value;\n }\n return array;\n }\n\n /**\n * The base implementation of `_.filter` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\n function baseFilter(collection, predicate) {\n var result = [];\n baseEach(collection, function(value, index, collection) {\n if (predicate(value, index, collection)) {\n result.push(value);\n }\n });\n return result;\n }\n\n /**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\n function baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\n var baseFor = createBaseFor();\n\n /**\n * This function is like `baseFor` except that it iterates over properties\n * in the opposite order.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\n var baseForRight = createBaseFor(true);\n\n /**\n * The base implementation of `_.forOwn` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\n function baseForOwn(object, iteratee) {\n return object && baseFor(object, iteratee, keys);\n }\n\n /**\n * The base implementation of `_.forOwnRight` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\n function baseForOwnRight(object, iteratee) {\n return object && baseForRight(object, iteratee, keys);\n }\n\n /**\n * The base implementation of `_.functions` which creates an array of\n * `object` function property names filtered from `props`.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Array} props The property names to filter.\n * @returns {Array} Returns the function names.\n */\n function baseFunctions(object, props) {\n return arrayFilter(props, function(key) {\n return isFunction(object[key]);\n });\n }\n\n /**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\n function baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n }\n\n /**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n }\n\n /**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\n function baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n }\n\n /**\n * The base implementation of `_.gt` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than `other`,\n * else `false`.\n */\n function baseGt(value, other) {\n return value > other;\n }\n\n /**\n * The base implementation of `_.has` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\n function baseHas(object, key) {\n return object != null && hasOwnProperty.call(object, key);\n }\n\n /**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\n function baseHasIn(object, key) {\n return object != null && key in Object(object);\n }\n\n /**\n * The base implementation of `_.inRange` which doesn't coerce arguments.\n *\n * @private\n * @param {number} number The number to check.\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n */\n function baseInRange(number, start, end) {\n return number >= nativeMin(start, end) && number < nativeMax(start, end);\n }\n\n /**\n * The base implementation of methods like `_.intersection`, without support\n * for iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of shared values.\n */\n function baseIntersection(arrays, iteratee, comparator) {\n var includes = comparator ? arrayIncludesWith : arrayIncludes,\n length = arrays[0].length,\n othLength = arrays.length,\n othIndex = othLength,\n caches = Array(othLength),\n maxLength = Infinity,\n result = [];\n\n while (othIndex--) {\n var array = arrays[othIndex];\n if (othIndex && iteratee) {\n array = arrayMap(array, baseUnary(iteratee));\n }\n maxLength = nativeMin(array.length, maxLength);\n caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n ? new SetCache(othIndex && array)\n : undefined;\n }\n array = arrays[0];\n\n var index = -1,\n seen = caches[0];\n\n outer:\n while (++index < length && result.length < maxLength) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (!(seen\n ? cacheHas(seen, computed)\n : includes(result, computed, comparator)\n )) {\n othIndex = othLength;\n while (--othIndex) {\n var cache = caches[othIndex];\n if (!(cache\n ? cacheHas(cache, computed)\n : includes(arrays[othIndex], computed, comparator))\n ) {\n continue outer;\n }\n }\n if (seen) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.invert` and `_.invertBy` which inverts\n * `object` with values transformed by `iteratee` and set by `setter`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform values.\n * @param {Object} accumulator The initial inverted object.\n * @returns {Function} Returns `accumulator`.\n */\n function baseInverter(object, setter, iteratee, accumulator) {\n baseForOwn(object, function(value, key, object) {\n setter(accumulator, iteratee(value), key, object);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.invoke` without support for individual\n * method arguments.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the method to invoke.\n * @param {Array} args The arguments to invoke the method with.\n * @returns {*} Returns the result of the invoked method.\n */\n function baseInvoke(object, path, args) {\n path = castPath(path, object);\n object = parent(object, path);\n var func = object == null ? object : object[toKey(last(path))];\n return func == null ? undefined : apply(func, object, args);\n }\n\n /**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\n function baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n }\n\n /**\n * The base implementation of `_.isArrayBuffer` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n */\n function baseIsArrayBuffer(value) {\n return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;\n }\n\n /**\n * The base implementation of `_.isDate` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n */\n function baseIsDate(value) {\n return isObjectLike(value) && baseGetTag(value) == dateTag;\n }\n\n /**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\n function baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n }\n\n /**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n }\n\n /**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\n function baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n }\n\n /**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\n function baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\n function baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n }\n\n /**\n * The base implementation of `_.isRegExp` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n */\n function baseIsRegExp(value) {\n return isObjectLike(value) && baseGetTag(value) == regexpTag;\n }\n\n /**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\n function baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n }\n\n /**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\n function baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n }\n\n /**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\n function baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n }\n\n /**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.lt` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than `other`,\n * else `false`.\n */\n function baseLt(value, other) {\n return value < other;\n }\n\n /**\n * The base implementation of `_.map` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\n function baseMap(collection, iteratee) {\n var index = -1,\n result = isArrayLike(collection) ? Array(collection.length) : [];\n\n baseEach(collection, function(value, key, collection) {\n result[++index] = iteratee(value, key, collection);\n });\n return result;\n }\n\n /**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\n function baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n }\n\n /**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\n function baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n }\n\n /**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\n function baseMerge(object, source, srcIndex, customizer, stack) {\n if (object === source) {\n return;\n }\n baseFor(source, function(srcValue, key) {\n stack || (stack = new Stack);\n if (isObject(srcValue)) {\n baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n }\n else {\n var newValue = customizer\n ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n : undefined;\n\n if (newValue === undefined) {\n newValue = srcValue;\n }\n assignMergeValue(object, key, newValue);\n }\n }, keysIn);\n }\n\n /**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\n function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n var objValue = safeGet(object, key),\n srcValue = safeGet(source, key),\n stacked = stack.get(srcValue);\n\n if (stacked) {\n assignMergeValue(object, key, stacked);\n return;\n }\n var newValue = customizer\n ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n : undefined;\n\n var isCommon = newValue === undefined;\n\n if (isCommon) {\n var isArr = isArray(srcValue),\n isBuff = !isArr && isBuffer(srcValue),\n isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n newValue = srcValue;\n if (isArr || isBuff || isTyped) {\n if (isArray(objValue)) {\n newValue = objValue;\n }\n else if (isArrayLikeObject(objValue)) {\n newValue = copyArray(objValue);\n }\n else if (isBuff) {\n isCommon = false;\n newValue = cloneBuffer(srcValue, true);\n }\n else if (isTyped) {\n isCommon = false;\n newValue = cloneTypedArray(srcValue, true);\n }\n else {\n newValue = [];\n }\n }\n else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n newValue = objValue;\n if (isArguments(objValue)) {\n newValue = toPlainObject(objValue);\n }\n else if (!isObject(objValue) || isFunction(objValue)) {\n newValue = initCloneObject(srcValue);\n }\n }\n else {\n isCommon = false;\n }\n }\n if (isCommon) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, newValue);\n mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n stack['delete'](srcValue);\n }\n assignMergeValue(object, key, newValue);\n }\n\n /**\n * The base implementation of `_.nth` which doesn't coerce arguments.\n *\n * @private\n * @param {Array} array The array to query.\n * @param {number} n The index of the element to return.\n * @returns {*} Returns the nth element of `array`.\n */\n function baseNth(array, n) {\n var length = array.length;\n if (!length) {\n return;\n }\n n += n < 0 ? length : 0;\n return isIndex(n, length) ? array[n] : undefined;\n }\n\n /**\n * The base implementation of `_.orderBy` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n * @param {string[]} orders The sort orders of `iteratees`.\n * @returns {Array} Returns the new sorted array.\n */\n function baseOrderBy(collection, iteratees, orders) {\n if (iteratees.length) {\n iteratees = arrayMap(iteratees, function(iteratee) {\n if (isArray(iteratee)) {\n return function(value) {\n return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);\n };\n }\n return iteratee;\n });\n } else {\n iteratees = [identity];\n }\n\n var index = -1;\n iteratees = arrayMap(iteratees, baseUnary(getIteratee()));\n\n var result = baseMap(collection, function(value, key, collection) {\n var criteria = arrayMap(iteratees, function(iteratee) {\n return iteratee(value);\n });\n return { 'criteria': criteria, 'index': ++index, 'value': value };\n });\n\n return baseSortBy(result, function(object, other) {\n return compareMultiple(object, other, orders);\n });\n }\n\n /**\n * The base implementation of `_.pick` without support for individual\n * property identifiers.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @returns {Object} Returns the new object.\n */\n function basePick(object, paths) {\n return basePickBy(object, paths, function(value, path) {\n return hasIn(object, path);\n });\n }\n\n /**\n * The base implementation of `_.pickBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @param {Function} predicate The function invoked per property.\n * @returns {Object} Returns the new object.\n */\n function basePickBy(object, paths, predicate) {\n var index = -1,\n length = paths.length,\n result = {};\n\n while (++index < length) {\n var path = paths[index],\n value = baseGet(object, path);\n\n if (predicate(value, path)) {\n baseSet(result, castPath(path, object), value);\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\n function basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n }\n\n /**\n * The base implementation of `_.pullAllBy` without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns `array`.\n */\n function basePullAll(array, values, iteratee, comparator) {\n var indexOf = comparator ? baseIndexOfWith : baseIndexOf,\n index = -1,\n length = values.length,\n seen = array;\n\n if (array === values) {\n values = copyArray(values);\n }\n if (iteratee) {\n seen = arrayMap(array, baseUnary(iteratee));\n }\n while (++index < length) {\n var fromIndex = 0,\n value = values[index],\n computed = iteratee ? iteratee(value) : value;\n\n while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {\n if (seen !== array) {\n splice.call(seen, fromIndex, 1);\n }\n splice.call(array, fromIndex, 1);\n }\n }\n return array;\n }\n\n /**\n * The base implementation of `_.pullAt` without support for individual\n * indexes or capturing the removed elements.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {number[]} indexes The indexes of elements to remove.\n * @returns {Array} Returns `array`.\n */\n function basePullAt(array, indexes) {\n var length = array ? indexes.length : 0,\n lastIndex = length - 1;\n\n while (length--) {\n var index = indexes[length];\n if (length == lastIndex || index !== previous) {\n var previous = index;\n if (isIndex(index)) {\n splice.call(array, index, 1);\n } else {\n baseUnset(array, index);\n }\n }\n }\n return array;\n }\n\n /**\n * The base implementation of `_.random` without support for returning\n * floating-point numbers.\n *\n * @private\n * @param {number} lower The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the random number.\n */\n function baseRandom(lower, upper) {\n return lower + nativeFloor(nativeRandom() * (upper - lower + 1));\n }\n\n /**\n * The base implementation of `_.range` and `_.rangeRight` which doesn't\n * coerce arguments.\n *\n * @private\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @param {number} step The value to increment or decrement by.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the range of numbers.\n */\n function baseRange(start, end, step, fromRight) {\n var index = -1,\n length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n result = Array(length);\n\n while (length--) {\n result[fromRight ? length : ++index] = start;\n start += step;\n }\n return result;\n }\n\n /**\n * The base implementation of `_.repeat` which doesn't coerce arguments.\n *\n * @private\n * @param {string} string The string to repeat.\n * @param {number} n The number of times to repeat the string.\n * @returns {string} Returns the repeated string.\n */\n function baseRepeat(string, n) {\n var result = '';\n if (!string || n < 1 || n > MAX_SAFE_INTEGER) {\n return result;\n }\n // Leverage the exponentiation by squaring algorithm for a faster repeat.\n // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.\n do {\n if (n % 2) {\n result += string;\n }\n n = nativeFloor(n / 2);\n if (n) {\n string += string;\n }\n } while (n);\n\n return result;\n }\n\n /**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\n function baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n }\n\n /**\n * The base implementation of `_.sample`.\n *\n * @private\n * @param {Array|Object} collection The collection to sample.\n * @returns {*} Returns the random element.\n */\n function baseSample(collection) {\n return arraySample(values(collection));\n }\n\n /**\n * The base implementation of `_.sampleSize` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to sample.\n * @param {number} n The number of elements to sample.\n * @returns {Array} Returns the random elements.\n */\n function baseSampleSize(collection, n) {\n var array = values(collection);\n return shuffleSelf(array, baseClamp(n, 0, array.length));\n }\n\n /**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\n function baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n return object;\n }\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n }\n\n /**\n * The base implementation of `setData` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to associate metadata with.\n * @param {*} data The metadata.\n * @returns {Function} Returns `func`.\n */\n var baseSetData = !metaMap ? identity : function(func, data) {\n metaMap.set(func, data);\n return func;\n };\n\n /**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\n var baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n };\n\n /**\n * The base implementation of `_.shuffle`.\n *\n * @private\n * @param {Array|Object} collection The collection to shuffle.\n * @returns {Array} Returns the new shuffled array.\n */\n function baseShuffle(collection) {\n return shuffleSelf(values(collection));\n }\n\n /**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\n function baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n }\n\n /**\n * The base implementation of `_.some` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\n function baseSome(collection, predicate) {\n var result;\n\n baseEach(collection, function(value, index, collection) {\n result = predicate(value, index, collection);\n return !result;\n });\n return !!result;\n }\n\n /**\n * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which\n * performs a binary search of `array` to determine the index at which `value`\n * should be inserted into `array` in order to maintain its sort order.\n *\n * @private\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {boolean} [retHighest] Specify returning the highest qualified index.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n */\n function baseSortedIndex(array, value, retHighest) {\n var low = 0,\n high = array == null ? low : array.length;\n\n if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\n while (low < high) {\n var mid = (low + high) >>> 1,\n computed = array[mid];\n\n if (computed !== null && !isSymbol(computed) &&\n (retHighest ? (computed <= value) : (computed < value))) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return high;\n }\n return baseSortedIndexBy(array, value, identity, retHighest);\n }\n\n /**\n * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`\n * which invokes `iteratee` for `value` and each element of `array` to compute\n * their sort ranking. The iteratee is invoked with one argument; (value).\n *\n * @private\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} iteratee The iteratee invoked per element.\n * @param {boolean} [retHighest] Specify returning the highest qualified index.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n */\n function baseSortedIndexBy(array, value, iteratee, retHighest) {\n var low = 0,\n high = array == null ? 0 : array.length;\n if (high === 0) {\n return 0;\n }\n\n value = iteratee(value);\n var valIsNaN = value !== value,\n valIsNull = value === null,\n valIsSymbol = isSymbol(value),\n valIsUndefined = value === undefined;\n\n while (low < high) {\n var mid = nativeFloor((low + high) / 2),\n computed = iteratee(array[mid]),\n othIsDefined = computed !== undefined,\n othIsNull = computed === null,\n othIsReflexive = computed === computed,\n othIsSymbol = isSymbol(computed);\n\n if (valIsNaN) {\n var setLow = retHighest || othIsReflexive;\n } else if (valIsUndefined) {\n setLow = othIsReflexive && (retHighest || othIsDefined);\n } else if (valIsNull) {\n setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);\n } else if (valIsSymbol) {\n setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);\n } else if (othIsNull || othIsSymbol) {\n setLow = false;\n } else {\n setLow = retHighest ? (computed <= value) : (computed < value);\n }\n if (setLow) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return nativeMin(high, MAX_ARRAY_INDEX);\n }\n\n /**\n * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\n function baseSortedUniq(array, iteratee) {\n var index = -1,\n length = array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n if (!index || !eq(computed, seen)) {\n var seen = computed;\n result[resIndex++] = value === 0 ? 0 : value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.toNumber` which doesn't ensure correct\n * conversions of binary, hexadecimal, or octal string values.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n */\n function baseToNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n return +value;\n }\n\n /**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\n function baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n }\n\n /**\n * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\n function baseUniq(array, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n length = array.length,\n isCommon = true,\n result = [],\n seen = result;\n\n if (comparator) {\n isCommon = false;\n includes = arrayIncludesWith;\n }\n else if (length >= LARGE_ARRAY_SIZE) {\n var set = iteratee ? null : createSet(array);\n if (set) {\n return setToArray(set);\n }\n isCommon = false;\n includes = cacheHas;\n seen = new SetCache;\n }\n else {\n seen = iteratee ? [] : result;\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var seenIndex = seen.length;\n while (seenIndex--) {\n if (seen[seenIndex] === computed) {\n continue outer;\n }\n }\n if (iteratee) {\n seen.push(computed);\n }\n result.push(value);\n }\n else if (!includes(seen, computed, comparator)) {\n if (seen !== result) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.unset`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The property path to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n */\n function baseUnset(object, path) {\n path = castPath(path, object);\n\n // Prevent prototype pollution:\n // https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg\n // https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh\n var index = -1,\n length = path.length;\n\n if (!length) {\n return true;\n }\n\n while (++index < length) {\n var key = toKey(path[index]);\n\n // Always block \"__proto__\" anywhere in the path if it's not expected\n if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {\n return false;\n }\n\n // Block constructor/prototype as non-terminal traversal keys to prevent\n // escaping the object graph into built-in constructors and prototypes.\n if ((key === 'constructor' || key === 'prototype') && index < length - 1) {\n return false;\n }\n }\n\n var obj = parent(object, path);\n return obj == null || delete obj[toKey(last(path))];\n }\n\n /**\n * The base implementation of `_.update`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to update.\n * @param {Function} updater The function to produce the updated value.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\n function baseUpdate(object, path, updater, customizer) {\n return baseSet(object, path, updater(baseGet(object, path)), customizer);\n }\n\n /**\n * The base implementation of methods like `_.dropWhile` and `_.takeWhile`\n * without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to query.\n * @param {Function} predicate The function invoked per iteration.\n * @param {boolean} [isDrop] Specify dropping elements instead of taking them.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the slice of `array`.\n */\n function baseWhile(array, predicate, isDrop, fromRight) {\n var length = array.length,\n index = fromRight ? length : -1;\n\n while ((fromRight ? index-- : ++index < length) &&\n predicate(array[index], index, array)) {}\n\n return isDrop\n ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))\n : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));\n }\n\n /**\n * The base implementation of `wrapperValue` which returns the result of\n * performing a sequence of actions on the unwrapped `value`, where each\n * successive action is supplied the return value of the previous.\n *\n * @private\n * @param {*} value The unwrapped value.\n * @param {Array} actions Actions to perform to resolve the unwrapped value.\n * @returns {*} Returns the resolved value.\n */\n function baseWrapperValue(value, actions) {\n var result = value;\n if (result instanceof LazyWrapper) {\n result = result.value();\n }\n return arrayReduce(actions, function(result, action) {\n return action.func.apply(action.thisArg, arrayPush([result], action.args));\n }, result);\n }\n\n /**\n * The base implementation of methods like `_.xor`, without support for\n * iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of values.\n */\n function baseXor(arrays, iteratee, comparator) {\n var length = arrays.length;\n if (length < 2) {\n return length ? baseUniq(arrays[0]) : [];\n }\n var index = -1,\n result = Array(length);\n\n while (++index < length) {\n var array = arrays[index],\n othIndex = -1;\n\n while (++othIndex < length) {\n if (othIndex != index) {\n result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);\n }\n }\n }\n return baseUniq(baseFlatten(result, 1), iteratee, comparator);\n }\n\n /**\n * This base implementation of `_.zipObject` which assigns values using `assignFunc`.\n *\n * @private\n * @param {Array} props The property identifiers.\n * @param {Array} values The property values.\n * @param {Function} assignFunc The function to assign values.\n * @returns {Object} Returns the new object.\n */\n function baseZipObject(props, values, assignFunc) {\n var index = -1,\n length = props.length,\n valsLength = values.length,\n result = {};\n\n while (++index < length) {\n var value = index < valsLength ? values[index] : undefined;\n assignFunc(result, props[index], value);\n }\n return result;\n }\n\n /**\n * Casts `value` to an empty array if it's not an array like object.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Array|Object} Returns the cast array-like object.\n */\n function castArrayLikeObject(value) {\n return isArrayLikeObject(value) ? value : [];\n }\n\n /**\n * Casts `value` to `identity` if it's not a function.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Function} Returns cast function.\n */\n function castFunction(value) {\n return typeof value == 'function' ? value : identity;\n }\n\n /**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\n function castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n }\n\n /**\n * A `baseRest` alias which can be replaced with `identity` by module\n * replacement plugins.\n *\n * @private\n * @type {Function}\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\n var castRest = baseRest;\n\n /**\n * Casts `array` to a slice if it's needed.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {number} start The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the cast slice.\n */\n function castSlice(array, start, end) {\n var length = array.length;\n end = end === undefined ? length : end;\n return (!start && end >= length) ? array : baseSlice(array, start, end);\n }\n\n /**\n * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).\n *\n * @private\n * @param {number|Object} id The timer id or timeout object of the timer to clear.\n */\n var clearTimeout = ctxClearTimeout || function(id) {\n return root.clearTimeout(id);\n };\n\n /**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\n function cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n }\n\n /**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\n function cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n }\n\n /**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\n function cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n }\n\n /**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\n function cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n }\n\n /**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\n function cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n }\n\n /**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\n function cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n }\n\n /**\n * Compares values to sort them in ascending order.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {number} Returns the sort order indicator for `value`.\n */\n function compareAscending(value, other) {\n if (value !== other) {\n var valIsDefined = value !== undefined,\n valIsNull = value === null,\n valIsReflexive = value === value,\n valIsSymbol = isSymbol(value);\n\n var othIsDefined = other !== undefined,\n othIsNull = other === null,\n othIsReflexive = other === other,\n othIsSymbol = isSymbol(other);\n\n if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n (valIsNull && othIsDefined && othIsReflexive) ||\n (!valIsDefined && othIsReflexive) ||\n !valIsReflexive) {\n return 1;\n }\n if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n (othIsNull && valIsDefined && valIsReflexive) ||\n (!othIsDefined && valIsReflexive) ||\n !othIsReflexive) {\n return -1;\n }\n }\n return 0;\n }\n\n /**\n * Used by `_.orderBy` to compare multiple properties of a value to another\n * and stable sort them.\n *\n * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,\n * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n * of corresponding values.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {boolean[]|string[]} orders The order to sort by for each property.\n * @returns {number} Returns the sort order indicator for `object`.\n */\n function compareMultiple(object, other, orders) {\n var index = -1,\n objCriteria = object.criteria,\n othCriteria = other.criteria,\n length = objCriteria.length,\n ordersLength = orders.length;\n\n while (++index < length) {\n var result = compareAscending(objCriteria[index], othCriteria[index]);\n if (result) {\n if (index >= ordersLength) {\n return result;\n }\n var order = orders[index];\n return result * (order == 'desc' ? -1 : 1);\n }\n }\n // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n // that causes it, under certain circumstances, to provide the same value for\n // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n // for more details.\n //\n // This also ensures a stable sort in V8 and other engines.\n // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n return object.index - other.index;\n }\n\n /**\n * Creates an array that is the composition of partially applied arguments,\n * placeholders, and provided arguments into a single array of arguments.\n *\n * @private\n * @param {Array} args The provided arguments.\n * @param {Array} partials The arguments to prepend to those provided.\n * @param {Array} holders The `partials` placeholder indexes.\n * @params {boolean} [isCurried] Specify composing for a curried function.\n * @returns {Array} Returns the new array of composed arguments.\n */\n function composeArgs(args, partials, holders, isCurried) {\n var argsIndex = -1,\n argsLength = args.length,\n holdersLength = holders.length,\n leftIndex = -1,\n leftLength = partials.length,\n rangeLength = nativeMax(argsLength - holdersLength, 0),\n result = Array(leftLength + rangeLength),\n isUncurried = !isCurried;\n\n while (++leftIndex < leftLength) {\n result[leftIndex] = partials[leftIndex];\n }\n while (++argsIndex < holdersLength) {\n if (isUncurried || argsIndex < argsLength) {\n result[holders[argsIndex]] = args[argsIndex];\n }\n }\n while (rangeLength--) {\n result[leftIndex++] = args[argsIndex++];\n }\n return result;\n }\n\n /**\n * This function is like `composeArgs` except that the arguments composition\n * is tailored for `_.partialRight`.\n *\n * @private\n * @param {Array} args The provided arguments.\n * @param {Array} partials The arguments to append to those provided.\n * @param {Array} holders The `partials` placeholder indexes.\n * @params {boolean} [isCurried] Specify composing for a curried function.\n * @returns {Array} Returns the new array of composed arguments.\n */\n function composeArgsRight(args, partials, holders, isCurried) {\n var argsIndex = -1,\n argsLength = args.length,\n holdersIndex = -1,\n holdersLength = holders.length,\n rightIndex = -1,\n rightLength = partials.length,\n rangeLength = nativeMax(argsLength - holdersLength, 0),\n result = Array(rangeLength + rightLength),\n isUncurried = !isCurried;\n\n while (++argsIndex < rangeLength) {\n result[argsIndex] = args[argsIndex];\n }\n var offset = argsIndex;\n while (++rightIndex < rightLength) {\n result[offset + rightIndex] = partials[rightIndex];\n }\n while (++holdersIndex < holdersLength) {\n if (isUncurried || argsIndex < argsLength) {\n result[offset + holders[holdersIndex]] = args[argsIndex++];\n }\n }\n return result;\n }\n\n /**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\n function copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n }\n\n /**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\n function copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n }\n\n /**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\n function copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n }\n\n /**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\n function copySymbolsIn(source, object) {\n return copyObject(source, getSymbolsIn(source), object);\n }\n\n /**\n * Creates a function like `_.groupBy`.\n *\n * @private\n * @param {Function} setter The function to set accumulator values.\n * @param {Function} [initializer] The accumulator object initializer.\n * @returns {Function} Returns the new aggregator function.\n */\n function createAggregator(setter, initializer) {\n return function(collection, iteratee) {\n var func = isArray(collection) ? arrayAggregator : baseAggregator,\n accumulator = initializer ? initializer() : {};\n\n return func(collection, setter, getIteratee(iteratee, 2), accumulator);\n };\n }\n\n /**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\n function createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n }\n\n /**\n * Creates a `baseEach` or `baseEachRight` function.\n *\n * @private\n * @param {Function} eachFunc The function to iterate over a collection.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\n function createBaseEach(eachFunc, fromRight) {\n return function(collection, iteratee) {\n if (collection == null) {\n return collection;\n }\n if (!isArrayLike(collection)) {\n return eachFunc(collection, iteratee);\n }\n var length = collection.length,\n index = fromRight ? length : -1,\n iterable = Object(collection);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (iteratee(iterable[index], index, iterable) === false) {\n break;\n }\n }\n return collection;\n };\n }\n\n /**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\n function createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with the optional `this`\n * binding of `thisArg`.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createBind(func, bitmask, thisArg) {\n var isBind = bitmask & WRAP_BIND_FLAG,\n Ctor = createCtor(func);\n\n function wrapper() {\n var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n return fn.apply(isBind ? thisArg : this, arguments);\n }\n return wrapper;\n }\n\n /**\n * Creates a function like `_.lowerFirst`.\n *\n * @private\n * @param {string} methodName The name of the `String` case method to use.\n * @returns {Function} Returns the new case function.\n */\n function createCaseFirst(methodName) {\n return function(string) {\n string = toString(string);\n\n var strSymbols = hasUnicode(string)\n ? stringToArray(string)\n : undefined;\n\n var chr = strSymbols\n ? strSymbols[0]\n : string.charAt(0);\n\n var trailing = strSymbols\n ? castSlice(strSymbols, 1).join('')\n : string.slice(1);\n\n return chr[methodName]() + trailing;\n };\n }\n\n /**\n * Creates a function like `_.camelCase`.\n *\n * @private\n * @param {Function} callback The function to combine each word.\n * @returns {Function} Returns the new compounder function.\n */\n function createCompounder(callback) {\n return function(string) {\n return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n };\n }\n\n /**\n * Creates a function that produces an instance of `Ctor` regardless of\n * whether it was invoked as part of a `new` expression or by `call` or `apply`.\n *\n * @private\n * @param {Function} Ctor The constructor to wrap.\n * @returns {Function} Returns the new wrapped function.\n */\n function createCtor(Ctor) {\n return function() {\n // Use a `switch` statement to work with class constructors. See\n // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\n // for more details.\n var args = arguments;\n switch (args.length) {\n case 0: return new Ctor;\n case 1: return new Ctor(args[0]);\n case 2: return new Ctor(args[0], args[1]);\n case 3: return new Ctor(args[0], args[1], args[2]);\n case 4: return new Ctor(args[0], args[1], args[2], args[3]);\n case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\n case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\n case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\n }\n var thisBinding = baseCreate(Ctor.prototype),\n result = Ctor.apply(thisBinding, args);\n\n // Mimic the constructor's `return` behavior.\n // See https://es5.github.io/#x13.2.2 for more details.\n return isObject(result) ? result : thisBinding;\n };\n }\n\n /**\n * Creates a function that wraps `func` to enable currying.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {number} arity The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createCurry(func, bitmask, arity) {\n var Ctor = createCtor(func);\n\n function wrapper() {\n var length = arguments.length,\n args = Array(length),\n index = length,\n placeholder = getHolder(wrapper);\n\n while (index--) {\n args[index] = arguments[index];\n }\n var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)\n ? []\n : replaceHolders(args, placeholder);\n\n length -= holders.length;\n if (length < arity) {\n return createRecurry(\n func, bitmask, createHybrid, wrapper.placeholder, undefined,\n args, holders, undefined, undefined, arity - length);\n }\n var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n return apply(fn, this, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a `_.find` or `_.findLast` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\n function createFind(findIndexFunc) {\n return function(collection, predicate, fromIndex) {\n var iterable = Object(collection);\n if (!isArrayLike(collection)) {\n var iteratee = getIteratee(predicate, 3);\n collection = keys(collection);\n predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n }\n var index = findIndexFunc(collection, predicate, fromIndex);\n return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n };\n }\n\n /**\n * Creates a `_.flow` or `_.flowRight` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new flow function.\n */\n function createFlow(fromRight) {\n return flatRest(function(funcs) {\n var length = funcs.length,\n index = length,\n prereq = LodashWrapper.prototype.thru;\n\n if (fromRight) {\n funcs.reverse();\n }\n while (index--) {\n var func = funcs[index];\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (prereq && !wrapper && getFuncName(func) == 'wrapper') {\n var wrapper = new LodashWrapper([], true);\n }\n }\n index = wrapper ? index : length;\n while (++index < length) {\n func = funcs[index];\n\n var funcName = getFuncName(func),\n data = funcName == 'wrapper' ? getData(func) : undefined;\n\n if (data && isLaziable(data[0]) &&\n data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&\n !data[4].length && data[9] == 1\n ) {\n wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);\n } else {\n wrapper = (func.length == 1 && isLaziable(func))\n ? wrapper[funcName]()\n : wrapper.thru(func);\n }\n }\n return function() {\n var args = arguments,\n value = args[0];\n\n if (wrapper && args.length == 1 && isArray(value)) {\n return wrapper.plant(value).value();\n }\n var index = 0,\n result = length ? funcs[index].apply(this, args) : value;\n\n while (++index < length) {\n result = funcs[index].call(this, result);\n }\n return result;\n };\n });\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with optional `this`\n * binding of `thisArg`, partial application, and currying.\n *\n * @private\n * @param {Function|string} func The function or method name to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to prepend to those provided to\n * the new function.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [partialsRight] The arguments to append to those provided\n * to the new function.\n * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\n var isAry = bitmask & WRAP_ARY_FLAG,\n isBind = bitmask & WRAP_BIND_FLAG,\n isBindKey = bitmask & WRAP_BIND_KEY_FLAG,\n isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),\n isFlip = bitmask & WRAP_FLIP_FLAG,\n Ctor = isBindKey ? undefined : createCtor(func);\n\n function wrapper() {\n var length = arguments.length,\n args = Array(length),\n index = length;\n\n while (index--) {\n args[index] = arguments[index];\n }\n if (isCurried) {\n var placeholder = getHolder(wrapper),\n holdersCount = countHolders(args, placeholder);\n }\n if (partials) {\n args = composeArgs(args, partials, holders, isCurried);\n }\n if (partialsRight) {\n args = composeArgsRight(args, partialsRight, holdersRight, isCurried);\n }\n length -= holdersCount;\n if (isCurried && length < arity) {\n var newHolders = replaceHolders(args, placeholder);\n return createRecurry(\n func, bitmask, createHybrid, wrapper.placeholder, thisArg,\n args, newHolders, argPos, ary, arity - length\n );\n }\n var thisBinding = isBind ? thisArg : this,\n fn = isBindKey ? thisBinding[func] : func;\n\n length = args.length;\n if (argPos) {\n args = reorder(args, argPos);\n } else if (isFlip && length > 1) {\n args.reverse();\n }\n if (isAry && ary < length) {\n args.length = ary;\n }\n if (this && this !== root && this instanceof wrapper) {\n fn = Ctor || createCtor(fn);\n }\n return fn.apply(thisBinding, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a function like `_.invertBy`.\n *\n * @private\n * @param {Function} setter The function to set accumulator values.\n * @param {Function} toIteratee The function to resolve iteratees.\n * @returns {Function} Returns the new inverter function.\n */\n function createInverter(setter, toIteratee) {\n return function(object, iteratee) {\n return baseInverter(object, setter, toIteratee(iteratee), {});\n };\n }\n\n /**\n * Creates a function that performs a mathematical operation on two values.\n *\n * @private\n * @param {Function} operator The function to perform the operation.\n * @param {number} [defaultValue] The value used for `undefined` arguments.\n * @returns {Function} Returns the new mathematical operation function.\n */\n function createMathOperation(operator, defaultValue) {\n return function(value, other) {\n var result;\n if (value === undefined && other === undefined) {\n return defaultValue;\n }\n if (value !== undefined) {\n result = value;\n }\n if (other !== undefined) {\n if (result === undefined) {\n return other;\n }\n if (typeof value == 'string' || typeof other == 'string') {\n value = baseToString(value);\n other = baseToString(other);\n } else {\n value = baseToNumber(value);\n other = baseToNumber(other);\n }\n result = operator(value, other);\n }\n return result;\n };\n }\n\n /**\n * Creates a function like `_.over`.\n *\n * @private\n * @param {Function} arrayFunc The function to iterate over iteratees.\n * @returns {Function} Returns the new over function.\n */\n function createOver(arrayFunc) {\n return flatRest(function(iteratees) {\n iteratees = arrayMap(iteratees, baseUnary(getIteratee()));\n return baseRest(function(args) {\n var thisArg = this;\n return arrayFunc(iteratees, function(iteratee) {\n return apply(iteratee, thisArg, args);\n });\n });\n });\n }\n\n /**\n * Creates the padding for `string` based on `length`. The `chars` string\n * is truncated if the number of characters exceeds `length`.\n *\n * @private\n * @param {number} length The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padding for `string`.\n */\n function createPadding(length, chars) {\n chars = chars === undefined ? ' ' : baseToString(chars);\n\n var charsLength = chars.length;\n if (charsLength < 2) {\n return charsLength ? baseRepeat(chars, length) : chars;\n }\n var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));\n return hasUnicode(chars)\n ? castSlice(stringToArray(result), 0, length).join('')\n : result.slice(0, length);\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with the `this` binding\n * of `thisArg` and `partials` prepended to the arguments it receives.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} partials The arguments to prepend to those provided to\n * the new function.\n * @returns {Function} Returns the new wrapped function.\n */\n function createPartial(func, bitmask, thisArg, partials) {\n var isBind = bitmask & WRAP_BIND_FLAG,\n Ctor = createCtor(func);\n\n function wrapper() {\n var argsIndex = -1,\n argsLength = arguments.length,\n leftIndex = -1,\n leftLength = partials.length,\n args = Array(leftLength + argsLength),\n fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n\n while (++leftIndex < leftLength) {\n args[leftIndex] = partials[leftIndex];\n }\n while (argsLength--) {\n args[leftIndex++] = arguments[++argsIndex];\n }\n return apply(fn, isBind ? thisArg : this, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a `_.range` or `_.rangeRight` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new range function.\n */\n function createRange(fromRight) {\n return function(start, end, step) {\n if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {\n end = step = undefined;\n }\n // Ensure the sign of `-0` is preserved.\n start = toFinite(start);\n if (end === undefined) {\n end = start;\n start = 0;\n } else {\n end = toFinite(end);\n }\n step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);\n return baseRange(start, end, step, fromRight);\n };\n }\n\n /**\n * Creates a function that performs a relational operation on two values.\n *\n * @private\n * @param {Function} operator The function to perform the operation.\n * @returns {Function} Returns the new relational operation function.\n */\n function createRelationalOperation(operator) {\n return function(value, other) {\n if (!(typeof value == 'string' && typeof other == 'string')) {\n value = toNumber(value);\n other = toNumber(other);\n }\n return operator(value, other);\n };\n }\n\n /**\n * Creates a function that wraps `func` to continue currying.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {Function} wrapFunc The function to create the `func` wrapper.\n * @param {*} placeholder The placeholder value.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to prepend to those provided to\n * the new function.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {\n var isCurry = bitmask & WRAP_CURRY_FLAG,\n newHolders = isCurry ? holders : undefined,\n newHoldersRight = isCurry ? undefined : holders,\n newPartials = isCurry ? partials : undefined,\n newPartialsRight = isCurry ? undefined : partials;\n\n bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);\n bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);\n\n if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {\n bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);\n }\n var newData = [\n func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,\n newHoldersRight, argPos, ary, arity\n ];\n\n var result = wrapFunc.apply(undefined, newData);\n if (isLaziable(func)) {\n setData(result, newData);\n }\n result.placeholder = placeholder;\n return setWrapToString(result, func, bitmask);\n }\n\n /**\n * Creates a function like `_.round`.\n *\n * @private\n * @param {string} methodName The name of the `Math` method to use when rounding.\n * @returns {Function} Returns the new round function.\n */\n function createRound(methodName) {\n var func = Math[methodName];\n return function(number, precision) {\n number = toNumber(number);\n precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);\n if (precision && nativeIsFinite(number)) {\n // Shift with exponential notation to avoid floating-point issues.\n // See [MDN](https://mdn.io/round#Examples) for more details.\n var pair = (toString(number) + 'e').split('e'),\n value = func(pair[0] + 'e' + (+pair[1] + precision));\n\n pair = (toString(value) + 'e').split('e');\n return +(pair[0] + 'e' + (+pair[1] - precision));\n }\n return func(number);\n };\n }\n\n /**\n * Creates a set object of `values`.\n *\n * @private\n * @param {Array} values The values to add to the set.\n * @returns {Object} Returns the new set.\n */\n var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n return new Set(values);\n };\n\n /**\n * Creates a `_.toPairs` or `_.toPairsIn` function.\n *\n * @private\n * @param {Function} keysFunc The function to get the keys of a given object.\n * @returns {Function} Returns the new pairs function.\n */\n function createToPairs(keysFunc) {\n return function(object) {\n var tag = getTag(object);\n if (tag == mapTag) {\n return mapToArray(object);\n }\n if (tag == setTag) {\n return setToPairs(object);\n }\n return baseToPairs(object, keysFunc(object));\n };\n }\n\n /**\n * Creates a function that either curries or invokes `func` with optional\n * `this` binding and partially applied arguments.\n *\n * @private\n * @param {Function|string} func The function or method name to wrap.\n * @param {number} bitmask The bitmask flags.\n * 1 - `_.bind`\n * 2 - `_.bindKey`\n * 4 - `_.curry` or `_.curryRight` of a bound function\n * 8 - `_.curry`\n * 16 - `_.curryRight`\n * 32 - `_.partial`\n * 64 - `_.partialRight`\n * 128 - `_.rearg`\n * 256 - `_.ary`\n * 512 - `_.flip`\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to be partially applied.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\n var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;\n if (!isBindKey && typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var length = partials ? partials.length : 0;\n if (!length) {\n bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);\n partials = holders = undefined;\n }\n ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);\n arity = arity === undefined ? arity : toInteger(arity);\n length -= holders ? holders.length : 0;\n\n if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {\n var partialsRight = partials,\n holdersRight = holders;\n\n partials = holders = undefined;\n }\n var data = isBindKey ? undefined : getData(func);\n\n var newData = [\n func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,\n argPos, ary, arity\n ];\n\n if (data) {\n mergeData(newData, data);\n }\n func = newData[0];\n bitmask = newData[1];\n thisArg = newData[2];\n partials = newData[3];\n holders = newData[4];\n arity = newData[9] = newData[9] === undefined\n ? (isBindKey ? 0 : func.length)\n : nativeMax(newData[9] - length, 0);\n\n if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {\n bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);\n }\n if (!bitmask || bitmask == WRAP_BIND_FLAG) {\n var result = createBind(func, bitmask, thisArg);\n } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {\n result = createCurry(func, bitmask, arity);\n } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {\n result = createPartial(func, bitmask, thisArg, partials);\n } else {\n result = createHybrid.apply(undefined, newData);\n }\n var setter = data ? baseSetData : setData;\n return setWrapToString(setter(result, newData), func, bitmask);\n }\n\n /**\n * Used by `_.defaults` to customize its `_.assignIn` use to assign properties\n * of source objects to the destination object for all destination properties\n * that resolve to `undefined`.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to assign.\n * @param {Object} object The parent object of `objValue`.\n * @returns {*} Returns the value to assign.\n */\n function customDefaultsAssignIn(objValue, srcValue, key, object) {\n if (objValue === undefined ||\n (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n return srcValue;\n }\n return objValue;\n }\n\n /**\n * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n * objects into destination objects that are passed thru.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to merge.\n * @param {Object} object The parent object of `objValue`.\n * @param {Object} source The parent object of `srcValue`.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n * @returns {*} Returns the value to assign.\n */\n function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n if (isObject(objValue) && isObject(srcValue)) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, objValue);\n baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n stack['delete'](srcValue);\n }\n return objValue;\n }\n\n /**\n * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n * objects.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {string} key The key of the property to inspect.\n * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n */\n function customOmitClone(value) {\n return isPlainObject(value) ? undefined : value;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\n function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Check that cyclic values are equal.\n var arrStacked = stack.get(array);\n var othStacked = stack.get(other);\n if (arrStacked && othStacked) {\n return arrStacked == other && othStacked == array;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Check that cyclic values are equal.\n var objStacked = stack.get(object);\n var othStacked = stack.get(other);\n if (objStacked && othStacked) {\n return objStacked == other && othStacked == object;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n }\n\n /**\n * A specialized version of `baseRest` which flattens the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\n function flatRest(func) {\n return setToString(overRest(func, undefined, flatten), func + '');\n }\n\n /**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n }\n\n /**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n }\n\n /**\n * Gets metadata for `func`.\n *\n * @private\n * @param {Function} func The function to query.\n * @returns {*} Returns the metadata for `func`.\n */\n var getData = !metaMap ? noop : function(func) {\n return metaMap.get(func);\n };\n\n /**\n * Gets the name of `func`.\n *\n * @private\n * @param {Function} func The function to query.\n * @returns {string} Returns the function name.\n */\n function getFuncName(func) {\n var result = (func.name + ''),\n array = realNames[result],\n length = hasOwnProperty.call(realNames, result) ? array.length : 0;\n\n while (length--) {\n var data = array[length],\n otherFunc = data.func;\n if (otherFunc == null || otherFunc == func) {\n return data.name;\n }\n }\n return result;\n }\n\n /**\n * Gets the argument placeholder value for `func`.\n *\n * @private\n * @param {Function} func The function to inspect.\n * @returns {*} Returns the placeholder value.\n */\n function getHolder(func) {\n var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;\n return object.placeholder;\n }\n\n /**\n * Gets the appropriate \"iteratee\" function. If `_.iteratee` is customized,\n * this function returns the custom method, otherwise it returns `baseIteratee`.\n * If arguments are provided, the chosen function is invoked with them and\n * its result is returned.\n *\n * @private\n * @param {*} [value] The value to convert to an iteratee.\n * @param {number} [arity] The arity of the created iteratee.\n * @returns {Function} Returns the chosen function or its result.\n */\n function getIteratee() {\n var result = lodash.iteratee || iteratee;\n result = result === iteratee ? baseIteratee : result;\n return arguments.length ? result(arguments[0], arguments[1]) : result;\n }\n\n /**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\n function getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n }\n\n /**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\n function getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n }\n\n /**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\n function getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n }\n\n /**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\n function getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n }\n\n /**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\n var getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n };\n\n /**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\n var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n };\n\n /**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\n var getTag = baseGetTag;\n\n // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\n if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n }\n\n /**\n * Gets the view, applying any `transforms` to the `start` and `end` positions.\n *\n * @private\n * @param {number} start The start of the view.\n * @param {number} end The end of the view.\n * @param {Array} transforms The transformations to apply to the view.\n * @returns {Object} Returns an object containing the `start` and `end`\n * positions of the view.\n */\n function getView(start, end, transforms) {\n var index = -1,\n length = transforms.length;\n\n while (++index < length) {\n var data = transforms[index],\n size = data.size;\n\n switch (data.type) {\n case 'drop': start += size; break;\n case 'dropRight': end -= size; break;\n case 'take': end = nativeMin(end, start + size); break;\n case 'takeRight': start = nativeMax(start, end - size); break;\n }\n }\n return { 'start': start, 'end': end };\n }\n\n /**\n * Extracts wrapper details from the `source` body comment.\n *\n * @private\n * @param {string} source The source to inspect.\n * @returns {Array} Returns the wrapper details.\n */\n function getWrapDetails(source) {\n var match = source.match(reWrapDetails);\n return match ? match[1].split(reSplitDetails) : [];\n }\n\n /**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\n function hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n }\n\n /**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\n function initCloneArray(array) {\n var length = array.length,\n result = new array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n }\n\n /**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\n function initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n }\n\n /**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\n function initCloneByTag(object, tag, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return new Ctor;\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return new Ctor;\n\n case symbolTag:\n return cloneSymbol(object);\n }\n }\n\n /**\n * Inserts wrapper `details` in a comment at the top of the `source` body.\n *\n * @private\n * @param {string} source The source to modify.\n * @returns {Array} details The details to insert.\n * @returns {string} Returns the modified source.\n */\n function insertWrapDetails(source, details) {\n var length = details.length;\n if (!length) {\n return source;\n }\n var lastIndex = length - 1;\n details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];\n details = details.join(length > 2 ? ', ' : ' ');\n return source.replace(reWrapComment, '{\\n/* [wrapped with ' + details + '] */\\n');\n }\n\n /**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\n function isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n }\n\n /**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\n function isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n }\n\n /**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\n function isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n }\n\n /**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\n function isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n }\n\n /**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\n function isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n }\n\n /**\n * Checks if `func` has a lazy counterpart.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` has a lazy counterpart,\n * else `false`.\n */\n function isLaziable(func) {\n var funcName = getFuncName(func),\n other = lodash[funcName];\n\n if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {\n return false;\n }\n if (func === other) {\n return true;\n }\n var data = getData(other);\n return !!data && func === data[0];\n }\n\n /**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\n function isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n }\n\n /**\n * Checks if `func` is capable of being masked.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `func` is maskable, else `false`.\n */\n var isMaskable = coreJsData ? isFunction : stubFalse;\n\n /**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\n function isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n }\n\n /**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\n function isStrictComparable(value) {\n return value === value && !isObject(value);\n }\n\n /**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\n function matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n }\n\n /**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\n function memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n }\n\n /**\n * Merges the function metadata of `source` into `data`.\n *\n * Merging metadata reduces the number of wrappers used to invoke a function.\n * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\n * may be applied regardless of execution order. Methods like `_.ary` and\n * `_.rearg` modify function arguments, making the order in which they are\n * executed important, preventing the merging of metadata. However, we make\n * an exception for a safe combined case where curried functions have `_.ary`\n * and or `_.rearg` applied.\n *\n * @private\n * @param {Array} data The destination metadata.\n * @param {Array} source The source metadata.\n * @returns {Array} Returns `data`.\n */\n function mergeData(data, source) {\n var bitmask = data[1],\n srcBitmask = source[1],\n newBitmask = bitmask | srcBitmask,\n isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);\n\n var isCombo =\n ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||\n ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||\n ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));\n\n // Exit early if metadata can't be merged.\n if (!(isCommon || isCombo)) {\n return data;\n }\n // Use source `thisArg` if available.\n if (srcBitmask & WRAP_BIND_FLAG) {\n data[2] = source[2];\n // Set when currying a bound function.\n newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;\n }\n // Compose partial arguments.\n var value = source[3];\n if (value) {\n var partials = data[3];\n data[3] = partials ? composeArgs(partials, value, source[4]) : value;\n data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];\n }\n // Compose partial right arguments.\n value = source[5];\n if (value) {\n partials = data[5];\n data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;\n data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];\n }\n // Use source `argPos` if available.\n value = source[7];\n if (value) {\n data[7] = value;\n }\n // Use source `ary` if it's smaller.\n if (srcBitmask & WRAP_ARY_FLAG) {\n data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\n }\n // Use source `arity` if one is not provided.\n if (data[9] == null) {\n data[9] = source[9];\n }\n // Use source `func` and merge bitmasks.\n data[0] = source[0];\n data[1] = newBitmask;\n\n return data;\n }\n\n /**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\n function objectToString(value) {\n return nativeObjectToString.call(value);\n }\n\n /**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\n function overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n }\n\n /**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\n function parent(object, path) {\n return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n }\n\n /**\n * Reorder `array` according to the specified indexes where the element at\n * the first index is assigned as the first element, the element at\n * the second index is assigned as the second element, and so on.\n *\n * @private\n * @param {Array} array The array to reorder.\n * @param {Array} indexes The arranged array indexes.\n * @returns {Array} Returns `array`.\n */\n function reorder(array, indexes) {\n var arrLength = array.length,\n length = nativeMin(indexes.length, arrLength),\n oldArray = copyArray(array);\n\n while (length--) {\n var index = indexes[length];\n array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\n }\n return array;\n }\n\n /**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\n function safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n }\n\n /**\n * Sets metadata for `func`.\n *\n * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\n * period of time, it will trip its breaker and transition to an identity\n * function to avoid garbage collection pauses in V8. See\n * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)\n * for more details.\n *\n * @private\n * @param {Function} func The function to associate metadata with.\n * @param {*} data The metadata.\n * @returns {Function} Returns `func`.\n */\n var setData = shortOut(baseSetData);\n\n /**\n * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\n var setTimeout = ctxSetTimeout || function(func, wait) {\n return root.setTimeout(func, wait);\n };\n\n /**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\n var setToString = shortOut(baseSetToString);\n\n /**\n * Sets the `toString` method of `wrapper` to mimic the source of `reference`\n * with wrapper details in a comment at the top of the source body.\n *\n * @private\n * @param {Function} wrapper The function to modify.\n * @param {Function} reference The reference function.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @returns {Function} Returns `wrapper`.\n */\n function setWrapToString(wrapper, reference, bitmask) {\n var source = (reference + '');\n return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));\n }\n\n /**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\n function shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n }\n\n /**\n * A specialized version of `_.shuffle` which mutates and sets the size of `array`.\n *\n * @private\n * @param {Array} array The array to shuffle.\n * @param {number} [size=array.length] The size of `array`.\n * @returns {Array} Returns `array`.\n */\n function shuffleSelf(array, size) {\n var index = -1,\n length = array.length,\n lastIndex = length - 1;\n\n size = size === undefined ? length : size;\n while (++index < size) {\n var rand = baseRandom(index, lastIndex),\n value = array[rand];\n\n array[rand] = array[index];\n array[index] = value;\n }\n array.length = size;\n return array;\n }\n\n /**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\n var stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n });\n\n /**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\n function toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n }\n\n /**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\n function toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n }\n\n /**\n * Updates wrapper `details` based on `bitmask` flags.\n *\n * @private\n * @returns {Array} details The details to modify.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @returns {Array} Returns `details`.\n */\n function updateWrapDetails(details, bitmask) {\n arrayEach(wrapFlags, function(pair) {\n var value = '_.' + pair[0];\n if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {\n details.push(value);\n }\n });\n return details.sort();\n }\n\n /**\n * Creates a clone of `wrapper`.\n *\n * @private\n * @param {Object} wrapper The wrapper to clone.\n * @returns {Object} Returns the cloned wrapper.\n */\n function wrapperClone(wrapper) {\n if (wrapper instanceof LazyWrapper) {\n return wrapper.clone();\n }\n var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);\n result.__actions__ = copyArray(wrapper.__actions__);\n result.__index__ = wrapper.__index__;\n result.__values__ = wrapper.__values__;\n return result;\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an array of elements split into groups the length of `size`.\n * If `array` can't be split evenly, the final chunk will be the remaining\n * elements.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to process.\n * @param {number} [size=1] The length of each chunk\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the new array of chunks.\n * @example\n *\n * _.chunk(['a', 'b', 'c', 'd'], 2);\n * // => [['a', 'b'], ['c', 'd']]\n *\n * _.chunk(['a', 'b', 'c', 'd'], 3);\n * // => [['a', 'b', 'c'], ['d']]\n */\n function chunk(array, size, guard) {\n if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {\n size = 1;\n } else {\n size = nativeMax(toInteger(size), 0);\n }\n var length = array == null ? 0 : array.length;\n if (!length || size < 1) {\n return [];\n }\n var index = 0,\n resIndex = 0,\n result = Array(nativeCeil(length / size));\n\n while (index < length) {\n result[resIndex++] = baseSlice(array, index, (index += size));\n }\n return result;\n }\n\n /**\n * Creates an array with all falsey values removed. The values `false`, `null`,\n * `0`, `-0`, `0n`, `\"\"`, `undefined`, and `NaN` are falsy.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to compact.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.compact([0, 1, false, 2, '', 3]);\n * // => [1, 2, 3]\n */\n function compact(array) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (value) {\n result[resIndex++] = value;\n }\n }\n return result;\n }\n\n /**\n * Creates a new array concatenating `array` with any additional arrays\n * and/or values.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to concatenate.\n * @param {...*} [values] The values to concatenate.\n * @returns {Array} Returns the new concatenated array.\n * @example\n *\n * var array = [1];\n * var other = _.concat(array, 2, [3], [[4]]);\n *\n * console.log(other);\n * // => [1, 2, 3, [4]]\n *\n * console.log(array);\n * // => [1]\n */\n function concat() {\n var length = arguments.length;\n if (!length) {\n return [];\n }\n var args = Array(length - 1),\n array = arguments[0],\n index = length;\n\n while (index--) {\n args[index - 1] = arguments[index];\n }\n return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));\n }\n\n /**\n * Creates an array of `array` values not included in the other given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * **Note:** Unlike `_.pullAll`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.without, _.xor\n * @example\n *\n * _.difference([2, 1], [2, 3]);\n * // => [1]\n */\n var difference = baseRest(function(array, values) {\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))\n : [];\n });\n\n /**\n * This method is like `_.difference` except that it accepts `iteratee` which\n * is invoked for each element of `array` and `values` to generate the criterion\n * by which they're compared. The order and references of result values are\n * determined by the first array. The iteratee is invoked with one argument:\n * (value).\n *\n * **Note:** Unlike `_.pullAllBy`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');\n * // => [{ 'x': 2 }]\n */\n var differenceBy = baseRest(function(array, values) {\n var iteratee = last(values);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))\n : [];\n });\n\n /**\n * This method is like `_.difference` except that it accepts `comparator`\n * which is invoked to compare elements of `array` to `values`. The order and\n * references of result values are determined by the first array. The comparator\n * is invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.pullAllWith`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n *\n * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }]\n */\n var differenceWith = baseRest(function(array, values) {\n var comparator = last(values);\n if (isArrayLikeObject(comparator)) {\n comparator = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n : [];\n });\n\n /**\n * Creates a slice of `array` with `n` elements dropped from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.drop([1, 2, 3]);\n * // => [2, 3]\n *\n * _.drop([1, 2, 3], 2);\n * // => [3]\n *\n * _.drop([1, 2, 3], 5);\n * // => []\n *\n * _.drop([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\n function drop(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n return baseSlice(array, n < 0 ? 0 : n, length);\n }\n\n /**\n * Creates a slice of `array` with `n` elements dropped from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.dropRight([1, 2, 3]);\n * // => [1, 2]\n *\n * _.dropRight([1, 2, 3], 2);\n * // => [1]\n *\n * _.dropRight([1, 2, 3], 5);\n * // => []\n *\n * _.dropRight([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\n function dropRight(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n n = length - n;\n return baseSlice(array, 0, n < 0 ? 0 : n);\n }\n\n /**\n * Creates a slice of `array` excluding elements dropped from the end.\n * Elements are dropped until `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.dropRightWhile(users, function(o) { return !o.active; });\n * // => objects for ['barney']\n *\n * // The `_.matches` iteratee shorthand.\n * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });\n * // => objects for ['barney', 'fred']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.dropRightWhile(users, ['active', false]);\n * // => objects for ['barney']\n *\n * // The `_.property` iteratee shorthand.\n * _.dropRightWhile(users, 'active');\n * // => objects for ['barney', 'fred', 'pebbles']\n */\n function dropRightWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), true, true)\n : [];\n }\n\n /**\n * Creates a slice of `array` excluding elements dropped from the beginning.\n * Elements are dropped until `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.dropWhile(users, function(o) { return !o.active; });\n * // => objects for ['pebbles']\n *\n * // The `_.matches` iteratee shorthand.\n * _.dropWhile(users, { 'user': 'barney', 'active': false });\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.dropWhile(users, ['active', false]);\n * // => objects for ['pebbles']\n *\n * // The `_.property` iteratee shorthand.\n * _.dropWhile(users, 'active');\n * // => objects for ['barney', 'fred', 'pebbles']\n */\n function dropWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), true)\n : [];\n }\n\n /**\n * Fills elements of `array` with `value` from `start` up to, but not\n * including, `end`.\n *\n * **Note:** This method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 3.2.0\n * @category Array\n * @param {Array} array The array to fill.\n * @param {*} value The value to fill `array` with.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _.fill(array, 'a');\n * console.log(array);\n * // => ['a', 'a', 'a']\n *\n * _.fill(Array(3), 2);\n * // => [2, 2, 2]\n *\n * _.fill([4, 6, 8, 10], '*', 1, 3);\n * // => [4, '*', '*', 10]\n */\n function fill(array, value, start, end) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {\n start = 0;\n end = length;\n }\n return baseFill(array, value, start, end);\n }\n\n /**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\n function findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, getIteratee(predicate, 3), index);\n }\n\n /**\n * This method is like `_.findIndex` except that it iterates over elements\n * of `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=array.length-1] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });\n * // => 2\n *\n * // The `_.matches` iteratee shorthand.\n * _.findLastIndex(users, { 'user': 'barney', 'active': true });\n * // => 0\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findLastIndex(users, ['active', false]);\n * // => 2\n *\n * // The `_.property` iteratee shorthand.\n * _.findLastIndex(users, 'active');\n * // => 0\n */\n function findLastIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = length - 1;\n if (fromIndex !== undefined) {\n index = toInteger(fromIndex);\n index = fromIndex < 0\n ? nativeMax(length + index, 0)\n : nativeMin(index, length - 1);\n }\n return baseFindIndex(array, getIteratee(predicate, 3), index, true);\n }\n\n /**\n * Flattens `array` a single level deep.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flatten([1, [2, [3, [4]], 5]]);\n * // => [1, 2, [3, [4]], 5]\n */\n function flatten(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, 1) : [];\n }\n\n /**\n * Recursively flattens `array`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flattenDeep([1, [2, [3, [4]], 5]]);\n * // => [1, 2, 3, 4, 5]\n */\n function flattenDeep(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, INFINITY) : [];\n }\n\n /**\n * Recursively flatten `array` up to `depth` times.\n *\n * @static\n * @memberOf _\n * @since 4.4.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @param {number} [depth=1] The maximum recursion depth.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * var array = [1, [2, [3, [4]], 5]];\n *\n * _.flattenDepth(array, 1);\n * // => [1, 2, [3, [4]], 5]\n *\n * _.flattenDepth(array, 2);\n * // => [1, 2, 3, [4], 5]\n */\n function flattenDepth(array, depth) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n depth = depth === undefined ? 1 : toInteger(depth);\n return baseFlatten(array, depth);\n }\n\n /**\n * The inverse of `_.toPairs`; this method returns an object composed\n * from key-value `pairs`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} pairs The key-value pairs.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.fromPairs([['a', 1], ['b', 2]]);\n * // => { 'a': 1, 'b': 2 }\n */\n function fromPairs(pairs) {\n var index = -1,\n length = pairs == null ? 0 : pairs.length,\n result = {};\n\n while (++index < length) {\n var pair = pairs[index];\n baseAssignValue(result, pair[0], pair[1]);\n }\n return result;\n }\n\n /**\n * Gets the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias first\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the first element of `array`.\n * @example\n *\n * _.head([1, 2, 3]);\n * // => 1\n *\n * _.head([]);\n * // => undefined\n */\n function head(array) {\n return (array && array.length) ? array[0] : undefined;\n }\n\n /**\n * Gets the index at which the first occurrence of `value` is found in `array`\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. If `fromIndex` is negative, it's used as the\n * offset from the end of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.indexOf([1, 2, 1, 2], 2);\n * // => 1\n *\n * // Search from the `fromIndex`.\n * _.indexOf([1, 2, 1, 2], 2, 2);\n * // => 3\n */\n function indexOf(array, value, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseIndexOf(array, value, index);\n }\n\n /**\n * Gets all but the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.initial([1, 2, 3]);\n * // => [1, 2]\n */\n function initial(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseSlice(array, 0, -1) : [];\n }\n\n /**\n * Creates an array of unique values that are included in all given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersection([2, 1], [2, 3]);\n * // => [2]\n */\n var intersection = baseRest(function(arrays) {\n var mapped = arrayMap(arrays, castArrayLikeObject);\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped)\n : [];\n });\n\n /**\n * This method is like `_.intersection` except that it accepts `iteratee`\n * which is invoked for each element of each `arrays` to generate the criterion\n * by which they're compared. The order and references of result values are\n * determined by the first array. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [2.1]\n *\n * // The `_.property` iteratee shorthand.\n * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }]\n */\n var intersectionBy = baseRest(function(arrays) {\n var iteratee = last(arrays),\n mapped = arrayMap(arrays, castArrayLikeObject);\n\n if (iteratee === last(mapped)) {\n iteratee = undefined;\n } else {\n mapped.pop();\n }\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped, getIteratee(iteratee, 2))\n : [];\n });\n\n /**\n * This method is like `_.intersection` except that it accepts `comparator`\n * which is invoked to compare elements of `arrays`. The order and references\n * of result values are determined by the first array. The comparator is\n * invoked with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.intersectionWith(objects, others, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }]\n */\n var intersectionWith = baseRest(function(arrays) {\n var comparator = last(arrays),\n mapped = arrayMap(arrays, castArrayLikeObject);\n\n comparator = typeof comparator == 'function' ? comparator : undefined;\n if (comparator) {\n mapped.pop();\n }\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped, undefined, comparator)\n : [];\n });\n\n /**\n * Converts all elements in `array` into a string separated by `separator`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to convert.\n * @param {string} [separator=','] The element separator.\n * @returns {string} Returns the joined string.\n * @example\n *\n * _.join(['a', 'b', 'c'], '~');\n * // => 'a~b~c'\n */\n function join(array, separator) {\n return array == null ? '' : nativeJoin.call(array, separator);\n }\n\n /**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\n function last(array) {\n var length = array == null ? 0 : array.length;\n return length ? array[length - 1] : undefined;\n }\n\n /**\n * This method is like `_.indexOf` except that it iterates over elements of\n * `array` from right to left.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=array.length-1] The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.lastIndexOf([1, 2, 1, 2], 2);\n * // => 3\n *\n * // Search from the `fromIndex`.\n * _.lastIndexOf([1, 2, 1, 2], 2, 2);\n * // => 1\n */\n function lastIndexOf(array, value, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = length;\n if (fromIndex !== undefined) {\n index = toInteger(fromIndex);\n index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);\n }\n return value === value\n ? strictLastIndexOf(array, value, index)\n : baseFindIndex(array, baseIsNaN, index, true);\n }\n\n /**\n * Gets the element at index `n` of `array`. If `n` is negative, the nth\n * element from the end is returned.\n *\n * @static\n * @memberOf _\n * @since 4.11.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=0] The index of the element to return.\n * @returns {*} Returns the nth element of `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'd'];\n *\n * _.nth(array, 1);\n * // => 'b'\n *\n * _.nth(array, -2);\n * // => 'c';\n */\n function nth(array, n) {\n return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;\n }\n\n /**\n * Removes all given values from `array` using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`\n * to remove elements from an array by predicate.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {...*} [values] The values to remove.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n *\n * _.pull(array, 'a', 'c');\n * console.log(array);\n * // => ['b', 'b']\n */\n var pull = baseRest(pullAll);\n\n /**\n * This method is like `_.pull` except that it accepts an array of values to remove.\n *\n * **Note:** Unlike `_.difference`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n *\n * _.pullAll(array, ['a', 'c']);\n * console.log(array);\n * // => ['b', 'b']\n */\n function pullAll(array, values) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values)\n : array;\n }\n\n /**\n * This method is like `_.pullAll` except that it accepts `iteratee` which is\n * invoked for each element of `array` and `values` to generate the criterion\n * by which they're compared. The iteratee is invoked with one argument: (value).\n *\n * **Note:** Unlike `_.differenceBy`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];\n *\n * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');\n * console.log(array);\n * // => [{ 'x': 2 }]\n */\n function pullAllBy(array, values, iteratee) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values, getIteratee(iteratee, 2))\n : array;\n }\n\n /**\n * This method is like `_.pullAll` except that it accepts `comparator` which\n * is invoked to compare elements of `array` to `values`. The comparator is\n * invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.differenceWith`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];\n *\n * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);\n * console.log(array);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]\n */\n function pullAllWith(array, values, comparator) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values, undefined, comparator)\n : array;\n }\n\n /**\n * Removes elements from `array` corresponding to `indexes` and returns an\n * array of removed elements.\n *\n * **Note:** Unlike `_.at`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {...(number|number[])} [indexes] The indexes of elements to remove.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = ['a', 'b', 'c', 'd'];\n * var pulled = _.pullAt(array, [1, 3]);\n *\n * console.log(array);\n * // => ['a', 'c']\n *\n * console.log(pulled);\n * // => ['b', 'd']\n */\n var pullAt = flatRest(function(array, indexes) {\n var length = array == null ? 0 : array.length,\n result = baseAt(array, indexes);\n\n basePullAt(array, arrayMap(indexes, function(index) {\n return isIndex(index, length) ? +index : index;\n }).sort(compareAscending));\n\n return result;\n });\n\n /**\n * Removes all elements from `array` that `predicate` returns truthy for\n * and returns an array of the removed elements. The predicate is invoked\n * with three arguments: (value, index, array).\n *\n * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n * to pull elements from an array by value.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = [1, 2, 3, 4];\n * var evens = _.remove(array, function(n) {\n * return n % 2 == 0;\n * });\n *\n * console.log(array);\n * // => [1, 3]\n *\n * console.log(evens);\n * // => [2, 4]\n */\n function remove(array, predicate) {\n var result = [];\n if (!(array && array.length)) {\n return result;\n }\n var index = -1,\n indexes = [],\n length = array.length;\n\n predicate = getIteratee(predicate, 3);\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result.push(value);\n indexes.push(index);\n }\n }\n basePullAt(array, indexes);\n return result;\n }\n\n /**\n * Reverses `array` so that the first element becomes the last, the second\n * element becomes the second to last, and so on.\n *\n * **Note:** This method mutates `array` and is based on\n * [`Array#reverse`](https://mdn.io/Array/reverse).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _.reverse(array);\n * // => [3, 2, 1]\n *\n * console.log(array);\n * // => [3, 2, 1]\n */\n function reverse(array) {\n return array == null ? array : nativeReverse.call(array);\n }\n\n /**\n * Creates a slice of `array` from `start` up to, but not including, `end`.\n *\n * **Note:** This method is used instead of\n * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are\n * returned.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\n function slice(array, start, end) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {\n start = 0;\n end = length;\n }\n else {\n start = start == null ? 0 : toInteger(start);\n end = end === undefined ? length : toInteger(end);\n }\n return baseSlice(array, start, end);\n }\n\n /**\n * Uses a binary search to determine the lowest index at which `value`\n * should be inserted into `array` in order to maintain its sort order.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * _.sortedIndex([30, 50], 40);\n * // => 1\n */\n function sortedIndex(array, value) {\n return baseSortedIndex(array, value);\n }\n\n /**\n * This method is like `_.sortedIndex` except that it accepts `iteratee`\n * which is invoked for `value` and each element of `array` to compute their\n * sort ranking. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * var objects = [{ 'x': 4 }, { 'x': 5 }];\n *\n * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.sortedIndexBy(objects, { 'x': 4 }, 'x');\n * // => 0\n */\n function sortedIndexBy(array, value, iteratee) {\n return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));\n }\n\n /**\n * This method is like `_.indexOf` except that it performs a binary\n * search on a sorted `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.sortedIndexOf([4, 5, 5, 5, 6], 5);\n * // => 1\n */\n function sortedIndexOf(array, value) {\n var length = array == null ? 0 : array.length;\n if (length) {\n var index = baseSortedIndex(array, value);\n if (index < length && eq(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * This method is like `_.sortedIndex` except that it returns the highest\n * index at which `value` should be inserted into `array` in order to\n * maintain its sort order.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * _.sortedLastIndex([4, 5, 5, 5, 6], 5);\n * // => 4\n */\n function sortedLastIndex(array, value) {\n return baseSortedIndex(array, value, true);\n }\n\n /**\n * This method is like `_.sortedLastIndex` except that it accepts `iteratee`\n * which is invoked for `value` and each element of `array` to compute their\n * sort ranking. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * var objects = [{ 'x': 4 }, { 'x': 5 }];\n *\n * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n * // => 1\n *\n * // The `_.property` iteratee shorthand.\n * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');\n * // => 1\n */\n function sortedLastIndexBy(array, value, iteratee) {\n return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);\n }\n\n /**\n * This method is like `_.lastIndexOf` except that it performs a binary\n * search on a sorted `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);\n * // => 3\n */\n function sortedLastIndexOf(array, value) {\n var length = array == null ? 0 : array.length;\n if (length) {\n var index = baseSortedIndex(array, value, true) - 1;\n if (eq(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * This method is like `_.uniq` except that it's designed and optimized\n * for sorted arrays.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.sortedUniq([1, 1, 2]);\n * // => [1, 2]\n */\n function sortedUniq(array) {\n return (array && array.length)\n ? baseSortedUniq(array)\n : [];\n }\n\n /**\n * This method is like `_.uniqBy` except that it's designed and optimized\n * for sorted arrays.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);\n * // => [1.1, 2.3]\n */\n function sortedUniqBy(array, iteratee) {\n return (array && array.length)\n ? baseSortedUniq(array, getIteratee(iteratee, 2))\n : [];\n }\n\n /**\n * Gets all but the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.tail([1, 2, 3]);\n * // => [2, 3]\n */\n function tail(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseSlice(array, 1, length) : [];\n }\n\n /**\n * Creates a slice of `array` with `n` elements taken from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.take([1, 2, 3]);\n * // => [1]\n *\n * _.take([1, 2, 3], 2);\n * // => [1, 2]\n *\n * _.take([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.take([1, 2, 3], 0);\n * // => []\n */\n function take(array, n, guard) {\n if (!(array && array.length)) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n return baseSlice(array, 0, n < 0 ? 0 : n);\n }\n\n /**\n * Creates a slice of `array` with `n` elements taken from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.takeRight([1, 2, 3]);\n * // => [3]\n *\n * _.takeRight([1, 2, 3], 2);\n * // => [2, 3]\n *\n * _.takeRight([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.takeRight([1, 2, 3], 0);\n * // => []\n */\n function takeRight(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n n = length - n;\n return baseSlice(array, n < 0 ? 0 : n, length);\n }\n\n /**\n * Creates a slice of `array` with elements taken from the end. Elements are\n * taken until `predicate` returns falsey. The predicate is invoked with\n * three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.takeRightWhile(users, function(o) { return !o.active; });\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.matches` iteratee shorthand.\n * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });\n * // => objects for ['pebbles']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.takeRightWhile(users, ['active', false]);\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.property` iteratee shorthand.\n * _.takeRightWhile(users, 'active');\n * // => []\n */\n function takeRightWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), false, true)\n : [];\n }\n\n /**\n * Creates a slice of `array` with elements taken from the beginning. Elements\n * are taken until `predicate` returns falsey. The predicate is invoked with\n * three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.takeWhile(users, function(o) { return !o.active; });\n * // => objects for ['barney', 'fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.takeWhile(users, { 'user': 'barney', 'active': false });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.takeWhile(users, ['active', false]);\n * // => objects for ['barney', 'fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.takeWhile(users, 'active');\n * // => []\n */\n function takeWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3))\n : [];\n }\n\n /**\n * Creates an array of unique values, in order, from all given arrays using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.union([2], [1, 2]);\n * // => [2, 1]\n */\n var union = baseRest(function(arrays) {\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));\n });\n\n /**\n * This method is like `_.union` except that it accepts `iteratee` which is\n * invoked for each element of each `arrays` to generate the criterion by\n * which uniqueness is computed. Result values are chosen from the first\n * array in which the value occurs. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.unionBy([2.1], [1.2, 2.3], Math.floor);\n * // => [2.1, 1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\n var unionBy = baseRest(function(arrays) {\n var iteratee = last(arrays);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));\n });\n\n /**\n * This method is like `_.union` except that it accepts `comparator` which\n * is invoked to compare elements of `arrays`. Result values are chosen from\n * the first array in which the value occurs. The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.unionWith(objects, others, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n */\n var unionWith = baseRest(function(arrays) {\n var comparator = last(arrays);\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);\n });\n\n /**\n * Creates a duplicate-free version of an array, using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons, in which only the first occurrence of each element\n * is kept. The order of result values is determined by the order they occur\n * in the array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniq([2, 1, 2]);\n * // => [2, 1]\n */\n function uniq(array) {\n return (array && array.length) ? baseUniq(array) : [];\n }\n\n /**\n * This method is like `_.uniq` except that it accepts `iteratee` which is\n * invoked for each element in `array` to generate the criterion by which\n * uniqueness is computed. The order of result values is determined by the\n * order they occur in the array. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n * // => [2.1, 1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\n function uniqBy(array, iteratee) {\n return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];\n }\n\n /**\n * This method is like `_.uniq` except that it accepts `comparator` which\n * is invoked to compare elements of `array`. The order of result values is\n * determined by the order they occur in the array.The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.uniqWith(objects, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n */\n function uniqWith(array, comparator) {\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return (array && array.length) ? baseUniq(array, undefined, comparator) : [];\n }\n\n /**\n * This method is like `_.zip` except that it accepts an array of grouped\n * elements and creates an array regrouping the elements to their pre-zip\n * configuration.\n *\n * @static\n * @memberOf _\n * @since 1.2.0\n * @category Array\n * @param {Array} array The array of grouped elements to process.\n * @returns {Array} Returns the new array of regrouped elements.\n * @example\n *\n * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);\n * // => [['a', 1, true], ['b', 2, false]]\n *\n * _.unzip(zipped);\n * // => [['a', 'b'], [1, 2], [true, false]]\n */\n function unzip(array) {\n if (!(array && array.length)) {\n return [];\n }\n var length = 0;\n array = arrayFilter(array, function(group) {\n if (isArrayLikeObject(group)) {\n length = nativeMax(group.length, length);\n return true;\n }\n });\n return baseTimes(length, function(index) {\n return arrayMap(array, baseProperty(index));\n });\n }\n\n /**\n * This method is like `_.unzip` except that it accepts `iteratee` to specify\n * how regrouped values should be combined. The iteratee is invoked with the\n * elements of each group: (...group).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Array\n * @param {Array} array The array of grouped elements to process.\n * @param {Function} [iteratee=_.identity] The function to combine\n * regrouped values.\n * @returns {Array} Returns the new array of regrouped elements.\n * @example\n *\n * var zipped = _.zip([1, 2], [10, 20], [100, 200]);\n * // => [[1, 10, 100], [2, 20, 200]]\n *\n * _.unzipWith(zipped, _.add);\n * // => [3, 30, 300]\n */\n function unzipWith(array, iteratee) {\n if (!(array && array.length)) {\n return [];\n }\n var result = unzip(array);\n if (iteratee == null) {\n return result;\n }\n return arrayMap(result, function(group) {\n return apply(iteratee, undefined, group);\n });\n }\n\n /**\n * Creates an array excluding all given values using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * **Note:** Unlike `_.pull`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...*} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.xor\n * @example\n *\n * _.without([2, 1, 2, 3], 1, 2);\n * // => [3]\n */\n var without = baseRest(function(array, values) {\n return isArrayLikeObject(array)\n ? baseDifference(array, values)\n : [];\n });\n\n /**\n * Creates an array of unique values that is the\n * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)\n * of the given arrays. The order of result values is determined by the order\n * they occur in the arrays.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.without\n * @example\n *\n * _.xor([2, 1], [2, 3]);\n * // => [1, 3]\n */\n var xor = baseRest(function(arrays) {\n return baseXor(arrayFilter(arrays, isArrayLikeObject));\n });\n\n /**\n * This method is like `_.xor` except that it accepts `iteratee` which is\n * invoked for each element of each `arrays` to generate the criterion by\n * which by which they're compared. The order of result values is determined\n * by the order they occur in the arrays. The iteratee is invoked with one\n * argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [1.2, 3.4]\n *\n * // The `_.property` iteratee shorthand.\n * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 2 }]\n */\n var xorBy = baseRest(function(arrays) {\n var iteratee = last(arrays);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));\n });\n\n /**\n * This method is like `_.xor` except that it accepts `comparator` which is\n * invoked to compare elements of `arrays`. The order of result values is\n * determined by the order they occur in the arrays. The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.xorWith(objects, others, _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n */\n var xorWith = baseRest(function(arrays) {\n var comparator = last(arrays);\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);\n });\n\n /**\n * Creates an array of grouped elements, the first of which contains the\n * first elements of the given arrays, the second of which contains the\n * second elements of the given arrays, and so on.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to process.\n * @returns {Array} Returns the new array of grouped elements.\n * @example\n *\n * _.zip(['a', 'b'], [1, 2], [true, false]);\n * // => [['a', 1, true], ['b', 2, false]]\n */\n var zip = baseRest(unzip);\n\n /**\n * This method is like `_.fromPairs` except that it accepts two arrays,\n * one of property identifiers and one of corresponding values.\n *\n * @static\n * @memberOf _\n * @since 0.4.0\n * @category Array\n * @param {Array} [props=[]] The property identifiers.\n * @param {Array} [values=[]] The property values.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.zipObject(['a', 'b'], [1, 2]);\n * // => { 'a': 1, 'b': 2 }\n */\n function zipObject(props, values) {\n return baseZipObject(props || [], values || [], assignValue);\n }\n\n /**\n * This method is like `_.zipObject` except that it supports property paths.\n *\n * @static\n * @memberOf _\n * @since 4.1.0\n * @category Array\n * @param {Array} [props=[]] The property identifiers.\n * @param {Array} [values=[]] The property values.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);\n * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }\n */\n function zipObjectDeep(props, values) {\n return baseZipObject(props || [], values || [], baseSet);\n }\n\n /**\n * This method is like `_.zip` except that it accepts `iteratee` to specify\n * how grouped values should be combined. The iteratee is invoked with the\n * elements of each group: (...group).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Array\n * @param {...Array} [arrays] The arrays to process.\n * @param {Function} [iteratee=_.identity] The function to combine\n * grouped values.\n * @returns {Array} Returns the new array of grouped elements.\n * @example\n *\n * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {\n * return a + b + c;\n * });\n * // => [111, 222]\n */\n var zipWith = baseRest(function(arrays) {\n var length = arrays.length,\n iteratee = length > 1 ? arrays[length - 1] : undefined;\n\n iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;\n return unzipWith(arrays, iteratee);\n });\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a `lodash` wrapper instance that wraps `value` with explicit method\n * chain sequences enabled. The result of such sequences must be unwrapped\n * with `_#value`.\n *\n * @static\n * @memberOf _\n * @since 1.3.0\n * @category Seq\n * @param {*} value The value to wrap.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 40 },\n * { 'user': 'pebbles', 'age': 1 }\n * ];\n *\n * var youngest = _\n * .chain(users)\n * .sortBy('age')\n * .map(function(o) {\n * return o.user + ' is ' + o.age;\n * })\n * .head()\n * .value();\n * // => 'pebbles is 1'\n */\n function chain(value) {\n var result = lodash(value);\n result.__chain__ = true;\n return result;\n }\n\n /**\n * This method invokes `interceptor` and returns `value`. The interceptor\n * is invoked with one argument; (value). The purpose of this method is to\n * \"tap into\" a method chain sequence in order to modify intermediate results.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @param {*} value The value to provide to `interceptor`.\n * @param {Function} interceptor The function to invoke.\n * @returns {*} Returns `value`.\n * @example\n *\n * _([1, 2, 3])\n * .tap(function(array) {\n * // Mutate input array.\n * array.pop();\n * })\n * .reverse()\n * .value();\n * // => [2, 1]\n */\n function tap(value, interceptor) {\n interceptor(value);\n return value;\n }\n\n /**\n * This method is like `_.tap` except that it returns the result of `interceptor`.\n * The purpose of this method is to \"pass thru\" values replacing intermediate\n * results in a method chain sequence.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Seq\n * @param {*} value The value to provide to `interceptor`.\n * @param {Function} interceptor The function to invoke.\n * @returns {*} Returns the result of `interceptor`.\n * @example\n *\n * _(' abc ')\n * .chain()\n * .trim()\n * .thru(function(value) {\n * return [value];\n * })\n * .value();\n * // => ['abc']\n */\n function thru(value, interceptor) {\n return interceptor(value);\n }\n\n /**\n * This method is the wrapper version of `_.at`.\n *\n * @name at\n * @memberOf _\n * @since 1.0.0\n * @category Seq\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n *\n * _(object).at(['a[0].b.c', 'a[1]']).value();\n * // => [3, 4]\n */\n var wrapperAt = flatRest(function(paths) {\n var length = paths.length,\n start = length ? paths[0] : 0,\n value = this.__wrapped__,\n interceptor = function(object) { return baseAt(object, paths); };\n\n if (length > 1 || this.__actions__.length ||\n !(value instanceof LazyWrapper) || !isIndex(start)) {\n return this.thru(interceptor);\n }\n value = value.slice(start, +start + (length ? 1 : 0));\n value.__actions__.push({\n 'func': thru,\n 'args': [interceptor],\n 'thisArg': undefined\n });\n return new LodashWrapper(value, this.__chain__).thru(function(array) {\n if (length && !array.length) {\n array.push(undefined);\n }\n return array;\n });\n });\n\n /**\n * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.\n *\n * @name chain\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 40 }\n * ];\n *\n * // A sequence without explicit chaining.\n * _(users).head();\n * // => { 'user': 'barney', 'age': 36 }\n *\n * // A sequence with explicit chaining.\n * _(users)\n * .chain()\n * .head()\n * .pick('user')\n * .value();\n * // => { 'user': 'barney' }\n */\n function wrapperChain() {\n return chain(this);\n }\n\n /**\n * Executes the chain sequence and returns the wrapped result.\n *\n * @name commit\n * @memberOf _\n * @since 3.2.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var array = [1, 2];\n * var wrapped = _(array).push(3);\n *\n * console.log(array);\n * // => [1, 2]\n *\n * wrapped = wrapped.commit();\n * console.log(array);\n * // => [1, 2, 3]\n *\n * wrapped.last();\n * // => 3\n *\n * console.log(array);\n * // => [1, 2, 3]\n */\n function wrapperCommit() {\n return new LodashWrapper(this.value(), this.__chain__);\n }\n\n /**\n * Gets the next value on a wrapped object following the\n * [iterator protocol](https://mdn.io/iteration_protocols#iterator).\n *\n * @name next\n * @memberOf _\n * @since 4.0.0\n * @category Seq\n * @returns {Object} Returns the next iterator value.\n * @example\n *\n * var wrapped = _([1, 2]);\n *\n * wrapped.next();\n * // => { 'done': false, 'value': 1 }\n *\n * wrapped.next();\n * // => { 'done': false, 'value': 2 }\n *\n * wrapped.next();\n * // => { 'done': true, 'value': undefined }\n */\n function wrapperNext() {\n if (this.__values__ === undefined) {\n this.__values__ = toArray(this.value());\n }\n var done = this.__index__ >= this.__values__.length,\n value = done ? undefined : this.__values__[this.__index__++];\n\n return { 'done': done, 'value': value };\n }\n\n /**\n * Enables the wrapper to be iterable.\n *\n * @name Symbol.iterator\n * @memberOf _\n * @since 4.0.0\n * @category Seq\n * @returns {Object} Returns the wrapper object.\n * @example\n *\n * var wrapped = _([1, 2]);\n *\n * wrapped[Symbol.iterator]() === wrapped;\n * // => true\n *\n * Array.from(wrapped);\n * // => [1, 2]\n */\n function wrapperToIterator() {\n return this;\n }\n\n /**\n * Creates a clone of the chain sequence planting `value` as the wrapped value.\n *\n * @name plant\n * @memberOf _\n * @since 3.2.0\n * @category Seq\n * @param {*} value The value to plant.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var wrapped = _([1, 2]).map(square);\n * var other = wrapped.plant([3, 4]);\n *\n * other.value();\n * // => [9, 16]\n *\n * wrapped.value();\n * // => [1, 4]\n */\n function wrapperPlant(value) {\n var result,\n parent = this;\n\n while (parent instanceof baseLodash) {\n var clone = wrapperClone(parent);\n clone.__index__ = 0;\n clone.__values__ = undefined;\n if (result) {\n previous.__wrapped__ = clone;\n } else {\n result = clone;\n }\n var previous = clone;\n parent = parent.__wrapped__;\n }\n previous.__wrapped__ = value;\n return result;\n }\n\n /**\n * This method is the wrapper version of `_.reverse`.\n *\n * **Note:** This method mutates the wrapped array.\n *\n * @name reverse\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _(array).reverse().value()\n * // => [3, 2, 1]\n *\n * console.log(array);\n * // => [3, 2, 1]\n */\n function wrapperReverse() {\n var value = this.__wrapped__;\n if (value instanceof LazyWrapper) {\n var wrapped = value;\n if (this.__actions__.length) {\n wrapped = new LazyWrapper(this);\n }\n wrapped = wrapped.reverse();\n wrapped.__actions__.push({\n 'func': thru,\n 'args': [reverse],\n 'thisArg': undefined\n });\n return new LodashWrapper(wrapped, this.__chain__);\n }\n return this.thru(reverse);\n }\n\n /**\n * Executes the chain sequence to resolve the unwrapped value.\n *\n * @name value\n * @memberOf _\n * @since 0.1.0\n * @alias toJSON, valueOf\n * @category Seq\n * @returns {*} Returns the resolved unwrapped value.\n * @example\n *\n * _([1, 2, 3]).value();\n * // => [1, 2, 3]\n */\n function wrapperValue() {\n return baseWrapperValue(this.__wrapped__, this.__actions__);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The corresponding value of\n * each key is the number of times the key was returned by `iteratee`. The\n * iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * _.countBy([6.1, 4.2, 6.3], Math.floor);\n * // => { '4': 1, '6': 2 }\n *\n * // The `_.property` iteratee shorthand.\n * _.countBy(['one', 'two', 'three'], 'length');\n * // => { '3': 2, '5': 1 }\n */\n var countBy = createAggregator(function(result, value, key) {\n if (hasOwnProperty.call(result, key)) {\n ++result[key];\n } else {\n baseAssignValue(result, key, 1);\n }\n });\n\n /**\n * Checks if `predicate` returns truthy for **all** elements of `collection`.\n * Iteration is stopped once `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * **Note:** This method returns `true` for\n * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because\n * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of\n * elements of empty collections.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`.\n * @example\n *\n * _.every([true, 1, null, 'yes'], Boolean);\n * // => false\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.every(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.every(users, ['active', false]);\n * // => true\n *\n * // The `_.property` iteratee shorthand.\n * _.every(users, 'active');\n * // => false\n */\n function every(collection, predicate, guard) {\n var func = isArray(collection) ? arrayEvery : baseEvery;\n if (guard && isIterateeCall(collection, predicate, guard)) {\n predicate = undefined;\n }\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Iterates over elements of `collection`, returning an array of all elements\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * **Note:** Unlike `_.remove`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.reject\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * _.filter(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.filter(users, { 'age': 36, 'active': true });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.filter(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.filter(users, 'active');\n * // => objects for ['barney']\n *\n * // Combining several predicates using `_.overEvery` or `_.overSome`.\n * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));\n * // => objects for ['fred', 'barney']\n */\n function filter(collection, predicate) {\n var func = isArray(collection) ? arrayFilter : baseFilter;\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Iterates over elements of `collection`, returning the first element\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false },\n * { 'user': 'pebbles', 'age': 1, 'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\n var find = createFind(findIndex);\n\n /**\n * This method is like `_.find` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=collection.length-1] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * _.findLast([1, 2, 3, 4], function(n) {\n * return n % 2 == 1;\n * });\n * // => 3\n */\n var findLast = createFind(findLastIndex);\n\n /**\n * Creates a flattened array of values by running each element in `collection`\n * thru `iteratee` and flattening the mapped results. The iteratee is invoked\n * with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [n, n];\n * }\n *\n * _.flatMap([1, 2], duplicate);\n * // => [1, 1, 2, 2]\n */\n function flatMap(collection, iteratee) {\n return baseFlatten(map(collection, iteratee), 1);\n }\n\n /**\n * This method is like `_.flatMap` except that it recursively flattens the\n * mapped results.\n *\n * @static\n * @memberOf _\n * @since 4.7.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [[[n, n]]];\n * }\n *\n * _.flatMapDeep([1, 2], duplicate);\n * // => [1, 1, 2, 2]\n */\n function flatMapDeep(collection, iteratee) {\n return baseFlatten(map(collection, iteratee), INFINITY);\n }\n\n /**\n * This method is like `_.flatMap` except that it recursively flattens the\n * mapped results up to `depth` times.\n *\n * @static\n * @memberOf _\n * @since 4.7.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {number} [depth=1] The maximum recursion depth.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [[[n, n]]];\n * }\n *\n * _.flatMapDepth([1, 2], duplicate, 2);\n * // => [[1, 1], [2, 2]]\n */\n function flatMapDepth(collection, iteratee, depth) {\n depth = depth === undefined ? 1 : toInteger(depth);\n return baseFlatten(map(collection, iteratee), depth);\n }\n\n /**\n * Iterates over elements of `collection` and invokes `iteratee` for each element.\n * The iteratee is invoked with three arguments: (value, index|key, collection).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * **Note:** As with other \"Collections\" methods, objects with a \"length\"\n * property are iterated like arrays. To avoid this behavior use `_.forIn`\n * or `_.forOwn` for object iteration.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias each\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n * @see _.forEachRight\n * @example\n *\n * _.forEach([1, 2], function(value) {\n * console.log(value);\n * });\n * // => Logs `1` then `2`.\n *\n * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n */\n function forEach(collection, iteratee) {\n var func = isArray(collection) ? arrayEach : baseEach;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.forEach` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @alias eachRight\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n * @see _.forEach\n * @example\n *\n * _.forEachRight([1, 2], function(value) {\n * console.log(value);\n * });\n * // => Logs `2` then `1`.\n */\n function forEachRight(collection, iteratee) {\n var func = isArray(collection) ? arrayEachRight : baseEachRight;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The order of grouped values\n * is determined by the order they occur in `collection`. The corresponding\n * value of each key is an array of elements responsible for generating the\n * key. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * _.groupBy([6.1, 4.2, 6.3], Math.floor);\n * // => { '4': [4.2], '6': [6.1, 6.3] }\n *\n * // The `_.property` iteratee shorthand.\n * _.groupBy(['one', 'two', 'three'], 'length');\n * // => { '3': ['one', 'two'], '5': ['three'] }\n */\n var groupBy = createAggregator(function(result, value, key) {\n if (hasOwnProperty.call(result, key)) {\n result[key].push(value);\n } else {\n baseAssignValue(result, key, [value]);\n }\n });\n\n /**\n * Checks if `value` is in `collection`. If `collection` is a string, it's\n * checked for a substring of `value`, otherwise\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * is used for equality comparisons. If `fromIndex` is negative, it's used as\n * the offset from the end of `collection`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object|string} collection The collection to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=0] The index to search from.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n * @returns {boolean} Returns `true` if `value` is found, else `false`.\n * @example\n *\n * _.includes([1, 2, 3], 1);\n * // => true\n *\n * _.includes([1, 2, 3], 1, 2);\n * // => false\n *\n * _.includes({ 'a': 1, 'b': 2 }, 1);\n * // => true\n *\n * _.includes('abcd', 'bc');\n * // => true\n */\n function includes(collection, value, fromIndex, guard) {\n collection = isArrayLike(collection) ? collection : values(collection);\n fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;\n\n var length = collection.length;\n if (fromIndex < 0) {\n fromIndex = nativeMax(length + fromIndex, 0);\n }\n return isString(collection)\n ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)\n : (!!length && baseIndexOf(collection, value, fromIndex) > -1);\n }\n\n /**\n * Invokes the method at `path` of each element in `collection`, returning\n * an array of the results of each invoked method. Any additional arguments\n * are provided to each invoked method. If `path` is a function, it's invoked\n * for, and `this` bound to, each element in `collection`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Array|Function|string} path The path of the method to invoke or\n * the function invoked per iteration.\n * @param {...*} [args] The arguments to invoke each method with.\n * @returns {Array} Returns the array of results.\n * @example\n *\n * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');\n * // => [[1, 5, 7], [1, 2, 3]]\n *\n * _.invokeMap([123, 456], String.prototype.split, '');\n * // => [['1', '2', '3'], ['4', '5', '6']]\n */\n var invokeMap = baseRest(function(collection, path, args) {\n var index = -1,\n isFunc = typeof path == 'function',\n result = isArrayLike(collection) ? Array(collection.length) : [];\n\n baseEach(collection, function(value) {\n result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);\n });\n return result;\n });\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The corresponding value of\n * each key is the last element responsible for generating the key. The\n * iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * var array = [\n * { 'dir': 'left', 'code': 97 },\n * { 'dir': 'right', 'code': 100 }\n * ];\n *\n * _.keyBy(array, function(o) {\n * return String.fromCharCode(o.code);\n * });\n * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n *\n * _.keyBy(array, 'dir');\n * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }\n */\n var keyBy = createAggregator(function(result, value, key) {\n baseAssignValue(result, key, value);\n });\n\n /**\n * Creates an array of values by running each element in `collection` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n *\n * The guarded methods are:\n * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,\n * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,\n * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,\n * `template`, `trim`, `trimEnd`, `trimStart`, and `words`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * _.map([4, 8], square);\n * // => [16, 64]\n *\n * _.map({ 'a': 4, 'b': 8 }, square);\n * // => [16, 64] (iteration order is not guaranteed)\n *\n * var users = [\n * { 'user': 'barney' },\n * { 'user': 'fred' }\n * ];\n *\n * // The `_.property` iteratee shorthand.\n * _.map(users, 'user');\n * // => ['barney', 'fred']\n */\n function map(collection, iteratee) {\n var func = isArray(collection) ? arrayMap : baseMap;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.sortBy` except that it allows specifying the sort\n * orders of the iteratees to sort by. If `orders` is unspecified, all values\n * are sorted in ascending order. Otherwise, specify an order of \"desc\" for\n * descending or \"asc\" for ascending sort order of corresponding values.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]\n * The iteratees to sort by.\n * @param {string[]} [orders] The sort orders of `iteratees`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n * { 'user': 'fred', 'age': 48 },\n * { 'user': 'barney', 'age': 34 },\n * { 'user': 'fred', 'age': 40 },\n * { 'user': 'barney', 'age': 36 }\n * ];\n *\n * // Sort by `user` in ascending order and by `age` in descending order.\n * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n */\n function orderBy(collection, iteratees, orders, guard) {\n if (collection == null) {\n return [];\n }\n if (!isArray(iteratees)) {\n iteratees = iteratees == null ? [] : [iteratees];\n }\n orders = guard ? undefined : orders;\n if (!isArray(orders)) {\n orders = orders == null ? [] : [orders];\n }\n return baseOrderBy(collection, iteratees, orders);\n }\n\n /**\n * Creates an array of elements split into two groups, the first of which\n * contains elements `predicate` returns truthy for, the second of which\n * contains elements `predicate` returns falsey for. The predicate is\n * invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the array of grouped elements.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': true },\n * { 'user': 'pebbles', 'age': 1, 'active': false }\n * ];\n *\n * _.partition(users, function(o) { return o.active; });\n * // => objects for [['fred'], ['barney', 'pebbles']]\n *\n * // The `_.matches` iteratee shorthand.\n * _.partition(users, { 'age': 1, 'active': false });\n * // => objects for [['pebbles'], ['barney', 'fred']]\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.partition(users, ['active', false]);\n * // => objects for [['barney', 'pebbles'], ['fred']]\n *\n * // The `_.property` iteratee shorthand.\n * _.partition(users, 'active');\n * // => objects for [['fred'], ['barney', 'pebbles']]\n */\n var partition = createAggregator(function(result, value, key) {\n result[key ? 0 : 1].push(value);\n }, function() { return [[], []]; });\n\n /**\n * Reduces `collection` to a value which is the accumulated result of running\n * each element in `collection` thru `iteratee`, where each successive\n * invocation is supplied the return value of the previous. If `accumulator`\n * is not given, the first element of `collection` is used as the initial\n * value. The iteratee is invoked with four arguments:\n * (accumulator, value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.reduce`, `_.reduceRight`, and `_.transform`.\n *\n * The guarded methods are:\n * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,\n * and `sortBy`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @returns {*} Returns the accumulated value.\n * @see _.reduceRight\n * @example\n *\n * _.reduce([1, 2], function(sum, n) {\n * return sum + n;\n * }, 0);\n * // => 3\n *\n * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n * (result[value] || (result[value] = [])).push(key);\n * return result;\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)\n */\n function reduce(collection, iteratee, accumulator) {\n var func = isArray(collection) ? arrayReduce : baseReduce,\n initAccum = arguments.length < 3;\n\n return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);\n }\n\n /**\n * This method is like `_.reduce` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @returns {*} Returns the accumulated value.\n * @see _.reduce\n * @example\n *\n * var array = [[0, 1], [2, 3], [4, 5]];\n *\n * _.reduceRight(array, function(flattened, other) {\n * return flattened.concat(other);\n * }, []);\n * // => [4, 5, 2, 3, 0, 1]\n */\n function reduceRight(collection, iteratee, accumulator) {\n var func = isArray(collection) ? arrayReduceRight : baseReduce,\n initAccum = arguments.length < 3;\n\n return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);\n }\n\n /**\n * The opposite of `_.filter`; this method returns the elements of `collection`\n * that `predicate` does **not** return truthy for.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.filter\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': true }\n * ];\n *\n * _.reject(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.reject(users, { 'age': 40, 'active': true });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.reject(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.reject(users, 'active');\n * // => objects for ['barney']\n */\n function reject(collection, predicate) {\n var func = isArray(collection) ? arrayFilter : baseFilter;\n return func(collection, negate(getIteratee(predicate, 3)));\n }\n\n /**\n * Gets a random element from `collection`.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to sample.\n * @returns {*} Returns the random element.\n * @example\n *\n * _.sample([1, 2, 3, 4]);\n * // => 2\n */\n function sample(collection) {\n var func = isArray(collection) ? arraySample : baseSample;\n return func(collection);\n }\n\n /**\n * Gets `n` random elements at unique keys from `collection` up to the\n * size of `collection`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to sample.\n * @param {number} [n=1] The number of elements to sample.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the random elements.\n * @example\n *\n * _.sampleSize([1, 2, 3], 2);\n * // => [3, 1]\n *\n * _.sampleSize([1, 2, 3], 4);\n * // => [2, 3, 1]\n */\n function sampleSize(collection, n, guard) {\n if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {\n n = 1;\n } else {\n n = toInteger(n);\n }\n var func = isArray(collection) ? arraySampleSize : baseSampleSize;\n return func(collection, n);\n }\n\n /**\n * Creates an array of shuffled values, using a version of the\n * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to shuffle.\n * @returns {Array} Returns the new shuffled array.\n * @example\n *\n * _.shuffle([1, 2, 3, 4]);\n * // => [4, 1, 3, 2]\n */\n function shuffle(collection) {\n var func = isArray(collection) ? arrayShuffle : baseShuffle;\n return func(collection);\n }\n\n /**\n * Gets the size of `collection` by returning its length for array-like\n * values or the number of own enumerable string keyed properties for objects.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object|string} collection The collection to inspect.\n * @returns {number} Returns the collection size.\n * @example\n *\n * _.size([1, 2, 3]);\n * // => 3\n *\n * _.size({ 'a': 1, 'b': 2 });\n * // => 2\n *\n * _.size('pebbles');\n * // => 7\n */\n function size(collection) {\n if (collection == null) {\n return 0;\n }\n if (isArrayLike(collection)) {\n return isString(collection) ? stringSize(collection) : collection.length;\n }\n var tag = getTag(collection);\n if (tag == mapTag || tag == setTag) {\n return collection.size;\n }\n return baseKeys(collection).length;\n }\n\n /**\n * Checks if `predicate` returns truthy for **any** element of `collection`.\n * Iteration is stopped once `predicate` returns truthy. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n * @example\n *\n * _.some([null, 0, 'yes', false], Boolean);\n * // => true\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.some(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.some(users, ['active', false]);\n * // => true\n *\n * // The `_.property` iteratee shorthand.\n * _.some(users, 'active');\n * // => true\n */\n function some(collection, predicate, guard) {\n var func = isArray(collection) ? arraySome : baseSome;\n if (guard && isIterateeCall(collection, predicate, guard)) {\n predicate = undefined;\n }\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Creates an array of elements, sorted in ascending order by the results of\n * running each element in a collection thru each iteratee. This method\n * performs a stable sort, that is, it preserves the original sort order of\n * equal elements. The iteratees are invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {...(Function|Function[])} [iteratees=[_.identity]]\n * The iteratees to sort by.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n * { 'user': 'fred', 'age': 48 },\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 30 },\n * { 'user': 'barney', 'age': 34 }\n * ];\n *\n * _.sortBy(users, [function(o) { return o.user; }]);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]\n *\n * _.sortBy(users, ['user', 'age']);\n * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]\n */\n var sortBy = baseRest(function(collection, iteratees) {\n if (collection == null) {\n return [];\n }\n var length = iteratees.length;\n if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n iteratees = [];\n } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n iteratees = [iteratees[0]];\n }\n return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n });\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\n var now = ctxNow || function() {\n return root.Date.now();\n };\n\n /*------------------------------------------------------------------------*/\n\n /**\n * The opposite of `_.before`; this method creates a function that invokes\n * `func` once it's called `n` or more times.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {number} n The number of calls before `func` is invoked.\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * var saves = ['profile', 'settings'];\n *\n * var done = _.after(saves.length, function() {\n * console.log('done saving!');\n * });\n *\n * _.forEach(saves, function(type) {\n * asyncSave({ 'type': type, 'complete': done });\n * });\n * // => Logs 'done saving!' after the two async saves have completed.\n */\n function after(n, func) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n n = toInteger(n);\n return function() {\n if (--n < 1) {\n return func.apply(this, arguments);\n }\n };\n }\n\n /**\n * Creates a function that invokes `func`, with up to `n` arguments,\n * ignoring any additional arguments.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to cap arguments for.\n * @param {number} [n=func.length] The arity cap.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new capped function.\n * @example\n *\n * _.map(['6', '8', '10'], _.ary(parseInt, 1));\n * // => [6, 8, 10]\n */\n function ary(func, n, guard) {\n n = guard ? undefined : n;\n n = (func && n == null) ? func.length : n;\n return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);\n }\n\n /**\n * Creates a function that invokes `func`, with the `this` binding and arguments\n * of the created function, while it's called less than `n` times. Subsequent\n * calls to the created function return the result of the last `func` invocation.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {number} n The number of calls at which `func` is no longer invoked.\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * jQuery(element).on('click', _.before(5, addContactToList));\n * // => Allows adding up to 4 contacts to the list.\n */\n function before(n, func) {\n var result;\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n n = toInteger(n);\n return function() {\n if (--n > 0) {\n result = func.apply(this, arguments);\n }\n if (n <= 1) {\n func = undefined;\n }\n return result;\n };\n }\n\n /**\n * Creates a function that invokes `func` with the `this` binding of `thisArg`\n * and `partials` prepended to the arguments it receives.\n *\n * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,\n * may be used as a placeholder for partially applied arguments.\n *\n * **Note:** Unlike native `Function#bind`, this method doesn't set the \"length\"\n * property of bound functions.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to bind.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new bound function.\n * @example\n *\n * function greet(greeting, punctuation) {\n * return greeting + ' ' + this.user + punctuation;\n * }\n *\n * var object = { 'user': 'fred' };\n *\n * var bound = _.bind(greet, object, 'hi');\n * bound('!');\n * // => 'hi fred!'\n *\n * // Bound with placeholders.\n * var bound = _.bind(greet, object, _, '!');\n * bound('hi');\n * // => 'hi fred!'\n */\n var bind = baseRest(function(func, thisArg, partials) {\n var bitmask = WRAP_BIND_FLAG;\n if (partials.length) {\n var holders = replaceHolders(partials, getHolder(bind));\n bitmask |= WRAP_PARTIAL_FLAG;\n }\n return createWrap(func, bitmask, thisArg, partials, holders);\n });\n\n /**\n * Creates a function that invokes the method at `object[key]` with `partials`\n * prepended to the arguments it receives.\n *\n * This method differs from `_.bind` by allowing bound functions to reference\n * methods that may be redefined or don't yet exist. See\n * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)\n * for more details.\n *\n * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Function\n * @param {Object} object The object to invoke the method on.\n * @param {string} key The key of the method.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new bound function.\n * @example\n *\n * var object = {\n * 'user': 'fred',\n * 'greet': function(greeting, punctuation) {\n * return greeting + ' ' + this.user + punctuation;\n * }\n * };\n *\n * var bound = _.bindKey(object, 'greet', 'hi');\n * bound('!');\n * // => 'hi fred!'\n *\n * object.greet = function(greeting, punctuation) {\n * return greeting + 'ya ' + this.user + punctuation;\n * };\n *\n * bound('!');\n * // => 'hiya fred!'\n *\n * // Bound with placeholders.\n * var bound = _.bindKey(object, 'greet', _, '!');\n * bound('hi');\n * // => 'hiya fred!'\n */\n var bindKey = baseRest(function(object, key, partials) {\n var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;\n if (partials.length) {\n var holders = replaceHolders(partials, getHolder(bindKey));\n bitmask |= WRAP_PARTIAL_FLAG;\n }\n return createWrap(key, bitmask, object, partials, holders);\n });\n\n /**\n * Creates a function that accepts arguments of `func` and either invokes\n * `func` returning its result, if at least `arity` number of arguments have\n * been provided, or returns a function that accepts the remaining `func`\n * arguments, and so on. The arity of `func` may be specified if `func.length`\n * is not sufficient.\n *\n * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,\n * may be used as a placeholder for provided arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of curried functions.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Function\n * @param {Function} func The function to curry.\n * @param {number} [arity=func.length] The arity of `func`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new curried function.\n * @example\n *\n * var abc = function(a, b, c) {\n * return [a, b, c];\n * };\n *\n * var curried = _.curry(abc);\n *\n * curried(1)(2)(3);\n * // => [1, 2, 3]\n *\n * curried(1, 2)(3);\n * // => [1, 2, 3]\n *\n * curried(1, 2, 3);\n * // => [1, 2, 3]\n *\n * // Curried with placeholders.\n * curried(1)(_, 3)(2);\n * // => [1, 2, 3]\n */\n function curry(func, arity, guard) {\n arity = guard ? undefined : arity;\n var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n result.placeholder = curry.placeholder;\n return result;\n }\n\n /**\n * This method is like `_.curry` except that arguments are applied to `func`\n * in the manner of `_.partialRight` instead of `_.partial`.\n *\n * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for provided arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of curried functions.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to curry.\n * @param {number} [arity=func.length] The arity of `func`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new curried function.\n * @example\n *\n * var abc = function(a, b, c) {\n * return [a, b, c];\n * };\n *\n * var curried = _.curryRight(abc);\n *\n * curried(3)(2)(1);\n * // => [1, 2, 3]\n *\n * curried(2, 3)(1);\n * // => [1, 2, 3]\n *\n * curried(1, 2, 3);\n * // => [1, 2, 3]\n *\n * // Curried with placeholders.\n * curried(3)(1, _)(2);\n * // => [1, 2, 3]\n */\n function curryRight(func, arity, guard) {\n arity = guard ? undefined : arity;\n var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n result.placeholder = curryRight.placeholder;\n return result;\n }\n\n /**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\n function debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n timeWaiting = wait - timeSinceLastCall;\n\n return maxing\n ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n }\n\n /**\n * Defers invoking the `func` until the current call stack has cleared. Any\n * additional arguments are provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to defer.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.defer(function(text) {\n * console.log(text);\n * }, 'deferred');\n * // => Logs 'deferred' after one millisecond.\n */\n var defer = baseRest(function(func, args) {\n return baseDelay(func, 1, args);\n });\n\n /**\n * Invokes `func` after `wait` milliseconds. Any additional arguments are\n * provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.delay(function(text) {\n * console.log(text);\n * }, 1000, 'later');\n * // => Logs 'later' after one second.\n */\n var delay = baseRest(function(func, wait, args) {\n return baseDelay(func, toNumber(wait) || 0, args);\n });\n\n /**\n * Creates a function that invokes `func` with arguments reversed.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to flip arguments for.\n * @returns {Function} Returns the new flipped function.\n * @example\n *\n * var flipped = _.flip(function() {\n * return _.toArray(arguments);\n * });\n *\n * flipped('a', 'b', 'c', 'd');\n * // => ['d', 'c', 'b', 'a']\n */\n function flip(func) {\n return createWrap(func, WRAP_FLIP_FLAG);\n }\n\n /**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\n function memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n }\n\n // Expose `MapCache`.\n memoize.Cache = MapCache;\n\n /**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\n function negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n }\n\n /**\n * Creates a function that is restricted to invoking `func` once. Repeat calls\n * to the function return the value of the first invocation. The `func` is\n * invoked with the `this` binding and arguments of the created function.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * var initialize = _.once(createApplication);\n * initialize();\n * initialize();\n * // => `createApplication` is invoked once\n */\n function once(func) {\n return before(2, func);\n }\n\n /**\n * Creates a function that invokes `func` with its arguments transformed.\n *\n * @static\n * @since 4.0.0\n * @memberOf _\n * @category Function\n * @param {Function} func The function to wrap.\n * @param {...(Function|Function[])} [transforms=[_.identity]]\n * The argument transforms.\n * @returns {Function} Returns the new function.\n * @example\n *\n * function doubled(n) {\n * return n * 2;\n * }\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var func = _.overArgs(function(x, y) {\n * return [x, y];\n * }, [square, doubled]);\n *\n * func(9, 3);\n * // => [81, 6]\n *\n * func(10, 5);\n * // => [100, 10]\n */\n var overArgs = castRest(function(func, transforms) {\n transforms = (transforms.length == 1 && isArray(transforms[0]))\n ? arrayMap(transforms[0], baseUnary(getIteratee()))\n : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));\n\n var funcsLength = transforms.length;\n return baseRest(function(args) {\n var index = -1,\n length = nativeMin(args.length, funcsLength);\n\n while (++index < length) {\n args[index] = transforms[index].call(this, args[index]);\n }\n return apply(func, this, args);\n });\n });\n\n /**\n * Creates a function that invokes `func` with `partials` prepended to the\n * arguments it receives. This method is like `_.bind` except it does **not**\n * alter the `this` binding.\n *\n * The `_.partial.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of partially\n * applied functions.\n *\n * @static\n * @memberOf _\n * @since 0.2.0\n * @category Function\n * @param {Function} func The function to partially apply arguments to.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new partially applied function.\n * @example\n *\n * function greet(greeting, name) {\n * return greeting + ' ' + name;\n * }\n *\n * var sayHelloTo = _.partial(greet, 'hello');\n * sayHelloTo('fred');\n * // => 'hello fred'\n *\n * // Partially applied with placeholders.\n * var greetFred = _.partial(greet, _, 'fred');\n * greetFred('hi');\n * // => 'hi fred'\n */\n var partial = baseRest(function(func, partials) {\n var holders = replaceHolders(partials, getHolder(partial));\n return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);\n });\n\n /**\n * This method is like `_.partial` except that partially applied arguments\n * are appended to the arguments it receives.\n *\n * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of partially\n * applied functions.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Function\n * @param {Function} func The function to partially apply arguments to.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new partially applied function.\n * @example\n *\n * function greet(greeting, name) {\n * return greeting + ' ' + name;\n * }\n *\n * var greetFred = _.partialRight(greet, 'fred');\n * greetFred('hi');\n * // => 'hi fred'\n *\n * // Partially applied with placeholders.\n * var sayHelloTo = _.partialRight(greet, 'hello', _);\n * sayHelloTo('fred');\n * // => 'hello fred'\n */\n var partialRight = baseRest(function(func, partials) {\n var holders = replaceHolders(partials, getHolder(partialRight));\n return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);\n });\n\n /**\n * Creates a function that invokes `func` with arguments arranged according\n * to the specified `indexes` where the argument value at the first index is\n * provided as the first argument, the argument value at the second index is\n * provided as the second argument, and so on.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to rearrange arguments for.\n * @param {...(number|number[])} indexes The arranged argument indexes.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var rearged = _.rearg(function(a, b, c) {\n * return [a, b, c];\n * }, [2, 0, 1]);\n *\n * rearged('b', 'c', 'a')\n * // => ['a', 'b', 'c']\n */\n var rearg = flatRest(function(func, indexes) {\n return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);\n });\n\n /**\n * Creates a function that invokes `func` with the `this` binding of the\n * created function and arguments from `start` and beyond provided as\n * an array.\n *\n * **Note:** This method is based on the\n * [rest parameter](https://mdn.io/rest_parameters).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.rest(function(what, names) {\n * return what + ' ' + _.initial(names).join(', ') +\n * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n * });\n *\n * say('hello', 'fred', 'barney', 'pebbles');\n * // => 'hello fred, barney, & pebbles'\n */\n function rest(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = start === undefined ? start : toInteger(start);\n return baseRest(func, start);\n }\n\n /**\n * Creates a function that invokes `func` with the `this` binding of the\n * create function and an array of arguments much like\n * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).\n *\n * **Note:** This method is based on the\n * [spread operator](https://mdn.io/spread_operator).\n *\n * @static\n * @memberOf _\n * @since 3.2.0\n * @category Function\n * @param {Function} func The function to spread arguments over.\n * @param {number} [start=0] The start position of the spread.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.spread(function(who, what) {\n * return who + ' says ' + what;\n * });\n *\n * say(['fred', 'hello']);\n * // => 'fred says hello'\n *\n * var numbers = Promise.all([\n * Promise.resolve(40),\n * Promise.resolve(36)\n * ]);\n *\n * numbers.then(_.spread(function(x, y) {\n * return x + y;\n * }));\n * // => a Promise of 76\n */\n function spread(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = start == null ? 0 : nativeMax(toInteger(start), 0);\n return baseRest(function(args) {\n var array = args[start],\n otherArgs = castSlice(args, 0, start);\n\n if (array) {\n arrayPush(otherArgs, array);\n }\n return apply(func, this, otherArgs);\n });\n }\n\n /**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds. The throttled function comes with a `cancel`\n * method to cancel delayed `func` invocations and a `flush` method to\n * immediately invoke them. Provide `options` to indicate whether `func`\n * should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.throttle` and `_.debounce`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n * Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\n function throttle(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (isObject(options)) {\n leading = 'leading' in options ? !!options.leading : leading;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n return debounce(func, wait, {\n 'leading': leading,\n 'maxWait': wait,\n 'trailing': trailing\n });\n }\n\n /**\n * Creates a function that accepts up to one argument, ignoring any\n * additional arguments.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n * @example\n *\n * _.map(['6', '8', '10'], _.unary(parseInt));\n * // => [6, 8, 10]\n */\n function unary(func) {\n return ary(func, 1);\n }\n\n /**\n * Creates a function that provides `value` to `wrapper` as its first\n * argument. Any additional arguments provided to the function are appended\n * to those provided to the `wrapper`. The wrapper is invoked with the `this`\n * binding of the created function.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {*} value The value to wrap.\n * @param {Function} [wrapper=identity] The wrapper function.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var p = _.wrap(_.escape, function(func, text) {\n * return '

    ' + func(text) + '

    ';\n * });\n *\n * p('fred, barney, & pebbles');\n * // => '

    fred, barney, & pebbles

    '\n */\n function wrap(value, wrapper) {\n return partial(castFunction(wrapper), value);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Casts `value` as an array if it's not one.\n *\n * @static\n * @memberOf _\n * @since 4.4.0\n * @category Lang\n * @param {*} value The value to inspect.\n * @returns {Array} Returns the cast array.\n * @example\n *\n * _.castArray(1);\n * // => [1]\n *\n * _.castArray({ 'a': 1 });\n * // => [{ 'a': 1 }]\n *\n * _.castArray('abc');\n * // => ['abc']\n *\n * _.castArray(null);\n * // => [null]\n *\n * _.castArray(undefined);\n * // => [undefined]\n *\n * _.castArray();\n * // => []\n *\n * var array = [1, 2, 3];\n * console.log(_.castArray(array) === array);\n * // => true\n */\n function castArray() {\n if (!arguments.length) {\n return [];\n }\n var value = arguments[0];\n return isArray(value) ? value : [value];\n }\n\n /**\n * Creates a shallow clone of `value`.\n *\n * **Note:** This method is loosely based on the\n * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n * and supports cloning arrays, array buffers, booleans, date objects, maps,\n * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n * arrays. The own enumerable properties of `arguments` objects are cloned\n * as plain objects. An empty object is returned for uncloneable values such\n * as error objects, functions, DOM nodes, and WeakMaps.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to clone.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeep\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var shallow = _.clone(objects);\n * console.log(shallow[0] === objects[0]);\n * // => true\n */\n function clone(value) {\n return baseClone(value, CLONE_SYMBOLS_FLAG);\n }\n\n /**\n * This method is like `_.clone` except that it accepts `customizer` which\n * is invoked to produce the cloned value. If `customizer` returns `undefined`,\n * cloning is handled by the method instead. The `customizer` is invoked with\n * up to four arguments; (value [, index|key, object, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeepWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(false);\n * }\n * }\n *\n * var el = _.cloneWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 0\n */\n function cloneWith(value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);\n }\n\n /**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\n function cloneDeep(value) {\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n }\n\n /**\n * This method is like `_.cloneWith` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the deep cloned value.\n * @see _.cloneWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(true);\n * }\n * }\n *\n * var el = _.cloneDeepWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 20\n */\n function cloneDeepWith(value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n }\n\n /**\n * Checks if `object` conforms to `source` by invoking the predicate\n * properties of `source` with the corresponding property values of `object`.\n *\n * **Note:** This method is equivalent to `_.conforms` when `source` is\n * partially applied.\n *\n * @static\n * @memberOf _\n * @since 4.14.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property predicates to conform to.\n * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n *\n * _.conformsTo(object, { 'b': function(n) { return n > 1; } });\n * // => true\n *\n * _.conformsTo(object, { 'b': function(n) { return n > 2; } });\n * // => false\n */\n function conformsTo(object, source) {\n return source == null || baseConformsTo(object, source, keys(source));\n }\n\n /**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\n function eq(value, other) {\n return value === other || (value !== value && other !== other);\n }\n\n /**\n * Checks if `value` is greater than `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than `other`,\n * else `false`.\n * @see _.lt\n * @example\n *\n * _.gt(3, 1);\n * // => true\n *\n * _.gt(3, 3);\n * // => false\n *\n * _.gt(1, 3);\n * // => false\n */\n var gt = createRelationalOperation(baseGt);\n\n /**\n * Checks if `value` is greater than or equal to `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than or equal to\n * `other`, else `false`.\n * @see _.lte\n * @example\n *\n * _.gte(3, 1);\n * // => true\n *\n * _.gte(3, 3);\n * // => true\n *\n * _.gte(1, 3);\n * // => false\n */\n var gte = createRelationalOperation(function(value, other) {\n return value >= other;\n });\n\n /**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\n var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n };\n\n /**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\n var isArray = Array.isArray;\n\n /**\n * Checks if `value` is classified as an `ArrayBuffer` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n * @example\n *\n * _.isArrayBuffer(new ArrayBuffer(2));\n * // => true\n *\n * _.isArrayBuffer(new Array(2));\n * // => false\n */\n var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;\n\n /**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\n function isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n }\n\n /**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\n function isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n }\n\n /**\n * Checks if `value` is classified as a boolean primitive or object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.\n * @example\n *\n * _.isBoolean(false);\n * // => true\n *\n * _.isBoolean(null);\n * // => false\n */\n function isBoolean(value) {\n return value === true || value === false ||\n (isObjectLike(value) && baseGetTag(value) == boolTag);\n }\n\n /**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\n var isBuffer = nativeIsBuffer || stubFalse;\n\n /**\n * Checks if `value` is classified as a `Date` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n * @example\n *\n * _.isDate(new Date);\n * // => true\n *\n * _.isDate('Mon April 23 2012');\n * // => false\n */\n var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;\n\n /**\n * Checks if `value` is likely a DOM element.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n * @example\n *\n * _.isElement(document.body);\n * // => true\n *\n * _.isElement('');\n * // => false\n */\n function isElement(value) {\n return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);\n }\n\n /**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * Objects are considered empty if they have no own enumerable string keyed\n * properties.\n *\n * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n * jQuery-like collections are considered empty if they have a `length` of `0`.\n * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n * @example\n *\n * _.isEmpty(null);\n * // => true\n *\n * _.isEmpty(true);\n * // => true\n *\n * _.isEmpty(1);\n * // => true\n *\n * _.isEmpty([1, 2, 3]);\n * // => false\n *\n * _.isEmpty({ 'a': 1 });\n * // => false\n */\n function isEmpty(value) {\n if (value == null) {\n return true;\n }\n if (isArrayLike(value) &&\n (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n return !value.length;\n }\n var tag = getTag(value);\n if (tag == mapTag || tag == setTag) {\n return !value.size;\n }\n if (isPrototype(value)) {\n return !baseKeys(value).length;\n }\n for (var key in value) {\n if (hasOwnProperty.call(value, key)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\n function isEqual(value, other) {\n return baseIsEqual(value, other);\n }\n\n /**\n * This method is like `_.isEqual` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with up to\n * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, othValue) {\n * if (isGreeting(objValue) && isGreeting(othValue)) {\n * return true;\n * }\n * }\n *\n * var array = ['hello', 'goodbye'];\n * var other = ['hi', 'goodbye'];\n *\n * _.isEqualWith(array, other, customizer);\n * // => true\n */\n function isEqualWith(value, other, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n var result = customizer ? customizer(value, other) : undefined;\n return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;\n }\n\n /**\n * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,\n * `SyntaxError`, `TypeError`, or `URIError` object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an error object, else `false`.\n * @example\n *\n * _.isError(new Error);\n * // => true\n *\n * _.isError(Error);\n * // => false\n */\n function isError(value) {\n if (!isObjectLike(value)) {\n return false;\n }\n var tag = baseGetTag(value);\n return tag == errorTag || tag == domExcTag ||\n (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));\n }\n\n /**\n * Checks if `value` is a finite primitive number.\n *\n * **Note:** This method is based on\n * [`Number.isFinite`](https://mdn.io/Number/isFinite).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n * @example\n *\n * _.isFinite(3);\n * // => true\n *\n * _.isFinite(Number.MIN_VALUE);\n * // => true\n *\n * _.isFinite(Infinity);\n * // => false\n *\n * _.isFinite('3');\n * // => false\n */\n function isFinite(value) {\n return typeof value == 'number' && nativeIsFinite(value);\n }\n\n /**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\n function isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n }\n\n /**\n * Checks if `value` is an integer.\n *\n * **Note:** This method is based on\n * [`Number.isInteger`](https://mdn.io/Number/isInteger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an integer, else `false`.\n * @example\n *\n * _.isInteger(3);\n * // => true\n *\n * _.isInteger(Number.MIN_VALUE);\n * // => false\n *\n * _.isInteger(Infinity);\n * // => false\n *\n * _.isInteger('3');\n * // => false\n */\n function isInteger(value) {\n return typeof value == 'number' && value == toInteger(value);\n }\n\n /**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\n function isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\n function isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n }\n\n /**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\n function isObjectLike(value) {\n return value != null && typeof value == 'object';\n }\n\n /**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\n var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\n /**\n * Performs a partial deep comparison between `object` and `source` to\n * determine if `object` contains equivalent property values.\n *\n * **Note:** This method is equivalent to `_.matches` when `source` is\n * partially applied.\n *\n * Partial comparisons will match empty array and empty object `source`\n * values against any array or object value, respectively. See `_.isEqual`\n * for a list of supported value comparisons.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n *\n * _.isMatch(object, { 'b': 2 });\n * // => true\n *\n * _.isMatch(object, { 'b': 1 });\n * // => false\n */\n function isMatch(object, source) {\n return object === source || baseIsMatch(object, source, getMatchData(source));\n }\n\n /**\n * This method is like `_.isMatch` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with five\n * arguments: (objValue, srcValue, index|key, object, source).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, srcValue) {\n * if (isGreeting(objValue) && isGreeting(srcValue)) {\n * return true;\n * }\n * }\n *\n * var object = { 'greeting': 'hello' };\n * var source = { 'greeting': 'hi' };\n *\n * _.isMatchWith(object, source, customizer);\n * // => true\n */\n function isMatchWith(object, source, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseIsMatch(object, source, getMatchData(source), customizer);\n }\n\n /**\n * Checks if `value` is `NaN`.\n *\n * **Note:** This method is based on\n * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as\n * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for\n * `undefined` and other non-number values.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n * @example\n *\n * _.isNaN(NaN);\n * // => true\n *\n * _.isNaN(new Number(NaN));\n * // => true\n *\n * isNaN(undefined);\n * // => true\n *\n * _.isNaN(undefined);\n * // => false\n */\n function isNaN(value) {\n // An `NaN` primitive is the only value that is not equal to itself.\n // Perform the `toStringTag` check first to avoid errors with some\n // ActiveX objects in IE.\n return isNumber(value) && value != +value;\n }\n\n /**\n * Checks if `value` is a pristine native function.\n *\n * **Note:** This method can't reliably detect native functions in the presence\n * of the core-js package because core-js circumvents this kind of detection.\n * Despite multiple requests, the core-js maintainer has made it clear: any\n * attempt to fix the detection will be obstructed. As a result, we're left\n * with little choice but to throw an error. Unfortunately, this also affects\n * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),\n * which rely on core-js.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\n function isNative(value) {\n if (isMaskable(value)) {\n throw new Error(CORE_ERROR_TEXT);\n }\n return baseIsNative(value);\n }\n\n /**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\n function isNull(value) {\n return value === null;\n }\n\n /**\n * Checks if `value` is `null` or `undefined`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n * @example\n *\n * _.isNil(null);\n * // => true\n *\n * _.isNil(void 0);\n * // => true\n *\n * _.isNil(NaN);\n * // => false\n */\n function isNil(value) {\n return value == null;\n }\n\n /**\n * Checks if `value` is classified as a `Number` primitive or object.\n *\n * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are\n * classified as numbers, use the `_.isFinite` method.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a number, else `false`.\n * @example\n *\n * _.isNumber(3);\n * // => true\n *\n * _.isNumber(Number.MIN_VALUE);\n * // => true\n *\n * _.isNumber(Infinity);\n * // => true\n *\n * _.isNumber('3');\n * // => false\n */\n function isNumber(value) {\n return typeof value == 'number' ||\n (isObjectLike(value) && baseGetTag(value) == numberTag);\n }\n\n /**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\n function isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n }\n\n /**\n * Checks if `value` is classified as a `RegExp` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n * @example\n *\n * _.isRegExp(/abc/);\n * // => true\n *\n * _.isRegExp('/abc/');\n * // => false\n */\n var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;\n\n /**\n * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754\n * double precision number which isn't the result of a rounded unsafe integer.\n *\n * **Note:** This method is based on\n * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.\n * @example\n *\n * _.isSafeInteger(3);\n * // => true\n *\n * _.isSafeInteger(Number.MIN_VALUE);\n * // => false\n *\n * _.isSafeInteger(Infinity);\n * // => false\n *\n * _.isSafeInteger('3');\n * // => false\n */\n function isSafeInteger(value) {\n return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\n var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\n /**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\n function isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n }\n\n /**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\n function isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n }\n\n /**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\n var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\n /**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\n function isUndefined(value) {\n return value === undefined;\n }\n\n /**\n * Checks if `value` is classified as a `WeakMap` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.\n * @example\n *\n * _.isWeakMap(new WeakMap);\n * // => true\n *\n * _.isWeakMap(new Map);\n * // => false\n */\n function isWeakMap(value) {\n return isObjectLike(value) && getTag(value) == weakMapTag;\n }\n\n /**\n * Checks if `value` is classified as a `WeakSet` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.\n * @example\n *\n * _.isWeakSet(new WeakSet);\n * // => true\n *\n * _.isWeakSet(new Set);\n * // => false\n */\n function isWeakSet(value) {\n return isObjectLike(value) && baseGetTag(value) == weakSetTag;\n }\n\n /**\n * Checks if `value` is less than `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than `other`,\n * else `false`.\n * @see _.gt\n * @example\n *\n * _.lt(1, 3);\n * // => true\n *\n * _.lt(3, 3);\n * // => false\n *\n * _.lt(3, 1);\n * // => false\n */\n var lt = createRelationalOperation(baseLt);\n\n /**\n * Checks if `value` is less than or equal to `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than or equal to\n * `other`, else `false`.\n * @see _.gte\n * @example\n *\n * _.lte(1, 3);\n * // => true\n *\n * _.lte(3, 3);\n * // => true\n *\n * _.lte(3, 1);\n * // => false\n */\n var lte = createRelationalOperation(function(value, other) {\n return value <= other;\n });\n\n /**\n * Converts `value` to an array.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Array} Returns the converted array.\n * @example\n *\n * _.toArray({ 'a': 1, 'b': 2 });\n * // => [1, 2]\n *\n * _.toArray('abc');\n * // => ['a', 'b', 'c']\n *\n * _.toArray(1);\n * // => []\n *\n * _.toArray(null);\n * // => []\n */\n function toArray(value) {\n if (!value) {\n return [];\n }\n if (isArrayLike(value)) {\n return isString(value) ? stringToArray(value) : copyArray(value);\n }\n if (symIterator && value[symIterator]) {\n return iteratorToArray(value[symIterator]());\n }\n var tag = getTag(value),\n func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);\n\n return func(value);\n }\n\n /**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\n function toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n }\n\n /**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\n function toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n }\n\n /**\n * Converts `value` to an integer suitable for use as the length of an\n * array-like object.\n *\n * **Note:** This method is based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toLength(3.2);\n * // => 3\n *\n * _.toLength(Number.MIN_VALUE);\n * // => 0\n *\n * _.toLength(Infinity);\n * // => 4294967295\n *\n * _.toLength('3.2');\n * // => 3\n */\n function toLength(value) {\n return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;\n }\n\n /**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\n function toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n }\n\n /**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\n function toPlainObject(value) {\n return copyObject(value, keysIn(value));\n }\n\n /**\n * Converts `value` to a safe integer. A safe integer can be compared and\n * represented correctly.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toSafeInteger(3.2);\n * // => 3\n *\n * _.toSafeInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toSafeInteger(Infinity);\n * // => 9007199254740991\n *\n * _.toSafeInteger('3.2');\n * // => 3\n */\n function toSafeInteger(value) {\n return value\n ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)\n : (value === 0 ? value : 0);\n }\n\n /**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\n function toString(value) {\n return value == null ? '' : baseToString(value);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assign({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3 }\n */\n var assign = createAssigner(function(object, source) {\n if (isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n });\n\n /**\n * This method is like `_.assign` except that it iterates over own and\n * inherited source properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extend\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assign\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assignIn({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\n */\n var assignIn = createAssigner(function(object, source) {\n copyObject(source, keysIn(source), object);\n });\n\n /**\n * This method is like `_.assignIn` except that it accepts `customizer`\n * which is invoked to produce the assigned values. If `customizer` returns\n * `undefined`, assignment is handled by the method instead. The `customizer`\n * is invoked with five arguments: (objValue, srcValue, key, object, source).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extendWith\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @see _.assignWith\n * @example\n *\n * function customizer(objValue, srcValue) {\n * return _.isUndefined(objValue) ? srcValue : objValue;\n * }\n *\n * var defaults = _.partialRight(_.assignInWith, customizer);\n *\n * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {\n copyObject(source, keysIn(source), object, customizer);\n });\n\n /**\n * This method is like `_.assign` except that it accepts `customizer`\n * which is invoked to produce the assigned values. If `customizer` returns\n * `undefined`, assignment is handled by the method instead. The `customizer`\n * is invoked with five arguments: (objValue, srcValue, key, object, source).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @see _.assignInWith\n * @example\n *\n * function customizer(objValue, srcValue) {\n * return _.isUndefined(objValue) ? srcValue : objValue;\n * }\n *\n * var defaults = _.partialRight(_.assignWith, customizer);\n *\n * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var assignWith = createAssigner(function(object, source, srcIndex, customizer) {\n copyObject(source, keys(source), object, customizer);\n });\n\n /**\n * Creates an array of values corresponding to `paths` of `object`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Array} Returns the picked values.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n *\n * _.at(object, ['a[0].b.c', 'a[1]']);\n * // => [3, 4]\n */\n var at = flatRest(baseAt);\n\n /**\n * Creates an object that inherits from the `prototype` object. If a\n * `properties` object is given, its own enumerable string keyed properties\n * are assigned to the created object.\n *\n * @static\n * @memberOf _\n * @since 2.3.0\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n * this.x = 0;\n * this.y = 0;\n * }\n *\n * function Circle() {\n * Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n * 'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\n function create(prototype, properties) {\n var result = baseCreate(prototype);\n return properties == null ? result : baseAssign(result, properties);\n }\n\n /**\n * Assigns own and inherited enumerable string keyed properties of source\n * objects to the destination object for all destination properties that\n * resolve to `undefined`. Source objects are applied from left to right.\n * Once a property is set, additional values of the same property are ignored.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaultsDeep\n * @example\n *\n * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var defaults = baseRest(function(object, sources) {\n object = Object(object);\n\n var index = -1;\n var length = sources.length;\n var guard = length > 2 ? sources[2] : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n length = 1;\n }\n\n while (++index < length) {\n var source = sources[index];\n var props = keysIn(source);\n var propsIndex = -1;\n var propsLength = props.length;\n\n while (++propsIndex < propsLength) {\n var key = props[propsIndex];\n var value = object[key];\n\n if (value === undefined ||\n (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n object[key] = source[key];\n }\n }\n }\n\n return object;\n });\n\n /**\n * This method is like `_.defaults` except that it recursively assigns\n * default properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaults\n * @example\n *\n * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n * // => { 'a': { 'b': 2, 'c': 3 } }\n */\n var defaultsDeep = baseRest(function(args) {\n args.push(undefined, customDefaultsMerge);\n return apply(mergeWith, undefined, args);\n });\n\n /**\n * This method is like `_.find` except that it returns the key of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {string|undefined} Returns the key of the matched element,\n * else `undefined`.\n * @example\n *\n * var users = {\n * 'barney': { 'age': 36, 'active': true },\n * 'fred': { 'age': 40, 'active': false },\n * 'pebbles': { 'age': 1, 'active': true }\n * };\n *\n * _.findKey(users, function(o) { return o.age < 40; });\n * // => 'barney' (iteration order is not guaranteed)\n *\n * // The `_.matches` iteratee shorthand.\n * _.findKey(users, { 'age': 1, 'active': true });\n * // => 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findKey(users, ['active', false]);\n * // => 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.findKey(users, 'active');\n * // => 'barney'\n */\n function findKey(object, predicate) {\n return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);\n }\n\n /**\n * This method is like `_.findKey` except that it iterates over elements of\n * a collection in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {string|undefined} Returns the key of the matched element,\n * else `undefined`.\n * @example\n *\n * var users = {\n * 'barney': { 'age': 36, 'active': true },\n * 'fred': { 'age': 40, 'active': false },\n * 'pebbles': { 'age': 1, 'active': true }\n * };\n *\n * _.findLastKey(users, function(o) { return o.age < 40; });\n * // => returns 'pebbles' assuming `_.findKey` returns 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.findLastKey(users, { 'age': 36, 'active': true });\n * // => 'barney'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findLastKey(users, ['active', false]);\n * // => 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.findLastKey(users, 'active');\n * // => 'pebbles'\n */\n function findLastKey(object, predicate) {\n return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);\n }\n\n /**\n * Iterates over own and inherited enumerable string keyed properties of an\n * object and invokes `iteratee` for each property. The iteratee is invoked\n * with three arguments: (value, key, object). Iteratee functions may exit\n * iteration early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 0.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forInRight\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forIn(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).\n */\n function forIn(object, iteratee) {\n return object == null\n ? object\n : baseFor(object, getIteratee(iteratee, 3), keysIn);\n }\n\n /**\n * This method is like `_.forIn` except that it iterates over properties of\n * `object` in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forInRight(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.\n */\n function forInRight(object, iteratee) {\n return object == null\n ? object\n : baseForRight(object, getIteratee(iteratee, 3), keysIn);\n }\n\n /**\n * Iterates over own enumerable string keyed properties of an object and\n * invokes `iteratee` for each property. The iteratee is invoked with three\n * arguments: (value, key, object). Iteratee functions may exit iteration\n * early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 0.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forOwnRight\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forOwn(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n */\n function forOwn(object, iteratee) {\n return object && baseForOwn(object, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.forOwn` except that it iterates over properties of\n * `object` in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forOwn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forOwnRight(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.\n */\n function forOwnRight(object, iteratee) {\n return object && baseForOwnRight(object, getIteratee(iteratee, 3));\n }\n\n /**\n * Creates an array of function property names from own enumerable properties\n * of `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to inspect.\n * @returns {Array} Returns the function names.\n * @see _.functionsIn\n * @example\n *\n * function Foo() {\n * this.a = _.constant('a');\n * this.b = _.constant('b');\n * }\n *\n * Foo.prototype.c = _.constant('c');\n *\n * _.functions(new Foo);\n * // => ['a', 'b']\n */\n function functions(object) {\n return object == null ? [] : baseFunctions(object, keys(object));\n }\n\n /**\n * Creates an array of function property names from own and inherited\n * enumerable properties of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @returns {Array} Returns the function names.\n * @see _.functions\n * @example\n *\n * function Foo() {\n * this.a = _.constant('a');\n * this.b = _.constant('b');\n * }\n *\n * Foo.prototype.c = _.constant('c');\n *\n * _.functionsIn(new Foo);\n * // => ['a', 'b', 'c']\n */\n function functionsIn(object) {\n return object == null ? [] : baseFunctions(object, keysIn(object));\n }\n\n /**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\n function get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n }\n\n /**\n * Checks if `path` is a direct property of `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = { 'a': { 'b': 2 } };\n * var other = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.has(object, 'a');\n * // => true\n *\n * _.has(object, 'a.b');\n * // => true\n *\n * _.has(object, ['a', 'b']);\n * // => true\n *\n * _.has(other, 'a');\n * // => false\n */\n function has(object, path) {\n return object != null && hasPath(object, path, baseHas);\n }\n\n /**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\n function hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n }\n\n /**\n * Creates an object composed of the inverted keys and values of `object`.\n * If `object` contains duplicate values, subsequent values overwrite\n * property assignments of previous values.\n *\n * @static\n * @memberOf _\n * @since 0.7.0\n * @category Object\n * @param {Object} object The object to invert.\n * @returns {Object} Returns the new inverted object.\n * @example\n *\n * var object = { 'a': 1, 'b': 2, 'c': 1 };\n *\n * _.invert(object);\n * // => { '1': 'c', '2': 'b' }\n */\n var invert = createInverter(function(result, value, key) {\n if (value != null &&\n typeof value.toString != 'function') {\n value = nativeObjectToString.call(value);\n }\n\n result[value] = key;\n }, constant(identity));\n\n /**\n * This method is like `_.invert` except that the inverted object is generated\n * from the results of running each element of `object` thru `iteratee`. The\n * corresponding inverted value of each inverted key is an array of keys\n * responsible for generating the inverted value. The iteratee is invoked\n * with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.1.0\n * @category Object\n * @param {Object} object The object to invert.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Object} Returns the new inverted object.\n * @example\n *\n * var object = { 'a': 1, 'b': 2, 'c': 1 };\n *\n * _.invertBy(object);\n * // => { '1': ['a', 'c'], '2': ['b'] }\n *\n * _.invertBy(object, function(value) {\n * return 'group' + value;\n * });\n * // => { 'group1': ['a', 'c'], 'group2': ['b'] }\n */\n var invertBy = createInverter(function(result, value, key) {\n if (value != null &&\n typeof value.toString != 'function') {\n value = nativeObjectToString.call(value);\n }\n\n if (hasOwnProperty.call(result, value)) {\n result[value].push(key);\n } else {\n result[value] = [key];\n }\n }, getIteratee);\n\n /**\n * Invokes the method at `path` of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the method to invoke.\n * @param {...*} [args] The arguments to invoke the method with.\n * @returns {*} Returns the result of the invoked method.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };\n *\n * _.invoke(object, 'a[0].b.c.slice', 1, 3);\n * // => [2, 3]\n */\n var invoke = baseRest(baseInvoke);\n\n /**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\n function keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n }\n\n /**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\n function keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n }\n\n /**\n * The opposite of `_.mapValues`; this method creates an object with the\n * same values as `object` and keys generated by running each own enumerable\n * string keyed property of `object` thru `iteratee`. The iteratee is invoked\n * with three arguments: (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapValues\n * @example\n *\n * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {\n * return key + value;\n * });\n * // => { 'a1': 1, 'b2': 2 }\n */\n function mapKeys(object, iteratee) {\n var result = {};\n iteratee = getIteratee(iteratee, 3);\n\n baseForOwn(object, function(value, key, object) {\n baseAssignValue(result, iteratee(value, key, object), value);\n });\n return result;\n }\n\n /**\n * Creates an object with the same keys as `object` and values generated\n * by running each own enumerable string keyed property of `object` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapKeys\n * @example\n *\n * var users = {\n * 'fred': { 'user': 'fred', 'age': 40 },\n * 'pebbles': { 'user': 'pebbles', 'age': 1 }\n * };\n *\n * _.mapValues(users, function(o) { return o.age; });\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n *\n * // The `_.property` iteratee shorthand.\n * _.mapValues(users, 'age');\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n */\n function mapValues(object, iteratee) {\n var result = {};\n iteratee = getIteratee(iteratee, 3);\n\n baseForOwn(object, function(value, key, object) {\n baseAssignValue(result, key, iteratee(value, key, object));\n });\n return result;\n }\n\n /**\n * This method is like `_.assign` except that it recursively merges own and\n * inherited enumerable string keyed properties of source objects into the\n * destination object. Source properties that resolve to `undefined` are\n * skipped if a destination value exists. Array and plain object properties\n * are merged recursively. Other objects and value types are overridden by\n * assignment. Source objects are applied from left to right. Subsequent\n * sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {\n * 'a': [{ 'b': 2 }, { 'd': 4 }]\n * };\n *\n * var other = {\n * 'a': [{ 'c': 3 }, { 'e': 5 }]\n * };\n *\n * _.merge(object, other);\n * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n */\n var merge = createAssigner(function(object, source, srcIndex) {\n baseMerge(object, source, srcIndex);\n });\n\n /**\n * This method is like `_.merge` except that it accepts `customizer` which\n * is invoked to produce the merged values of the destination and source\n * properties. If `customizer` returns `undefined`, merging is handled by the\n * method instead. The `customizer` is invoked with six arguments:\n * (objValue, srcValue, key, object, source, stack).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} customizer The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * function customizer(objValue, srcValue) {\n * if (_.isArray(objValue)) {\n * return objValue.concat(srcValue);\n * }\n * }\n *\n * var object = { 'a': [1], 'b': [2] };\n * var other = { 'a': [3], 'b': [4] };\n *\n * _.mergeWith(object, other, customizer);\n * // => { 'a': [1, 3], 'b': [2, 4] }\n */\n var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n baseMerge(object, source, srcIndex, customizer);\n });\n\n /**\n * The opposite of `_.pick`; this method creates an object composed of the\n * own and inherited enumerable property paths of `object` that are not omitted.\n *\n * **Note:** This method is considerably slower than `_.pick`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to omit.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omit(object, ['a', 'c']);\n * // => { 'b': '2' }\n */\n var omit = flatRest(function(object, paths) {\n var result = {};\n if (object == null) {\n return result;\n }\n var isDeep = false;\n paths = arrayMap(paths, function(path) {\n path = castPath(path, object);\n isDeep || (isDeep = path.length > 1);\n return path;\n });\n copyObject(object, getAllKeysIn(object), result);\n if (isDeep) {\n result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n }\n var length = paths.length;\n while (length--) {\n baseUnset(result, paths[length]);\n }\n return result;\n });\n\n /**\n * The opposite of `_.pickBy`; this method creates an object composed of\n * the own and inherited enumerable string keyed properties of `object` that\n * `predicate` doesn't return truthy for. The predicate is invoked with two\n * arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omitBy(object, _.isNumber);\n * // => { 'b': '2' }\n */\n function omitBy(object, predicate) {\n return pickBy(object, negate(getIteratee(predicate)));\n }\n\n /**\n * Creates an object composed of the picked `object` properties.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pick(object, ['a', 'c']);\n * // => { 'a': 1, 'c': 3 }\n */\n var pick = flatRest(function(object, paths) {\n return object == null ? {} : basePick(object, paths);\n });\n\n /**\n * Creates an object composed of the `object` properties `predicate` returns\n * truthy for. The predicate is invoked with two arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pickBy(object, _.isNumber);\n * // => { 'a': 1, 'c': 3 }\n */\n function pickBy(object, predicate) {\n if (object == null) {\n return {};\n }\n var props = arrayMap(getAllKeysIn(object), function(prop) {\n return [prop];\n });\n predicate = getIteratee(predicate);\n return basePickBy(object, props, function(value, path) {\n return predicate(value, path[0]);\n });\n }\n\n /**\n * This method is like `_.get` except that if the resolved value is a\n * function it's invoked with the `this` binding of its parent object and\n * its result is returned.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to resolve.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };\n *\n * _.result(object, 'a[0].b.c1');\n * // => 3\n *\n * _.result(object, 'a[0].b.c2');\n * // => 4\n *\n * _.result(object, 'a[0].b.c3', 'default');\n * // => 'default'\n *\n * _.result(object, 'a[0].b.c3', _.constant('default'));\n * // => 'default'\n */\n function result(object, path, defaultValue) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length;\n\n // Ensure the loop is entered when path is empty.\n if (!length) {\n length = 1;\n object = undefined;\n }\n while (++index < length) {\n var value = object == null ? undefined : object[toKey(path[index])];\n if (value === undefined) {\n index = length;\n value = defaultValue;\n }\n object = isFunction(value) ? value.call(object) : value;\n }\n return object;\n }\n\n /**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\n function set(object, path, value) {\n return object == null ? object : baseSet(object, path, value);\n }\n\n /**\n * This method is like `_.set` except that it accepts `customizer` which is\n * invoked to produce the objects of `path`. If `customizer` returns `undefined`\n * path creation is handled by the method instead. The `customizer` is invoked\n * with three arguments: (nsValue, key, nsObject).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {};\n *\n * _.setWith(object, '[0][1]', 'a', Object);\n * // => { '0': { '1': 'a' } }\n */\n function setWith(object, path, value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return object == null ? object : baseSet(object, path, value, customizer);\n }\n\n /**\n * Creates an array of own enumerable string keyed-value pairs for `object`\n * which can be consumed by `_.fromPairs`. If `object` is a map or set, its\n * entries are returned.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias entries\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the key-value pairs.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.toPairs(new Foo);\n * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)\n */\n var toPairs = createToPairs(keys);\n\n /**\n * Creates an array of own and inherited enumerable string keyed-value pairs\n * for `object` which can be consumed by `_.fromPairs`. If `object` is a map\n * or set, its entries are returned.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias entriesIn\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the key-value pairs.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.toPairsIn(new Foo);\n * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)\n */\n var toPairsIn = createToPairs(keysIn);\n\n /**\n * An alternative to `_.reduce`; this method transforms `object` to a new\n * `accumulator` object which is the result of running each of its own\n * enumerable string keyed properties thru `iteratee`, with each invocation\n * potentially mutating the `accumulator` object. If `accumulator` is not\n * provided, a new object with the same `[[Prototype]]` will be used. The\n * iteratee is invoked with four arguments: (accumulator, value, key, object).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 1.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The custom accumulator value.\n * @returns {*} Returns the accumulated value.\n * @example\n *\n * _.transform([2, 3, 4], function(result, n) {\n * result.push(n *= n);\n * return n % 2 == 0;\n * }, []);\n * // => [4, 9]\n *\n * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n * (result[value] || (result[value] = [])).push(key);\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] }\n */\n function transform(object, iteratee, accumulator) {\n var isArr = isArray(object),\n isArrLike = isArr || isBuffer(object) || isTypedArray(object);\n\n iteratee = getIteratee(iteratee, 4);\n if (accumulator == null) {\n var Ctor = object && object.constructor;\n if (isArrLike) {\n accumulator = isArr ? new Ctor : [];\n }\n else if (isObject(object)) {\n accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};\n }\n else {\n accumulator = {};\n }\n }\n (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {\n return iteratee(accumulator, value, index, object);\n });\n return accumulator;\n }\n\n /**\n * Removes the property at `path` of `object`.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 7 } }] };\n * _.unset(object, 'a[0].b.c');\n * // => true\n *\n * console.log(object);\n * // => { 'a': [{ 'b': {} }] };\n *\n * _.unset(object, ['a', '0', 'b', 'c']);\n * // => true\n *\n * console.log(object);\n * // => { 'a': [{ 'b': {} }] };\n */\n function unset(object, path) {\n return object == null ? true : baseUnset(object, path);\n }\n\n /**\n * This method is like `_.set` except that accepts `updater` to produce the\n * value to set. Use `_.updateWith` to customize `path` creation. The `updater`\n * is invoked with one argument: (value).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {Function} updater The function to produce the updated value.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.update(object, 'a[0].b.c', function(n) { return n * n; });\n * console.log(object.a[0].b.c);\n * // => 9\n *\n * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });\n * console.log(object.x[0].y.z);\n * // => 0\n */\n function update(object, path, updater) {\n return object == null ? object : baseUpdate(object, path, castFunction(updater));\n }\n\n /**\n * This method is like `_.update` except that it accepts `customizer` which is\n * invoked to produce the objects of `path`. If `customizer` returns `undefined`\n * path creation is handled by the method instead. The `customizer` is invoked\n * with three arguments: (nsValue, key, nsObject).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {Function} updater The function to produce the updated value.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {};\n *\n * _.updateWith(object, '[0][1]', _.constant('a'), Object);\n * // => { '0': { '1': 'a' } }\n */\n function updateWith(object, path, updater, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);\n }\n\n /**\n * Creates an array of the own enumerable string keyed property values of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property values.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.values(new Foo);\n * // => [1, 2] (iteration order is not guaranteed)\n *\n * _.values('hi');\n * // => ['h', 'i']\n */\n function values(object) {\n return object == null ? [] : baseValues(object, keys(object));\n }\n\n /**\n * Creates an array of the own and inherited enumerable string keyed property\n * values of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property values.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.valuesIn(new Foo);\n * // => [1, 2, 3] (iteration order is not guaranteed)\n */\n function valuesIn(object) {\n return object == null ? [] : baseValues(object, keysIn(object));\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Clamps `number` within the inclusive `lower` and `upper` bounds.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Number\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n * @example\n *\n * _.clamp(-10, -5, 5);\n * // => -5\n *\n * _.clamp(10, -5, 5);\n * // => 5\n */\n function clamp(number, lower, upper) {\n if (upper === undefined) {\n upper = lower;\n lower = undefined;\n }\n if (upper !== undefined) {\n upper = toNumber(upper);\n upper = upper === upper ? upper : 0;\n }\n if (lower !== undefined) {\n lower = toNumber(lower);\n lower = lower === lower ? lower : 0;\n }\n return baseClamp(toNumber(number), lower, upper);\n }\n\n /**\n * Checks if `n` is between `start` and up to, but not including, `end`. If\n * `end` is not specified, it's set to `start` with `start` then set to `0`.\n * If `start` is greater than `end` the params are swapped to support\n * negative ranges.\n *\n * @static\n * @memberOf _\n * @since 3.3.0\n * @category Number\n * @param {number} number The number to check.\n * @param {number} [start=0] The start of the range.\n * @param {number} end The end of the range.\n * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n * @see _.range, _.rangeRight\n * @example\n *\n * _.inRange(3, 2, 4);\n * // => true\n *\n * _.inRange(4, 8);\n * // => true\n *\n * _.inRange(4, 2);\n * // => false\n *\n * _.inRange(2, 2);\n * // => false\n *\n * _.inRange(1.2, 2);\n * // => true\n *\n * _.inRange(5.2, 4);\n * // => false\n *\n * _.inRange(-3, -2, -6);\n * // => true\n */\n function inRange(number, start, end) {\n start = toFinite(start);\n if (end === undefined) {\n end = start;\n start = 0;\n } else {\n end = toFinite(end);\n }\n number = toNumber(number);\n return baseInRange(number, start, end);\n }\n\n /**\n * Produces a random number between the inclusive `lower` and `upper` bounds.\n * If only one argument is provided a number between `0` and the given number\n * is returned. If `floating` is `true`, or either `lower` or `upper` are\n * floats, a floating-point number is returned instead of an integer.\n *\n * **Note:** JavaScript follows the IEEE-754 standard for resolving\n * floating-point values which can produce unexpected results.\n *\n * **Note:** If `lower` is greater than `upper`, the values are swapped.\n *\n * @static\n * @memberOf _\n * @since 0.7.0\n * @category Number\n * @param {number} [lower=0] The lower bound.\n * @param {number} [upper=1] The upper bound.\n * @param {boolean} [floating] Specify returning a floating-point number.\n * @returns {number} Returns the random number.\n * @example\n *\n * _.random(0, 5);\n * // => an integer between 0 and 5\n *\n * // when lower is greater than upper the values are swapped\n * _.random(5, 0);\n * // => an integer between 0 and 5\n *\n * _.random(5);\n * // => also an integer between 0 and 5\n *\n * _.random(-5);\n * // => an integer between -5 and 0\n *\n * _.random(5, true);\n * // => a floating-point number between 0 and 5\n *\n * _.random(1.2, 5.2);\n * // => a floating-point number between 1.2 and 5.2\n */\n function random(lower, upper, floating) {\n if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {\n upper = floating = undefined;\n }\n if (floating === undefined) {\n if (typeof upper == 'boolean') {\n floating = upper;\n upper = undefined;\n }\n else if (typeof lower == 'boolean') {\n floating = lower;\n lower = undefined;\n }\n }\n if (lower === undefined && upper === undefined) {\n lower = 0;\n upper = 1;\n }\n else {\n lower = toFinite(lower);\n if (upper === undefined) {\n upper = lower;\n lower = 0;\n } else {\n upper = toFinite(upper);\n }\n }\n if (lower > upper) {\n var temp = lower;\n lower = upper;\n upper = temp;\n }\n if (floating || lower % 1 || upper % 1) {\n var rand = nativeRandom();\n return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);\n }\n return baseRandom(lower, upper);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the camel cased string.\n * @example\n *\n * _.camelCase('Foo Bar');\n * // => 'fooBar'\n *\n * _.camelCase('--foo-bar--');\n * // => 'fooBar'\n *\n * _.camelCase('__FOO_BAR__');\n * // => 'fooBar'\n */\n var camelCase = createCompounder(function(result, word, index) {\n word = word.toLowerCase();\n return result + (index ? capitalize(word) : word);\n });\n\n /**\n * Converts the first character of `string` to upper case and the remaining\n * to lower case.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to capitalize.\n * @returns {string} Returns the capitalized string.\n * @example\n *\n * _.capitalize('FRED');\n * // => 'Fred'\n */\n function capitalize(string) {\n return upperFirst(toString(string).toLowerCase());\n }\n\n /**\n * Deburrs `string` by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to deburr.\n * @returns {string} Returns the deburred string.\n * @example\n *\n * _.deburr('d\u00E9j\u00E0 vu');\n * // => 'deja vu'\n */\n function deburr(string) {\n string = toString(string);\n return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n }\n\n /**\n * Checks if `string` ends with the given target string.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {string} [target] The string to search for.\n * @param {number} [position=string.length] The position to search up to.\n * @returns {boolean} Returns `true` if `string` ends with `target`,\n * else `false`.\n * @example\n *\n * _.endsWith('abc', 'c');\n * // => true\n *\n * _.endsWith('abc', 'b');\n * // => false\n *\n * _.endsWith('abc', 'b', 2);\n * // => true\n */\n function endsWith(string, target, position) {\n string = toString(string);\n target = baseToString(target);\n\n var length = string.length;\n position = position === undefined\n ? length\n : baseClamp(toInteger(position), 0, length);\n\n var end = position;\n position -= target.length;\n return position >= 0 && string.slice(position, end) == target;\n }\n\n /**\n * Converts the characters \"&\", \"<\", \">\", '\"', and \"'\" in `string` to their\n * corresponding HTML entities.\n *\n * **Note:** No other characters are escaped. To escape additional\n * characters use a third-party library like [_he_](https://mths.be/he).\n *\n * Though the \">\" character is escaped for symmetry, characters like\n * \">\" and \"/\" don't need escaping in HTML and have no special meaning\n * unless they're part of a tag or unquoted attribute value. See\n * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)\n * (under \"semi-related fun fact\") for more details.\n *\n * When working with HTML you should always\n * [quote attribute values](http://wonko.com/post/html-escaping) to reduce\n * XSS vectors.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category String\n * @param {string} [string=''] The string to escape.\n * @returns {string} Returns the escaped string.\n * @example\n *\n * _.escape('fred, barney, & pebbles');\n * // => 'fred, barney, & pebbles'\n */\n function escape(string) {\n string = toString(string);\n return (string && reHasUnescapedHtml.test(string))\n ? string.replace(reUnescapedHtml, escapeHtmlChar)\n : string;\n }\n\n /**\n * Escapes the `RegExp` special characters \"^\", \"$\", \"\\\", \".\", \"*\", \"+\",\n * \"?\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", and \"|\" in `string`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to escape.\n * @returns {string} Returns the escaped string.\n * @example\n *\n * _.escapeRegExp('[lodash](https://lodash.com/)');\n * // => '\\[lodash\\]\\(https://lodash\\.com/\\)'\n */\n function escapeRegExp(string) {\n string = toString(string);\n return (string && reHasRegExpChar.test(string))\n ? string.replace(reRegExpChar, '\\\\$&')\n : string;\n }\n\n /**\n * Converts `string` to\n * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the kebab cased string.\n * @example\n *\n * _.kebabCase('Foo Bar');\n * // => 'foo-bar'\n *\n * _.kebabCase('fooBar');\n * // => 'foo-bar'\n *\n * _.kebabCase('__FOO_BAR__');\n * // => 'foo-bar'\n */\n var kebabCase = createCompounder(function(result, word, index) {\n return result + (index ? '-' : '') + word.toLowerCase();\n });\n\n /**\n * Converts `string`, as space separated words, to lower case.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the lower cased string.\n * @example\n *\n * _.lowerCase('--Foo-Bar--');\n * // => 'foo bar'\n *\n * _.lowerCase('fooBar');\n * // => 'foo bar'\n *\n * _.lowerCase('__FOO_BAR__');\n * // => 'foo bar'\n */\n var lowerCase = createCompounder(function(result, word, index) {\n return result + (index ? ' ' : '') + word.toLowerCase();\n });\n\n /**\n * Converts the first character of `string` to lower case.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.lowerFirst('Fred');\n * // => 'fred'\n *\n * _.lowerFirst('FRED');\n * // => 'fRED'\n */\n var lowerFirst = createCaseFirst('toLowerCase');\n\n /**\n * Pads `string` on the left and right sides if it's shorter than `length`.\n * Padding characters are truncated if they can't be evenly divided by `length`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.pad('abc', 8);\n * // => ' abc '\n *\n * _.pad('abc', 8, '_-');\n * // => '_-abc_-_'\n *\n * _.pad('abc', 3);\n * // => 'abc'\n */\n function pad(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n if (!length || strLength >= length) {\n return string;\n }\n var mid = (length - strLength) / 2;\n return (\n createPadding(nativeFloor(mid), chars) +\n string +\n createPadding(nativeCeil(mid), chars)\n );\n }\n\n /**\n * Pads `string` on the right side if it's shorter than `length`. Padding\n * characters are truncated if they exceed `length`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.padEnd('abc', 6);\n * // => 'abc '\n *\n * _.padEnd('abc', 6, '_-');\n * // => 'abc_-_'\n *\n * _.padEnd('abc', 3);\n * // => 'abc'\n */\n function padEnd(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n return (length && strLength < length)\n ? (string + createPadding(length - strLength, chars))\n : string;\n }\n\n /**\n * Pads `string` on the left side if it's shorter than `length`. Padding\n * characters are truncated if they exceed `length`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.padStart('abc', 6);\n * // => ' abc'\n *\n * _.padStart('abc', 6, '_-');\n * // => '_-_abc'\n *\n * _.padStart('abc', 3);\n * // => 'abc'\n */\n function padStart(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n return (length && strLength < length)\n ? (createPadding(length - strLength, chars) + string)\n : string;\n }\n\n /**\n * Converts `string` to an integer of the specified radix. If `radix` is\n * `undefined` or `0`, a `radix` of `10` is used unless `value` is a\n * hexadecimal, in which case a `radix` of `16` is used.\n *\n * **Note:** This method aligns with the\n * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category String\n * @param {string} string The string to convert.\n * @param {number} [radix=10] The radix to interpret `value` by.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.parseInt('08');\n * // => 8\n *\n * _.map(['6', '08', '10'], _.parseInt);\n * // => [6, 8, 10]\n */\n function parseInt(string, radix, guard) {\n if (guard || radix == null) {\n radix = 0;\n } else if (radix) {\n radix = +radix;\n }\n return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);\n }\n\n /**\n * Repeats the given string `n` times.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to repeat.\n * @param {number} [n=1] The number of times to repeat the string.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {string} Returns the repeated string.\n * @example\n *\n * _.repeat('*', 3);\n * // => '***'\n *\n * _.repeat('abc', 2);\n * // => 'abcabc'\n *\n * _.repeat('abc', 0);\n * // => ''\n */\n function repeat(string, n, guard) {\n if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {\n n = 1;\n } else {\n n = toInteger(n);\n }\n return baseRepeat(toString(string), n);\n }\n\n /**\n * Replaces matches for `pattern` in `string` with `replacement`.\n *\n * **Note:** This method is based on\n * [`String#replace`](https://mdn.io/String/replace).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to modify.\n * @param {RegExp|string} pattern The pattern to replace.\n * @param {Function|string} replacement The match replacement.\n * @returns {string} Returns the modified string.\n * @example\n *\n * _.replace('Hi Fred', 'Fred', 'Barney');\n * // => 'Hi Barney'\n */\n function replace() {\n var args = arguments,\n string = toString(args[0]);\n\n return args.length < 3 ? string : string.replace(args[1], args[2]);\n }\n\n /**\n * Converts `string` to\n * [snake case](https://en.wikipedia.org/wiki/Snake_case).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the snake cased string.\n * @example\n *\n * _.snakeCase('Foo Bar');\n * // => 'foo_bar'\n *\n * _.snakeCase('fooBar');\n * // => 'foo_bar'\n *\n * _.snakeCase('--FOO-BAR--');\n * // => 'foo_bar'\n */\n var snakeCase = createCompounder(function(result, word, index) {\n return result + (index ? '_' : '') + word.toLowerCase();\n });\n\n /**\n * Splits `string` by `separator`.\n *\n * **Note:** This method is based on\n * [`String#split`](https://mdn.io/String/split).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to split.\n * @param {RegExp|string} separator The separator pattern to split by.\n * @param {number} [limit] The length to truncate results to.\n * @returns {Array} Returns the string segments.\n * @example\n *\n * _.split('a-b-c', '-', 2);\n * // => ['a', 'b']\n */\n function split(string, separator, limit) {\n if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {\n separator = limit = undefined;\n }\n limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;\n if (!limit) {\n return [];\n }\n string = toString(string);\n if (string && (\n typeof separator == 'string' ||\n (separator != null && !isRegExp(separator))\n )) {\n separator = baseToString(separator);\n if (!separator && hasUnicode(string)) {\n return castSlice(stringToArray(string), 0, limit);\n }\n }\n return string.split(separator, limit);\n }\n\n /**\n * Converts `string` to\n * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).\n *\n * @static\n * @memberOf _\n * @since 3.1.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the start cased string.\n * @example\n *\n * _.startCase('--foo-bar--');\n * // => 'Foo Bar'\n *\n * _.startCase('fooBar');\n * // => 'Foo Bar'\n *\n * _.startCase('__FOO_BAR__');\n * // => 'FOO BAR'\n */\n var startCase = createCompounder(function(result, word, index) {\n return result + (index ? ' ' : '') + upperFirst(word);\n });\n\n /**\n * Checks if `string` starts with the given target string.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {string} [target] The string to search for.\n * @param {number} [position=0] The position to search from.\n * @returns {boolean} Returns `true` if `string` starts with `target`,\n * else `false`.\n * @example\n *\n * _.startsWith('abc', 'a');\n * // => true\n *\n * _.startsWith('abc', 'b');\n * // => false\n *\n * _.startsWith('abc', 'b', 1);\n * // => true\n */\n function startsWith(string, target, position) {\n string = toString(string);\n position = position == null\n ? 0\n : baseClamp(toInteger(position), 0, string.length);\n\n target = baseToString(target);\n return string.slice(position, position + target.length) == target;\n }\n\n /**\n * Creates a compiled template function that can interpolate data properties\n * in \"interpolate\" delimiters, HTML-escape interpolated data properties in\n * \"escape\" delimiters, and execute JavaScript in \"evaluate\" delimiters. Data\n * properties may be accessed as free variables in the template. If a setting\n * object is given, it takes precedence over `_.templateSettings` values.\n *\n * **Security:** `_.template` is insecure and should not be used. It will be\n * removed in Lodash v5. Avoid untrusted input. See\n * [threat model](https://github.com/lodash/lodash/blob/main/threat-model.md).\n *\n * **Note:** In the development build `_.template` utilizes\n * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)\n * for easier debugging.\n *\n * For more information on precompiling templates see\n * [lodash's custom builds documentation](https://lodash.com/custom-builds).\n *\n * For more information on Chrome extension sandboxes see\n * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category String\n * @param {string} [string=''] The template string.\n * @param {Object} [options={}] The options object.\n * @param {RegExp} [options.escape=_.templateSettings.escape]\n * The HTML \"escape\" delimiter.\n * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]\n * The \"evaluate\" delimiter.\n * @param {Object} [options.imports=_.templateSettings.imports]\n * An object to import into the template as free variables.\n * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]\n * The \"interpolate\" delimiter.\n * @param {string} [options.sourceURL='lodash.templateSources[n]']\n * The sourceURL of the compiled template.\n * @param {string} [options.variable='obj']\n * The data object variable name.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the compiled template function.\n * @example\n *\n * // Use the \"interpolate\" delimiter to create a compiled template.\n * var compiled = _.template('hello <%= user %>!');\n * compiled({ 'user': 'fred' });\n * // => 'hello fred!'\n *\n * // Use the HTML \"escape\" delimiter to escape data property values.\n * var compiled = _.template('<%- value %>');\n * compiled({ 'value': '\n * ^\n * ```\n *\n * @type {State}\n */\n function continuationRawTagOpen(code) {\n if (code === 47) {\n effects.consume(code);\n buffer = '';\n return continuationRawEndTag;\n }\n return continuation(code);\n }\n\n /**\n * In raw continuation, after ` | \n * ^^^^^^\n * ```\n *\n * @type {State}\n */\n function continuationRawEndTag(code) {\n if (code === 62) {\n const name = buffer.toLowerCase();\n if (htmlRawNames.includes(name)) {\n effects.consume(code);\n return continuationClose;\n }\n return continuation(code);\n }\n if (asciiAlpha(code) && buffer.length < 8) {\n // Always the case.\n effects.consume(code);\n buffer += String.fromCharCode(code);\n return continuationRawEndTag;\n }\n return continuation(code);\n }\n\n /**\n * In cdata continuation, after `]`, expecting `]>`.\n *\n * ```markdown\n * > | &<]]>\n * ^\n * ```\n *\n * @type {State}\n */\n function continuationCdataInside(code) {\n if (code === 93) {\n effects.consume(code);\n return continuationDeclarationInside;\n }\n return continuation(code);\n }\n\n /**\n * In declaration or instruction continuation, at `>`.\n *\n * ```markdown\n * > | \n * ^\n * > | \n * ^\n * > | \n * ^\n * > | \n * ^\n * > | &<]]>\n * ^\n * ```\n *\n * @type {State}\n */\n function continuationDeclarationInside(code) {\n if (code === 62) {\n effects.consume(code);\n return continuationClose;\n }\n\n // More dashes.\n if (code === 45 && marker === 2) {\n effects.consume(code);\n return continuationDeclarationInside;\n }\n return continuation(code);\n }\n\n /**\n * In closed continuation: everything we get until the eol/eof is part of it.\n *\n * ```markdown\n * > | \n * ^\n * ```\n *\n * @type {State}\n */\n function continuationClose(code) {\n if (code === null || markdownLineEnding(code)) {\n effects.exit(\"htmlFlowData\");\n return continuationAfter(code);\n }\n effects.consume(code);\n return continuationClose;\n }\n\n /**\n * Done.\n *\n * ```markdown\n * > | \n * ^\n * ```\n *\n * @type {State}\n */\n function continuationAfter(code) {\n effects.exit(\"htmlFlow\");\n // // Feel free to interrupt.\n // tokenizer.interrupt = false\n // // No longer concrete.\n // tokenizer.concrete = false\n return ok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeNonLazyContinuationStart(effects, ok, nok) {\n const self = this;\n return start;\n\n /**\n * At eol, before continuation.\n *\n * ```markdown\n * > | * ```js\n * ^\n * | b\n * ```\n *\n * @type {State}\n */\n function start(code) {\n if (markdownLineEnding(code)) {\n effects.enter(\"lineEnding\");\n effects.consume(code);\n effects.exit(\"lineEnding\");\n return after;\n }\n return nok(code);\n }\n\n /**\n * A continuation.\n *\n * ```markdown\n * | * ```js\n * > | b\n * ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n return self.parser.lazy[self.now().line] ? nok(code) : ok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeBlankLineBefore(effects, ok, nok) {\n return start;\n\n /**\n * Before eol, expecting blank line.\n *\n * ```markdown\n * > |
    \n * ^\n * |\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter(\"lineEnding\");\n effects.consume(code);\n effects.exit(\"lineEnding\");\n return effects.attempt(blankLine, ok, nok);\n }\n}", "/**\n * @import {\n * Code,\n * Construct,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { asciiAlphanumeric, asciiAlpha, markdownLineEndingOrSpace, markdownLineEnding, markdownSpace } from 'micromark-util-character';\n/** @type {Construct} */\nexport const htmlText = {\n name: 'htmlText',\n tokenize: tokenizeHtmlText\n};\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeHtmlText(effects, ok, nok) {\n const self = this;\n /** @type {NonNullable | undefined} */\n let marker;\n /** @type {number} */\n let index;\n /** @type {State} */\n let returnState;\n return start;\n\n /**\n * Start of HTML (text).\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter(\"htmlText\");\n effects.enter(\"htmlTextData\");\n effects.consume(code);\n return open;\n }\n\n /**\n * After `<`, at tag name or other stuff.\n *\n * ```markdown\n * > | a c\n * ^\n * > | a c\n * ^\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function open(code) {\n if (code === 33) {\n effects.consume(code);\n return declarationOpen;\n }\n if (code === 47) {\n effects.consume(code);\n return tagCloseStart;\n }\n if (code === 63) {\n effects.consume(code);\n return instruction;\n }\n\n // ASCII alphabetical.\n if (asciiAlpha(code)) {\n effects.consume(code);\n return tagOpen;\n }\n return nok(code);\n }\n\n /**\n * After ` | a c\n * ^\n * > | a c\n * ^\n * > | a &<]]> c\n * ^\n * ```\n *\n * @type {State}\n */\n function declarationOpen(code) {\n if (code === 45) {\n effects.consume(code);\n return commentOpenInside;\n }\n if (code === 91) {\n effects.consume(code);\n index = 0;\n return cdataOpenInside;\n }\n if (asciiAlpha(code)) {\n effects.consume(code);\n return declaration;\n }\n return nok(code);\n }\n\n /**\n * In a comment, after ` | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function commentOpenInside(code) {\n if (code === 45) {\n effects.consume(code);\n return commentEnd;\n }\n return nok(code);\n }\n\n /**\n * In comment.\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function comment(code) {\n if (code === null) {\n return nok(code);\n }\n if (code === 45) {\n effects.consume(code);\n return commentClose;\n }\n if (markdownLineEnding(code)) {\n returnState = comment;\n return lineEndingBefore(code);\n }\n effects.consume(code);\n return comment;\n }\n\n /**\n * In comment, after `-`.\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function commentClose(code) {\n if (code === 45) {\n effects.consume(code);\n return commentEnd;\n }\n return comment(code);\n }\n\n /**\n * In comment, after `--`.\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function commentEnd(code) {\n return code === 62 ? end(code) : code === 45 ? commentClose(code) : comment(code);\n }\n\n /**\n * After ` | a &<]]> b\n * ^^^^^^\n * ```\n *\n * @type {State}\n */\n function cdataOpenInside(code) {\n const value = \"CDATA[\";\n if (code === value.charCodeAt(index++)) {\n effects.consume(code);\n return index === value.length ? cdata : cdataOpenInside;\n }\n return nok(code);\n }\n\n /**\n * In CDATA.\n *\n * ```markdown\n * > | a &<]]> b\n * ^^^\n * ```\n *\n * @type {State}\n */\n function cdata(code) {\n if (code === null) {\n return nok(code);\n }\n if (code === 93) {\n effects.consume(code);\n return cdataClose;\n }\n if (markdownLineEnding(code)) {\n returnState = cdata;\n return lineEndingBefore(code);\n }\n effects.consume(code);\n return cdata;\n }\n\n /**\n * In CDATA, after `]`, at another `]`.\n *\n * ```markdown\n * > | a &<]]> b\n * ^\n * ```\n *\n * @type {State}\n */\n function cdataClose(code) {\n if (code === 93) {\n effects.consume(code);\n return cdataEnd;\n }\n return cdata(code);\n }\n\n /**\n * In CDATA, after `]]`, at `>`.\n *\n * ```markdown\n * > | a &<]]> b\n * ^\n * ```\n *\n * @type {State}\n */\n function cdataEnd(code) {\n if (code === 62) {\n return end(code);\n }\n if (code === 93) {\n effects.consume(code);\n return cdataEnd;\n }\n return cdata(code);\n }\n\n /**\n * In declaration.\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function declaration(code) {\n if (code === null || code === 62) {\n return end(code);\n }\n if (markdownLineEnding(code)) {\n returnState = declaration;\n return lineEndingBefore(code);\n }\n effects.consume(code);\n return declaration;\n }\n\n /**\n * In instruction.\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function instruction(code) {\n if (code === null) {\n return nok(code);\n }\n if (code === 63) {\n effects.consume(code);\n return instructionClose;\n }\n if (markdownLineEnding(code)) {\n returnState = instruction;\n return lineEndingBefore(code);\n }\n effects.consume(code);\n return instruction;\n }\n\n /**\n * In instruction, after `?`, at `>`.\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function instructionClose(code) {\n return code === 62 ? end(code) : instruction(code);\n }\n\n /**\n * After ` | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function tagCloseStart(code) {\n // ASCII alphabetical.\n if (asciiAlpha(code)) {\n effects.consume(code);\n return tagClose;\n }\n return nok(code);\n }\n\n /**\n * After ` | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function tagClose(code) {\n // ASCII alphanumerical and `-`.\n if (code === 45 || asciiAlphanumeric(code)) {\n effects.consume(code);\n return tagClose;\n }\n return tagCloseBetween(code);\n }\n\n /**\n * In closing tag, after tag name.\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function tagCloseBetween(code) {\n if (markdownLineEnding(code)) {\n returnState = tagCloseBetween;\n return lineEndingBefore(code);\n }\n if (markdownSpace(code)) {\n effects.consume(code);\n return tagCloseBetween;\n }\n return end(code);\n }\n\n /**\n * After ` | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function tagOpen(code) {\n // ASCII alphanumerical and `-`.\n if (code === 45 || asciiAlphanumeric(code)) {\n effects.consume(code);\n return tagOpen;\n }\n if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {\n return tagOpenBetween(code);\n }\n return nok(code);\n }\n\n /**\n * In opening tag, after tag name.\n *\n * ```markdown\n * > | a c\n * ^\n * ```\n *\n * @type {State}\n */\n function tagOpenBetween(code) {\n if (code === 47) {\n effects.consume(code);\n return end;\n }\n\n // ASCII alphabetical and `:` and `_`.\n if (code === 58 || code === 95 || asciiAlpha(code)) {\n effects.consume(code);\n return tagOpenAttributeName;\n }\n if (markdownLineEnding(code)) {\n returnState = tagOpenBetween;\n return lineEndingBefore(code);\n }\n if (markdownSpace(code)) {\n effects.consume(code);\n return tagOpenBetween;\n }\n return end(code);\n }\n\n /**\n * In attribute name.\n *\n * ```markdown\n * > | a d\n * ^\n * ```\n *\n * @type {State}\n */\n function tagOpenAttributeName(code) {\n // ASCII alphabetical and `-`, `.`, `:`, and `_`.\n if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric(code)) {\n effects.consume(code);\n return tagOpenAttributeName;\n }\n return tagOpenAttributeNameAfter(code);\n }\n\n /**\n * After attribute name, before initializer, the end of the tag, or\n * whitespace.\n *\n * ```markdown\n * > | a d\n * ^\n * ```\n *\n * @type {State}\n */\n function tagOpenAttributeNameAfter(code) {\n if (code === 61) {\n effects.consume(code);\n return tagOpenAttributeValueBefore;\n }\n if (markdownLineEnding(code)) {\n returnState = tagOpenAttributeNameAfter;\n return lineEndingBefore(code);\n }\n if (markdownSpace(code)) {\n effects.consume(code);\n return tagOpenAttributeNameAfter;\n }\n return tagOpenBetween(code);\n }\n\n /**\n * Before unquoted, double quoted, or single quoted attribute value, allowing\n * whitespace.\n *\n * ```markdown\n * > | a e\n * ^\n * ```\n *\n * @type {State}\n */\n function tagOpenAttributeValueBefore(code) {\n if (code === null || code === 60 || code === 61 || code === 62 || code === 96) {\n return nok(code);\n }\n if (code === 34 || code === 39) {\n effects.consume(code);\n marker = code;\n return tagOpenAttributeValueQuoted;\n }\n if (markdownLineEnding(code)) {\n returnState = tagOpenAttributeValueBefore;\n return lineEndingBefore(code);\n }\n if (markdownSpace(code)) {\n effects.consume(code);\n return tagOpenAttributeValueBefore;\n }\n effects.consume(code);\n return tagOpenAttributeValueUnquoted;\n }\n\n /**\n * In double or single quoted attribute value.\n *\n * ```markdown\n * > | a e\n * ^\n * ```\n *\n * @type {State}\n */\n function tagOpenAttributeValueQuoted(code) {\n if (code === marker) {\n effects.consume(code);\n marker = undefined;\n return tagOpenAttributeValueQuotedAfter;\n }\n if (code === null) {\n return nok(code);\n }\n if (markdownLineEnding(code)) {\n returnState = tagOpenAttributeValueQuoted;\n return lineEndingBefore(code);\n }\n effects.consume(code);\n return tagOpenAttributeValueQuoted;\n }\n\n /**\n * In unquoted attribute value.\n *\n * ```markdown\n * > | a e\n * ^\n * ```\n *\n * @type {State}\n */\n function tagOpenAttributeValueUnquoted(code) {\n if (code === null || code === 34 || code === 39 || code === 60 || code === 61 || code === 96) {\n return nok(code);\n }\n if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {\n return tagOpenBetween(code);\n }\n effects.consume(code);\n return tagOpenAttributeValueUnquoted;\n }\n\n /**\n * After double or single quoted attribute value, before whitespace or the end\n * of the tag.\n *\n * ```markdown\n * > | a e\n * ^\n * ```\n *\n * @type {State}\n */\n function tagOpenAttributeValueQuotedAfter(code) {\n if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {\n return tagOpenBetween(code);\n }\n return nok(code);\n }\n\n /**\n * In certain circumstances of a tag where only an `>` is allowed.\n *\n * ```markdown\n * > | a e\n * ^\n * ```\n *\n * @type {State}\n */\n function end(code) {\n if (code === 62) {\n effects.consume(code);\n effects.exit(\"htmlTextData\");\n effects.exit(\"htmlText\");\n return ok;\n }\n return nok(code);\n }\n\n /**\n * At eol.\n *\n * > \uD83D\uDC49 **Note**: we can\u2019t have blank lines in text, so no need to worry about\n * > empty tokens.\n *\n * ```markdown\n * > | a \n * ```\n *\n * @type {State}\n */\n function lineEndingBefore(code) {\n effects.exit(\"htmlTextData\");\n effects.enter(\"lineEnding\");\n effects.consume(code);\n effects.exit(\"lineEnding\");\n return lineEndingAfter;\n }\n\n /**\n * After eol, at optional whitespace.\n *\n * > \uD83D\uDC49 **Note**: we can\u2019t have blank lines in text, so no need to worry about\n * > empty tokens.\n *\n * ```markdown\n * | a \n * ^\n * ```\n *\n * @type {State}\n */\n function lineEndingAfter(code) {\n // Always populated by defaults.\n\n return markdownSpace(code) ? factorySpace(effects, lineEndingAfterPrefix, \"linePrefix\", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code) : lineEndingAfterPrefix(code);\n }\n\n /**\n * After eol, after optional whitespace.\n *\n * > \uD83D\uDC49 **Note**: we can\u2019t have blank lines in text, so no need to worry about\n * > empty tokens.\n *\n * ```markdown\n * | a \n * ^\n * ```\n *\n * @type {State}\n */\n function lineEndingAfterPrefix(code) {\n effects.enter(\"htmlTextData\");\n return returnState(code);\n }\n}", "/**\n * @import {\n * Construct,\n * Event,\n * Resolver,\n * State,\n * TokenizeContext,\n * Tokenizer,\n * Token\n * } from 'micromark-util-types'\n */\n\nimport { factoryDestination } from 'micromark-factory-destination';\nimport { factoryLabel } from 'micromark-factory-label';\nimport { factoryTitle } from 'micromark-factory-title';\nimport { factoryWhitespace } from 'micromark-factory-whitespace';\nimport { markdownLineEndingOrSpace } from 'micromark-util-character';\nimport { push, splice } from 'micromark-util-chunked';\nimport { normalizeIdentifier } from 'micromark-util-normalize-identifier';\nimport { resolveAll } from 'micromark-util-resolve-all';\n/** @type {Construct} */\nexport const labelEnd = {\n name: 'labelEnd',\n resolveAll: resolveAllLabelEnd,\n resolveTo: resolveToLabelEnd,\n tokenize: tokenizeLabelEnd\n};\n\n/** @type {Construct} */\nconst resourceConstruct = {\n tokenize: tokenizeResource\n};\n/** @type {Construct} */\nconst referenceFullConstruct = {\n tokenize: tokenizeReferenceFull\n};\n/** @type {Construct} */\nconst referenceCollapsedConstruct = {\n tokenize: tokenizeReferenceCollapsed\n};\n\n/** @type {Resolver} */\nfunction resolveAllLabelEnd(events) {\n let index = -1;\n /** @type {Array} */\n const newEvents = [];\n while (++index < events.length) {\n const token = events[index][1];\n newEvents.push(events[index]);\n if (token.type === \"labelImage\" || token.type === \"labelLink\" || token.type === \"labelEnd\") {\n // Remove the marker.\n const offset = token.type === \"labelImage\" ? 4 : 2;\n token.type = \"data\";\n index += offset;\n }\n }\n\n // If the events are equal, we don't have to copy newEvents to events\n if (events.length !== newEvents.length) {\n splice(events, 0, events.length, newEvents);\n }\n return events;\n}\n\n/** @type {Resolver} */\nfunction resolveToLabelEnd(events, context) {\n let index = events.length;\n let offset = 0;\n /** @type {Token} */\n let token;\n /** @type {number | undefined} */\n let open;\n /** @type {number | undefined} */\n let close;\n /** @type {Array} */\n let media;\n\n // Find an opening.\n while (index--) {\n token = events[index][1];\n if (open) {\n // If we see another link, or inactive link label, we\u2019ve been here before.\n if (token.type === \"link\" || token.type === \"labelLink\" && token._inactive) {\n break;\n }\n\n // Mark other link openings as inactive, as we can\u2019t have links in\n // links.\n if (events[index][0] === 'enter' && token.type === \"labelLink\") {\n token._inactive = true;\n }\n } else if (close) {\n if (events[index][0] === 'enter' && (token.type === \"labelImage\" || token.type === \"labelLink\") && !token._balanced) {\n open = index;\n if (token.type !== \"labelLink\") {\n offset = 2;\n break;\n }\n }\n } else if (token.type === \"labelEnd\") {\n close = index;\n }\n }\n const group = {\n type: events[open][1].type === \"labelLink\" ? \"link\" : \"image\",\n start: {\n ...events[open][1].start\n },\n end: {\n ...events[events.length - 1][1].end\n }\n };\n const label = {\n type: \"label\",\n start: {\n ...events[open][1].start\n },\n end: {\n ...events[close][1].end\n }\n };\n const text = {\n type: \"labelText\",\n start: {\n ...events[open + offset + 2][1].end\n },\n end: {\n ...events[close - 2][1].start\n }\n };\n media = [['enter', group, context], ['enter', label, context]];\n\n // Opening marker.\n media = push(media, events.slice(open + 1, open + offset + 3));\n\n // Text open.\n media = push(media, [['enter', text, context]]);\n\n // Always populated by defaults.\n\n // Between.\n media = push(media, resolveAll(context.parser.constructs.insideSpan.null, events.slice(open + offset + 4, close - 3), context));\n\n // Text close, marker close, label close.\n media = push(media, [['exit', text, context], events[close - 2], events[close - 1], ['exit', label, context]]);\n\n // Reference, resource, or so.\n media = push(media, events.slice(close + 1));\n\n // Media close.\n media = push(media, [['exit', group, context]]);\n splice(events, open, events.length, media);\n return events;\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeLabelEnd(effects, ok, nok) {\n const self = this;\n let index = self.events.length;\n /** @type {Token} */\n let labelStart;\n /** @type {boolean} */\n let defined;\n\n // Find an opening.\n while (index--) {\n if ((self.events[index][1].type === \"labelImage\" || self.events[index][1].type === \"labelLink\") && !self.events[index][1]._balanced) {\n labelStart = self.events[index][1];\n break;\n }\n }\n return start;\n\n /**\n * Start of label end.\n *\n * ```markdown\n * > | [a](b) c\n * ^\n * > | [a][b] c\n * ^\n * > | [a][] b\n * ^\n * > | [a] b\n * ```\n *\n * @type {State}\n */\n function start(code) {\n // If there is not an okay opening.\n if (!labelStart) {\n return nok(code);\n }\n\n // If the corresponding label (link) start is marked as inactive,\n // it means we\u2019d be wrapping a link, like this:\n //\n // ```markdown\n // > | a [b [c](d) e](f) g.\n // ^\n // ```\n //\n // We can\u2019t have that, so it\u2019s just balanced brackets.\n if (labelStart._inactive) {\n return labelEndNok(code);\n }\n defined = self.parser.defined.includes(normalizeIdentifier(self.sliceSerialize({\n start: labelStart.end,\n end: self.now()\n })));\n effects.enter(\"labelEnd\");\n effects.enter(\"labelMarker\");\n effects.consume(code);\n effects.exit(\"labelMarker\");\n effects.exit(\"labelEnd\");\n return after;\n }\n\n /**\n * After `]`.\n *\n * ```markdown\n * > | [a](b) c\n * ^\n * > | [a][b] c\n * ^\n * > | [a][] b\n * ^\n * > | [a] b\n * ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n // Note: `markdown-rs` also parses GFM footnotes here, which for us is in\n // an extension.\n\n // Resource (`[asd](fgh)`)?\n if (code === 40) {\n return effects.attempt(resourceConstruct, labelEndOk, defined ? labelEndOk : labelEndNok)(code);\n }\n\n // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference?\n if (code === 91) {\n return effects.attempt(referenceFullConstruct, labelEndOk, defined ? referenceNotFull : labelEndNok)(code);\n }\n\n // Shortcut (`[asd]`) reference?\n return defined ? labelEndOk(code) : labelEndNok(code);\n }\n\n /**\n * After `]`, at `[`, but not at a full reference.\n *\n * > \uD83D\uDC49 **Note**: we only get here if the label is defined.\n *\n * ```markdown\n * > | [a][] b\n * ^\n * > | [a] b\n * ^\n * ```\n *\n * @type {State}\n */\n function referenceNotFull(code) {\n return effects.attempt(referenceCollapsedConstruct, labelEndOk, labelEndNok)(code);\n }\n\n /**\n * Done, we found something.\n *\n * ```markdown\n * > | [a](b) c\n * ^\n * > | [a][b] c\n * ^\n * > | [a][] b\n * ^\n * > | [a] b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelEndOk(code) {\n // Note: `markdown-rs` does a bunch of stuff here.\n return ok(code);\n }\n\n /**\n * Done, it\u2019s nothing.\n *\n * There was an okay opening, but we didn\u2019t match anything.\n *\n * ```markdown\n * > | [a](b c\n * ^\n * > | [a][b c\n * ^\n * > | [a] b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelEndNok(code) {\n labelStart._balanced = true;\n return nok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeResource(effects, ok, nok) {\n return resourceStart;\n\n /**\n * At a resource.\n *\n * ```markdown\n * > | [a](b) c\n * ^\n * ```\n *\n * @type {State}\n */\n function resourceStart(code) {\n effects.enter(\"resource\");\n effects.enter(\"resourceMarker\");\n effects.consume(code);\n effects.exit(\"resourceMarker\");\n return resourceBefore;\n }\n\n /**\n * In resource, after `(`, at optional whitespace.\n *\n * ```markdown\n * > | [a](b) c\n * ^\n * ```\n *\n * @type {State}\n */\n function resourceBefore(code) {\n return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, resourceOpen)(code) : resourceOpen(code);\n }\n\n /**\n * In resource, after optional whitespace, at `)` or a destination.\n *\n * ```markdown\n * > | [a](b) c\n * ^\n * ```\n *\n * @type {State}\n */\n function resourceOpen(code) {\n if (code === 41) {\n return resourceEnd(code);\n }\n return factoryDestination(effects, resourceDestinationAfter, resourceDestinationMissing, \"resourceDestination\", \"resourceDestinationLiteral\", \"resourceDestinationLiteralMarker\", \"resourceDestinationRaw\", \"resourceDestinationString\", 32)(code);\n }\n\n /**\n * In resource, after destination, at optional whitespace.\n *\n * ```markdown\n * > | [a](b) c\n * ^\n * ```\n *\n * @type {State}\n */\n function resourceDestinationAfter(code) {\n return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, resourceBetween)(code) : resourceEnd(code);\n }\n\n /**\n * At invalid destination.\n *\n * ```markdown\n * > | [a](<<) b\n * ^\n * ```\n *\n * @type {State}\n */\n function resourceDestinationMissing(code) {\n return nok(code);\n }\n\n /**\n * In resource, after destination and whitespace, at `(` or title.\n *\n * ```markdown\n * > | [a](b ) c\n * ^\n * ```\n *\n * @type {State}\n */\n function resourceBetween(code) {\n if (code === 34 || code === 39 || code === 40) {\n return factoryTitle(effects, resourceTitleAfter, nok, \"resourceTitle\", \"resourceTitleMarker\", \"resourceTitleString\")(code);\n }\n return resourceEnd(code);\n }\n\n /**\n * In resource, after title, at optional whitespace.\n *\n * ```markdown\n * > | [a](b \"c\") d\n * ^\n * ```\n *\n * @type {State}\n */\n function resourceTitleAfter(code) {\n return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, resourceEnd)(code) : resourceEnd(code);\n }\n\n /**\n * In resource, at `)`.\n *\n * ```markdown\n * > | [a](b) d\n * ^\n * ```\n *\n * @type {State}\n */\n function resourceEnd(code) {\n if (code === 41) {\n effects.enter(\"resourceMarker\");\n effects.consume(code);\n effects.exit(\"resourceMarker\");\n effects.exit(\"resource\");\n return ok;\n }\n return nok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeReferenceFull(effects, ok, nok) {\n const self = this;\n return referenceFull;\n\n /**\n * In a reference (full), at the `[`.\n *\n * ```markdown\n * > | [a][b] d\n * ^\n * ```\n *\n * @type {State}\n */\n function referenceFull(code) {\n return factoryLabel.call(self, effects, referenceFullAfter, referenceFullMissing, \"reference\", \"referenceMarker\", \"referenceString\")(code);\n }\n\n /**\n * In a reference (full), after `]`.\n *\n * ```markdown\n * > | [a][b] d\n * ^\n * ```\n *\n * @type {State}\n */\n function referenceFullAfter(code) {\n return self.parser.defined.includes(normalizeIdentifier(self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1))) ? ok(code) : nok(code);\n }\n\n /**\n * In reference (full) that was missing.\n *\n * ```markdown\n * > | [a][b d\n * ^\n * ```\n *\n * @type {State}\n */\n function referenceFullMissing(code) {\n return nok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeReferenceCollapsed(effects, ok, nok) {\n return referenceCollapsedStart;\n\n /**\n * In reference (collapsed), at `[`.\n *\n * > \uD83D\uDC49 **Note**: we only get here if the label is defined.\n *\n * ```markdown\n * > | [a][] d\n * ^\n * ```\n *\n * @type {State}\n */\n function referenceCollapsedStart(code) {\n // We only attempt a collapsed label if there\u2019s a `[`.\n\n effects.enter(\"reference\");\n effects.enter(\"referenceMarker\");\n effects.consume(code);\n effects.exit(\"referenceMarker\");\n return referenceCollapsedOpen;\n }\n\n /**\n * In reference (collapsed), at `]`.\n *\n * > \uD83D\uDC49 **Note**: we only get here if the label is defined.\n *\n * ```markdown\n * > | [a][] d\n * ^\n * ```\n *\n * @type {State}\n */\n function referenceCollapsedOpen(code) {\n if (code === 93) {\n effects.enter(\"referenceMarker\");\n effects.consume(code);\n effects.exit(\"referenceMarker\");\n effects.exit(\"reference\");\n return ok;\n }\n return nok(code);\n }\n}", "/**\n * @import {\n * Construct,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { labelEnd } from './label-end.js';\n\n/** @type {Construct} */\nexport const labelStartImage = {\n name: 'labelStartImage',\n resolveAll: labelEnd.resolveAll,\n tokenize: tokenizeLabelStartImage\n};\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeLabelStartImage(effects, ok, nok) {\n const self = this;\n return start;\n\n /**\n * Start of label (image) start.\n *\n * ```markdown\n * > | a ![b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter(\"labelImage\");\n effects.enter(\"labelImageMarker\");\n effects.consume(code);\n effects.exit(\"labelImageMarker\");\n return open;\n }\n\n /**\n * After `!`, at `[`.\n *\n * ```markdown\n * > | a ![b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function open(code) {\n if (code === 91) {\n effects.enter(\"labelMarker\");\n effects.consume(code);\n effects.exit(\"labelMarker\");\n effects.exit(\"labelImage\");\n return after;\n }\n return nok(code);\n }\n\n /**\n * After `![`.\n *\n * ```markdown\n * > | a ![b] c\n * ^\n * ```\n *\n * This is needed in because, when GFM footnotes are enabled, images never\n * form when started with a `^`.\n * Instead, links form:\n *\n * ```markdown\n * ![^a](b)\n *\n * ![^a][b]\n *\n * [b]: c\n * ```\n *\n * ```html\n *

    !^a

    \n *

    !^a

    \n * ```\n *\n * @type {State}\n */\n function after(code) {\n // To do: use a new field to do this, this is still needed for\n // `micromark-extension-gfm-footnote`, but the `label-start-link`\n // behavior isn\u2019t.\n // Hidden footnotes hook.\n /* c8 ignore next 3 */\n return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs ? nok(code) : ok(code);\n }\n}", "/**\n * @import {\n * Construct,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { labelEnd } from './label-end.js';\n\n/** @type {Construct} */\nexport const labelStartLink = {\n name: 'labelStartLink',\n resolveAll: labelEnd.resolveAll,\n tokenize: tokenizeLabelStartLink\n};\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeLabelStartLink(effects, ok, nok) {\n const self = this;\n return start;\n\n /**\n * Start of label (link) start.\n *\n * ```markdown\n * > | a [b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter(\"labelLink\");\n effects.enter(\"labelMarker\");\n effects.consume(code);\n effects.exit(\"labelMarker\");\n effects.exit(\"labelLink\");\n return after;\n }\n\n /** @type {State} */\n function after(code) {\n // To do: this isn\u2019t needed in `micromark-extension-gfm-footnote`,\n // remove.\n // Hidden footnotes hook.\n /* c8 ignore next 3 */\n return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs ? nok(code) : ok(code);\n }\n}", "/**\n * @import {\n * Construct,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding } from 'micromark-util-character';\n/** @type {Construct} */\nexport const lineEnding = {\n name: 'lineEnding',\n tokenize: tokenizeLineEnding\n};\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeLineEnding(effects, ok) {\n return start;\n\n /** @type {State} */\n function start(code) {\n effects.enter(\"lineEnding\");\n effects.consume(code);\n effects.exit(\"lineEnding\");\n return factorySpace(effects, ok, \"linePrefix\");\n }\n}", "/**\n * @import {\n * Code,\n * Construct,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownSpace } from 'micromark-util-character';\n/** @type {Construct} */\nexport const thematicBreak = {\n name: 'thematicBreak',\n tokenize: tokenizeThematicBreak\n};\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeThematicBreak(effects, ok, nok) {\n let size = 0;\n /** @type {NonNullable} */\n let marker;\n return start;\n\n /**\n * Start of thematic break.\n *\n * ```markdown\n * > | ***\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter(\"thematicBreak\");\n // To do: parse indent like `markdown-rs`.\n return before(code);\n }\n\n /**\n * After optional whitespace, at marker.\n *\n * ```markdown\n * > | ***\n * ^\n * ```\n *\n * @type {State}\n */\n function before(code) {\n marker = code;\n return atBreak(code);\n }\n\n /**\n * After something, before something else.\n *\n * ```markdown\n * > | ***\n * ^\n * ```\n *\n * @type {State}\n */\n function atBreak(code) {\n if (code === marker) {\n effects.enter(\"thematicBreakSequence\");\n return sequence(code);\n }\n if (size >= 3 && (code === null || markdownLineEnding(code))) {\n effects.exit(\"thematicBreak\");\n return ok(code);\n }\n return nok(code);\n }\n\n /**\n * In sequence.\n *\n * ```markdown\n * > | ***\n * ^\n * ```\n *\n * @type {State}\n */\n function sequence(code) {\n if (code === marker) {\n effects.consume(code);\n size++;\n return sequence;\n }\n effects.exit(\"thematicBreakSequence\");\n return markdownSpace(code) ? factorySpace(effects, atBreak, \"whitespace\")(code) : atBreak(code);\n }\n}", "/**\n * @import {\n * Code,\n * Construct,\n * Exiter,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { asciiDigit, markdownSpace } from 'micromark-util-character';\nimport { blankLine } from './blank-line.js';\nimport { thematicBreak } from './thematic-break.js';\n\n/** @type {Construct} */\nexport const list = {\n continuation: {\n tokenize: tokenizeListContinuation\n },\n exit: tokenizeListEnd,\n name: 'list',\n tokenize: tokenizeListStart\n};\n\n/** @type {Construct} */\nconst listItemPrefixWhitespaceConstruct = {\n partial: true,\n tokenize: tokenizeListItemPrefixWhitespace\n};\n\n/** @type {Construct} */\nconst indentConstruct = {\n partial: true,\n tokenize: tokenizeIndent\n};\n\n// To do: `markdown-rs` parses list items on their own and later stitches them\n// together.\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeListStart(effects, ok, nok) {\n const self = this;\n const tail = self.events[self.events.length - 1];\n let initialSize = tail && tail[1].type === \"linePrefix\" ? tail[2].sliceSerialize(tail[1], true).length : 0;\n let size = 0;\n return start;\n\n /** @type {State} */\n function start(code) {\n const kind = self.containerState.type || (code === 42 || code === 43 || code === 45 ? \"listUnordered\" : \"listOrdered\");\n if (kind === \"listUnordered\" ? !self.containerState.marker || code === self.containerState.marker : asciiDigit(code)) {\n if (!self.containerState.type) {\n self.containerState.type = kind;\n effects.enter(kind, {\n _container: true\n });\n }\n if (kind === \"listUnordered\") {\n effects.enter(\"listItemPrefix\");\n return code === 42 || code === 45 ? effects.check(thematicBreak, nok, atMarker)(code) : atMarker(code);\n }\n if (!self.interrupt || code === 49) {\n effects.enter(\"listItemPrefix\");\n effects.enter(\"listItemValue\");\n return inside(code);\n }\n }\n return nok(code);\n }\n\n /** @type {State} */\n function inside(code) {\n if (asciiDigit(code) && ++size < 10) {\n effects.consume(code);\n return inside;\n }\n if ((!self.interrupt || size < 2) && (self.containerState.marker ? code === self.containerState.marker : code === 41 || code === 46)) {\n effects.exit(\"listItemValue\");\n return atMarker(code);\n }\n return nok(code);\n }\n\n /**\n * @type {State}\n **/\n function atMarker(code) {\n effects.enter(\"listItemMarker\");\n effects.consume(code);\n effects.exit(\"listItemMarker\");\n self.containerState.marker = self.containerState.marker || code;\n return effects.check(blankLine,\n // Can\u2019t be empty when interrupting.\n self.interrupt ? nok : onBlank, effects.attempt(listItemPrefixWhitespaceConstruct, endOfPrefix, otherPrefix));\n }\n\n /** @type {State} */\n function onBlank(code) {\n self.containerState.initialBlankLine = true;\n initialSize++;\n return endOfPrefix(code);\n }\n\n /** @type {State} */\n function otherPrefix(code) {\n if (markdownSpace(code)) {\n effects.enter(\"listItemPrefixWhitespace\");\n effects.consume(code);\n effects.exit(\"listItemPrefixWhitespace\");\n return endOfPrefix;\n }\n return nok(code);\n }\n\n /** @type {State} */\n function endOfPrefix(code) {\n self.containerState.size = initialSize + self.sliceSerialize(effects.exit(\"listItemPrefix\"), true).length;\n return ok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeListContinuation(effects, ok, nok) {\n const self = this;\n self.containerState._closeFlow = undefined;\n return effects.check(blankLine, onBlank, notBlank);\n\n /** @type {State} */\n function onBlank(code) {\n self.containerState.furtherBlankLines = self.containerState.furtherBlankLines || self.containerState.initialBlankLine;\n\n // We have a blank line.\n // Still, try to consume at most the items size.\n return factorySpace(effects, ok, \"listItemIndent\", self.containerState.size + 1)(code);\n }\n\n /** @type {State} */\n function notBlank(code) {\n if (self.containerState.furtherBlankLines || !markdownSpace(code)) {\n self.containerState.furtherBlankLines = undefined;\n self.containerState.initialBlankLine = undefined;\n return notInCurrentItem(code);\n }\n self.containerState.furtherBlankLines = undefined;\n self.containerState.initialBlankLine = undefined;\n return effects.attempt(indentConstruct, ok, notInCurrentItem)(code);\n }\n\n /** @type {State} */\n function notInCurrentItem(code) {\n // While we do continue, we signal that the flow should be closed.\n self.containerState._closeFlow = true;\n // As we\u2019re closing flow, we\u2019re no longer interrupting.\n self.interrupt = undefined;\n // Always populated by defaults.\n\n return factorySpace(effects, effects.attempt(list, ok, nok), \"linePrefix\", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeIndent(effects, ok, nok) {\n const self = this;\n return factorySpace(effects, afterPrefix, \"listItemIndent\", self.containerState.size + 1);\n\n /** @type {State} */\n function afterPrefix(code) {\n const tail = self.events[self.events.length - 1];\n return tail && tail[1].type === \"listItemIndent\" && tail[2].sliceSerialize(tail[1], true).length === self.containerState.size ? ok(code) : nok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Exiter}\n */\nfunction tokenizeListEnd(effects) {\n effects.exit(this.containerState.type);\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeListItemPrefixWhitespace(effects, ok, nok) {\n const self = this;\n\n // Always populated by defaults.\n\n return factorySpace(effects, afterPrefix, \"listItemPrefixWhitespace\", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + 1);\n\n /** @type {State} */\n function afterPrefix(code) {\n const tail = self.events[self.events.length - 1];\n return !markdownSpace(code) && tail && tail[1].type === \"listItemPrefixWhitespace\" ? ok(code) : nok(code);\n }\n}", "/**\n * @import {\n * Code,\n * Construct,\n * Resolver,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownSpace } from 'micromark-util-character';\n/** @type {Construct} */\nexport const setextUnderline = {\n name: 'setextUnderline',\n resolveTo: resolveToSetextUnderline,\n tokenize: tokenizeSetextUnderline\n};\n\n/** @type {Resolver} */\nfunction resolveToSetextUnderline(events, context) {\n // To do: resolve like `markdown-rs`.\n let index = events.length;\n /** @type {number | undefined} */\n let content;\n /** @type {number | undefined} */\n let text;\n /** @type {number | undefined} */\n let definition;\n\n // Find the opening of the content.\n // It\u2019ll always exist: we don\u2019t tokenize if it isn\u2019t there.\n while (index--) {\n if (events[index][0] === 'enter') {\n if (events[index][1].type === \"content\") {\n content = index;\n break;\n }\n if (events[index][1].type === \"paragraph\") {\n text = index;\n }\n }\n // Exit\n else {\n if (events[index][1].type === \"content\") {\n // Remove the content end (if needed we\u2019ll add it later)\n events.splice(index, 1);\n }\n if (!definition && events[index][1].type === \"definition\") {\n definition = index;\n }\n }\n }\n const heading = {\n type: \"setextHeading\",\n start: {\n ...events[content][1].start\n },\n end: {\n ...events[events.length - 1][1].end\n }\n };\n\n // Change the paragraph to setext heading text.\n events[text][1].type = \"setextHeadingText\";\n\n // If we have definitions in the content, we\u2019ll keep on having content,\n // but we need move it.\n if (definition) {\n events.splice(text, 0, ['enter', heading, context]);\n events.splice(definition + 1, 0, ['exit', events[content][1], context]);\n events[content][1].end = {\n ...events[definition][1].end\n };\n } else {\n events[content][1] = heading;\n }\n\n // Add the heading exit at the end.\n events.push(['exit', heading, context]);\n return events;\n}\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeSetextUnderline(effects, ok, nok) {\n const self = this;\n /** @type {NonNullable} */\n let marker;\n return start;\n\n /**\n * At start of heading (setext) underline.\n *\n * ```markdown\n * | aa\n * > | ==\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n let index = self.events.length;\n /** @type {boolean | undefined} */\n let paragraph;\n // Find an opening.\n while (index--) {\n // Skip enter/exit of line ending, line prefix, and content.\n // We can now either have a definition or a paragraph.\n if (self.events[index][1].type !== \"lineEnding\" && self.events[index][1].type !== \"linePrefix\" && self.events[index][1].type !== \"content\") {\n paragraph = self.events[index][1].type === \"paragraph\";\n break;\n }\n }\n\n // To do: handle lazy/pierce like `markdown-rs`.\n // To do: parse indent like `markdown-rs`.\n if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) {\n effects.enter(\"setextHeadingLine\");\n marker = code;\n return before(code);\n }\n return nok(code);\n }\n\n /**\n * After optional whitespace, at `-` or `=`.\n *\n * ```markdown\n * | aa\n * > | ==\n * ^\n * ```\n *\n * @type {State}\n */\n function before(code) {\n effects.enter(\"setextHeadingLineSequence\");\n return inside(code);\n }\n\n /**\n * In sequence.\n *\n * ```markdown\n * | aa\n * > | ==\n * ^\n * ```\n *\n * @type {State}\n */\n function inside(code) {\n if (code === marker) {\n effects.consume(code);\n return inside;\n }\n effects.exit(\"setextHeadingLineSequence\");\n return markdownSpace(code) ? factorySpace(effects, after, \"lineSuffix\")(code) : after(code);\n }\n\n /**\n * After sequence, after optional whitespace.\n *\n * ```markdown\n * | aa\n * > | ==\n * ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n if (code === null || markdownLineEnding(code)) {\n effects.exit(\"setextHeadingLine\");\n return ok(code);\n }\n return nok(code);\n }\n}", "export { attention } from './lib/attention.js';\nexport { autolink } from './lib/autolink.js';\nexport { blankLine } from './lib/blank-line.js';\nexport { blockQuote } from './lib/block-quote.js';\nexport { characterEscape } from './lib/character-escape.js';\nexport { characterReference } from './lib/character-reference.js';\nexport { codeFenced } from './lib/code-fenced.js';\nexport { codeIndented } from './lib/code-indented.js';\nexport { codeText } from './lib/code-text.js';\nexport { content } from './lib/content.js';\nexport { definition } from './lib/definition.js';\nexport { hardBreakEscape } from './lib/hard-break-escape.js';\nexport { headingAtx } from './lib/heading-atx.js';\nexport { htmlFlow } from './lib/html-flow.js';\nexport { htmlText } from './lib/html-text.js';\nexport { labelEnd } from './lib/label-end.js';\nexport { labelStartImage } from './lib/label-start-image.js';\nexport { labelStartLink } from './lib/label-start-link.js';\nexport { lineEnding } from './lib/line-ending.js';\nexport { list } from './lib/list.js';\nexport { setextUnderline } from './lib/setext-underline.js';\nexport { thematicBreak } from './lib/thematic-break.js';", "/**\n * @import {\n * InitialConstruct,\n * Initializer,\n * State,\n * TokenizeContext\n * } from 'micromark-util-types'\n */\n\nimport { blankLine, content } from 'micromark-core-commonmark';\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding } from 'micromark-util-character';\n/** @type {InitialConstruct} */\nexport const flow = {\n tokenize: initializeFlow\n};\n\n/**\n * @this {TokenizeContext}\n * Self.\n * @type {Initializer}\n * Initializer.\n */\nfunction initializeFlow(effects) {\n const self = this;\n const initial = effects.attempt(\n // Try to parse a blank line.\n blankLine, atBlankEnding,\n // Try to parse initial flow (essentially, only code).\n effects.attempt(this.parser.constructs.flowInitial, afterConstruct, factorySpace(effects, effects.attempt(this.parser.constructs.flow, afterConstruct, effects.attempt(content, afterConstruct)), \"linePrefix\")));\n return initial;\n\n /** @type {State} */\n function atBlankEnding(code) {\n if (code === null) {\n effects.consume(code);\n return;\n }\n effects.enter(\"lineEndingBlank\");\n effects.consume(code);\n effects.exit(\"lineEndingBlank\");\n self.currentConstruct = undefined;\n return initial;\n }\n\n /** @type {State} */\n function afterConstruct(code) {\n if (code === null) {\n effects.consume(code);\n return;\n }\n effects.enter(\"lineEnding\");\n effects.consume(code);\n effects.exit(\"lineEnding\");\n self.currentConstruct = undefined;\n return initial;\n }\n}", "/**\n * @import {\n * Code,\n * InitialConstruct,\n * Initializer,\n * Resolver,\n * State,\n * TokenizeContext\n * } from 'micromark-util-types'\n */\n\nexport const resolver = {\n resolveAll: createResolver()\n};\nexport const string = initializeFactory('string');\nexport const text = initializeFactory('text');\n\n/**\n * @param {'string' | 'text'} field\n * Field.\n * @returns {InitialConstruct}\n * Construct.\n */\nfunction initializeFactory(field) {\n return {\n resolveAll: createResolver(field === 'text' ? resolveAllLineSuffixes : undefined),\n tokenize: initializeText\n };\n\n /**\n * @this {TokenizeContext}\n * Context.\n * @type {Initializer}\n */\n function initializeText(effects) {\n const self = this;\n const constructs = this.parser.constructs[field];\n const text = effects.attempt(constructs, start, notText);\n return start;\n\n /** @type {State} */\n function start(code) {\n return atBreak(code) ? text(code) : notText(code);\n }\n\n /** @type {State} */\n function notText(code) {\n if (code === null) {\n effects.consume(code);\n return;\n }\n effects.enter(\"data\");\n effects.consume(code);\n return data;\n }\n\n /** @type {State} */\n function data(code) {\n if (atBreak(code)) {\n effects.exit(\"data\");\n return text(code);\n }\n\n // Data.\n effects.consume(code);\n return data;\n }\n\n /**\n * @param {Code} code\n * Code.\n * @returns {boolean}\n * Whether the code is a break.\n */\n function atBreak(code) {\n if (code === null) {\n return true;\n }\n const list = constructs[code];\n let index = -1;\n if (list) {\n // Always populated by defaults.\n\n while (++index < list.length) {\n const item = list[index];\n if (!item.previous || item.previous.call(self, self.previous)) {\n return true;\n }\n }\n }\n return false;\n }\n }\n}\n\n/**\n * @param {Resolver | undefined} [extraResolver]\n * Resolver.\n * @returns {Resolver}\n * Resolver.\n */\nfunction createResolver(extraResolver) {\n return resolveAllText;\n\n /** @type {Resolver} */\n function resolveAllText(events, context) {\n let index = -1;\n /** @type {number | undefined} */\n let enter;\n\n // A rather boring computation (to merge adjacent `data` events) which\n // improves mm performance by 29%.\n while (++index <= events.length) {\n if (enter === undefined) {\n if (events[index] && events[index][1].type === \"data\") {\n enter = index;\n index++;\n }\n } else if (!events[index] || events[index][1].type !== \"data\") {\n // Don\u2019t do anything if there is one data token.\n if (index !== enter + 2) {\n events[enter][1].end = events[index - 1][1].end;\n events.splice(enter + 2, index - enter - 2);\n index = enter + 2;\n }\n enter = undefined;\n }\n }\n return extraResolver ? extraResolver(events, context) : events;\n }\n}\n\n/**\n * A rather ugly set of instructions which again looks at chunks in the input\n * stream.\n * The reason to do this here is that it is *much* faster to parse in reverse.\n * And that we can\u2019t hook into `null` to split the line suffix before an EOF.\n * To do: figure out if we can make this into a clean utility, or even in core.\n * As it will be useful for GFMs literal autolink extension (and maybe even\n * tables?)\n *\n * @type {Resolver}\n */\nfunction resolveAllLineSuffixes(events, context) {\n let eventIndex = 0; // Skip first.\n\n while (++eventIndex <= events.length) {\n if ((eventIndex === events.length || events[eventIndex][1].type === \"lineEnding\") && events[eventIndex - 1][1].type === \"data\") {\n const data = events[eventIndex - 1][1];\n const chunks = context.sliceStream(data);\n let index = chunks.length;\n let bufferIndex = -1;\n let size = 0;\n /** @type {boolean | undefined} */\n let tabs;\n while (index--) {\n const chunk = chunks[index];\n if (typeof chunk === 'string') {\n bufferIndex = chunk.length;\n while (chunk.charCodeAt(bufferIndex - 1) === 32) {\n size++;\n bufferIndex--;\n }\n if (bufferIndex) break;\n bufferIndex = -1;\n }\n // Number\n else if (chunk === -2) {\n tabs = true;\n size++;\n } else if (chunk === -1) {\n // Empty\n } else {\n // Replacement character, exit.\n index++;\n break;\n }\n }\n\n // Allow final trailing whitespace.\n if (context._contentTypeTextTrailing && eventIndex === events.length) {\n size = 0;\n }\n if (size) {\n const token = {\n type: eventIndex === events.length || tabs || size < 2 ? \"lineSuffix\" : \"hardBreakTrailing\",\n start: {\n _bufferIndex: index ? bufferIndex : data.start._bufferIndex + bufferIndex,\n _index: data.start._index + index,\n line: data.end.line,\n column: data.end.column - size,\n offset: data.end.offset - size\n },\n end: {\n ...data.end\n }\n };\n data.end = {\n ...token.start\n };\n if (data.start.offset === data.end.offset) {\n Object.assign(data, token);\n } else {\n events.splice(eventIndex, 0, ['enter', token, context], ['exit', token, context]);\n eventIndex += 2;\n }\n }\n eventIndex++;\n }\n }\n return events;\n}", "/**\n * @import {Extension} from 'micromark-util-types'\n */\n\nimport { attention, autolink, blockQuote, characterEscape, characterReference, codeFenced, codeIndented, codeText, definition, hardBreakEscape, headingAtx, htmlFlow, htmlText, labelEnd, labelStartImage, labelStartLink, lineEnding, list, setextUnderline, thematicBreak } from 'micromark-core-commonmark';\nimport { resolver as resolveText } from './initialize/text.js';\n\n/** @satisfies {Extension['document']} */\nexport const document = {\n [42]: list,\n [43]: list,\n [45]: list,\n [48]: list,\n [49]: list,\n [50]: list,\n [51]: list,\n [52]: list,\n [53]: list,\n [54]: list,\n [55]: list,\n [56]: list,\n [57]: list,\n [62]: blockQuote\n};\n\n/** @satisfies {Extension['contentInitial']} */\nexport const contentInitial = {\n [91]: definition\n};\n\n/** @satisfies {Extension['flowInitial']} */\nexport const flowInitial = {\n [-2]: codeIndented,\n [-1]: codeIndented,\n [32]: codeIndented\n};\n\n/** @satisfies {Extension['flow']} */\nexport const flow = {\n [35]: headingAtx,\n [42]: thematicBreak,\n [45]: [setextUnderline, thematicBreak],\n [60]: htmlFlow,\n [61]: setextUnderline,\n [95]: thematicBreak,\n [96]: codeFenced,\n [126]: codeFenced\n};\n\n/** @satisfies {Extension['string']} */\nexport const string = {\n [38]: characterReference,\n [92]: characterEscape\n};\n\n/** @satisfies {Extension['text']} */\nexport const text = {\n [-5]: lineEnding,\n [-4]: lineEnding,\n [-3]: lineEnding,\n [33]: labelStartImage,\n [38]: characterReference,\n [42]: attention,\n [60]: [autolink, htmlText],\n [91]: labelStartLink,\n [92]: [hardBreakEscape, characterEscape],\n [93]: labelEnd,\n [95]: attention,\n [96]: codeText\n};\n\n/** @satisfies {Extension['insideSpan']} */\nexport const insideSpan = {\n null: [attention, resolveText]\n};\n\n/** @satisfies {Extension['attentionMarkers']} */\nexport const attentionMarkers = {\n null: [42, 95]\n};\n\n/** @satisfies {Extension['disable']} */\nexport const disable = {\n null: []\n};", "/**\n * @import {\n * Chunk,\n * Code,\n * ConstructRecord,\n * Construct,\n * Effects,\n * InitialConstruct,\n * ParseContext,\n * Point,\n * State,\n * TokenizeContext,\n * Token\n * } from 'micromark-util-types'\n */\n\n/**\n * @callback Restore\n * Restore the state.\n * @returns {undefined}\n * Nothing.\n *\n * @typedef Info\n * Info.\n * @property {Restore} restore\n * Restore.\n * @property {number} from\n * From.\n *\n * @callback ReturnHandle\n * Handle a successful run.\n * @param {Construct} construct\n * Construct.\n * @param {Info} info\n * Info.\n * @returns {undefined}\n * Nothing.\n */\n\nimport { markdownLineEnding } from 'micromark-util-character';\nimport { push, splice } from 'micromark-util-chunked';\nimport { resolveAll } from 'micromark-util-resolve-all';\n/**\n * Create a tokenizer.\n * Tokenizers deal with one type of data (e.g., containers, flow, text).\n * The parser is the object dealing with it all.\n * `initialize` works like other constructs, except that only its `tokenize`\n * function is used, in which case it doesn\u2019t receive an `ok` or `nok`.\n * `from` can be given to set the point before the first character, although\n * when further lines are indented, they must be set with `defineSkip`.\n *\n * @param {ParseContext} parser\n * Parser.\n * @param {InitialConstruct} initialize\n * Construct.\n * @param {Omit | undefined} [from]\n * Point (optional).\n * @returns {TokenizeContext}\n * Context.\n */\nexport function createTokenizer(parser, initialize, from) {\n /** @type {Point} */\n let point = {\n _bufferIndex: -1,\n _index: 0,\n line: from && from.line || 1,\n column: from && from.column || 1,\n offset: from && from.offset || 0\n };\n /** @type {Record} */\n const columnStart = {};\n /** @type {Array} */\n const resolveAllConstructs = [];\n /** @type {Array} */\n let chunks = [];\n /** @type {Array} */\n let stack = [];\n /** @type {boolean | undefined} */\n let consumed = true;\n\n /**\n * Tools used for tokenizing.\n *\n * @type {Effects}\n */\n const effects = {\n attempt: constructFactory(onsuccessfulconstruct),\n check: constructFactory(onsuccessfulcheck),\n consume,\n enter,\n exit,\n interrupt: constructFactory(onsuccessfulcheck, {\n interrupt: true\n })\n };\n\n /**\n * State and tools for resolving and serializing.\n *\n * @type {TokenizeContext}\n */\n const context = {\n code: null,\n containerState: {},\n defineSkip,\n events: [],\n now,\n parser,\n previous: null,\n sliceSerialize,\n sliceStream,\n write\n };\n\n /**\n * The state function.\n *\n * @type {State | undefined}\n */\n let state = initialize.tokenize.call(context, effects);\n\n /**\n * Track which character we expect to be consumed, to catch bugs.\n *\n * @type {Code}\n */\n let expectedCode;\n if (initialize.resolveAll) {\n resolveAllConstructs.push(initialize);\n }\n return context;\n\n /** @type {TokenizeContext['write']} */\n function write(slice) {\n chunks = push(chunks, slice);\n main();\n\n // Exit if we\u2019re not done, resolve might change stuff.\n if (chunks[chunks.length - 1] !== null) {\n return [];\n }\n addResult(initialize, 0);\n\n // Otherwise, resolve, and exit.\n context.events = resolveAll(resolveAllConstructs, context.events, context);\n return context.events;\n }\n\n //\n // Tools.\n //\n\n /** @type {TokenizeContext['sliceSerialize']} */\n function sliceSerialize(token, expandTabs) {\n return serializeChunks(sliceStream(token), expandTabs);\n }\n\n /** @type {TokenizeContext['sliceStream']} */\n function sliceStream(token) {\n return sliceChunks(chunks, token);\n }\n\n /** @type {TokenizeContext['now']} */\n function now() {\n // This is a hot path, so we clone manually instead of `Object.assign({}, point)`\n const {\n _bufferIndex,\n _index,\n line,\n column,\n offset\n } = point;\n return {\n _bufferIndex,\n _index,\n line,\n column,\n offset\n };\n }\n\n /** @type {TokenizeContext['defineSkip']} */\n function defineSkip(value) {\n columnStart[value.line] = value.column;\n accountForPotentialSkip();\n }\n\n //\n // State management.\n //\n\n /**\n * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by\n * `consume`).\n * Here is where we walk through the chunks, which either include strings of\n * several characters, or numerical character codes.\n * The reason to do this in a loop instead of a call is so the stack can\n * drain.\n *\n * @returns {undefined}\n * Nothing.\n */\n function main() {\n /** @type {number} */\n let chunkIndex;\n while (point._index < chunks.length) {\n const chunk = chunks[point._index];\n\n // If we\u2019re in a buffer chunk, loop through it.\n if (typeof chunk === 'string') {\n chunkIndex = point._index;\n if (point._bufferIndex < 0) {\n point._bufferIndex = 0;\n }\n while (point._index === chunkIndex && point._bufferIndex < chunk.length) {\n go(chunk.charCodeAt(point._bufferIndex));\n }\n } else {\n go(chunk);\n }\n }\n }\n\n /**\n * Deal with one code.\n *\n * @param {Code} code\n * Code.\n * @returns {undefined}\n * Nothing.\n */\n function go(code) {\n consumed = undefined;\n expectedCode = code;\n state = state(code);\n }\n\n /** @type {Effects['consume']} */\n function consume(code) {\n if (markdownLineEnding(code)) {\n point.line++;\n point.column = 1;\n point.offset += code === -3 ? 2 : 1;\n accountForPotentialSkip();\n } else if (code !== -1) {\n point.column++;\n point.offset++;\n }\n\n // Not in a string chunk.\n if (point._bufferIndex < 0) {\n point._index++;\n } else {\n point._bufferIndex++;\n\n // At end of string chunk.\n if (point._bufferIndex ===\n // Points w/ non-negative `_bufferIndex` reference\n // strings.\n /** @type {string} */\n chunks[point._index].length) {\n point._bufferIndex = -1;\n point._index++;\n }\n }\n\n // Expose the previous character.\n context.previous = code;\n\n // Mark as consumed.\n consumed = true;\n }\n\n /** @type {Effects['enter']} */\n function enter(type, fields) {\n /** @type {Token} */\n // @ts-expect-error Patch instead of assign required fields to help GC.\n const token = fields || {};\n token.type = type;\n token.start = now();\n context.events.push(['enter', token, context]);\n stack.push(token);\n return token;\n }\n\n /** @type {Effects['exit']} */\n function exit(type) {\n const token = stack.pop();\n token.end = now();\n context.events.push(['exit', token, context]);\n return token;\n }\n\n /**\n * Use results.\n *\n * @type {ReturnHandle}\n */\n function onsuccessfulconstruct(construct, info) {\n addResult(construct, info.from);\n }\n\n /**\n * Discard results.\n *\n * @type {ReturnHandle}\n */\n function onsuccessfulcheck(_, info) {\n info.restore();\n }\n\n /**\n * Factory to attempt/check/interrupt.\n *\n * @param {ReturnHandle} onreturn\n * Callback.\n * @param {{interrupt?: boolean | undefined} | undefined} [fields]\n * Fields.\n */\n function constructFactory(onreturn, fields) {\n return hook;\n\n /**\n * Handle either an object mapping codes to constructs, a list of\n * constructs, or a single construct.\n *\n * @param {Array | ConstructRecord | Construct} constructs\n * Constructs.\n * @param {State} returnState\n * State.\n * @param {State | undefined} [bogusState]\n * State.\n * @returns {State}\n * State.\n */\n function hook(constructs, returnState, bogusState) {\n /** @type {ReadonlyArray} */\n let listOfConstructs;\n /** @type {number} */\n let constructIndex;\n /** @type {Construct} */\n let currentConstruct;\n /** @type {Info} */\n let info;\n return Array.isArray(constructs) ? /* c8 ignore next 1 */\n handleListOfConstructs(constructs) : 'tokenize' in constructs ?\n // Looks like a construct.\n handleListOfConstructs([(/** @type {Construct} */constructs)]) : handleMapOfConstructs(constructs);\n\n /**\n * Handle a list of construct.\n *\n * @param {ConstructRecord} map\n * Constructs.\n * @returns {State}\n * State.\n */\n function handleMapOfConstructs(map) {\n return start;\n\n /** @type {State} */\n function start(code) {\n const left = code !== null && map[code];\n const all = code !== null && map.null;\n const list = [\n // To do: add more extension tests.\n /* c8 ignore next 2 */\n ...(Array.isArray(left) ? left : left ? [left] : []), ...(Array.isArray(all) ? all : all ? [all] : [])];\n return handleListOfConstructs(list)(code);\n }\n }\n\n /**\n * Handle a list of construct.\n *\n * @param {ReadonlyArray} list\n * Constructs.\n * @returns {State}\n * State.\n */\n function handleListOfConstructs(list) {\n listOfConstructs = list;\n constructIndex = 0;\n if (list.length === 0) {\n return bogusState;\n }\n return handleConstruct(list[constructIndex]);\n }\n\n /**\n * Handle a single construct.\n *\n * @param {Construct} construct\n * Construct.\n * @returns {State}\n * State.\n */\n function handleConstruct(construct) {\n return start;\n\n /** @type {State} */\n function start(code) {\n // To do: not needed to store if there is no bogus state, probably?\n // Currently doesn\u2019t work because `inspect` in document does a check\n // w/o a bogus, which doesn\u2019t make sense. But it does seem to help perf\n // by not storing.\n info = store();\n currentConstruct = construct;\n if (!construct.partial) {\n context.currentConstruct = construct;\n }\n\n // Always populated by defaults.\n\n if (construct.name && context.parser.constructs.disable.null.includes(construct.name)) {\n return nok(code);\n }\n return construct.tokenize.call(\n // If we do have fields, create an object w/ `context` as its\n // prototype.\n // This allows a \u201Clive binding\u201D, which is needed for `interrupt`.\n fields ? Object.assign(Object.create(context), fields) : context, effects, ok, nok)(code);\n }\n }\n\n /** @type {State} */\n function ok(code) {\n consumed = true;\n onreturn(currentConstruct, info);\n return returnState;\n }\n\n /** @type {State} */\n function nok(code) {\n consumed = true;\n info.restore();\n if (++constructIndex < listOfConstructs.length) {\n return handleConstruct(listOfConstructs[constructIndex]);\n }\n return bogusState;\n }\n }\n }\n\n /**\n * @param {Construct} construct\n * Construct.\n * @param {number} from\n * From.\n * @returns {undefined}\n * Nothing.\n */\n function addResult(construct, from) {\n if (construct.resolveAll && !resolveAllConstructs.includes(construct)) {\n resolveAllConstructs.push(construct);\n }\n if (construct.resolve) {\n splice(context.events, from, context.events.length - from, construct.resolve(context.events.slice(from), context));\n }\n if (construct.resolveTo) {\n context.events = construct.resolveTo(context.events, context);\n }\n }\n\n /**\n * Store state.\n *\n * @returns {Info}\n * Info.\n */\n function store() {\n const startPoint = now();\n const startPrevious = context.previous;\n const startCurrentConstruct = context.currentConstruct;\n const startEventsIndex = context.events.length;\n const startStack = Array.from(stack);\n return {\n from: startEventsIndex,\n restore\n };\n\n /**\n * Restore state.\n *\n * @returns {undefined}\n * Nothing.\n */\n function restore() {\n point = startPoint;\n context.previous = startPrevious;\n context.currentConstruct = startCurrentConstruct;\n context.events.length = startEventsIndex;\n stack = startStack;\n accountForPotentialSkip();\n }\n }\n\n /**\n * Move the current point a bit forward in the line when it\u2019s on a column\n * skip.\n *\n * @returns {undefined}\n * Nothing.\n */\n function accountForPotentialSkip() {\n if (point.line in columnStart && point.column < 2) {\n point.column = columnStart[point.line];\n point.offset += columnStart[point.line] - 1;\n }\n }\n}\n\n/**\n * Get the chunks from a slice of chunks in the range of a token.\n *\n * @param {ReadonlyArray} chunks\n * Chunks.\n * @param {Pick} token\n * Token.\n * @returns {Array}\n * Chunks.\n */\nfunction sliceChunks(chunks, token) {\n const startIndex = token.start._index;\n const startBufferIndex = token.start._bufferIndex;\n const endIndex = token.end._index;\n const endBufferIndex = token.end._bufferIndex;\n /** @type {Array} */\n let view;\n if (startIndex === endIndex) {\n // @ts-expect-error `_bufferIndex` is used on string chunks.\n view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)];\n } else {\n view = chunks.slice(startIndex, endIndex);\n if (startBufferIndex > -1) {\n const head = view[0];\n if (typeof head === 'string') {\n view[0] = head.slice(startBufferIndex);\n /* c8 ignore next 4 -- used to be used, no longer */\n } else {\n view.shift();\n }\n }\n if (endBufferIndex > 0) {\n // @ts-expect-error `_bufferIndex` is used on string chunks.\n view.push(chunks[endIndex].slice(0, endBufferIndex));\n }\n }\n return view;\n}\n\n/**\n * Get the string value of a slice of chunks.\n *\n * @param {ReadonlyArray} chunks\n * Chunks.\n * @param {boolean | undefined} [expandTabs=false]\n * Whether to expand tabs (default: `false`).\n * @returns {string}\n * Result.\n */\nfunction serializeChunks(chunks, expandTabs) {\n let index = -1;\n /** @type {Array} */\n const result = [];\n /** @type {boolean | undefined} */\n let atTab;\n while (++index < chunks.length) {\n const chunk = chunks[index];\n /** @type {string} */\n let value;\n if (typeof chunk === 'string') {\n value = chunk;\n } else switch (chunk) {\n case -5:\n {\n value = \"\\r\";\n break;\n }\n case -4:\n {\n value = \"\\n\";\n break;\n }\n case -3:\n {\n value = \"\\r\" + \"\\n\";\n break;\n }\n case -2:\n {\n value = expandTabs ? \" \" : \"\\t\";\n break;\n }\n case -1:\n {\n if (!expandTabs && atTab) continue;\n value = \" \";\n break;\n }\n default:\n {\n // Currently only replacement character.\n value = String.fromCharCode(chunk);\n }\n }\n atTab = chunk === -2;\n result.push(value);\n }\n return result.join('');\n}", "/**\n * @import {\n * Create,\n * FullNormalizedExtension,\n * InitialConstruct,\n * ParseContext,\n * ParseOptions\n * } from 'micromark-util-types'\n */\n\nimport { combineExtensions } from 'micromark-util-combine-extensions';\nimport { content } from './initialize/content.js';\nimport { document } from './initialize/document.js';\nimport { flow } from './initialize/flow.js';\nimport { string, text } from './initialize/text.js';\nimport * as defaultConstructs from './constructs.js';\nimport { createTokenizer } from './create-tokenizer.js';\n\n/**\n * @param {ParseOptions | null | undefined} [options]\n * Configuration (optional).\n * @returns {ParseContext}\n * Parser.\n */\nexport function parse(options) {\n const settings = options || {};\n const constructs = /** @type {FullNormalizedExtension} */\n combineExtensions([defaultConstructs, ...(settings.extensions || [])]);\n\n /** @type {ParseContext} */\n const parser = {\n constructs,\n content: create(content),\n defined: [],\n document: create(document),\n flow: create(flow),\n lazy: {},\n string: create(string),\n text: create(text)\n };\n return parser;\n\n /**\n * @param {InitialConstruct} initial\n * Construct to start with.\n * @returns {Create}\n * Create a tokenizer.\n */\n function create(initial) {\n return creator;\n /** @type {Create} */\n function creator(from) {\n return createTokenizer(parser, initial, from);\n }\n }\n}", "/**\n * @import {Event} from 'micromark-util-types'\n */\n\nimport { subtokenize } from 'micromark-util-subtokenize';\n\n/**\n * @param {Array} events\n * Events.\n * @returns {Array}\n * Events.\n */\nexport function postprocess(events) {\n while (!subtokenize(events)) {\n // Empty\n }\n return events;\n}", "/**\n * @import {Chunk, Code, Encoding, Value} from 'micromark-util-types'\n */\n\n/**\n * @callback Preprocessor\n * Preprocess a value.\n * @param {Value} value\n * Value.\n * @param {Encoding | null | undefined} [encoding]\n * Encoding when `value` is a typed array (optional).\n * @param {boolean | null | undefined} [end=false]\n * Whether this is the last chunk (default: `false`).\n * @returns {Array}\n * Chunks.\n */\n\nconst search = /[\\0\\t\\n\\r]/g;\n\n/**\n * @returns {Preprocessor}\n * Preprocess a value.\n */\nexport function preprocess() {\n let column = 1;\n let buffer = '';\n /** @type {boolean | undefined} */\n let start = true;\n /** @type {boolean | undefined} */\n let atCarriageReturn;\n return preprocessor;\n\n /** @type {Preprocessor} */\n // eslint-disable-next-line complexity\n function preprocessor(value, encoding, end) {\n /** @type {Array} */\n const chunks = [];\n /** @type {RegExpMatchArray | null} */\n let match;\n /** @type {number} */\n let next;\n /** @type {number} */\n let startPosition;\n /** @type {number} */\n let endPosition;\n /** @type {Code} */\n let code;\n value = buffer + (typeof value === 'string' ? value.toString() : new TextDecoder(encoding || undefined).decode(value));\n startPosition = 0;\n buffer = '';\n if (start) {\n // To do: `markdown-rs` actually parses BOMs (byte order mark).\n if (value.charCodeAt(0) === 65279) {\n startPosition++;\n }\n start = undefined;\n }\n while (startPosition < value.length) {\n search.lastIndex = startPosition;\n match = search.exec(value);\n endPosition = match && match.index !== undefined ? match.index : value.length;\n code = value.charCodeAt(endPosition);\n if (!match) {\n buffer = value.slice(startPosition);\n break;\n }\n if (code === 10 && startPosition === endPosition && atCarriageReturn) {\n chunks.push(-3);\n atCarriageReturn = undefined;\n } else {\n if (atCarriageReturn) {\n chunks.push(-5);\n atCarriageReturn = undefined;\n }\n if (startPosition < endPosition) {\n chunks.push(value.slice(startPosition, endPosition));\n column += endPosition - startPosition;\n }\n switch (code) {\n case 0:\n {\n chunks.push(65533);\n column++;\n break;\n }\n case 9:\n {\n next = Math.ceil(column / 4) * 4;\n chunks.push(-2);\n while (column++ < next) chunks.push(-1);\n break;\n }\n case 10:\n {\n chunks.push(-4);\n column = 1;\n break;\n }\n default:\n {\n atCarriageReturn = true;\n column = 1;\n }\n }\n }\n startPosition = endPosition + 1;\n }\n if (end) {\n if (atCarriageReturn) chunks.push(-5);\n if (buffer) chunks.push(buffer);\n chunks.push(null);\n }\n return chunks;\n }\n}", "/**\n * @import {Encoding, Value} from 'micromark-util-types'\n */\n\n/**\n * @typedef {import('micromark-util-types').Options} Options\n */\n\nimport { compile } from './lib/compile.js';\nimport { parse } from './lib/parse.js';\nimport { postprocess } from './lib/postprocess.js';\nimport { preprocess } from './lib/preprocess.js';\nexport { compile } from './lib/compile.js';\nexport { parse } from './lib/parse.js';\nexport { postprocess } from './lib/postprocess.js';\nexport { preprocess } from './lib/preprocess.js';\n\n/**\n * Compile markdown to HTML.\n *\n * > Note: which encodings are supported depends on the engine.\n * > For info on Node.js, see:\n * > .\n *\n * @overload\n * @param {Value} value\n * Markdown to parse (`string` or `Uint8Array`).\n * @param {Encoding | null | undefined} encoding\n * Character encoding to understand `value` as when it\u2019s a `Uint8Array`\n * (`string`, default: `'utf8'`).\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {string}\n * Compiled HTML.\n *\n * @overload\n * @param {Value} value\n * Markdown to parse (`string` or `Uint8Array`).\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {string}\n * Compiled HTML.\n *\n * @param {Value} value\n * Markdown to parse (`string` or `Uint8Array`).\n * @param {Encoding | Options | null | undefined} [encoding]\n * Character encoding to understand `value` as when it\u2019s a `Uint8Array`\n * (`string`, default: `'utf8'`).\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {string}\n * Compiled HTML.\n */\nexport function micromark(value, encoding, options) {\n if (typeof encoding !== 'string') {\n options = encoding;\n encoding = undefined;\n }\n return compile(options)(postprocess(parse(options).document().write(preprocess()(value, encoding, true))));\n}", "import { decodeNamedCharacterReference } from 'decode-named-character-reference';\nimport { decodeNumericCharacterReference } from 'micromark-util-decode-numeric-character-reference';\nconst characterEscapeOrReference = /\\\\([!-/:-@[-`{-~])|&(#(?:\\d{1,7}|x[\\da-f]{1,6})|[\\da-z]{1,31});/gi;\n\n/**\n * Decode markdown strings (which occur in places such as fenced code info\n * strings, destinations, labels, and titles).\n *\n * The \u201Cstring\u201D content type allows character escapes and -references.\n * This decodes those.\n *\n * @param {string} value\n * Value to decode.\n * @returns {string}\n * Decoded value.\n */\nexport function decodeString(value) {\n return value.replace(characterEscapeOrReference, decode);\n}\n\n/**\n * @param {string} $0\n * Match.\n * @param {string} $1\n * Character escape.\n * @param {string} $2\n * Character reference.\n * @returns {string}\n * Decoded value\n */\nfunction decode($0, $1, $2) {\n if ($1) {\n // Escape.\n return $1;\n }\n\n // Reference.\n const head = $2.charCodeAt(0);\n if (head === 35) {\n const head = $2.charCodeAt(1);\n const hex = head === 120 || head === 88;\n return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10);\n }\n return decodeNamedCharacterReference($2) || $0;\n}", "/**\n * @import {\n * Break,\n * Blockquote,\n * Code,\n * Definition,\n * Emphasis,\n * Heading,\n * Html,\n * Image,\n * InlineCode,\n * Link,\n * ListItem,\n * List,\n * Nodes,\n * Paragraph,\n * PhrasingContent,\n * ReferenceType,\n * Root,\n * Strong,\n * Text,\n * ThematicBreak\n * } from 'mdast'\n * @import {\n * Encoding,\n * Event,\n * Token,\n * Value\n * } from 'micromark-util-types'\n * @import {Point} from 'unist'\n * @import {\n * CompileContext,\n * CompileData,\n * Config,\n * Extension,\n * Handle,\n * OnEnterError,\n * Options\n * } from './types.js'\n */\n\nimport { toString } from 'mdast-util-to-string';\nimport { parse, postprocess, preprocess } from 'micromark';\nimport { decodeNumericCharacterReference } from 'micromark-util-decode-numeric-character-reference';\nimport { decodeString } from 'micromark-util-decode-string';\nimport { normalizeIdentifier } from 'micromark-util-normalize-identifier';\nimport { decodeNamedCharacterReference } from 'decode-named-character-reference';\nimport { stringifyPosition } from 'unist-util-stringify-position';\nconst own = {}.hasOwnProperty;\n\n/**\n * Turn markdown into a syntax tree.\n *\n * @overload\n * @param {Value} value\n * @param {Encoding | null | undefined} [encoding]\n * @param {Options | null | undefined} [options]\n * @returns {Root}\n *\n * @overload\n * @param {Value} value\n * @param {Options | null | undefined} [options]\n * @returns {Root}\n *\n * @param {Value} value\n * Markdown to parse.\n * @param {Encoding | Options | null | undefined} [encoding]\n * Character encoding for when `value` is `Buffer`.\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {Root}\n * mdast tree.\n */\nexport function fromMarkdown(value, encoding, options) {\n if (encoding && typeof encoding === 'object') {\n options = encoding;\n encoding = undefined;\n }\n return compiler(options)(postprocess(parse(options).document().write(preprocess()(value, encoding, true))));\n}\n\n/**\n * Note this compiler only understand complete buffering, not streaming.\n *\n * @param {Options | null | undefined} [options]\n */\nfunction compiler(options) {\n /** @type {Config} */\n const config = {\n transforms: [],\n canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'],\n enter: {\n autolink: opener(link),\n autolinkProtocol: onenterdata,\n autolinkEmail: onenterdata,\n atxHeading: opener(heading),\n blockQuote: opener(blockQuote),\n characterEscape: onenterdata,\n characterReference: onenterdata,\n codeFenced: opener(codeFlow),\n codeFencedFenceInfo: buffer,\n codeFencedFenceMeta: buffer,\n codeIndented: opener(codeFlow, buffer),\n codeText: opener(codeText, buffer),\n codeTextData: onenterdata,\n data: onenterdata,\n codeFlowValue: onenterdata,\n definition: opener(definition),\n definitionDestinationString: buffer,\n definitionLabelString: buffer,\n definitionTitleString: buffer,\n emphasis: opener(emphasis),\n hardBreakEscape: opener(hardBreak),\n hardBreakTrailing: opener(hardBreak),\n htmlFlow: opener(html, buffer),\n htmlFlowData: onenterdata,\n htmlText: opener(html, buffer),\n htmlTextData: onenterdata,\n image: opener(image),\n label: buffer,\n link: opener(link),\n listItem: opener(listItem),\n listItemValue: onenterlistitemvalue,\n listOrdered: opener(list, onenterlistordered),\n listUnordered: opener(list),\n paragraph: opener(paragraph),\n reference: onenterreference,\n referenceString: buffer,\n resourceDestinationString: buffer,\n resourceTitleString: buffer,\n setextHeading: opener(heading),\n strong: opener(strong),\n thematicBreak: opener(thematicBreak)\n },\n exit: {\n atxHeading: closer(),\n atxHeadingSequence: onexitatxheadingsequence,\n autolink: closer(),\n autolinkEmail: onexitautolinkemail,\n autolinkProtocol: onexitautolinkprotocol,\n blockQuote: closer(),\n characterEscapeValue: onexitdata,\n characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker,\n characterReferenceMarkerNumeric: onexitcharacterreferencemarker,\n characterReferenceValue: onexitcharacterreferencevalue,\n characterReference: onexitcharacterreference,\n codeFenced: closer(onexitcodefenced),\n codeFencedFence: onexitcodefencedfence,\n codeFencedFenceInfo: onexitcodefencedfenceinfo,\n codeFencedFenceMeta: onexitcodefencedfencemeta,\n codeFlowValue: onexitdata,\n codeIndented: closer(onexitcodeindented),\n codeText: closer(onexitcodetext),\n codeTextData: onexitdata,\n data: onexitdata,\n definition: closer(),\n definitionDestinationString: onexitdefinitiondestinationstring,\n definitionLabelString: onexitdefinitionlabelstring,\n definitionTitleString: onexitdefinitiontitlestring,\n emphasis: closer(),\n hardBreakEscape: closer(onexithardbreak),\n hardBreakTrailing: closer(onexithardbreak),\n htmlFlow: closer(onexithtmlflow),\n htmlFlowData: onexitdata,\n htmlText: closer(onexithtmltext),\n htmlTextData: onexitdata,\n image: closer(onexitimage),\n label: onexitlabel,\n labelText: onexitlabeltext,\n lineEnding: onexitlineending,\n link: closer(onexitlink),\n listItem: closer(),\n listOrdered: closer(),\n listUnordered: closer(),\n paragraph: closer(),\n referenceString: onexitreferencestring,\n resourceDestinationString: onexitresourcedestinationstring,\n resourceTitleString: onexitresourcetitlestring,\n resource: onexitresource,\n setextHeading: closer(onexitsetextheading),\n setextHeadingLineSequence: onexitsetextheadinglinesequence,\n setextHeadingText: onexitsetextheadingtext,\n strong: closer(),\n thematicBreak: closer()\n }\n };\n configure(config, (options || {}).mdastExtensions || []);\n\n /** @type {CompileData} */\n const data = {};\n return compile;\n\n /**\n * Turn micromark events into an mdast tree.\n *\n * @param {Array} events\n * Events.\n * @returns {Root}\n * mdast tree.\n */\n function compile(events) {\n /** @type {Root} */\n let tree = {\n type: 'root',\n children: []\n };\n /** @type {Omit} */\n const context = {\n stack: [tree],\n tokenStack: [],\n config,\n enter,\n exit,\n buffer,\n resume,\n data\n };\n /** @type {Array} */\n const listStack = [];\n let index = -1;\n while (++index < events.length) {\n // We preprocess lists to add `listItem` tokens, and to infer whether\n // items the list itself are spread out.\n if (events[index][1].type === \"listOrdered\" || events[index][1].type === \"listUnordered\") {\n if (events[index][0] === 'enter') {\n listStack.push(index);\n } else {\n const tail = listStack.pop();\n index = prepareList(events, tail, index);\n }\n }\n }\n index = -1;\n while (++index < events.length) {\n const handler = config[events[index][0]];\n if (own.call(handler, events[index][1].type)) {\n handler[events[index][1].type].call(Object.assign({\n sliceSerialize: events[index][2].sliceSerialize\n }, context), events[index][1]);\n }\n }\n\n // Handle tokens still being open.\n if (context.tokenStack.length > 0) {\n const tail = context.tokenStack[context.tokenStack.length - 1];\n const handler = tail[1] || defaultOnError;\n handler.call(context, undefined, tail[0]);\n }\n\n // Figure out `root` position.\n tree.position = {\n start: point(events.length > 0 ? events[0][1].start : {\n line: 1,\n column: 1,\n offset: 0\n }),\n end: point(events.length > 0 ? events[events.length - 2][1].end : {\n line: 1,\n column: 1,\n offset: 0\n })\n };\n\n // Call transforms.\n index = -1;\n while (++index < config.transforms.length) {\n tree = config.transforms[index](tree) || tree;\n }\n return tree;\n }\n\n /**\n * @param {Array} events\n * @param {number} start\n * @param {number} length\n * @returns {number}\n */\n function prepareList(events, start, length) {\n let index = start - 1;\n let containerBalance = -1;\n let listSpread = false;\n /** @type {Token | undefined} */\n let listItem;\n /** @type {number | undefined} */\n let lineIndex;\n /** @type {number | undefined} */\n let firstBlankLineIndex;\n /** @type {boolean | undefined} */\n let atMarker;\n while (++index <= length) {\n const event = events[index];\n switch (event[1].type) {\n case \"listUnordered\":\n case \"listOrdered\":\n case \"blockQuote\":\n {\n if (event[0] === 'enter') {\n containerBalance++;\n } else {\n containerBalance--;\n }\n atMarker = undefined;\n break;\n }\n case \"lineEndingBlank\":\n {\n if (event[0] === 'enter') {\n if (listItem && !atMarker && !containerBalance && !firstBlankLineIndex) {\n firstBlankLineIndex = index;\n }\n atMarker = undefined;\n }\n break;\n }\n case \"linePrefix\":\n case \"listItemValue\":\n case \"listItemMarker\":\n case \"listItemPrefix\":\n case \"listItemPrefixWhitespace\":\n {\n // Empty.\n\n break;\n }\n default:\n {\n atMarker = undefined;\n }\n }\n if (!containerBalance && event[0] === 'enter' && event[1].type === \"listItemPrefix\" || containerBalance === -1 && event[0] === 'exit' && (event[1].type === \"listUnordered\" || event[1].type === \"listOrdered\")) {\n if (listItem) {\n let tailIndex = index;\n lineIndex = undefined;\n while (tailIndex--) {\n const tailEvent = events[tailIndex];\n if (tailEvent[1].type === \"lineEnding\" || tailEvent[1].type === \"lineEndingBlank\") {\n if (tailEvent[0] === 'exit') continue;\n if (lineIndex) {\n events[lineIndex][1].type = \"lineEndingBlank\";\n listSpread = true;\n }\n tailEvent[1].type = \"lineEnding\";\n lineIndex = tailIndex;\n } else if (tailEvent[1].type === \"linePrefix\" || tailEvent[1].type === \"blockQuotePrefix\" || tailEvent[1].type === \"blockQuotePrefixWhitespace\" || tailEvent[1].type === \"blockQuoteMarker\" || tailEvent[1].type === \"listItemIndent\") {\n // Empty\n } else {\n break;\n }\n }\n if (firstBlankLineIndex && (!lineIndex || firstBlankLineIndex < lineIndex)) {\n listItem._spread = true;\n }\n\n // Fix position.\n listItem.end = Object.assign({}, lineIndex ? events[lineIndex][1].start : event[1].end);\n events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]);\n index++;\n length++;\n }\n\n // Create a new list item.\n if (event[1].type === \"listItemPrefix\") {\n /** @type {Token} */\n const item = {\n type: 'listItem',\n _spread: false,\n start: Object.assign({}, event[1].start),\n // @ts-expect-error: we\u2019ll add `end` in a second.\n end: undefined\n };\n listItem = item;\n events.splice(index, 0, ['enter', item, event[2]]);\n index++;\n length++;\n firstBlankLineIndex = undefined;\n atMarker = true;\n }\n }\n }\n events[start][1]._spread = listSpread;\n return length;\n }\n\n /**\n * Create an opener handle.\n *\n * @param {(token: Token) => Nodes} create\n * Create a node.\n * @param {Handle | undefined} [and]\n * Optional function to also run.\n * @returns {Handle}\n * Handle.\n */\n function opener(create, and) {\n return open;\n\n /**\n * @this {CompileContext}\n * @param {Token} token\n * @returns {undefined}\n */\n function open(token) {\n enter.call(this, create(token), token);\n if (and) and.call(this, token);\n }\n }\n\n /**\n * @type {CompileContext['buffer']}\n */\n function buffer() {\n this.stack.push({\n type: 'fragment',\n children: []\n });\n }\n\n /**\n * @type {CompileContext['enter']}\n */\n function enter(node, token, errorHandler) {\n const parent = this.stack[this.stack.length - 1];\n /** @type {Array} */\n const siblings = parent.children;\n siblings.push(node);\n this.stack.push(node);\n this.tokenStack.push([token, errorHandler || undefined]);\n node.position = {\n start: point(token.start),\n // @ts-expect-error: `end` will be patched later.\n end: undefined\n };\n }\n\n /**\n * Create a closer handle.\n *\n * @param {Handle | undefined} [and]\n * Optional function to also run.\n * @returns {Handle}\n * Handle.\n */\n function closer(and) {\n return close;\n\n /**\n * @this {CompileContext}\n * @param {Token} token\n * @returns {undefined}\n */\n function close(token) {\n if (and) and.call(this, token);\n exit.call(this, token);\n }\n }\n\n /**\n * @type {CompileContext['exit']}\n */\n function exit(token, onExitError) {\n const node = this.stack.pop();\n const open = this.tokenStack.pop();\n if (!open) {\n throw new Error('Cannot close `' + token.type + '` (' + stringifyPosition({\n start: token.start,\n end: token.end\n }) + '): it\u2019s not open');\n } else if (open[0].type !== token.type) {\n if (onExitError) {\n onExitError.call(this, token, open[0]);\n } else {\n const handler = open[1] || defaultOnError;\n handler.call(this, token, open[0]);\n }\n }\n node.position.end = point(token.end);\n }\n\n /**\n * @type {CompileContext['resume']}\n */\n function resume() {\n return toString(this.stack.pop());\n }\n\n //\n // Handlers.\n //\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onenterlistordered() {\n this.data.expectingFirstListItemValue = true;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onenterlistitemvalue(token) {\n if (this.data.expectingFirstListItemValue) {\n const ancestor = this.stack[this.stack.length - 2];\n ancestor.start = Number.parseInt(this.sliceSerialize(token), 10);\n this.data.expectingFirstListItemValue = undefined;\n }\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitcodefencedfenceinfo() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.lang = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitcodefencedfencemeta() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.meta = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitcodefencedfence() {\n // Exit if this is the closing fence.\n if (this.data.flowCodeInside) return;\n this.buffer();\n this.data.flowCodeInside = true;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitcodefenced() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.value = data.replace(/^(\\r?\\n|\\r)|(\\r?\\n|\\r)$/g, '');\n this.data.flowCodeInside = undefined;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitcodeindented() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.value = data.replace(/(\\r?\\n|\\r)$/g, '');\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitdefinitionlabelstring(token) {\n const label = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.label = label;\n node.identifier = normalizeIdentifier(this.sliceSerialize(token)).toLowerCase();\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitdefinitiontitlestring() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.title = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitdefinitiondestinationstring() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.url = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitatxheadingsequence(token) {\n const node = this.stack[this.stack.length - 1];\n if (!node.depth) {\n const depth = this.sliceSerialize(token).length;\n node.depth = depth;\n }\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitsetextheadingtext() {\n this.data.setextHeadingSlurpLineEnding = true;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitsetextheadinglinesequence(token) {\n const node = this.stack[this.stack.length - 1];\n node.depth = this.sliceSerialize(token).codePointAt(0) === 61 ? 1 : 2;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitsetextheading() {\n this.data.setextHeadingSlurpLineEnding = undefined;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onenterdata(token) {\n const node = this.stack[this.stack.length - 1];\n /** @type {Array} */\n const siblings = node.children;\n let tail = siblings[siblings.length - 1];\n if (!tail || tail.type !== 'text') {\n // Add a new text node.\n tail = text();\n tail.position = {\n start: point(token.start),\n // @ts-expect-error: we\u2019ll add `end` later.\n end: undefined\n };\n siblings.push(tail);\n }\n this.stack.push(tail);\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitdata(token) {\n const tail = this.stack.pop();\n tail.value += this.sliceSerialize(token);\n tail.position.end = point(token.end);\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitlineending(token) {\n const context = this.stack[this.stack.length - 1];\n // If we\u2019re at a hard break, include the line ending in there.\n if (this.data.atHardBreak) {\n const tail = context.children[context.children.length - 1];\n tail.position.end = point(token.end);\n this.data.atHardBreak = undefined;\n return;\n }\n if (!this.data.setextHeadingSlurpLineEnding && config.canContainEols.includes(context.type)) {\n onenterdata.call(this, token);\n onexitdata.call(this, token);\n }\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexithardbreak() {\n this.data.atHardBreak = true;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexithtmlflow() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.value = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexithtmltext() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.value = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitcodetext() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.value = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitlink() {\n const node = this.stack[this.stack.length - 1];\n // Note: there are also `identifier` and `label` fields on this link node!\n // These are used / cleaned here.\n\n // To do: clean.\n if (this.data.inReference) {\n /** @type {ReferenceType} */\n const referenceType = this.data.referenceType || 'shortcut';\n node.type += 'Reference';\n // @ts-expect-error: mutate.\n node.referenceType = referenceType;\n // @ts-expect-error: mutate.\n delete node.url;\n delete node.title;\n } else {\n // @ts-expect-error: mutate.\n delete node.identifier;\n // @ts-expect-error: mutate.\n delete node.label;\n }\n this.data.referenceType = undefined;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitimage() {\n const node = this.stack[this.stack.length - 1];\n // Note: there are also `identifier` and `label` fields on this link node!\n // These are used / cleaned here.\n\n // To do: clean.\n if (this.data.inReference) {\n /** @type {ReferenceType} */\n const referenceType = this.data.referenceType || 'shortcut';\n node.type += 'Reference';\n // @ts-expect-error: mutate.\n node.referenceType = referenceType;\n // @ts-expect-error: mutate.\n delete node.url;\n delete node.title;\n } else {\n // @ts-expect-error: mutate.\n delete node.identifier;\n // @ts-expect-error: mutate.\n delete node.label;\n }\n this.data.referenceType = undefined;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitlabeltext(token) {\n const string = this.sliceSerialize(token);\n const ancestor = this.stack[this.stack.length - 2];\n // @ts-expect-error: stash this on the node, as it might become a reference\n // later.\n ancestor.label = decodeString(string);\n // @ts-expect-error: same as above.\n ancestor.identifier = normalizeIdentifier(string).toLowerCase();\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitlabel() {\n const fragment = this.stack[this.stack.length - 1];\n const value = this.resume();\n const node = this.stack[this.stack.length - 1];\n // Assume a reference.\n this.data.inReference = true;\n if (node.type === 'link') {\n /** @type {Array} */\n const children = fragment.children;\n node.children = children;\n } else {\n node.alt = value;\n }\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitresourcedestinationstring() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.url = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitresourcetitlestring() {\n const data = this.resume();\n const node = this.stack[this.stack.length - 1];\n node.title = data;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitresource() {\n this.data.inReference = undefined;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onenterreference() {\n this.data.referenceType = 'collapsed';\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitreferencestring(token) {\n const label = this.resume();\n const node = this.stack[this.stack.length - 1];\n // @ts-expect-error: stash this on the node, as it might become a reference\n // later.\n node.label = label;\n // @ts-expect-error: same as above.\n node.identifier = normalizeIdentifier(this.sliceSerialize(token)).toLowerCase();\n this.data.referenceType = 'full';\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n\n function onexitcharacterreferencemarker(token) {\n this.data.characterReferenceType = token.type;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitcharacterreferencevalue(token) {\n const data = this.sliceSerialize(token);\n const type = this.data.characterReferenceType;\n /** @type {string} */\n let value;\n if (type) {\n value = decodeNumericCharacterReference(data, type === \"characterReferenceMarkerNumeric\" ? 10 : 16);\n this.data.characterReferenceType = undefined;\n } else {\n const result = decodeNamedCharacterReference(data);\n value = result;\n }\n const tail = this.stack[this.stack.length - 1];\n tail.value += value;\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitcharacterreference(token) {\n const tail = this.stack.pop();\n tail.position.end = point(token.end);\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitautolinkprotocol(token) {\n onexitdata.call(this, token);\n const node = this.stack[this.stack.length - 1];\n node.url = this.sliceSerialize(token);\n }\n\n /**\n * @this {CompileContext}\n * @type {Handle}\n */\n function onexitautolinkemail(token) {\n onexitdata.call(this, token);\n const node = this.stack[this.stack.length - 1];\n node.url = 'mailto:' + this.sliceSerialize(token);\n }\n\n //\n // Creaters.\n //\n\n /** @returns {Blockquote} */\n function blockQuote() {\n return {\n type: 'blockquote',\n children: []\n };\n }\n\n /** @returns {Code} */\n function codeFlow() {\n return {\n type: 'code',\n lang: null,\n meta: null,\n value: ''\n };\n }\n\n /** @returns {InlineCode} */\n function codeText() {\n return {\n type: 'inlineCode',\n value: ''\n };\n }\n\n /** @returns {Definition} */\n function definition() {\n return {\n type: 'definition',\n identifier: '',\n label: null,\n title: null,\n url: ''\n };\n }\n\n /** @returns {Emphasis} */\n function emphasis() {\n return {\n type: 'emphasis',\n children: []\n };\n }\n\n /** @returns {Heading} */\n function heading() {\n return {\n type: 'heading',\n // @ts-expect-error `depth` will be set later.\n depth: 0,\n children: []\n };\n }\n\n /** @returns {Break} */\n function hardBreak() {\n return {\n type: 'break'\n };\n }\n\n /** @returns {Html} */\n function html() {\n return {\n type: 'html',\n value: ''\n };\n }\n\n /** @returns {Image} */\n function image() {\n return {\n type: 'image',\n title: null,\n url: '',\n alt: null\n };\n }\n\n /** @returns {Link} */\n function link() {\n return {\n type: 'link',\n title: null,\n url: '',\n children: []\n };\n }\n\n /**\n * @param {Token} token\n * @returns {List}\n */\n function list(token) {\n return {\n type: 'list',\n ordered: token.type === 'listOrdered',\n start: null,\n spread: token._spread,\n children: []\n };\n }\n\n /**\n * @param {Token} token\n * @returns {ListItem}\n */\n function listItem(token) {\n return {\n type: 'listItem',\n spread: token._spread,\n checked: null,\n children: []\n };\n }\n\n /** @returns {Paragraph} */\n function paragraph() {\n return {\n type: 'paragraph',\n children: []\n };\n }\n\n /** @returns {Strong} */\n function strong() {\n return {\n type: 'strong',\n children: []\n };\n }\n\n /** @returns {Text} */\n function text() {\n return {\n type: 'text',\n value: ''\n };\n }\n\n /** @returns {ThematicBreak} */\n function thematicBreak() {\n return {\n type: 'thematicBreak'\n };\n }\n}\n\n/**\n * Copy a point-like value.\n *\n * @param {Point} d\n * Point-like value.\n * @returns {Point}\n * unist point.\n */\nfunction point(d) {\n return {\n line: d.line,\n column: d.column,\n offset: d.offset\n };\n}\n\n/**\n * @param {Config} combined\n * @param {Array | Extension>} extensions\n * @returns {undefined}\n */\nfunction configure(combined, extensions) {\n let index = -1;\n while (++index < extensions.length) {\n const value = extensions[index];\n if (Array.isArray(value)) {\n configure(combined, value);\n } else {\n extension(combined, value);\n }\n }\n}\n\n/**\n * @param {Config} combined\n * @param {Extension} extension\n * @returns {undefined}\n */\nfunction extension(combined, extension) {\n /** @type {keyof Extension} */\n let key;\n for (key in extension) {\n if (own.call(extension, key)) {\n switch (key) {\n case 'canContainEols':\n {\n const right = extension[key];\n if (right) {\n combined[key].push(...right);\n }\n break;\n }\n case 'transforms':\n {\n const right = extension[key];\n if (right) {\n combined[key].push(...right);\n }\n break;\n }\n case 'enter':\n case 'exit':\n {\n const right = extension[key];\n if (right) {\n Object.assign(combined[key], right);\n }\n break;\n }\n // No default\n }\n }\n }\n}\n\n/** @type {OnEnterError} */\nfunction defaultOnError(left, right) {\n if (left) {\n throw new Error('Cannot close `' + left.type + '` (' + stringifyPosition({\n start: left.start,\n end: left.end\n }) + '): a different token (`' + right.type + '`, ' + stringifyPosition({\n start: right.start,\n end: right.end\n }) + ') is open');\n } else {\n throw new Error('Cannot close document, a token (`' + right.type + '`, ' + stringifyPosition({\n start: right.start,\n end: right.end\n }) + ') is still open');\n }\n}", "// Note: types exported from `index.d.ts`.\nexport { fromMarkdown } from './lib/index.js';", "/**\n * @typedef {import('mdast').Root} Root\n * @typedef {import('mdast-util-from-markdown').Options} FromMarkdownOptions\n * @typedef {import('unified').Parser} Parser\n * @typedef {import('unified').Processor} Processor\n */\n\n/**\n * @typedef {Omit} Options\n */\n\nimport {fromMarkdown} from 'mdast-util-from-markdown'\n\n/**\n * Aadd support for parsing from markdown.\n *\n * @param {Readonly | null | undefined} [options]\n * Configuration (optional).\n * @returns {undefined}\n * Nothing.\n */\nexport default function remarkParse(options) {\n /** @type {Processor} */\n // @ts-expect-error: TS in JSDoc generates wrong types if `this` is typed regularly.\n const self = this\n\n self.parser = parser\n\n /**\n * @type {Parser}\n */\n function parser(doc) {\n return fromMarkdown(doc, {\n ...self.data('settings'),\n ...options,\n // Note: these options are not in the readme.\n // The goal is for them to be set by plugins on `data` instead of being\n // passed by users.\n extensions: self.data('micromarkExtensions') || [],\n mdastExtensions: self.data('fromMarkdownExtensions') || []\n })\n }\n}\n", "// Note: types exposed from `index.d.ts`.\nexport {default} from './lib/index.js'\n", "/**\n * @import {Element} from 'hast'\n * @import {Blockquote} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `blockquote` node into hast.\n *\n * @param {State} state\n * Info passed around.\n * @param {Blockquote} node\n * mdast node.\n * @returns {Element}\n * hast node.\n */\nexport function blockquote(state, node) {\n /** @type {Element} */\n const result = {\n type: 'element',\n tagName: 'blockquote',\n properties: {},\n children: state.wrap(state.all(node), true)\n }\n state.patch(node, result)\n return state.applyData(node, result)\n}\n", "/**\n * @import {Element, Text} from 'hast'\n * @import {Break} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `break` node into hast.\n *\n * @param {State} state\n * Info passed around.\n * @param {Break} node\n * mdast node.\n * @returns {Array}\n * hast element content.\n */\nexport function hardBreak(state, node) {\n /** @type {Element} */\n const result = {type: 'element', tagName: 'br', properties: {}, children: []}\n state.patch(node, result)\n return [state.applyData(node, result), {type: 'text', value: '\\n'}]\n}\n", "/**\n * @import {Element, Properties} from 'hast'\n * @import {Code} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `code` node into hast.\n *\n * @param {State} state\n * Info passed around.\n * @param {Code} node\n * mdast node.\n * @returns {Element}\n * hast node.\n */\nexport function code(state, node) {\n const value = node.value ? node.value + '\\n' : ''\n /** @type {Properties} */\n const properties = {}\n // Someone can write `js python ruby`.\n const language = node.lang ? node.lang.split(/\\s+/) : []\n\n // GH/CM still drop the non-first languages.\n if (language.length > 0) {\n properties.className = ['language-' + language[0]]\n }\n\n // Create ``.\n /** @type {Element} */\n let result = {\n type: 'element',\n tagName: 'code',\n properties,\n children: [{type: 'text', value}]\n }\n\n if (node.meta) {\n result.data = {meta: node.meta}\n }\n\n state.patch(node, result)\n result = state.applyData(node, result)\n\n // Create `
    `.\n  result = {type: 'element', tagName: 'pre', properties: {}, children: [result]}\n  state.patch(node, result)\n  return result\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {Delete} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `delete` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Delete} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function strikethrough(state, node) {\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'del',\n    properties: {},\n    children: state.all(node)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {Emphasis} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `emphasis` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Emphasis} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function emphasis(state, node) {\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'em',\n    properties: {},\n    children: state.all(node)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {FootnoteReference} from 'mdast'\n * @import {State} from '../state.js'\n */\n\nimport {normalizeUri} from 'micromark-util-sanitize-uri'\n\n/**\n * Turn an mdast `footnoteReference` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {FootnoteReference} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function footnoteReference(state, node) {\n  const clobberPrefix =\n    typeof state.options.clobberPrefix === 'string'\n      ? state.options.clobberPrefix\n      : 'user-content-'\n  const id = String(node.identifier).toUpperCase()\n  const safeId = normalizeUri(id.toLowerCase())\n  const index = state.footnoteOrder.indexOf(id)\n  /** @type {number} */\n  let counter\n\n  let reuseCounter = state.footnoteCounts.get(id)\n\n  if (reuseCounter === undefined) {\n    reuseCounter = 0\n    state.footnoteOrder.push(id)\n    counter = state.footnoteOrder.length\n  } else {\n    counter = index + 1\n  }\n\n  reuseCounter += 1\n  state.footnoteCounts.set(id, reuseCounter)\n\n  /** @type {Element} */\n  const link = {\n    type: 'element',\n    tagName: 'a',\n    properties: {\n      href: '#' + clobberPrefix + 'fn-' + safeId,\n      id:\n        clobberPrefix +\n        'fnref-' +\n        safeId +\n        (reuseCounter > 1 ? '-' + reuseCounter : ''),\n      dataFootnoteRef: true,\n      ariaDescribedBy: ['footnote-label']\n    },\n    children: [{type: 'text', value: String(counter)}]\n  }\n  state.patch(node, link)\n\n  /** @type {Element} */\n  const sup = {\n    type: 'element',\n    tagName: 'sup',\n    properties: {},\n    children: [link]\n  }\n  state.patch(node, sup)\n  return state.applyData(node, sup)\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {Heading} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `heading` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Heading} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function heading(state, node) {\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'h' + node.depth,\n    properties: {},\n    children: state.all(node)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {Html} from 'mdast'\n * @import {State} from '../state.js'\n * @import {Raw} from '../../index.js'\n */\n\n/**\n * Turn an mdast `html` node into hast (`raw` node in dangerous mode, otherwise\n * nothing).\n *\n * @param {State} state\n *   Info passed around.\n * @param {Html} node\n *   mdast node.\n * @returns {Element | Raw | undefined}\n *   hast node.\n */\nexport function html(state, node) {\n  if (state.options.allowDangerousHtml) {\n    /** @type {Raw} */\n    const result = {type: 'raw', value: node.value}\n    state.patch(node, result)\n    return state.applyData(node, result)\n  }\n\n  return undefined\n}\n", "/**\n * @import {ElementContent} from 'hast'\n * @import {Reference, Nodes} from 'mdast'\n * @import {State} from './state.js'\n */\n\n/**\n * Return the content of a reference without definition as plain text.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Extract} node\n *   Reference node (image, link).\n * @returns {Array}\n *   hast content.\n */\nexport function revert(state, node) {\n  const subtype = node.referenceType\n  let suffix = ']'\n\n  if (subtype === 'collapsed') {\n    suffix += '[]'\n  } else if (subtype === 'full') {\n    suffix += '[' + (node.label || node.identifier) + ']'\n  }\n\n  if (node.type === 'imageReference') {\n    return [{type: 'text', value: '![' + node.alt + suffix}]\n  }\n\n  const contents = state.all(node)\n  const head = contents[0]\n\n  if (head && head.type === 'text') {\n    head.value = '[' + head.value\n  } else {\n    contents.unshift({type: 'text', value: '['})\n  }\n\n  const tail = contents[contents.length - 1]\n\n  if (tail && tail.type === 'text') {\n    tail.value += suffix\n  } else {\n    contents.push({type: 'text', value: suffix})\n  }\n\n  return contents\n}\n", "/**\n * @import {ElementContent, Element, Properties} from 'hast'\n * @import {ImageReference} from 'mdast'\n * @import {State} from '../state.js'\n */\n\nimport {normalizeUri} from 'micromark-util-sanitize-uri'\nimport {revert} from '../revert.js'\n\n/**\n * Turn an mdast `imageReference` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {ImageReference} node\n *   mdast node.\n * @returns {Array | ElementContent}\n *   hast node.\n */\nexport function imageReference(state, node) {\n  const id = String(node.identifier).toUpperCase()\n  const definition = state.definitionById.get(id)\n\n  if (!definition) {\n    return revert(state, node)\n  }\n\n  /** @type {Properties} */\n  const properties = {src: normalizeUri(definition.url || ''), alt: node.alt}\n\n  if (definition.title !== null && definition.title !== undefined) {\n    properties.title = definition.title\n  }\n\n  /** @type {Element} */\n  const result = {type: 'element', tagName: 'img', properties, children: []}\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element, Properties} from 'hast'\n * @import {Image} from 'mdast'\n * @import {State} from '../state.js'\n */\n\nimport {normalizeUri} from 'micromark-util-sanitize-uri'\n\n/**\n * Turn an mdast `image` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Image} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function image(state, node) {\n  /** @type {Properties} */\n  const properties = {src: normalizeUri(node.url)}\n\n  if (node.alt !== null && node.alt !== undefined) {\n    properties.alt = node.alt\n  }\n\n  if (node.title !== null && node.title !== undefined) {\n    properties.title = node.title\n  }\n\n  /** @type {Element} */\n  const result = {type: 'element', tagName: 'img', properties, children: []}\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element, Text} from 'hast'\n * @import {InlineCode} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `inlineCode` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {InlineCode} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function inlineCode(state, node) {\n  /** @type {Text} */\n  const text = {type: 'text', value: node.value.replace(/\\r?\\n|\\r/g, ' ')}\n  state.patch(node, text)\n\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'code',\n    properties: {},\n    children: [text]\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {ElementContent, Element, Properties} from 'hast'\n * @import {LinkReference} from 'mdast'\n * @import {State} from '../state.js'\n */\n\nimport {normalizeUri} from 'micromark-util-sanitize-uri'\nimport {revert} from '../revert.js'\n\n/**\n * Turn an mdast `linkReference` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {LinkReference} node\n *   mdast node.\n * @returns {Array | ElementContent}\n *   hast node.\n */\nexport function linkReference(state, node) {\n  const id = String(node.identifier).toUpperCase()\n  const definition = state.definitionById.get(id)\n\n  if (!definition) {\n    return revert(state, node)\n  }\n\n  /** @type {Properties} */\n  const properties = {href: normalizeUri(definition.url || '')}\n\n  if (definition.title !== null && definition.title !== undefined) {\n    properties.title = definition.title\n  }\n\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'a',\n    properties,\n    children: state.all(node)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element, Properties} from 'hast'\n * @import {Link} from 'mdast'\n * @import {State} from '../state.js'\n */\n\nimport {normalizeUri} from 'micromark-util-sanitize-uri'\n\n/**\n * Turn an mdast `link` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Link} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function link(state, node) {\n  /** @type {Properties} */\n  const properties = {href: normalizeUri(node.url)}\n\n  if (node.title !== null && node.title !== undefined) {\n    properties.title = node.title\n  }\n\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'a',\n    properties,\n    children: state.all(node)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {ElementContent, Element, Properties} from 'hast'\n * @import {ListItem, Parents} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `listItem` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {ListItem} node\n *   mdast node.\n * @param {Parents | undefined} parent\n *   Parent of `node`.\n * @returns {Element}\n *   hast node.\n */\nexport function listItem(state, node, parent) {\n  const results = state.all(node)\n  const loose = parent ? listLoose(parent) : listItemLoose(node)\n  /** @type {Properties} */\n  const properties = {}\n  /** @type {Array} */\n  const children = []\n\n  if (typeof node.checked === 'boolean') {\n    const head = results[0]\n    /** @type {Element} */\n    let paragraph\n\n    if (head && head.type === 'element' && head.tagName === 'p') {\n      paragraph = head\n    } else {\n      paragraph = {type: 'element', tagName: 'p', properties: {}, children: []}\n      results.unshift(paragraph)\n    }\n\n    if (paragraph.children.length > 0) {\n      paragraph.children.unshift({type: 'text', value: ' '})\n    }\n\n    paragraph.children.unshift({\n      type: 'element',\n      tagName: 'input',\n      properties: {type: 'checkbox', checked: node.checked, disabled: true},\n      children: []\n    })\n\n    // According to github-markdown-css, this class hides bullet.\n    // See: .\n    properties.className = ['task-list-item']\n  }\n\n  let index = -1\n\n  while (++index < results.length) {\n    const child = results[index]\n\n    // Add eols before nodes, except if this is a loose, first paragraph.\n    if (\n      loose ||\n      index !== 0 ||\n      child.type !== 'element' ||\n      child.tagName !== 'p'\n    ) {\n      children.push({type: 'text', value: '\\n'})\n    }\n\n    if (child.type === 'element' && child.tagName === 'p' && !loose) {\n      children.push(...child.children)\n    } else {\n      children.push(child)\n    }\n  }\n\n  const tail = results[results.length - 1]\n\n  // Add a final eol.\n  if (tail && (loose || tail.type !== 'element' || tail.tagName !== 'p')) {\n    children.push({type: 'text', value: '\\n'})\n  }\n\n  /** @type {Element} */\n  const result = {type: 'element', tagName: 'li', properties, children}\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n\n/**\n * @param {Parents} node\n * @return {Boolean}\n */\nfunction listLoose(node) {\n  let loose = false\n  if (node.type === 'list') {\n    loose = node.spread || false\n    const children = node.children\n    let index = -1\n\n    while (!loose && ++index < children.length) {\n      loose = listItemLoose(children[index])\n    }\n  }\n\n  return loose\n}\n\n/**\n * @param {ListItem} node\n * @return {Boolean}\n */\nfunction listItemLoose(node) {\n  const spread = node.spread\n\n  return spread === null || spread === undefined\n    ? node.children.length > 1\n    : spread\n}\n", "/**\n * @import {Element, Properties} from 'hast'\n * @import {List} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `list` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {List} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function list(state, node) {\n  /** @type {Properties} */\n  const properties = {}\n  const results = state.all(node)\n  let index = -1\n\n  if (typeof node.start === 'number' && node.start !== 1) {\n    properties.start = node.start\n  }\n\n  // Like GitHub, add a class for custom styling.\n  while (++index < results.length) {\n    const child = results[index]\n\n    if (\n      child.type === 'element' &&\n      child.tagName === 'li' &&\n      child.properties &&\n      Array.isArray(child.properties.className) &&\n      child.properties.className.includes('task-list-item')\n    ) {\n      properties.className = ['contains-task-list']\n      break\n    }\n  }\n\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: node.ordered ? 'ol' : 'ul',\n    properties,\n    children: state.wrap(results, true)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {Paragraph} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `paragraph` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Paragraph} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function paragraph(state, node) {\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'p',\n    properties: {},\n    children: state.all(node)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Parents as HastParents, Root as HastRoot} from 'hast'\n * @import {Root as MdastRoot} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `root` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {MdastRoot} node\n *   mdast node.\n * @returns {HastParents}\n *   hast node.\n */\nexport function root(state, node) {\n  /** @type {HastRoot} */\n  const result = {type: 'root', children: state.wrap(state.all(node))}\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {Strong} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `strong` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Strong} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function strong(state, node) {\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'strong',\n    properties: {},\n    children: state.all(node)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Table} from 'mdast'\n * @import {Element} from 'hast'\n * @import {State} from '../state.js'\n */\n\nimport {pointEnd, pointStart} from 'unist-util-position'\n\n/**\n * Turn an mdast `table` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {Table} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function table(state, node) {\n  const rows = state.all(node)\n  const firstRow = rows.shift()\n  /** @type {Array} */\n  const tableContent = []\n\n  if (firstRow) {\n    /** @type {Element} */\n    const head = {\n      type: 'element',\n      tagName: 'thead',\n      properties: {},\n      children: state.wrap([firstRow], true)\n    }\n    state.patch(node.children[0], head)\n    tableContent.push(head)\n  }\n\n  if (rows.length > 0) {\n    /** @type {Element} */\n    const body = {\n      type: 'element',\n      tagName: 'tbody',\n      properties: {},\n      children: state.wrap(rows, true)\n    }\n\n    const start = pointStart(node.children[1])\n    const end = pointEnd(node.children[node.children.length - 1])\n    if (start && end) body.position = {start, end}\n    tableContent.push(body)\n  }\n\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'table',\n    properties: {},\n    children: state.wrap(tableContent, true)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element, ElementContent, Properties} from 'hast'\n * @import {Parents, TableRow} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `tableRow` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {TableRow} node\n *   mdast node.\n * @param {Parents | undefined} parent\n *   Parent of `node`.\n * @returns {Element}\n *   hast node.\n */\nexport function tableRow(state, node, parent) {\n  const siblings = parent ? parent.children : undefined\n  // Generate a body row when without parent.\n  const rowIndex = siblings ? siblings.indexOf(node) : 1\n  const tagName = rowIndex === 0 ? 'th' : 'td'\n  // To do: option to use `style`?\n  const align = parent && parent.type === 'table' ? parent.align : undefined\n  const length = align ? align.length : node.children.length\n  let cellIndex = -1\n  /** @type {Array} */\n  const cells = []\n\n  while (++cellIndex < length) {\n    // Note: can also be undefined.\n    const cell = node.children[cellIndex]\n    /** @type {Properties} */\n    const properties = {}\n    const alignValue = align ? align[cellIndex] : undefined\n\n    if (alignValue) {\n      properties.align = alignValue\n    }\n\n    /** @type {Element} */\n    let result = {type: 'element', tagName, properties, children: []}\n\n    if (cell) {\n      result.children = state.all(cell)\n      state.patch(cell, result)\n      result = state.applyData(cell, result)\n    }\n\n    cells.push(result)\n  }\n\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'tr',\n    properties: {},\n    children: state.wrap(cells, true)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {TableCell} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `tableCell` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {TableCell} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function tableCell(state, node) {\n  // Note: this function is normally not called: see `table-row` for how rows\n  // and their cells are compiled.\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'td', // Assume body cell.\n    properties: {},\n    children: state.all(node)\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "const tab = 9 /* `\\t` */\nconst space = 32 /* ` ` */\n\n/**\n * Remove initial and final spaces and tabs at the line breaks in `value`.\n * Does not trim initial and final spaces and tabs of the value itself.\n *\n * @param {string} value\n *   Value to trim.\n * @returns {string}\n *   Trimmed value.\n */\nexport function trimLines(value) {\n  const source = String(value)\n  const search = /\\r?\\n|\\r/g\n  let match = search.exec(source)\n  let last = 0\n  /** @type {Array} */\n  const lines = []\n\n  while (match) {\n    lines.push(\n      trimLine(source.slice(last, match.index), last > 0, true),\n      match[0]\n    )\n\n    last = match.index + match[0].length\n    match = search.exec(source)\n  }\n\n  lines.push(trimLine(source.slice(last), last > 0, false))\n\n  return lines.join('')\n}\n\n/**\n * @param {string} value\n *   Line to trim.\n * @param {boolean} start\n *   Whether to trim the start of the line.\n * @param {boolean} end\n *   Whether to trim the end of the line.\n * @returns {string}\n *   Trimmed line.\n */\nfunction trimLine(value, start, end) {\n  let startIndex = 0\n  let endIndex = value.length\n\n  if (start) {\n    let code = value.codePointAt(startIndex)\n\n    while (code === tab || code === space) {\n      startIndex++\n      code = value.codePointAt(startIndex)\n    }\n  }\n\n  if (end) {\n    let code = value.codePointAt(endIndex - 1)\n\n    while (code === tab || code === space) {\n      endIndex--\n      code = value.codePointAt(endIndex - 1)\n    }\n  }\n\n  return endIndex > startIndex ? value.slice(startIndex, endIndex) : ''\n}\n", "/**\n * @import {Element as HastElement, Text as HastText} from 'hast'\n * @import {Text as MdastText} from 'mdast'\n * @import {State} from '../state.js'\n */\n\nimport {trimLines} from 'trim-lines'\n\n/**\n * Turn an mdast `text` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {MdastText} node\n *   mdast node.\n * @returns {HastElement | HastText}\n *   hast node.\n */\nexport function text(state, node) {\n  /** @type {HastText} */\n  const result = {type: 'text', value: trimLines(String(node.value))}\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Element} from 'hast'\n * @import {ThematicBreak} from 'mdast'\n * @import {State} from '../state.js'\n */\n\n/**\n * Turn an mdast `thematicBreak` node into hast.\n *\n * @param {State} state\n *   Info passed around.\n * @param {ThematicBreak} node\n *   mdast node.\n * @returns {Element}\n *   hast node.\n */\nexport function thematicBreak(state, node) {\n  /** @type {Element} */\n  const result = {\n    type: 'element',\n    tagName: 'hr',\n    properties: {},\n    children: []\n  }\n  state.patch(node, result)\n  return state.applyData(node, result)\n}\n", "/**\n * @import {Handlers} from '../state.js'\n */\n\nimport {blockquote} from './blockquote.js'\nimport {hardBreak} from './break.js'\nimport {code} from './code.js'\nimport {strikethrough} from './delete.js'\nimport {emphasis} from './emphasis.js'\nimport {footnoteReference} from './footnote-reference.js'\nimport {heading} from './heading.js'\nimport {html} from './html.js'\nimport {imageReference} from './image-reference.js'\nimport {image} from './image.js'\nimport {inlineCode} from './inline-code.js'\nimport {linkReference} from './link-reference.js'\nimport {link} from './link.js'\nimport {listItem} from './list-item.js'\nimport {list} from './list.js'\nimport {paragraph} from './paragraph.js'\nimport {root} from './root.js'\nimport {strong} from './strong.js'\nimport {table} from './table.js'\nimport {tableRow} from './table-row.js'\nimport {tableCell} from './table-cell.js'\nimport {text} from './text.js'\nimport {thematicBreak} from './thematic-break.js'\n\n/**\n * Default handlers for nodes.\n *\n * @satisfies {Handlers}\n */\nexport const handlers = {\n  blockquote,\n  break: hardBreak,\n  code,\n  delete: strikethrough,\n  emphasis,\n  footnoteReference,\n  heading,\n  html,\n  imageReference,\n  image,\n  inlineCode,\n  linkReference,\n  link,\n  listItem,\n  list,\n  paragraph,\n  // @ts-expect-error: root is different, but hard to type.\n  root,\n  strong,\n  table,\n  tableCell,\n  tableRow,\n  text,\n  thematicBreak,\n  toml: ignore,\n  yaml: ignore,\n  definition: ignore,\n  footnoteDefinition: ignore\n}\n\n// Return nothing for nodes that are ignored.\nfunction ignore() {\n  return undefined\n}\n", "export const VOID       = -1;\nexport const PRIMITIVE  = 0;\nexport const ARRAY      = 1;\nexport const OBJECT     = 2;\nexport const DATE       = 3;\nexport const REGEXP     = 4;\nexport const MAP        = 5;\nexport const SET        = 6;\nexport const ERROR      = 7;\nexport const BIGINT     = 8;\n// export const SYMBOL = 9;\n", "import {\n  VOID, PRIMITIVE,\n  ARRAY, OBJECT,\n  DATE, REGEXP, MAP, SET,\n  ERROR, BIGINT\n} from './types.js';\n\nconst env = typeof self === 'object' ? self : globalThis;\n\nconst deserializer = ($, _) => {\n  const as = (out, index) => {\n    $.set(index, out);\n    return out;\n  };\n\n  const unpair = index => {\n    if ($.has(index))\n      return $.get(index);\n\n    const [type, value] = _[index];\n    switch (type) {\n      case PRIMITIVE:\n      case VOID:\n        return as(value, index);\n      case ARRAY: {\n        const arr = as([], index);\n        for (const index of value)\n          arr.push(unpair(index));\n        return arr;\n      }\n      case OBJECT: {\n        const object = as({}, index);\n        for (const [key, index] of value)\n          object[unpair(key)] = unpair(index);\n        return object;\n      }\n      case DATE:\n        return as(new Date(value), index);\n      case REGEXP: {\n        const {source, flags} = value;\n        return as(new RegExp(source, flags), index);\n      }\n      case MAP: {\n        const map = as(new Map, index);\n        for (const [key, index] of value)\n          map.set(unpair(key), unpair(index));\n        return map;\n      }\n      case SET: {\n        const set = as(new Set, index);\n        for (const index of value)\n          set.add(unpair(index));\n        return set;\n      }\n      case ERROR: {\n        const {name, message} = value;\n        return as(new env[name](message), index);\n      }\n      case BIGINT:\n        return as(BigInt(value), index);\n      case 'BigInt':\n        return as(Object(BigInt(value)), index);\n      case 'ArrayBuffer':\n        return as(new Uint8Array(value).buffer, value);\n      case 'DataView': {\n        const { buffer } = new Uint8Array(value);\n        return as(new DataView(buffer), value);\n      }\n    }\n    return as(new env[type](value), index);\n  };\n\n  return unpair;\n};\n\n/**\n * @typedef {Array} Record a type representation\n */\n\n/**\n * Returns a deserialized value from a serialized array of Records.\n * @param {Record[]} serialized a previously serialized value.\n * @returns {any}\n */\nexport const deserialize = serialized => deserializer(new Map, serialized)(0);\n", "import {\n  VOID, PRIMITIVE,\n  ARRAY, OBJECT,\n  DATE, REGEXP, MAP, SET,\n  ERROR, BIGINT\n} from './types.js';\n\nconst EMPTY = '';\n\nconst {toString} = {};\nconst {keys} = Object;\n\nconst typeOf = value => {\n  const type = typeof value;\n  if (type !== 'object' || !value)\n    return [PRIMITIVE, type];\n\n  const asString = toString.call(value).slice(8, -1);\n  switch (asString) {\n    case 'Array':\n      return [ARRAY, EMPTY];\n    case 'Object':\n      return [OBJECT, EMPTY];\n    case 'Date':\n      return [DATE, EMPTY];\n    case 'RegExp':\n      return [REGEXP, EMPTY];\n    case 'Map':\n      return [MAP, EMPTY];\n    case 'Set':\n      return [SET, EMPTY];\n    case 'DataView':\n      return [ARRAY, asString];\n  }\n\n  if (asString.includes('Array'))\n    return [ARRAY, asString];\n\n  if (asString.includes('Error'))\n    return [ERROR, asString];\n\n  return [OBJECT, asString];\n};\n\nconst shouldSkip = ([TYPE, type]) => (\n  TYPE === PRIMITIVE &&\n  (type === 'function' || type === 'symbol')\n);\n\nconst serializer = (strict, json, $, _) => {\n\n  const as = (out, value) => {\n    const index = _.push(out) - 1;\n    $.set(value, index);\n    return index;\n  };\n\n  const pair = value => {\n    if ($.has(value))\n      return $.get(value);\n\n    let [TYPE, type] = typeOf(value);\n    switch (TYPE) {\n      case PRIMITIVE: {\n        let entry = value;\n        switch (type) {\n          case 'bigint':\n            TYPE = BIGINT;\n            entry = value.toString();\n            break;\n          case 'function':\n          case 'symbol':\n            if (strict)\n              throw new TypeError('unable to serialize ' + type);\n            entry = null;\n            break;\n          case 'undefined':\n            return as([VOID], value);\n        }\n        return as([TYPE, entry], value);\n      }\n      case ARRAY: {\n        if (type) {\n          let spread = value;\n          if (type === 'DataView') {\n            spread = new Uint8Array(value.buffer);\n          }\n          else if (type === 'ArrayBuffer') {\n            spread = new Uint8Array(value);\n          }\n          return as([type, [...spread]], value);\n        }\n\n        const arr = [];\n        const index = as([TYPE, arr], value);\n        for (const entry of value)\n          arr.push(pair(entry));\n        return index;\n      }\n      case OBJECT: {\n        if (type) {\n          switch (type) {\n            case 'BigInt':\n              return as([type, value.toString()], value);\n            case 'Boolean':\n            case 'Number':\n            case 'String':\n              return as([type, value.valueOf()], value);\n          }\n        }\n\n        if (json && ('toJSON' in value))\n          return pair(value.toJSON());\n\n        const entries = [];\n        const index = as([TYPE, entries], value);\n        for (const key of keys(value)) {\n          if (strict || !shouldSkip(typeOf(value[key])))\n            entries.push([pair(key), pair(value[key])]);\n        }\n        return index;\n      }\n      case DATE:\n        return as([TYPE, value.toISOString()], value);\n      case REGEXP: {\n        const {source, flags} = value;\n        return as([TYPE, {source, flags}], value);\n      }\n      case MAP: {\n        const entries = [];\n        const index = as([TYPE, entries], value);\n        for (const [key, entry] of value) {\n          if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry))))\n            entries.push([pair(key), pair(entry)]);\n        }\n        return index;\n      }\n      case SET: {\n        const entries = [];\n        const index = as([TYPE, entries], value);\n        for (const entry of value) {\n          if (strict || !shouldSkip(typeOf(entry)))\n            entries.push(pair(entry));\n        }\n        return index;\n      }\n    }\n\n    const {message} = value;\n    return as([TYPE, {name: type, message}], value);\n  };\n\n  return pair;\n};\n\n/**\n * @typedef {Array} Record a type representation\n */\n\n/**\n * Returns an array of serialized Records.\n * @param {any} value a serializable value.\n * @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,\n *  if `true`, will not throw errors on incompatible types, and behave more\n *  like JSON stringify would behave. Symbol and Function will be discarded.\n * @returns {Record[]}\n */\n export const serialize = (value, {json, lossy} = {}) => {\n  const _ = [];\n  return serializer(!(json || lossy), !!json, new Map, _)(value), _;\n};\n", "import {deserialize} from './deserialize.js';\nimport {serialize} from './serialize.js';\n\n/**\n * @typedef {Array} Record a type representation\n */\n\n/**\n * Returns an array of serialized Records.\n * @param {any} any a serializable value.\n * @param {{transfer?: any[], json?: boolean, lossy?: boolean}?} options an object with\n * a transfer option (ignored when polyfilled) and/or non standard fields that\n * fallback to the polyfill if present.\n * @returns {Record[]}\n */\nexport default typeof structuredClone === \"function\" ?\n  /* c8 ignore start */\n  (any, options) => (\n    options && ('json' in options || 'lossy' in options) ?\n      deserialize(serialize(any, options)) : structuredClone(any)\n  ) :\n  (any, options) => deserialize(serialize(any, options));\n  /* c8 ignore stop */\n\nexport {deserialize, serialize};\n", "/**\n * @import {ElementContent, Element} from 'hast'\n * @import {State} from './state.js'\n */\n\n/**\n * @callback FootnoteBackContentTemplate\n *   Generate content for the backreference dynamically.\n *\n *   For the following markdown:\n *\n *   ```markdown\n *   Alpha[^micromark], bravo[^micromark], and charlie[^remark].\n *\n *   [^remark]: things about remark\n *   [^micromark]: things about micromark\n *   ```\n *\n *   This function will be called with:\n *\n *   *  `0` and `0` for the backreference from `things about micromark` to\n *      `alpha`, as it is the first used definition, and the first call to it\n *   *  `0` and `1` for the backreference from `things about micromark` to\n *      `bravo`, as it is the first used definition, and the second call to it\n *   *  `1` and `0` for the backreference from `things about remark` to\n *      `charlie`, as it is the second used definition\n * @param {number} referenceIndex\n *   Index of the definition in the order that they are first referenced,\n *   0-indexed.\n * @param {number} rereferenceIndex\n *   Index of calls to the same definition, 0-indexed.\n * @returns {Array | ElementContent | string}\n *   Content for the backreference when linking back from definitions to their\n *   reference.\n *\n * @callback FootnoteBackLabelTemplate\n *   Generate a back label dynamically.\n *\n *   For the following markdown:\n *\n *   ```markdown\n *   Alpha[^micromark], bravo[^micromark], and charlie[^remark].\n *\n *   [^remark]: things about remark\n *   [^micromark]: things about micromark\n *   ```\n *\n *   This function will be called with:\n *\n *   *  `0` and `0` for the backreference from `things about micromark` to\n *      `alpha`, as it is the first used definition, and the first call to it\n *   *  `0` and `1` for the backreference from `things about micromark` to\n *      `bravo`, as it is the first used definition, and the second call to it\n *   *  `1` and `0` for the backreference from `things about remark` to\n *      `charlie`, as it is the second used definition\n * @param {number} referenceIndex\n *   Index of the definition in the order that they are first referenced,\n *   0-indexed.\n * @param {number} rereferenceIndex\n *   Index of calls to the same definition, 0-indexed.\n * @returns {string}\n *   Back label to use when linking back from definitions to their reference.\n */\n\nimport structuredClone from '@ungap/structured-clone'\nimport {normalizeUri} from 'micromark-util-sanitize-uri'\n\n/**\n * Generate the default content that GitHub uses on backreferences.\n *\n * @param {number} _\n *   Index of the definition in the order that they are first referenced,\n *   0-indexed.\n * @param {number} rereferenceIndex\n *   Index of calls to the same definition, 0-indexed.\n * @returns {Array}\n *   Content.\n */\nexport function defaultFootnoteBackContent(_, rereferenceIndex) {\n  /** @type {Array} */\n  const result = [{type: 'text', value: '\u21A9'}]\n\n  if (rereferenceIndex > 1) {\n    result.push({\n      type: 'element',\n      tagName: 'sup',\n      properties: {},\n      children: [{type: 'text', value: String(rereferenceIndex)}]\n    })\n  }\n\n  return result\n}\n\n/**\n * Generate the default label that GitHub uses on backreferences.\n *\n * @param {number} referenceIndex\n *   Index of the definition in the order that they are first referenced,\n *   0-indexed.\n * @param {number} rereferenceIndex\n *   Index of calls to the same definition, 0-indexed.\n * @returns {string}\n *   Label.\n */\nexport function defaultFootnoteBackLabel(referenceIndex, rereferenceIndex) {\n  return (\n    'Back to reference ' +\n    (referenceIndex + 1) +\n    (rereferenceIndex > 1 ? '-' + rereferenceIndex : '')\n  )\n}\n\n/**\n * Generate a hast footer for called footnote definitions.\n *\n * @param {State} state\n *   Info passed around.\n * @returns {Element | undefined}\n *   `section` element or `undefined`.\n */\n// eslint-disable-next-line complexity\nexport function footer(state) {\n  const clobberPrefix =\n    typeof state.options.clobberPrefix === 'string'\n      ? state.options.clobberPrefix\n      : 'user-content-'\n  const footnoteBackContent =\n    state.options.footnoteBackContent || defaultFootnoteBackContent\n  const footnoteBackLabel =\n    state.options.footnoteBackLabel || defaultFootnoteBackLabel\n  const footnoteLabel = state.options.footnoteLabel || 'Footnotes'\n  const footnoteLabelTagName = state.options.footnoteLabelTagName || 'h2'\n  const footnoteLabelProperties = state.options.footnoteLabelProperties || {\n    className: ['sr-only']\n  }\n  /** @type {Array} */\n  const listItems = []\n  let referenceIndex = -1\n\n  while (++referenceIndex < state.footnoteOrder.length) {\n    const definition = state.footnoteById.get(\n      state.footnoteOrder[referenceIndex]\n    )\n\n    if (!definition) {\n      continue\n    }\n\n    const content = state.all(definition)\n    const id = String(definition.identifier).toUpperCase()\n    const safeId = normalizeUri(id.toLowerCase())\n    let rereferenceIndex = 0\n    /** @type {Array} */\n    const backReferences = []\n    const counts = state.footnoteCounts.get(id)\n\n    // eslint-disable-next-line no-unmodified-loop-condition\n    while (counts !== undefined && ++rereferenceIndex <= counts) {\n      if (backReferences.length > 0) {\n        backReferences.push({type: 'text', value: ' '})\n      }\n\n      let children =\n        typeof footnoteBackContent === 'string'\n          ? footnoteBackContent\n          : footnoteBackContent(referenceIndex, rereferenceIndex)\n\n      if (typeof children === 'string') {\n        children = {type: 'text', value: children}\n      }\n\n      backReferences.push({\n        type: 'element',\n        tagName: 'a',\n        properties: {\n          href:\n            '#' +\n            clobberPrefix +\n            'fnref-' +\n            safeId +\n            (rereferenceIndex > 1 ? '-' + rereferenceIndex : ''),\n          dataFootnoteBackref: '',\n          ariaLabel:\n            typeof footnoteBackLabel === 'string'\n              ? footnoteBackLabel\n              : footnoteBackLabel(referenceIndex, rereferenceIndex),\n          className: ['data-footnote-backref']\n        },\n        children: Array.isArray(children) ? children : [children]\n      })\n    }\n\n    const tail = content[content.length - 1]\n\n    if (tail && tail.type === 'element' && tail.tagName === 'p') {\n      const tailTail = tail.children[tail.children.length - 1]\n      if (tailTail && tailTail.type === 'text') {\n        tailTail.value += ' '\n      } else {\n        tail.children.push({type: 'text', value: ' '})\n      }\n\n      tail.children.push(...backReferences)\n    } else {\n      content.push(...backReferences)\n    }\n\n    /** @type {Element} */\n    const listItem = {\n      type: 'element',\n      tagName: 'li',\n      properties: {id: clobberPrefix + 'fn-' + safeId},\n      children: state.wrap(content, true)\n    }\n\n    state.patch(definition, listItem)\n\n    listItems.push(listItem)\n  }\n\n  if (listItems.length === 0) {\n    return\n  }\n\n  return {\n    type: 'element',\n    tagName: 'section',\n    properties: {dataFootnotes: true, className: ['footnotes']},\n    children: [\n      {\n        type: 'element',\n        tagName: footnoteLabelTagName,\n        properties: {\n          ...structuredClone(footnoteLabelProperties),\n          id: 'footnote-label'\n        },\n        children: [{type: 'text', value: footnoteLabel}]\n      },\n      {type: 'text', value: '\\n'},\n      {\n        type: 'element',\n        tagName: 'ol',\n        properties: {},\n        children: state.wrap(listItems, true)\n      },\n      {type: 'text', value: '\\n'}\n    ]\n  }\n}\n", "/**\n * @import {Node, Parent} from 'unist'\n */\n\n/**\n * @template Fn\n * @template Fallback\n * @typedef {Fn extends (value: any) => value is infer Thing ? Thing : Fallback} Predicate\n */\n\n/**\n * @callback Check\n *   Check that an arbitrary value is a node.\n * @param {unknown} this\n *   The given context.\n * @param {unknown} [node]\n *   Anything (typically a node).\n * @param {number | null | undefined} [index]\n *   The node\u2019s position in its parent.\n * @param {Parent | null | undefined} [parent]\n *   The node\u2019s parent.\n * @returns {boolean}\n *   Whether this is a node and passes a test.\n *\n * @typedef {Record | Node} Props\n *   Object to check for equivalence.\n *\n *   Note: `Node` is included as it is common but is not indexable.\n *\n * @typedef {Array | ReadonlyArray | Props | TestFunction | string | null | undefined} Test\n *   Check for an arbitrary node.\n *\n * @callback TestFunction\n *   Check if a node passes a test.\n * @param {unknown} this\n *   The given context.\n * @param {Node} node\n *   A node.\n * @param {number | undefined} [index]\n *   The node\u2019s position in its parent.\n * @param {Parent | undefined} [parent]\n *   The node\u2019s parent.\n * @returns {boolean | undefined | void}\n *   Whether this node passes the test.\n *\n *   Note: `void` is included until TS sees no return as `undefined`.\n */\n\n/**\n * Check if `node` is a `Node` and whether it passes the given test.\n *\n * @param {unknown} node\n *   Thing to check, typically `Node`.\n * @param {Test} test\n *   A check for a specific node.\n * @param {number | null | undefined} index\n *   The node\u2019s position in its parent.\n * @param {Parent | null | undefined} parent\n *   The node\u2019s parent.\n * @param {unknown} context\n *   Context object (`this`) to pass to `test` functions.\n * @returns {boolean}\n *   Whether `node` is a node and passes a test.\n */\nexport const is =\n  // Note: overloads in JSDoc can\u2019t yet use different `@template`s.\n  /**\n   * @type {(\n   *   (>(node: unknown, test: Condition, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition[number]}) &\n   *   (>(node: unknown, test: Condition, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition[number]}) &\n   *   ((node: unknown, test: Condition, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition}) &\n   *   ((node: unknown, test: Condition, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Condition) &\n   *   ((node: unknown, test: Condition, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Predicate) &\n   *   ((node?: null | undefined) => false) &\n   *   ((node: unknown, test?: null | undefined, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node) &\n   *   ((node: unknown, test?: Test, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => boolean)\n   * )}\n   */\n  (\n    /**\n     * @param {unknown} [node]\n     * @param {Test} [test]\n     * @param {number | null | undefined} [index]\n     * @param {Parent | null | undefined} [parent]\n     * @param {unknown} [context]\n     * @returns {boolean}\n     */\n    // eslint-disable-next-line max-params\n    function (node, test, index, parent, context) {\n      const check = convert(test)\n\n      if (\n        index !== undefined &&\n        index !== null &&\n        (typeof index !== 'number' ||\n          index < 0 ||\n          index === Number.POSITIVE_INFINITY)\n      ) {\n        throw new Error('Expected positive finite index')\n      }\n\n      if (\n        parent !== undefined &&\n        parent !== null &&\n        (!is(parent) || !parent.children)\n      ) {\n        throw new Error('Expected parent node')\n      }\n\n      if (\n        (parent === undefined || parent === null) !==\n        (index === undefined || index === null)\n      ) {\n        throw new Error('Expected both parent and index')\n      }\n\n      return looksLikeANode(node)\n        ? check.call(context, node, index, parent)\n        : false\n    }\n  )\n\n/**\n * Generate an assertion from a test.\n *\n * Useful if you\u2019re going to test many nodes, for example when creating a\n * utility where something else passes a compatible test.\n *\n * The created function is a bit faster because it expects valid input only:\n * a `node`, `index`, and `parent`.\n *\n * @param {Test} test\n *   *   when nullish, checks if `node` is a `Node`.\n *   *   when `string`, works like passing `(node) => node.type === test`.\n *   *   when `function` checks if function passed the node is true.\n *   *   when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.\n *   *   when `array`, checks if any one of the subtests pass.\n * @returns {Check}\n *   An assertion.\n */\nexport const convert =\n  // Note: overloads in JSDoc can\u2019t yet use different `@template`s.\n  /**\n   * @type {(\n   *   ((test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition}) &\n   *   ((test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Condition) &\n   *   ((test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Predicate) &\n   *   ((test?: null | undefined) => (node?: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node) &\n   *   ((test?: Test) => Check)\n   * )}\n   */\n  (\n    /**\n     * @param {Test} [test]\n     * @returns {Check}\n     */\n    function (test) {\n      if (test === null || test === undefined) {\n        return ok\n      }\n\n      if (typeof test === 'function') {\n        return castFactory(test)\n      }\n\n      if (typeof test === 'object') {\n        return Array.isArray(test)\n          ? anyFactory(test)\n          : // Cast because `ReadonlyArray` goes into the above but `isArray`\n            // narrows to `Array`.\n            propertiesFactory(/** @type {Props} */ (test))\n      }\n\n      if (typeof test === 'string') {\n        return typeFactory(test)\n      }\n\n      throw new Error('Expected function, string, or object as test')\n    }\n  )\n\n/**\n * @param {Array} tests\n * @returns {Check}\n */\nfunction anyFactory(tests) {\n  /** @type {Array} */\n  const checks = []\n  let index = -1\n\n  while (++index < tests.length) {\n    checks[index] = convert(tests[index])\n  }\n\n  return castFactory(any)\n\n  /**\n   * @this {unknown}\n   * @type {TestFunction}\n   */\n  function any(...parameters) {\n    let index = -1\n\n    while (++index < checks.length) {\n      if (checks[index].apply(this, parameters)) return true\n    }\n\n    return false\n  }\n}\n\n/**\n * Turn an object into a test for a node with a certain fields.\n *\n * @param {Props} check\n * @returns {Check}\n */\nfunction propertiesFactory(check) {\n  const checkAsRecord = /** @type {Record} */ (check)\n\n  return castFactory(all)\n\n  /**\n   * @param {Node} node\n   * @returns {boolean}\n   */\n  function all(node) {\n    const nodeAsRecord = /** @type {Record} */ (\n      /** @type {unknown} */ (node)\n    )\n\n    /** @type {string} */\n    let key\n\n    for (key in check) {\n      if (nodeAsRecord[key] !== checkAsRecord[key]) return false\n    }\n\n    return true\n  }\n}\n\n/**\n * Turn a string into a test for a node with a certain type.\n *\n * @param {string} check\n * @returns {Check}\n */\nfunction typeFactory(check) {\n  return castFactory(type)\n\n  /**\n   * @param {Node} node\n   */\n  function type(node) {\n    return node && node.type === check\n  }\n}\n\n/**\n * Turn a custom test into a test for a node that passes that test.\n *\n * @param {TestFunction} testFunction\n * @returns {Check}\n */\nfunction castFactory(testFunction) {\n  return check\n\n  /**\n   * @this {unknown}\n   * @type {Check}\n   */\n  function check(value, index, parent) {\n    return Boolean(\n      looksLikeANode(value) &&\n        testFunction.call(\n          this,\n          value,\n          typeof index === 'number' ? index : undefined,\n          parent || undefined\n        )\n    )\n  }\n}\n\nfunction ok() {\n  return true\n}\n\n/**\n * @param {unknown} value\n * @returns {value is Node}\n */\nfunction looksLikeANode(value) {\n  return value !== null && typeof value === 'object' && 'type' in value\n}\n", "/**\n * @typedef {import('./lib/index.js').Check} Check\n * @typedef {import('./lib/index.js').Test} Test\n * @typedef {import('./lib/index.js').TestFunction} TestFunction\n */\n\nexport {is, convert} from './lib/index.js'\n", "/**\n * @param {string} d\n * @returns {string}\n */\nexport function color(d) {\n  return d\n}\n", "/**\n * @import {Node as UnistNode, Parent as UnistParent} from 'unist'\n */\n\n/**\n * @typedef {Exclude | undefined} Test\n *   Test from `unist-util-is`.\n *\n *   Note: we have remove and add `undefined`, because otherwise when generating\n *   automatic `.d.ts` files, TS tries to flatten paths from a local perspective,\n *   which doesn\u2019t work when publishing on npm.\n */\n\n/**\n * @typedef {(\n *   Fn extends (value: any) => value is infer Thing\n *   ? Thing\n *   : Fallback\n * )} Predicate\n *   Get the value of a type guard `Fn`.\n * @template Fn\n *   Value; typically function that is a type guard (such as `(x): x is Y`).\n * @template Fallback\n *   Value to yield if `Fn` is not a type guard.\n */\n\n/**\n * @typedef {(\n *   Check extends null | undefined // No test.\n *   ? Value\n *   : Value extends {type: Check} // String (type) test.\n *   ? Value\n *   : Value extends Check // Partial test.\n *   ? Value\n *   : Check extends Function // Function test.\n *   ? Predicate extends Value\n *     ? Predicate\n *     : never\n *   : never // Some other test?\n * )} MatchesOne\n *   Check whether a node matches a primitive check in the type system.\n * @template Value\n *   Value; typically unist `Node`.\n * @template Check\n *   Value; typically `unist-util-is`-compatible test, but not arrays.\n */\n\n/**\n * @typedef {(\n *   Check extends ReadonlyArray\n *   ? MatchesOne\n *   : Check extends Array\n *   ? MatchesOne\n *   : MatchesOne\n * )} Matches\n *   Check whether a node matches a check in the type system.\n * @template Value\n *   Value; typically unist `Node`.\n * @template Check\n *   Value; typically `unist-util-is`-compatible test.\n */\n\n/**\n * @typedef {0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} Uint\n *   Number; capped reasonably.\n */\n\n/**\n * @typedef {I extends 0 ? 1 : I extends 1 ? 2 : I extends 2 ? 3 : I extends 3 ? 4 : I extends 4 ? 5 : I extends 5 ? 6 : I extends 6 ? 7 : I extends 7 ? 8 : I extends 8 ? 9 : 10} Increment\n *   Increment a number in the type system.\n * @template {Uint} [I=0]\n *   Index.\n */\n\n/**\n * @typedef {(\n *   Node extends UnistParent\n *   ? Node extends {children: Array}\n *     ? Child extends Children ? Node : never\n *     : never\n *   : never\n * )} InternalParent\n *   Collect nodes that can be parents of `Child`.\n * @template {UnistNode} Node\n *   All node types in a tree.\n * @template {UnistNode} Child\n *   Node to search for.\n */\n\n/**\n * @typedef {InternalParent, Child>} Parent\n *   Collect nodes in `Tree` that can be parents of `Child`.\n * @template {UnistNode} Tree\n *   All node types in a tree.\n * @template {UnistNode} Child\n *   Node to search for.\n */\n\n/**\n * @typedef {(\n *   Depth extends Max\n *   ? never\n *   :\n *     | InternalParent\n *     | InternalAncestor, Max, Increment>\n * )} InternalAncestor\n *   Collect nodes in `Tree` that can be ancestors of `Child`.\n * @template {UnistNode} Node\n *   All node types in a tree.\n * @template {UnistNode} Child\n *   Node to search for.\n * @template {Uint} [Max=10]\n *   Max; searches up to this depth.\n * @template {Uint} [Depth=0]\n *   Current depth.\n */\n\n/**\n * @typedef {InternalAncestor, Child>} Ancestor\n *   Collect nodes in `Tree` that can be ancestors of `Child`.\n * @template {UnistNode} Tree\n *   All node types in a tree.\n * @template {UnistNode} Child\n *   Node to search for.\n */\n\n/**\n * @typedef {(\n *   Tree extends UnistParent\n *     ? Depth extends Max\n *       ? Tree\n *       : Tree | InclusiveDescendant>\n *     : Tree\n * )} InclusiveDescendant\n *   Collect all (inclusive) descendants of `Tree`.\n *\n *   > \uD83D\uDC49 **Note**: for performance reasons, this seems to be the fastest way to\n *   > recurse without actually running into an infinite loop, which the\n *   > previous version did.\n *   >\n *   > Practically, a max of `2` is typically enough assuming a `Root` is\n *   > passed, but it doesn\u2019t improve performance.\n *   > It gets higher with `List > ListItem > Table > TableRow > TableCell`.\n *   > Using up to `10` doesn\u2019t hurt or help either.\n * @template {UnistNode} Tree\n *   Tree type.\n * @template {Uint} [Max=10]\n *   Max; searches up to this depth.\n * @template {Uint} [Depth=0]\n *   Current depth.\n */\n\n/**\n * @typedef {'skip' | boolean} Action\n *   Union of the action types.\n *\n * @typedef {number} Index\n *   Move to the sibling at `index` next (after node itself is completely\n *   traversed).\n *\n *   Useful if mutating the tree, such as removing the node the visitor is\n *   currently on, or any of its previous siblings.\n *   Results less than 0 or greater than or equal to `children.length` stop\n *   traversing the parent.\n *\n * @typedef {[(Action | null | undefined | void)?, (Index | null | undefined)?]} ActionTuple\n *   List with one or two values, the first an action, the second an index.\n *\n * @typedef {Action | ActionTuple | Index | null | undefined | void} VisitorResult\n *   Any value that can be returned from a visitor.\n */\n\n/**\n * @callback Visitor\n *   Handle a node (matching `test`, if given).\n *\n *   Visitors are free to transform `node`.\n *   They can also transform the parent of node (the last of `ancestors`).\n *\n *   Replacing `node` itself, if `SKIP` is not returned, still causes its\n *   descendants to be walked (which is a bug).\n *\n *   When adding or removing previous siblings of `node` (or next siblings, in\n *   case of reverse), the `Visitor` should return a new `Index` to specify the\n *   sibling to traverse after `node` is traversed.\n *   Adding or removing next siblings of `node` (or previous siblings, in case\n *   of reverse) is handled as expected without needing to return a new `Index`.\n *\n *   Removing the children property of an ancestor still results in them being\n *   traversed.\n * @param {Visited} node\n *   Found node.\n * @param {Array} ancestors\n *   Ancestors of `node`.\n * @returns {VisitorResult}\n *   What to do next.\n *\n *   An `Index` is treated as a tuple of `[CONTINUE, Index]`.\n *   An `Action` is treated as a tuple of `[Action]`.\n *\n *   Passing a tuple back only makes sense if the `Action` is `SKIP`.\n *   When the `Action` is `EXIT`, that action can be returned.\n *   When the `Action` is `CONTINUE`, `Index` can be returned.\n * @template {UnistNode} [Visited=UnistNode]\n *   Visited node type.\n * @template {UnistParent} [VisitedParents=UnistParent]\n *   Ancestor type.\n */\n\n/**\n * @typedef {Visitor, Check>, Ancestor, Check>>>} BuildVisitor\n *   Build a typed `Visitor` function from a tree and a test.\n *\n *   It will infer which values are passed as `node` and which as `parents`.\n * @template {UnistNode} [Tree=UnistNode]\n *   Tree type.\n * @template {Test} [Check=Test]\n *   Test type.\n */\n\nimport {convert} from 'unist-util-is'\nimport {color} from 'unist-util-visit-parents/do-not-use-color'\n\n/** @type {Readonly} */\nconst empty = []\n\n/**\n * Continue traversing as normal.\n */\nexport const CONTINUE = true\n\n/**\n * Stop traversing immediately.\n */\nexport const EXIT = false\n\n/**\n * Do not traverse this node\u2019s children.\n */\nexport const SKIP = 'skip'\n\n/**\n * Visit nodes, with ancestral information.\n *\n * This algorithm performs *depth-first* *tree traversal* in *preorder*\n * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).\n *\n * You can choose for which nodes `visitor` is called by passing a `test`.\n * For complex tests, you should test yourself in `visitor`, as it will be\n * faster and will have improved type information.\n *\n * Walking the tree is an intensive task.\n * Make use of the return values of the visitor when possible.\n * Instead of walking a tree multiple times, walk it once, use `unist-util-is`\n * to check if a node matches, and then perform different operations.\n *\n * You can change the tree.\n * See `Visitor` for more info.\n *\n * @overload\n * @param {Tree} tree\n * @param {Check} check\n * @param {BuildVisitor} visitor\n * @param {boolean | null | undefined} [reverse]\n * @returns {undefined}\n *\n * @overload\n * @param {Tree} tree\n * @param {BuildVisitor} visitor\n * @param {boolean | null | undefined} [reverse]\n * @returns {undefined}\n *\n * @param {UnistNode} tree\n *   Tree to traverse.\n * @param {Visitor | Test} test\n *   `unist-util-is`-compatible test\n * @param {Visitor | boolean | null | undefined} [visitor]\n *   Handle each node.\n * @param {boolean | null | undefined} [reverse]\n *   Traverse in reverse preorder (NRL) instead of the default preorder (NLR).\n * @returns {undefined}\n *   Nothing.\n *\n * @template {UnistNode} Tree\n *   Node type.\n * @template {Test} Check\n *   `unist-util-is`-compatible test.\n */\nexport function visitParents(tree, test, visitor, reverse) {\n  /** @type {Test} */\n  let check\n\n  if (typeof test === 'function' && typeof visitor !== 'function') {\n    reverse = visitor\n    // @ts-expect-error no visitor given, so `visitor` is test.\n    visitor = test\n  } else {\n    // @ts-expect-error visitor given, so `test` isn\u2019t a visitor.\n    check = test\n  }\n\n  const is = convert(check)\n  const step = reverse ? -1 : 1\n\n  factory(tree, undefined, [])()\n\n  /**\n   * @param {UnistNode} node\n   * @param {number | undefined} index\n   * @param {Array} parents\n   */\n  function factory(node, index, parents) {\n    const value = /** @type {Record} */ (\n      node && typeof node === 'object' ? node : {}\n    )\n\n    if (typeof value.type === 'string') {\n      const name =\n        // `hast`\n        typeof value.tagName === 'string'\n          ? value.tagName\n          : // `xast`\n            typeof value.name === 'string'\n            ? value.name\n            : undefined\n\n      Object.defineProperty(visit, 'name', {\n        value:\n          'node (' + color(node.type + (name ? '<' + name + '>' : '')) + ')'\n      })\n    }\n\n    return visit\n\n    function visit() {\n      /** @type {Readonly} */\n      let result = empty\n      /** @type {Readonly} */\n      let subresult\n      /** @type {number} */\n      let offset\n      /** @type {Array} */\n      let grandparents\n\n      if (!test || is(node, index, parents[parents.length - 1] || undefined)) {\n        // @ts-expect-error: `visitor` is now a visitor.\n        result = toResult(visitor(node, parents))\n\n        if (result[0] === EXIT) {\n          return result\n        }\n      }\n\n      if ('children' in node && node.children) {\n        const nodeAsParent = /** @type {UnistParent} */ (node)\n\n        if (nodeAsParent.children && result[0] !== SKIP) {\n          offset = (reverse ? nodeAsParent.children.length : -1) + step\n          grandparents = parents.concat(nodeAsParent)\n\n          while (offset > -1 && offset < nodeAsParent.children.length) {\n            const child = nodeAsParent.children[offset]\n\n            subresult = factory(child, offset, grandparents)()\n\n            if (subresult[0] === EXIT) {\n              return subresult\n            }\n\n            offset =\n              typeof subresult[1] === 'number' ? subresult[1] : offset + step\n          }\n        }\n      }\n\n      return result\n    }\n  }\n}\n\n/**\n * Turn a return value into a clean result.\n *\n * @param {VisitorResult} value\n *   Valid return values from visitors.\n * @returns {Readonly}\n *   Clean result.\n */\nfunction toResult(value) {\n  if (Array.isArray(value)) {\n    return value\n  }\n\n  if (typeof value === 'number') {\n    return [CONTINUE, value]\n  }\n\n  return value === null || value === undefined ? empty : [value]\n}\n", "// Note: types exported from `index.d.ts`\nexport {CONTINUE, EXIT, SKIP, visitParents} from './lib/index.js'\n", "/**\n * @import {Node as UnistNode, Parent as UnistParent} from 'unist'\n * @import {VisitorResult} from 'unist-util-visit-parents'\n */\n\n/**\n * @typedef {Exclude | undefined} Test\n *   Test from `unist-util-is`.\n *\n *   Note: we have remove and add `undefined`, because otherwise when generating\n *   automatic `.d.ts` files, TS tries to flatten paths from a local perspective,\n *   which doesn\u2019t work when publishing on npm.\n */\n\n// To do: use types from `unist-util-visit-parents` when it\u2019s released.\n\n/**\n * @typedef {(\n *   Fn extends (value: any) => value is infer Thing\n *   ? Thing\n *   : Fallback\n * )} Predicate\n *   Get the value of a type guard `Fn`.\n * @template Fn\n *   Value; typically function that is a type guard (such as `(x): x is Y`).\n * @template Fallback\n *   Value to yield if `Fn` is not a type guard.\n */\n\n/**\n * @typedef {(\n *   Check extends null | undefined // No test.\n *   ? Value\n *   : Value extends {type: Check} // String (type) test.\n *   ? Value\n *   : Value extends Check // Partial test.\n *   ? Value\n *   : Check extends Function // Function test.\n *   ? Predicate extends Value\n *     ? Predicate\n *     : never\n *   : never // Some other test?\n * )} MatchesOne\n *   Check whether a node matches a primitive check in the type system.\n * @template Value\n *   Value; typically unist `Node`.\n * @template Check\n *   Value; typically `unist-util-is`-compatible test, but not arrays.\n */\n\n/**\n * @typedef {(\n *   Check extends ReadonlyArray\n *   ? MatchesOne\n *   : MatchesOne\n * )} Matches\n *   Check whether a node matches a check in the type system.\n * @template Value\n *   Value; typically unist `Node`.\n * @template Check\n *   Value; typically `unist-util-is`-compatible test.\n */\n\n/**\n * @typedef {0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} Uint\n *   Number; capped reasonably.\n */\n\n/**\n * @typedef {I extends 0 ? 1 : I extends 1 ? 2 : I extends 2 ? 3 : I extends 3 ? 4 : I extends 4 ? 5 : I extends 5 ? 6 : I extends 6 ? 7 : I extends 7 ? 8 : I extends 8 ? 9 : 10} Increment\n *   Increment a number in the type system.\n * @template {Uint} [I=0]\n *   Index.\n */\n\n/**\n * @typedef {(\n *   Node extends UnistParent\n *   ? Node extends {children: Array}\n *     ? Child extends Children ? Node : never\n *     : never\n *   : never\n * )} InternalParent\n *   Collect nodes that can be parents of `Child`.\n * @template {UnistNode} Node\n *   All node types in a tree.\n * @template {UnistNode} Child\n *   Node to search for.\n */\n\n/**\n * @typedef {InternalParent, Child>} Parent\n *   Collect nodes in `Tree` that can be parents of `Child`.\n * @template {UnistNode} Tree\n *   All node types in a tree.\n * @template {UnistNode} Child\n *   Node to search for.\n */\n\n/**\n * @typedef {(\n *   Depth extends Max\n *   ? never\n *   :\n *     | InternalParent\n *     | InternalAncestor, Max, Increment>\n * )} InternalAncestor\n *   Collect nodes in `Tree` that can be ancestors of `Child`.\n * @template {UnistNode} Node\n *   All node types in a tree.\n * @template {UnistNode} Child\n *   Node to search for.\n * @template {Uint} [Max=10]\n *   Max; searches up to this depth.\n * @template {Uint} [Depth=0]\n *   Current depth.\n */\n\n/**\n * @typedef {(\n *   Tree extends UnistParent\n *     ? Depth extends Max\n *       ? Tree\n *       : Tree | InclusiveDescendant>\n *     : Tree\n * )} InclusiveDescendant\n *   Collect all (inclusive) descendants of `Tree`.\n *\n *   > \uD83D\uDC49 **Note**: for performance reasons, this seems to be the fastest way to\n *   > recurse without actually running into an infinite loop, which the\n *   > previous version did.\n *   >\n *   > Practically, a max of `2` is typically enough assuming a `Root` is\n *   > passed, but it doesn\u2019t improve performance.\n *   > It gets higher with `List > ListItem > Table > TableRow > TableCell`.\n *   > Using up to `10` doesn\u2019t hurt or help either.\n * @template {UnistNode} Tree\n *   Tree type.\n * @template {Uint} [Max=10]\n *   Max; searches up to this depth.\n * @template {Uint} [Depth=0]\n *   Current depth.\n */\n\n/**\n * @callback Visitor\n *   Handle a node (matching `test`, if given).\n *\n *   Visitors are free to transform `node`.\n *   They can also transform `parent`.\n *\n *   Replacing `node` itself, if `SKIP` is not returned, still causes its\n *   descendants to be walked (which is a bug).\n *\n *   When adding or removing previous siblings of `node` (or next siblings, in\n *   case of reverse), the `Visitor` should return a new `Index` to specify the\n *   sibling to traverse after `node` is traversed.\n *   Adding or removing next siblings of `node` (or previous siblings, in case\n *   of reverse) is handled as expected without needing to return a new `Index`.\n *\n *   Removing the children property of `parent` still results in them being\n *   traversed.\n * @param {Visited} node\n *   Found node.\n * @param {Visited extends UnistNode ? number | undefined : never} index\n *   Index of `node` in `parent`.\n * @param {Ancestor extends UnistParent ? Ancestor | undefined : never} parent\n *   Parent of `node`.\n * @returns {VisitorResult}\n *   What to do next.\n *\n *   An `Index` is treated as a tuple of `[CONTINUE, Index]`.\n *   An `Action` is treated as a tuple of `[Action]`.\n *\n *   Passing a tuple back only makes sense if the `Action` is `SKIP`.\n *   When the `Action` is `EXIT`, that action can be returned.\n *   When the `Action` is `CONTINUE`, `Index` can be returned.\n * @template {UnistNode} [Visited=UnistNode]\n *   Visited node type.\n * @template {UnistParent} [Ancestor=UnistParent]\n *   Ancestor type.\n */\n\n/**\n * @typedef {Visitor>} BuildVisitorFromMatch\n *   Build a typed `Visitor` function from a node and all possible parents.\n *\n *   It will infer which values are passed as `node` and which as `parent`.\n * @template {UnistNode} Visited\n *   Node type.\n * @template {UnistParent} Ancestor\n *   Parent type.\n */\n\n/**\n * @typedef {(\n *   BuildVisitorFromMatch<\n *     Matches,\n *     Extract\n *   >\n * )} BuildVisitorFromDescendants\n *   Build a typed `Visitor` function from a list of descendants and a test.\n *\n *   It will infer which values are passed as `node` and which as `parent`.\n * @template {UnistNode} Descendant\n *   Node type.\n * @template {Test} Check\n *   Test type.\n */\n\n/**\n * @typedef {(\n *   BuildVisitorFromDescendants<\n *     InclusiveDescendant,\n *     Check\n *   >\n * )} BuildVisitor\n *   Build a typed `Visitor` function from a tree and a test.\n *\n *   It will infer which values are passed as `node` and which as `parent`.\n * @template {UnistNode} [Tree=UnistNode]\n *   Node type.\n * @template {Test} [Check=Test]\n *   Test type.\n */\n\nimport {visitParents} from 'unist-util-visit-parents'\n\nexport {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'\n\n/**\n * Visit nodes.\n *\n * This algorithm performs *depth-first* *tree traversal* in *preorder*\n * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).\n *\n * You can choose for which nodes `visitor` is called by passing a `test`.\n * For complex tests, you should test yourself in `visitor`, as it will be\n * faster and will have improved type information.\n *\n * Walking the tree is an intensive task.\n * Make use of the return values of the visitor when possible.\n * Instead of walking a tree multiple times, walk it once, use `unist-util-is`\n * to check if a node matches, and then perform different operations.\n *\n * You can change the tree.\n * See `Visitor` for more info.\n *\n * @overload\n * @param {Tree} tree\n * @param {Check} check\n * @param {BuildVisitor} visitor\n * @param {boolean | null | undefined} [reverse]\n * @returns {undefined}\n *\n * @overload\n * @param {Tree} tree\n * @param {BuildVisitor} visitor\n * @param {boolean | null | undefined} [reverse]\n * @returns {undefined}\n *\n * @param {UnistNode} tree\n *   Tree to traverse.\n * @param {Visitor | Test} testOrVisitor\n *   `unist-util-is`-compatible test (optional, omit to pass a visitor).\n * @param {Visitor | boolean | null | undefined} [visitorOrReverse]\n *   Handle each node (when test is omitted, pass `reverse`).\n * @param {boolean | null | undefined} [maybeReverse=false]\n *   Traverse in reverse preorder (NRL) instead of the default preorder (NLR).\n * @returns {undefined}\n *   Nothing.\n *\n * @template {UnistNode} Tree\n *   Node type.\n * @template {Test} Check\n *   `unist-util-is`-compatible test.\n */\nexport function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {\n  /** @type {boolean | null | undefined} */\n  let reverse\n  /** @type {Test} */\n  let test\n  /** @type {Visitor} */\n  let visitor\n\n  if (\n    typeof testOrVisitor === 'function' &&\n    typeof visitorOrReverse !== 'function'\n  ) {\n    test = undefined\n    visitor = testOrVisitor\n    reverse = visitorOrReverse\n  } else {\n    // @ts-expect-error: assume the overload with test was given.\n    test = testOrVisitor\n    // @ts-expect-error: assume the overload with test was given.\n    visitor = visitorOrReverse\n    reverse = maybeReverse\n  }\n\n  visitParents(tree, test, overload, reverse)\n\n  /**\n   * @param {UnistNode} node\n   * @param {Array} parents\n   */\n  function overload(node, parents) {\n    const parent = parents[parents.length - 1]\n    const index = parent ? parent.children.indexOf(node) : undefined\n    return visitor(node, index, parent)\n  }\n}\n", "// Note: types exported from `index.d.ts`\nexport {CONTINUE, EXIT, SKIP, visit} from './lib/index.js'\n", "/**\n * @import {\n *   ElementContent as HastElementContent,\n *   Element as HastElement,\n *   Nodes as HastNodes,\n *   Properties as HastProperties,\n *   RootContent as HastRootContent,\n *   Text as HastText\n * } from 'hast'\n * @import {\n *   Definition as MdastDefinition,\n *   FootnoteDefinition as MdastFootnoteDefinition,\n *   Nodes as MdastNodes,\n *   Parents as MdastParents\n * } from 'mdast'\n * @import {VFile} from 'vfile'\n * @import {\n *   FootnoteBackContentTemplate,\n *   FootnoteBackLabelTemplate\n * } from './footer.js'\n */\n\n/**\n * @callback Handler\n *   Handle a node.\n * @param {State} state\n *   Info passed around.\n * @param {any} node\n *   mdast node to handle.\n * @param {MdastParents | undefined} parent\n *   Parent of `node`.\n * @returns {Array | HastElementContent | undefined}\n *   hast node.\n *\n * @typedef {Partial>} Handlers\n *   Handle nodes.\n *\n * @typedef Options\n *   Configuration (optional).\n * @property {boolean | null | undefined} [allowDangerousHtml=false]\n *   Whether to persist raw HTML in markdown in the hast tree (default:\n *   `false`).\n * @property {string | null | undefined} [clobberPrefix='user-content-']\n *   Prefix to use before the `id` property on footnotes to prevent them from\n *   *clobbering* (default: `'user-content-'`).\n *\n *   Pass `''` for trusted markdown and when you are careful with\n *   polyfilling.\n *   You could pass a different prefix.\n *\n *   DOM clobbering is this:\n *\n *   ```html\n *   

    \n * \n * ```\n *\n * The above example shows that elements are made available by browsers, by\n * their ID, on the `window` object.\n * This is a security risk because you might be expecting some other variable\n * at that place.\n * It can also break polyfills.\n * Using a prefix solves these problems.\n * @property {VFile | null | undefined} [file]\n * Corresponding virtual file representing the input document (optional).\n * @property {FootnoteBackContentTemplate | string | null | undefined} [footnoteBackContent]\n * Content of the backreference back to references (default: `defaultFootnoteBackContent`).\n *\n * The default value is:\n *\n * ```js\n * function defaultFootnoteBackContent(_, rereferenceIndex) {\n * const result = [{type: 'text', value: '\u21A9'}]\n *\n * if (rereferenceIndex > 1) {\n * result.push({\n * type: 'element',\n * tagName: 'sup',\n * properties: {},\n * children: [{type: 'text', value: String(rereferenceIndex)}]\n * })\n * }\n *\n * return result\n * }\n * ```\n *\n * This content is used in the `a` element of each backreference (the `\u21A9`\n * links).\n * @property {FootnoteBackLabelTemplate | string | null | undefined} [footnoteBackLabel]\n * Label to describe the backreference back to references (default:\n * `defaultFootnoteBackLabel`).\n *\n * The default value is:\n *\n * ```js\n * function defaultFootnoteBackLabel(referenceIndex, rereferenceIndex) {\n * return (\n * 'Back to reference ' +\n * (referenceIndex + 1) +\n * (rereferenceIndex > 1 ? '-' + rereferenceIndex : '')\n * )\n * }\n * ```\n *\n * Change it when the markdown is not in English.\n *\n * This label is used in the `ariaLabel` property on each backreference\n * (the `\u21A9` links).\n * It affects users of assistive technology.\n * @property {string | null | undefined} [footnoteLabel='Footnotes']\n * Textual label to use for the footnotes section (default: `'Footnotes'`).\n *\n * Change it when the markdown is not in English.\n *\n * This label is typically hidden visually (assuming a `sr-only` CSS class\n * is defined that does that) and so affects screen readers only.\n * If you do have such a class, but want to show this section to everyone,\n * pass different properties with the `footnoteLabelProperties` option.\n * @property {HastProperties | null | undefined} [footnoteLabelProperties={className: ['sr-only']}]\n * Properties to use on the footnote label (default: `{className:\n * ['sr-only']}`).\n *\n * Change it to show the label and add other properties.\n *\n * This label is typically hidden visually (assuming an `sr-only` CSS class\n * is defined that does that) and so affects screen readers only.\n * If you do have such a class, but want to show this section to everyone,\n * pass an empty string.\n * You can also add different properties.\n *\n * > **Note**: `id: 'footnote-label'` is always added, because footnote\n * > calls use it with `aria-describedby` to provide an accessible label.\n * @property {string | null | undefined} [footnoteLabelTagName='h2']\n * HTML tag name to use for the footnote label element (default: `'h2'`).\n *\n * Change it to match your document structure.\n *\n * This label is typically hidden visually (assuming a `sr-only` CSS class\n * is defined that does that) and so affects screen readers only.\n * If you do have such a class, but want to show this section to everyone,\n * pass different properties with the `footnoteLabelProperties` option.\n * @property {Handlers | null | undefined} [handlers]\n * Extra handlers for nodes (optional).\n * @property {Array | null | undefined} [passThrough]\n * List of custom mdast node types to pass through (keep) in hast (note that\n * the node itself is passed, but eventual children are transformed)\n * (optional).\n * @property {Handler | null | undefined} [unknownHandler]\n * Handler for all unknown nodes (optional).\n *\n * @typedef State\n * Info passed around.\n * @property {(node: MdastNodes) => Array} all\n * Transform the children of an mdast parent to hast.\n * @property {(from: MdastNodes, to: Type) => HastElement | Type} applyData\n * Honor the `data` of `from`, and generate an element instead of `node`.\n * @property {Map} definitionById\n * Definitions by their identifier.\n * @property {Map} footnoteById\n * Footnote definitions by their identifier.\n * @property {Map} footnoteCounts\n * Counts for how often the same footnote was called.\n * @property {Array} footnoteOrder\n * Identifiers of order when footnote calls first appear in tree order.\n * @property {Handlers} handlers\n * Applied handlers.\n * @property {(node: MdastNodes, parent: MdastParents | undefined) => Array | HastElementContent | undefined} one\n * Transform an mdast node to hast.\n * @property {Options} options\n * Configuration.\n * @property {(from: MdastNodes, node: HastNodes) => undefined} patch\n * Copy a node\u2019s positional info.\n * @property {(nodes: Array, loose?: boolean | undefined) => Array} wrap\n * Wrap `nodes` with line endings between each node, adds initial/final line endings when `loose`.\n */\n\nimport structuredClone from '@ungap/structured-clone'\nimport {visit} from 'unist-util-visit'\nimport {position} from 'unist-util-position'\nimport {handlers as defaultHandlers} from './handlers/index.js'\n\nconst own = {}.hasOwnProperty\n\n/** @type {Options} */\nconst emptyOptions = {}\n\n/**\n * Create `state` from an mdast tree.\n *\n * @param {MdastNodes} tree\n * mdast node to transform.\n * @param {Options | null | undefined} [options]\n * Configuration (optional).\n * @returns {State}\n * `state` function.\n */\nexport function createState(tree, options) {\n const settings = options || emptyOptions\n /** @type {Map} */\n const definitionById = new Map()\n /** @type {Map} */\n const footnoteById = new Map()\n /** @type {Map} */\n const footnoteCounts = new Map()\n /** @type {Handlers} */\n // @ts-expect-error: the root handler returns a root.\n // Hard to type.\n const handlers = {...defaultHandlers, ...settings.handlers}\n\n /** @type {State} */\n const state = {\n all,\n applyData,\n definitionById,\n footnoteById,\n footnoteCounts,\n footnoteOrder: [],\n handlers,\n one,\n options: settings,\n patch,\n wrap\n }\n\n visit(tree, function (node) {\n if (node.type === 'definition' || node.type === 'footnoteDefinition') {\n const map = node.type === 'definition' ? definitionById : footnoteById\n const id = String(node.identifier).toUpperCase()\n\n // Mimick CM behavior of link definitions.\n // See: .\n if (!map.has(id)) {\n // @ts-expect-error: node type matches map.\n map.set(id, node)\n }\n }\n })\n\n return state\n\n /**\n * Transform an mdast node into a hast node.\n *\n * @param {MdastNodes} node\n * mdast node.\n * @param {MdastParents | undefined} [parent]\n * Parent of `node`.\n * @returns {Array | HastElementContent | undefined}\n * Resulting hast node.\n */\n function one(node, parent) {\n const type = node.type\n const handle = state.handlers[type]\n\n if (own.call(state.handlers, type) && handle) {\n return handle(state, node, parent)\n }\n\n if (state.options.passThrough && state.options.passThrough.includes(type)) {\n if ('children' in node) {\n const {children, ...shallow} = node\n const result = structuredClone(shallow)\n // @ts-expect-error: TS doesn\u2019t understand\u2026\n result.children = state.all(node)\n // @ts-expect-error: TS doesn\u2019t understand\u2026\n return result\n }\n\n // @ts-expect-error: it\u2019s custom.\n return structuredClone(node)\n }\n\n const unknown = state.options.unknownHandler || defaultUnknownHandler\n\n return unknown(state, node, parent)\n }\n\n /**\n * Transform the children of an mdast node into hast nodes.\n *\n * @param {MdastNodes} parent\n * mdast node to compile\n * @returns {Array}\n * Resulting hast nodes.\n */\n function all(parent) {\n /** @type {Array} */\n const values = []\n\n if ('children' in parent) {\n const nodes = parent.children\n let index = -1\n while (++index < nodes.length) {\n const result = state.one(nodes[index], parent)\n\n // To do: see if we van clean this? Can we merge texts?\n if (result) {\n if (index && nodes[index - 1].type === 'break') {\n if (!Array.isArray(result) && result.type === 'text') {\n result.value = trimMarkdownSpaceStart(result.value)\n }\n\n if (!Array.isArray(result) && result.type === 'element') {\n const head = result.children[0]\n\n if (head && head.type === 'text') {\n head.value = trimMarkdownSpaceStart(head.value)\n }\n }\n }\n\n if (Array.isArray(result)) {\n values.push(...result)\n } else {\n values.push(result)\n }\n }\n }\n }\n\n return values\n }\n}\n\n/**\n * Copy a node\u2019s positional info.\n *\n * @param {MdastNodes} from\n * mdast node to copy from.\n * @param {HastNodes} to\n * hast node to copy into.\n * @returns {undefined}\n * Nothing.\n */\nfunction patch(from, to) {\n if (from.position) to.position = position(from)\n}\n\n/**\n * Honor the `data` of `from` and maybe generate an element instead of `to`.\n *\n * @template {HastNodes} Type\n * Node type.\n * @param {MdastNodes} from\n * mdast node to use data from.\n * @param {Type} to\n * hast node to change.\n * @returns {HastElement | Type}\n * Nothing.\n */\nfunction applyData(from, to) {\n /** @type {HastElement | Type} */\n let result = to\n\n // Handle `data.hName`, `data.hProperties, `data.hChildren`.\n if (from && from.data) {\n const hName = from.data.hName\n const hChildren = from.data.hChildren\n const hProperties = from.data.hProperties\n\n if (typeof hName === 'string') {\n // Transforming the node resulted in an element with a different name\n // than wanted:\n if (result.type === 'element') {\n result.tagName = hName\n }\n // Transforming the node resulted in a non-element, which happens for\n // raw, text, and root nodes (unless custom handlers are passed).\n // The intent of `hName` is to create an element, but likely also to keep\n // the content around (otherwise: pass `hChildren`).\n else {\n /** @type {Array} */\n // @ts-expect-error: assume no doctypes in `root`.\n const children = 'children' in result ? result.children : [result]\n result = {type: 'element', tagName: hName, properties: {}, children}\n }\n }\n\n if (result.type === 'element' && hProperties) {\n Object.assign(result.properties, structuredClone(hProperties))\n }\n\n if (\n 'children' in result &&\n result.children &&\n hChildren !== null &&\n hChildren !== undefined\n ) {\n result.children = hChildren\n }\n }\n\n return result\n}\n\n/**\n * Transform an unknown node.\n *\n * @param {State} state\n * Info passed around.\n * @param {MdastNodes} node\n * Unknown mdast node.\n * @returns {HastElement | HastText}\n * Resulting hast node.\n */\nfunction defaultUnknownHandler(state, node) {\n const data = node.data || {}\n /** @type {HastElement | HastText} */\n const result =\n 'value' in node &&\n !(own.call(data, 'hProperties') || own.call(data, 'hChildren'))\n ? {type: 'text', value: node.value}\n : {\n type: 'element',\n tagName: 'div',\n properties: {},\n children: state.all(node)\n }\n\n state.patch(node, result)\n return state.applyData(node, result)\n}\n\n/**\n * Wrap `nodes` with line endings between each node.\n *\n * @template {HastRootContent} Type\n * Node type.\n * @param {Array} nodes\n * List of nodes to wrap.\n * @param {boolean | undefined} [loose=false]\n * Whether to add line endings at start and end (default: `false`).\n * @returns {Array}\n * Wrapped nodes.\n */\nexport function wrap(nodes, loose) {\n /** @type {Array} */\n const result = []\n let index = -1\n\n if (loose) {\n result.push({type: 'text', value: '\\n'})\n }\n\n while (++index < nodes.length) {\n if (index) result.push({type: 'text', value: '\\n'})\n result.push(nodes[index])\n }\n\n if (loose && nodes.length > 0) {\n result.push({type: 'text', value: '\\n'})\n }\n\n return result\n}\n\n/**\n * Trim spaces and tabs at the start of `value`.\n *\n * @param {string} value\n * Value to trim.\n * @returns {string}\n * Result.\n */\nfunction trimMarkdownSpaceStart(value) {\n let index = 0\n let code = value.charCodeAt(index)\n\n while (code === 9 || code === 32) {\n index++\n code = value.charCodeAt(index)\n }\n\n return value.slice(index)\n}\n", "/**\n * @import {Nodes as HastNodes} from 'hast'\n * @import {Nodes as MdastNodes} from 'mdast'\n * @import {Options} from './state.js'\n */\n\nimport {ok as assert} from 'devlop'\nimport {footer} from './footer.js'\nimport {createState} from './state.js'\n\n/**\n * Transform mdast to hast.\n *\n * ##### Notes\n *\n * ###### HTML\n *\n * Raw HTML is available in mdast as `html` nodes and can be embedded in hast\n * as semistandard `raw` nodes.\n * Most utilities ignore `raw` nodes but two notable ones don\u2019t:\n *\n * * `hast-util-to-html` also has an option `allowDangerousHtml` which will\n * output the raw HTML.\n * This is typically discouraged as noted by the option name but is useful\n * if you completely trust authors\n * * `hast-util-raw` can handle the raw embedded HTML strings by parsing them\n * into standard hast nodes (`element`, `text`, etc).\n * This is a heavy task as it needs a full HTML parser, but it is the only\n * way to support untrusted content\n *\n * ###### Footnotes\n *\n * Many options supported here relate to footnotes.\n * Footnotes are not specified by CommonMark, which we follow by default.\n * They are supported by GitHub, so footnotes can be enabled in markdown with\n * `mdast-util-gfm`.\n *\n * The options `footnoteBackLabel` and `footnoteLabel` define natural language\n * that explains footnotes, which is hidden for sighted users but shown to\n * assistive technology.\n * When your page is not in English, you must define translated values.\n *\n * Back references use ARIA attributes, but the section label itself uses a\n * heading that is hidden with an `sr-only` class.\n * To show it to sighted users, define different attributes in\n * `footnoteLabelProperties`.\n *\n * ###### Clobbering\n *\n * Footnotes introduces a problem, as it links footnote calls to footnote\n * definitions on the page through `id` attributes generated from user content,\n * which results in DOM clobbering.\n *\n * DOM clobbering is this:\n *\n * ```html\n *

    \n * \n * ```\n *\n * Elements by their ID are made available by browsers on the `window` object,\n * which is a security risk.\n * Using a prefix solves this problem.\n *\n * More information on how to handle clobbering and the prefix is explained in\n * Example: headings (DOM clobbering) in `rehype-sanitize`.\n *\n * ###### Unknown nodes\n *\n * Unknown nodes are nodes with a type that isn\u2019t in `handlers` or `passThrough`.\n * The default behavior for unknown nodes is:\n *\n * * when the node has a `value` (and doesn\u2019t have `data.hName`,\n * `data.hProperties`, or `data.hChildren`, see later), create a hast `text`\n * node\n * * otherwise, create a `
    ` element (which could be changed with\n * `data.hName`), with its children mapped from mdast to hast as well\n *\n * This behavior can be changed by passing an `unknownHandler`.\n *\n * @param {MdastNodes} tree\n * mdast tree.\n * @param {Options | null | undefined} [options]\n * Configuration (optional).\n * @returns {HastNodes}\n * hast tree.\n */\nexport function toHast(tree, options) {\n const state = createState(tree, options)\n const node = state.one(tree, undefined)\n const foot = footer(state)\n /** @type {HastNodes} */\n const result = Array.isArray(node)\n ? {type: 'root', children: node}\n : node || {type: 'root', children: []}\n\n if (foot) {\n // If there\u2019s a footer, there were definitions, meaning block\n // content.\n // So `result` is a parent node.\n assert('children' in result)\n result.children.push({type: 'text', value: '\\n'}, foot)\n }\n\n return result\n}\n", "// Note: types exposed from `index.d.ts`.\nexport {handlers as defaultHandlers} from './lib/handlers/index.js'\nexport {toHast} from './lib/index.js'\nexport {\n defaultFootnoteBackContent,\n defaultFootnoteBackLabel\n} from './lib/footer.js'\n", "/**\n * @import {Root as HastRoot} from 'hast'\n * @import {Root as MdastRoot} from 'mdast'\n * @import {Options as ToHastOptions} from 'mdast-util-to-hast'\n * @import {Processor} from 'unified'\n * @import {VFile} from 'vfile'\n */\n\n/**\n * @typedef {Omit} Options\n *\n * @callback TransformBridge\n * Bridge-mode.\n *\n * Runs the destination with the new hast tree.\n * Discards result.\n * @param {MdastRoot} tree\n * Tree.\n * @param {VFile} file\n * File.\n * @returns {Promise}\n * Nothing.\n *\n * @callback TransformMutate\n * Mutate-mode.\n *\n * Further transformers run on the hast tree.\n * @param {MdastRoot} tree\n * Tree.\n * @param {VFile} file\n * File.\n * @returns {HastRoot}\n * Tree (hast).\n */\n\nimport {toHast} from 'mdast-util-to-hast'\n\n/**\n * Turn markdown into HTML.\n *\n * ##### Notes\n *\n * ###### Signature\n *\n * * if a processor is given,\n * runs the (rehype) plugins used on it with a hast tree,\n * then discards the result (*bridge mode*)\n * * otherwise,\n * returns a hast tree,\n * the plugins used after `remarkRehype` are rehype plugins (*mutate mode*)\n *\n * > \uD83D\uDC49 **Note**:\n * > It\u2019s highly unlikely that you want to pass a `processor`.\n *\n * ###### HTML\n *\n * Raw HTML is available in mdast as `html` nodes and can be embedded in hast\n * as semistandard `raw` nodes.\n * Most plugins ignore `raw` nodes but two notable ones don\u2019t:\n *\n * * `rehype-stringify` also has an option `allowDangerousHtml` which will\n * output the raw HTML.\n * This is typically discouraged as noted by the option name but is useful if\n * you completely trust authors\n * * `rehype-raw` can handle the raw embedded HTML strings by parsing them\n * into standard hast nodes (`element`, `text`, etc);\n * this is a heavy task as it needs a full HTML parser,\n * but it is the only way to support untrusted content\n *\n * ###### Footnotes\n *\n * Many options supported here relate to footnotes.\n * Footnotes are not specified by CommonMark,\n * which we follow by default.\n * They are supported by GitHub,\n * so footnotes can be enabled in markdown with `remark-gfm`.\n *\n * The options `footnoteBackLabel` and `footnoteLabel` define natural language\n * that explains footnotes,\n * which is hidden for sighted users but shown to assistive technology.\n * When your page is not in English,\n * you must define translated values.\n *\n * Back references use ARIA attributes,\n * but the section label itself uses a heading that is hidden with an\n * `sr-only` class.\n * To show it to sighted users,\n * define different attributes in `footnoteLabelProperties`.\n *\n * ###### Clobbering\n *\n * Footnotes introduces a problem,\n * as it links footnote calls to footnote definitions on the page through `id`\n * attributes generated from user content,\n * which results in DOM clobbering.\n *\n * DOM clobbering is this:\n *\n * ```html\n *

    \n * \n * ```\n *\n * Elements by their ID are made available by browsers on the `window` object,\n * which is a security risk.\n * Using a prefix solves this problem.\n *\n * More information on how to handle clobbering and the prefix is explained in\n * *Example: headings (DOM clobbering)* in `rehype-sanitize`.\n *\n * ###### Unknown nodes\n *\n * Unknown nodes are nodes with a type that isn\u2019t in `handlers` or `passThrough`.\n * The default behavior for unknown nodes is:\n *\n * * when the node has a `value`\n * (and doesn\u2019t have `data.hName`, `data.hProperties`, or `data.hChildren`,\n * see later),\n * create a hast `text` node\n * * otherwise,\n * create a `
    ` element (which could be changed with `data.hName`),\n * with its children mapped from mdast to hast as well\n *\n * This behavior can be changed by passing an `unknownHandler`.\n *\n * @overload\n * @param {Processor} processor\n * @param {Readonly | null | undefined} [options]\n * @returns {TransformBridge}\n *\n * @overload\n * @param {Readonly | null | undefined} [options]\n * @returns {TransformMutate}\n *\n * @overload\n * @param {Readonly | Processor | null | undefined} [destination]\n * @param {Readonly | null | undefined} [options]\n * @returns {TransformBridge | TransformMutate}\n *\n * @param {Readonly | Processor | null | undefined} [destination]\n * Processor or configuration (optional).\n * @param {Readonly | null | undefined} [options]\n * When a processor was given,\n * configuration (optional).\n * @returns {TransformBridge | TransformMutate}\n * Transform.\n */\nexport default function remarkRehype(destination, options) {\n if (destination && 'run' in destination) {\n /**\n * @type {TransformBridge}\n */\n return async function (tree, file) {\n // Cast because root in -> root out.\n const hastTree = /** @type {HastRoot} */ (\n toHast(tree, {file, ...options})\n )\n await destination.run(hastTree, file)\n }\n }\n\n /**\n * @type {TransformMutate}\n */\n return function (tree, file) {\n // Cast because root in -> root out.\n // To do: in the future, disallow ` || options` fallback.\n // With `unified-engine`, `destination` can be `undefined` but\n // `options` will be the file set.\n // We should not pass that as `options`.\n return /** @type {HastRoot} */ (\n toHast(tree, {file, ...(destination || options)})\n )\n }\n}\n", "/**\n * @typedef {import('./lib/index.js').Options} Options\n */\n\nexport {\n defaultFootnoteBackContent,\n defaultFootnoteBackLabel,\n defaultHandlers\n} from 'mdast-util-to-hast'\nexport {default} from './lib/index.js'\n", "/**\n * Throw a given error.\n *\n * @param {Error|null|undefined} [error]\n * Maybe error.\n * @returns {asserts error is null|undefined}\n */\nexport function bail(error) {\n if (error) {\n throw error\n }\n}\n", "'use strict';\n\nvar hasOwn = Object.prototype.hasOwnProperty;\nvar toStr = Object.prototype.toString;\nvar defineProperty = Object.defineProperty;\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nvar isArray = function isArray(arr) {\n\tif (typeof Array.isArray === 'function') {\n\t\treturn Array.isArray(arr);\n\t}\n\n\treturn toStr.call(arr) === '[object Array]';\n};\n\nvar isPlainObject = function isPlainObject(obj) {\n\tif (!obj || toStr.call(obj) !== '[object Object]') {\n\t\treturn false;\n\t}\n\n\tvar hasOwnConstructor = hasOwn.call(obj, 'constructor');\n\tvar hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');\n\t// Not own constructor property must be Object\n\tif (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\n\t\treturn false;\n\t}\n\n\t// Own properties are enumerated firstly, so to speed up,\n\t// if last one is own, then all properties are own.\n\tvar key;\n\tfor (key in obj) { /**/ }\n\n\treturn typeof key === 'undefined' || hasOwn.call(obj, key);\n};\n\n// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target\nvar setProperty = function setProperty(target, options) {\n\tif (defineProperty && options.name === '__proto__') {\n\t\tdefineProperty(target, options.name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\t\t\tvalue: options.newValue,\n\t\t\twritable: true\n\t\t});\n\t} else {\n\t\ttarget[options.name] = options.newValue;\n\t}\n};\n\n// Return undefined instead of __proto__ if '__proto__' is not an own property\nvar getProperty = function getProperty(obj, name) {\n\tif (name === '__proto__') {\n\t\tif (!hasOwn.call(obj, name)) {\n\t\t\treturn void 0;\n\t\t} else if (gOPD) {\n\t\t\t// In early versions of node, obj['__proto__'] is buggy when obj has\n\t\t\t// __proto__ as an own property. Object.getOwnPropertyDescriptor() works.\n\t\t\treturn gOPD(obj, name).value;\n\t\t}\n\t}\n\n\treturn obj[name];\n};\n\nmodule.exports = function extend() {\n\tvar options, name, src, copy, copyIsArray, clone;\n\tvar target = arguments[0];\n\tvar i = 1;\n\tvar length = arguments.length;\n\tvar deep = false;\n\n\t// Handle a deep copy situation\n\tif (typeof target === 'boolean') {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t}\n\tif (target == null || (typeof target !== 'object' && typeof target !== 'function')) {\n\t\ttarget = {};\n\t}\n\n\tfor (; i < length; ++i) {\n\t\toptions = arguments[i];\n\t\t// Only deal with non-null/undefined values\n\t\tif (options != null) {\n\t\t\t// Extend the base object\n\t\t\tfor (name in options) {\n\t\t\t\tsrc = getProperty(target, name);\n\t\t\t\tcopy = getProperty(options, name);\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif (target !== copy) {\n\t\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\t\tif (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {\n\t\t\t\t\t\tif (copyIsArray) {\n\t\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\t\tclone = src && isArray(src) ? src : [];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tclone = src && isPlainObject(src) ? src : {};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\t\tsetProperty(target, { name: name, newValue: extend(deep, clone, copy) });\n\n\t\t\t\t\t// Don't bring in undefined values\n\t\t\t\t\t} else if (typeof copy !== 'undefined') {\n\t\t\t\t\t\tsetProperty(target, { name: name, newValue: copy });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n", "export default function isPlainObject(value) {\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn false;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);\n}\n", "// To do: remove `void`s\n// To do: remove `null` from output of our APIs, allow it as user APIs.\n\n/**\n * @typedef {(error?: Error | null | undefined, ...output: Array) => void} Callback\n * Callback.\n *\n * @typedef {(...input: Array) => any} Middleware\n * Ware.\n *\n * @typedef Pipeline\n * Pipeline.\n * @property {Run} run\n * Run the pipeline.\n * @property {Use} use\n * Add middleware.\n *\n * @typedef {(...input: Array) => void} Run\n * Call all middleware.\n *\n * Calls `done` on completion with either an error or the output of the\n * last middleware.\n *\n * > \uD83D\uDC49 **Note**: as the length of input defines whether async functions get a\n * > `next` function,\n * > it\u2019s recommended to keep `input` at one value normally.\n\n *\n * @typedef {(fn: Middleware) => Pipeline} Use\n * Add middleware.\n */\n\n/**\n * Create new middleware.\n *\n * @returns {Pipeline}\n * Pipeline.\n */\nexport function trough() {\n /** @type {Array} */\n const fns = []\n /** @type {Pipeline} */\n const pipeline = {run, use}\n\n return pipeline\n\n /** @type {Run} */\n function run(...values) {\n let middlewareIndex = -1\n /** @type {Callback} */\n const callback = values.pop()\n\n if (typeof callback !== 'function') {\n throw new TypeError('Expected function as last argument, not ' + callback)\n }\n\n next(null, ...values)\n\n /**\n * Run the next `fn`, or we\u2019re done.\n *\n * @param {Error | null | undefined} error\n * @param {Array} output\n */\n function next(error, ...output) {\n const fn = fns[++middlewareIndex]\n let index = -1\n\n if (error) {\n callback(error)\n return\n }\n\n // Copy non-nullish input into values.\n while (++index < values.length) {\n if (output[index] === null || output[index] === undefined) {\n output[index] = values[index]\n }\n }\n\n // Save the newly created `output` for the next call.\n values = output\n\n // Next or done.\n if (fn) {\n wrap(fn, next)(...output)\n } else {\n callback(null, ...output)\n }\n }\n }\n\n /** @type {Use} */\n function use(middelware) {\n if (typeof middelware !== 'function') {\n throw new TypeError(\n 'Expected `middelware` to be a function, not ' + middelware\n )\n }\n\n fns.push(middelware)\n return pipeline\n }\n}\n\n/**\n * Wrap `middleware` into a uniform interface.\n *\n * You can pass all input to the resulting function.\n * `callback` is then called with the output of `middleware`.\n *\n * If `middleware` accepts more arguments than the later given in input,\n * an extra `done` function is passed to it after that input,\n * which must be called by `middleware`.\n *\n * The first value in `input` is the main input value.\n * All other input values are the rest input values.\n * The values given to `callback` are the input values,\n * merged with every non-nullish output value.\n *\n * * if `middleware` throws an error,\n * returns a promise that is rejected,\n * or calls the given `done` function with an error,\n * `callback` is called with that error\n * * if `middleware` returns a value or returns a promise that is resolved,\n * that value is the main output value\n * * if `middleware` calls `done`,\n * all non-nullish values except for the first one (the error) overwrite the\n * output values\n *\n * @param {Middleware} middleware\n * Function to wrap.\n * @param {Callback} callback\n * Callback called with the output of `middleware`.\n * @returns {Run}\n * Wrapped middleware.\n */\nexport function wrap(middleware, callback) {\n /** @type {boolean} */\n let called\n\n return wrapped\n\n /**\n * Call `middleware`.\n * @this {any}\n * @param {Array} parameters\n * @returns {void}\n */\n function wrapped(...parameters) {\n const fnExpectsCallback = middleware.length > parameters.length\n /** @type {any} */\n let result\n\n if (fnExpectsCallback) {\n parameters.push(done)\n }\n\n try {\n result = middleware.apply(this, parameters)\n } catch (error) {\n const exception = /** @type {Error} */ (error)\n\n // Well, this is quite the pickle.\n // `middleware` received a callback and called it synchronously, but that\n // threw an error.\n // The only thing left to do is to throw the thing instead.\n if (fnExpectsCallback && called) {\n throw exception\n }\n\n return done(exception)\n }\n\n if (!fnExpectsCallback) {\n if (result && result.then && typeof result.then === 'function') {\n result.then(then, done)\n } else if (result instanceof Error) {\n done(result)\n } else {\n then(result)\n }\n }\n }\n\n /**\n * Call `callback`, only once.\n *\n * @type {Callback}\n */\n function done(error, ...output) {\n if (!called) {\n called = true\n callback(error, ...output)\n }\n }\n\n /**\n * Call `done` with one value.\n *\n * @param {any} [value]\n */\n function then(value) {\n done(null, value)\n }\n}\n", "/**\n * @typedef {import('./lib/index.js').Callback} Callback\n * @typedef {import('./lib/index.js').Middleware} Middleware\n * @typedef {import('./lib/index.js').Pipeline} Pipeline\n * @typedef {import('./lib/index.js').Run} Run\n * @typedef {import('./lib/index.js').Use} Use\n */\n\nexport {trough, wrap} from './lib/index.js'\n", "// A derivative work based on:\n// .\n// Which is licensed:\n//\n// MIT License\n//\n// Copyright (c) 2013 James Halliday\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n// the Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n// A derivative work based on:\n//\n// Parts of that are extracted from Node\u2019s internal `path` module:\n// .\n// Which is licensed:\n//\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nexport const minpath = {basename, dirname, extname, join, sep: '/'}\n\n/* eslint-disable max-depth, complexity */\n\n/**\n * Get the basename from a path.\n *\n * @param {string} path\n * File path.\n * @param {string | null | undefined} [extname]\n * Extension to strip.\n * @returns {string}\n * Stem or basename.\n */\nfunction basename(path, extname) {\n if (extname !== undefined && typeof extname !== 'string') {\n throw new TypeError('\"ext\" argument must be a string')\n }\n\n assertPath(path)\n let start = 0\n let end = -1\n let index = path.length\n /** @type {boolean | undefined} */\n let seenNonSlash\n\n if (\n extname === undefined ||\n extname.length === 0 ||\n extname.length > path.length\n ) {\n while (index--) {\n if (path.codePointAt(index) === 47 /* `/` */) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now.\n if (seenNonSlash) {\n start = index + 1\n break\n }\n } else if (end < 0) {\n // We saw the first non-path separator, mark this as the end of our\n // path component.\n seenNonSlash = true\n end = index + 1\n }\n }\n\n return end < 0 ? '' : path.slice(start, end)\n }\n\n if (extname === path) {\n return ''\n }\n\n let firstNonSlashEnd = -1\n let extnameIndex = extname.length - 1\n\n while (index--) {\n if (path.codePointAt(index) === 47 /* `/` */) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now.\n if (seenNonSlash) {\n start = index + 1\n break\n }\n } else {\n if (firstNonSlashEnd < 0) {\n // We saw the first non-path separator, remember this index in case\n // we need it if the extension ends up not matching.\n seenNonSlash = true\n firstNonSlashEnd = index + 1\n }\n\n if (extnameIndex > -1) {\n // Try to match the explicit extension.\n if (path.codePointAt(index) === extname.codePointAt(extnameIndex--)) {\n if (extnameIndex < 0) {\n // We matched the extension, so mark this as the end of our path\n // component\n end = index\n }\n } else {\n // Extension does not match, so our result is the entire path\n // component\n extnameIndex = -1\n end = firstNonSlashEnd\n }\n }\n }\n }\n\n if (start === end) {\n end = firstNonSlashEnd\n } else if (end < 0) {\n end = path.length\n }\n\n return path.slice(start, end)\n}\n\n/**\n * Get the dirname from a path.\n *\n * @param {string} path\n * File path.\n * @returns {string}\n * File path.\n */\nfunction dirname(path) {\n assertPath(path)\n\n if (path.length === 0) {\n return '.'\n }\n\n let end = -1\n let index = path.length\n /** @type {boolean | undefined} */\n let unmatchedSlash\n\n // Prefix `--` is important to not run on `0`.\n while (--index) {\n if (path.codePointAt(index) === 47 /* `/` */) {\n if (unmatchedSlash) {\n end = index\n break\n }\n } else if (!unmatchedSlash) {\n // We saw the first non-path separator\n unmatchedSlash = true\n }\n }\n\n return end < 0\n ? path.codePointAt(0) === 47 /* `/` */\n ? '/'\n : '.'\n : end === 1 && path.codePointAt(0) === 47 /* `/` */\n ? '//'\n : path.slice(0, end)\n}\n\n/**\n * Get an extname from a path.\n *\n * @param {string} path\n * File path.\n * @returns {string}\n * Extname.\n */\nfunction extname(path) {\n assertPath(path)\n\n let index = path.length\n\n let end = -1\n let startPart = 0\n let startDot = -1\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find.\n let preDotState = 0\n /** @type {boolean | undefined} */\n let unmatchedSlash\n\n while (index--) {\n const code = path.codePointAt(index)\n\n if (code === 47 /* `/` */) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now.\n if (unmatchedSlash) {\n startPart = index + 1\n break\n }\n\n continue\n }\n\n if (end < 0) {\n // We saw the first non-path separator, mark this as the end of our\n // extension.\n unmatchedSlash = true\n end = index + 1\n }\n\n if (code === 46 /* `.` */) {\n // If this is our first dot, mark it as the start of our extension.\n if (startDot < 0) {\n startDot = index\n } else if (preDotState !== 1) {\n preDotState = 1\n }\n } else if (startDot > -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension.\n preDotState = -1\n }\n }\n\n if (\n startDot < 0 ||\n end < 0 ||\n // We saw a non-dot character immediately before the dot.\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly `..`.\n (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)\n ) {\n return ''\n }\n\n return path.slice(startDot, end)\n}\n\n/**\n * Join segments from a path.\n *\n * @param {Array} segments\n * Path segments.\n * @returns {string}\n * File path.\n */\nfunction join(...segments) {\n let index = -1\n /** @type {string | undefined} */\n let joined\n\n while (++index < segments.length) {\n assertPath(segments[index])\n\n if (segments[index]) {\n joined =\n joined === undefined ? segments[index] : joined + '/' + segments[index]\n }\n }\n\n return joined === undefined ? '.' : normalize(joined)\n}\n\n/**\n * Normalize a basic file path.\n *\n * @param {string} path\n * File path.\n * @returns {string}\n * File path.\n */\n// Note: `normalize` is not exposed as `path.normalize`, so some code is\n// manually removed from it.\nfunction normalize(path) {\n assertPath(path)\n\n const absolute = path.codePointAt(0) === 47 /* `/` */\n\n // Normalize the path according to POSIX rules.\n let value = normalizeString(path, !absolute)\n\n if (value.length === 0 && !absolute) {\n value = '.'\n }\n\n if (value.length > 0 && path.codePointAt(path.length - 1) === 47 /* / */) {\n value += '/'\n }\n\n return absolute ? '/' + value : value\n}\n\n/**\n * Resolve `.` and `..` elements in a path with directory names.\n *\n * @param {string} path\n * File path.\n * @param {boolean} allowAboveRoot\n * Whether `..` can move above root.\n * @returns {string}\n * File path.\n */\nfunction normalizeString(path, allowAboveRoot) {\n let result = ''\n let lastSegmentLength = 0\n let lastSlash = -1\n let dots = 0\n let index = -1\n /** @type {number | undefined} */\n let code\n /** @type {number} */\n let lastSlashIndex\n\n while (++index <= path.length) {\n if (index < path.length) {\n code = path.codePointAt(index)\n } else if (code === 47 /* `/` */) {\n break\n } else {\n code = 47 /* `/` */\n }\n\n if (code === 47 /* `/` */) {\n if (lastSlash === index - 1 || dots === 1) {\n // Empty.\n } else if (lastSlash !== index - 1 && dots === 2) {\n if (\n result.length < 2 ||\n lastSegmentLength !== 2 ||\n result.codePointAt(result.length - 1) !== 46 /* `.` */ ||\n result.codePointAt(result.length - 2) !== 46 /* `.` */\n ) {\n if (result.length > 2) {\n lastSlashIndex = result.lastIndexOf('/')\n\n if (lastSlashIndex !== result.length - 1) {\n if (lastSlashIndex < 0) {\n result = ''\n lastSegmentLength = 0\n } else {\n result = result.slice(0, lastSlashIndex)\n lastSegmentLength = result.length - 1 - result.lastIndexOf('/')\n }\n\n lastSlash = index\n dots = 0\n continue\n }\n } else if (result.length > 0) {\n result = ''\n lastSegmentLength = 0\n lastSlash = index\n dots = 0\n continue\n }\n }\n\n if (allowAboveRoot) {\n result = result.length > 0 ? result + '/..' : '..'\n lastSegmentLength = 2\n }\n } else {\n if (result.length > 0) {\n result += '/' + path.slice(lastSlash + 1, index)\n } else {\n result = path.slice(lastSlash + 1, index)\n }\n\n lastSegmentLength = index - lastSlash - 1\n }\n\n lastSlash = index\n dots = 0\n } else if (code === 46 /* `.` */ && dots > -1) {\n dots++\n } else {\n dots = -1\n }\n }\n\n return result\n}\n\n/**\n * Make sure `path` is a string.\n *\n * @param {string} path\n * File path.\n * @returns {asserts path is string}\n * Nothing.\n */\nfunction assertPath(path) {\n if (typeof path !== 'string') {\n throw new TypeError(\n 'Path must be a string. Received ' + JSON.stringify(path)\n )\n }\n}\n\n/* eslint-enable max-depth, complexity */\n", "// Somewhat based on:\n// .\n// But I don\u2019t think one tiny line of code can be copyrighted. \uD83D\uDE05\nexport const minproc = {cwd}\n\nfunction cwd() {\n return '/'\n}\n", "/**\n * Checks if a value has the shape of a WHATWG URL object.\n *\n * Using a symbol or instanceof would not be able to recognize URL objects\n * coming from other implementations (e.g. in Electron), so instead we are\n * checking some well known properties for a lack of a better test.\n *\n * We use `href` and `protocol` as they are the only properties that are\n * easy to retrieve and calculate due to the lazy nature of the getters.\n *\n * We check for auth attribute to distinguish legacy url instance with\n * WHATWG URL instance.\n *\n * @param {unknown} fileUrlOrPath\n * File path or URL.\n * @returns {fileUrlOrPath is URL}\n * Whether it\u2019s a URL.\n */\n// From: \nexport function isUrl(fileUrlOrPath) {\n return Boolean(\n fileUrlOrPath !== null &&\n typeof fileUrlOrPath === 'object' &&\n 'href' in fileUrlOrPath &&\n fileUrlOrPath.href &&\n 'protocol' in fileUrlOrPath &&\n fileUrlOrPath.protocol &&\n // @ts-expect-error: indexing is fine.\n fileUrlOrPath.auth === undefined\n )\n}\n", "import {isUrl} from './minurl.shared.js'\n\nexport {isUrl} from './minurl.shared.js'\n\n// See: \n\n/**\n * @param {URL | string} path\n * File URL.\n * @returns {string}\n * File URL.\n */\nexport function urlToPath(path) {\n if (typeof path === 'string') {\n path = new URL(path)\n } else if (!isUrl(path)) {\n /** @type {NodeJS.ErrnoException} */\n const error = new TypeError(\n 'The \"path\" argument must be of type string or an instance of URL. Received `' +\n path +\n '`'\n )\n error.code = 'ERR_INVALID_ARG_TYPE'\n throw error\n }\n\n if (path.protocol !== 'file:') {\n /** @type {NodeJS.ErrnoException} */\n const error = new TypeError('The URL must be of scheme file')\n error.code = 'ERR_INVALID_URL_SCHEME'\n throw error\n }\n\n return getPathFromURLPosix(path)\n}\n\n/**\n * Get a path from a POSIX URL.\n *\n * @param {URL} url\n * URL.\n * @returns {string}\n * File path.\n */\nfunction getPathFromURLPosix(url) {\n if (url.hostname !== '') {\n /** @type {NodeJS.ErrnoException} */\n const error = new TypeError(\n 'File URL host must be \"localhost\" or empty on darwin'\n )\n error.code = 'ERR_INVALID_FILE_URL_HOST'\n throw error\n }\n\n const pathname = url.pathname\n let index = -1\n\n while (++index < pathname.length) {\n if (\n pathname.codePointAt(index) === 37 /* `%` */ &&\n pathname.codePointAt(index + 1) === 50 /* `2` */\n ) {\n const third = pathname.codePointAt(index + 2)\n if (third === 70 /* `F` */ || third === 102 /* `f` */) {\n /** @type {NodeJS.ErrnoException} */\n const error = new TypeError(\n 'File URL path must not include encoded / characters'\n )\n error.code = 'ERR_INVALID_FILE_URL_PATH'\n throw error\n }\n }\n }\n\n return decodeURIComponent(pathname)\n}\n", "/**\n * @import {Node, Point, Position} from 'unist'\n * @import {Options as MessageOptions} from 'vfile-message'\n * @import {Compatible, Data, Map, Options, Value} from 'vfile'\n */\n\n/**\n * @typedef {object & {type: string, position?: Position | undefined}} NodeLike\n */\n\nimport {VFileMessage} from 'vfile-message'\nimport {minpath} from '#minpath'\nimport {minproc} from '#minproc'\nimport {urlToPath, isUrl} from '#minurl'\n\n/**\n * Order of setting (least specific to most), we need this because otherwise\n * `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a\n * stem can be set.\n */\nconst order = /** @type {const} */ ([\n 'history',\n 'path',\n 'basename',\n 'stem',\n 'extname',\n 'dirname'\n])\n\nexport class VFile {\n /**\n * Create a new virtual file.\n *\n * `options` is treated as:\n *\n * * `string` or `Uint8Array` \u2014 `{value: options}`\n * * `URL` \u2014 `{path: options}`\n * * `VFile` \u2014 shallow copies its data over to the new file\n * * `object` \u2014 all fields are shallow copied over to the new file\n *\n * Path related fields are set in the following order (least specific to\n * most specific): `history`, `path`, `basename`, `stem`, `extname`,\n * `dirname`.\n *\n * You cannot set `dirname` or `extname` without setting either `history`,\n * `path`, `basename`, or `stem` too.\n *\n * @param {Compatible | null | undefined} [value]\n * File value.\n * @returns\n * New instance.\n */\n constructor(value) {\n /** @type {Options | VFile} */\n let options\n\n if (!value) {\n options = {}\n } else if (isUrl(value)) {\n options = {path: value}\n } else if (typeof value === 'string' || isUint8Array(value)) {\n options = {value}\n } else {\n options = value\n }\n\n /* eslint-disable no-unused-expressions */\n\n /**\n * Base of `path` (default: `process.cwd()` or `'/'` in browsers).\n *\n * @type {string}\n */\n // Prevent calling `cwd` (which could be expensive) if it\u2019s not needed;\n // the empty string will be overridden in the next block.\n this.cwd = 'cwd' in options ? '' : minproc.cwd()\n\n /**\n * Place to store custom info (default: `{}`).\n *\n * It\u2019s OK to store custom data directly on the file but moving it to\n * `data` is recommended.\n *\n * @type {Data}\n */\n this.data = {}\n\n /**\n * List of file paths the file moved between.\n *\n * The first is the original path and the last is the current path.\n *\n * @type {Array}\n */\n this.history = []\n\n /**\n * List of messages associated with the file.\n *\n * @type {Array}\n */\n this.messages = []\n\n /**\n * Raw value.\n *\n * @type {Value}\n */\n this.value\n\n // The below are non-standard, they are \u201Cwell-known\u201D.\n // As in, used in several tools.\n /**\n * Source map.\n *\n * This type is equivalent to the `RawSourceMap` type from the `source-map`\n * module.\n *\n * @type {Map | null | undefined}\n */\n this.map\n\n /**\n * Custom, non-string, compiled, representation.\n *\n * This is used by unified to store non-string results.\n * One example is when turning markdown into React nodes.\n *\n * @type {unknown}\n */\n this.result\n\n /**\n * Whether a file was saved to disk.\n *\n * This is used by vfile reporters.\n *\n * @type {boolean}\n */\n this.stored\n /* eslint-enable no-unused-expressions */\n\n // Set path related properties in the correct order.\n let index = -1\n\n while (++index < order.length) {\n const field = order[index]\n\n // Note: we specifically use `in` instead of `hasOwnProperty` to accept\n // `vfile`s too.\n if (\n field in options &&\n options[field] !== undefined &&\n options[field] !== null\n ) {\n // @ts-expect-error: TS doesn\u2019t understand basic reality.\n this[field] = field === 'history' ? [...options[field]] : options[field]\n }\n }\n\n /** @type {string} */\n let field\n\n // Set non-path related properties.\n for (field in options) {\n // @ts-expect-error: fine to set other things.\n if (!order.includes(field)) {\n // @ts-expect-error: fine to set other things.\n this[field] = options[field]\n }\n }\n }\n\n /**\n * Get the basename (including extname) (example: `'index.min.js'`).\n *\n * @returns {string | undefined}\n * Basename.\n */\n get basename() {\n return typeof this.path === 'string'\n ? minpath.basename(this.path)\n : undefined\n }\n\n /**\n * Set basename (including extname) (`'index.min.js'`).\n *\n * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\\'`\n * on windows).\n * Cannot be nullified (use `file.path = file.dirname` instead).\n *\n * @param {string} basename\n * Basename.\n * @returns {undefined}\n * Nothing.\n */\n set basename(basename) {\n assertNonEmpty(basename, 'basename')\n assertPart(basename, 'basename')\n this.path = minpath.join(this.dirname || '', basename)\n }\n\n /**\n * Get the parent path (example: `'~'`).\n *\n * @returns {string | undefined}\n * Dirname.\n */\n get dirname() {\n return typeof this.path === 'string'\n ? minpath.dirname(this.path)\n : undefined\n }\n\n /**\n * Set the parent path (example: `'~'`).\n *\n * Cannot be set if there\u2019s no `path` yet.\n *\n * @param {string | undefined} dirname\n * Dirname.\n * @returns {undefined}\n * Nothing.\n */\n set dirname(dirname) {\n assertPath(this.basename, 'dirname')\n this.path = minpath.join(dirname || '', this.basename)\n }\n\n /**\n * Get the extname (including dot) (example: `'.js'`).\n *\n * @returns {string | undefined}\n * Extname.\n */\n get extname() {\n return typeof this.path === 'string'\n ? minpath.extname(this.path)\n : undefined\n }\n\n /**\n * Set the extname (including dot) (example: `'.js'`).\n *\n * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\\'`\n * on windows).\n * Cannot be set if there\u2019s no `path` yet.\n *\n * @param {string | undefined} extname\n * Extname.\n * @returns {undefined}\n * Nothing.\n */\n set extname(extname) {\n assertPart(extname, 'extname')\n assertPath(this.dirname, 'extname')\n\n if (extname) {\n if (extname.codePointAt(0) !== 46 /* `.` */) {\n throw new Error('`extname` must start with `.`')\n }\n\n if (extname.includes('.', 1)) {\n throw new Error('`extname` cannot contain multiple dots')\n }\n }\n\n this.path = minpath.join(this.dirname, this.stem + (extname || ''))\n }\n\n /**\n * Get the full path (example: `'~/index.min.js'`).\n *\n * @returns {string}\n * Path.\n */\n get path() {\n return this.history[this.history.length - 1]\n }\n\n /**\n * Set the full path (example: `'~/index.min.js'`).\n *\n * Cannot be nullified.\n * You can set a file URL (a `URL` object with a `file:` protocol) which will\n * be turned into a path with `url.fileURLToPath`.\n *\n * @param {URL | string} path\n * Path.\n * @returns {undefined}\n * Nothing.\n */\n set path(path) {\n if (isUrl(path)) {\n path = urlToPath(path)\n }\n\n assertNonEmpty(path, 'path')\n\n if (this.path !== path) {\n this.history.push(path)\n }\n }\n\n /**\n * Get the stem (basename w/o extname) (example: `'index.min'`).\n *\n * @returns {string | undefined}\n * Stem.\n */\n get stem() {\n return typeof this.path === 'string'\n ? minpath.basename(this.path, this.extname)\n : undefined\n }\n\n /**\n * Set the stem (basename w/o extname) (example: `'index.min'`).\n *\n * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\\'`\n * on windows).\n * Cannot be nullified (use `file.path = file.dirname` instead).\n *\n * @param {string} stem\n * Stem.\n * @returns {undefined}\n * Nothing.\n */\n set stem(stem) {\n assertNonEmpty(stem, 'stem')\n assertPart(stem, 'stem')\n this.path = minpath.join(this.dirname || '', stem + (this.extname || ''))\n }\n\n // Normal prototypal methods.\n /**\n * Create a fatal message for `reason` associated with the file.\n *\n * The `fatal` field of the message is set to `true` (error; file not usable)\n * and the `file` field is set to the current file path.\n * The message is added to the `messages` field on `file`.\n *\n * > \uD83E\uDEA6 **Note**: also has obsolete signatures.\n *\n * @overload\n * @param {string} reason\n * @param {MessageOptions | null | undefined} [options]\n * @returns {never}\n *\n * @overload\n * @param {string} reason\n * @param {Node | NodeLike | null | undefined} parent\n * @param {string | null | undefined} [origin]\n * @returns {never}\n *\n * @overload\n * @param {string} reason\n * @param {Point | Position | null | undefined} place\n * @param {string | null | undefined} [origin]\n * @returns {never}\n *\n * @overload\n * @param {string} reason\n * @param {string | null | undefined} [origin]\n * @returns {never}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {Node | NodeLike | null | undefined} parent\n * @param {string | null | undefined} [origin]\n * @returns {never}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {Point | Position | null | undefined} place\n * @param {string | null | undefined} [origin]\n * @returns {never}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {string | null | undefined} [origin]\n * @returns {never}\n *\n * @param {Error | VFileMessage | string} causeOrReason\n * Reason for message, should use markdown.\n * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace]\n * Configuration (optional).\n * @param {string | null | undefined} [origin]\n * Place in code where the message originates (example:\n * `'my-package:my-rule'` or `'my-rule'`).\n * @returns {never}\n * Never.\n * @throws {VFileMessage}\n * Message.\n */\n fail(causeOrReason, optionsOrParentOrPlace, origin) {\n // @ts-expect-error: the overloads are fine.\n const message = this.message(causeOrReason, optionsOrParentOrPlace, origin)\n\n message.fatal = true\n\n throw message\n }\n\n /**\n * Create an info message for `reason` associated with the file.\n *\n * The `fatal` field of the message is set to `undefined` (info; change\n * likely not needed) and the `file` field is set to the current file path.\n * The message is added to the `messages` field on `file`.\n *\n * > \uD83E\uDEA6 **Note**: also has obsolete signatures.\n *\n * @overload\n * @param {string} reason\n * @param {MessageOptions | null | undefined} [options]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {string} reason\n * @param {Node | NodeLike | null | undefined} parent\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {string} reason\n * @param {Point | Position | null | undefined} place\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {string} reason\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {Node | NodeLike | null | undefined} parent\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {Point | Position | null | undefined} place\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @param {Error | VFileMessage | string} causeOrReason\n * Reason for message, should use markdown.\n * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace]\n * Configuration (optional).\n * @param {string | null | undefined} [origin]\n * Place in code where the message originates (example:\n * `'my-package:my-rule'` or `'my-rule'`).\n * @returns {VFileMessage}\n * Message.\n */\n info(causeOrReason, optionsOrParentOrPlace, origin) {\n // @ts-expect-error: the overloads are fine.\n const message = this.message(causeOrReason, optionsOrParentOrPlace, origin)\n\n message.fatal = undefined\n\n return message\n }\n\n /**\n * Create a message for `reason` associated with the file.\n *\n * The `fatal` field of the message is set to `false` (warning; change may be\n * needed) and the `file` field is set to the current file path.\n * The message is added to the `messages` field on `file`.\n *\n * > \uD83E\uDEA6 **Note**: also has obsolete signatures.\n *\n * @overload\n * @param {string} reason\n * @param {MessageOptions | null | undefined} [options]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {string} reason\n * @param {Node | NodeLike | null | undefined} parent\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {string} reason\n * @param {Point | Position | null | undefined} place\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {string} reason\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {Node | NodeLike | null | undefined} parent\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {Point | Position | null | undefined} place\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @overload\n * @param {Error | VFileMessage} cause\n * @param {string | null | undefined} [origin]\n * @returns {VFileMessage}\n *\n * @param {Error | VFileMessage | string} causeOrReason\n * Reason for message, should use markdown.\n * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace]\n * Configuration (optional).\n * @param {string | null | undefined} [origin]\n * Place in code where the message originates (example:\n * `'my-package:my-rule'` or `'my-rule'`).\n * @returns {VFileMessage}\n * Message.\n */\n message(causeOrReason, optionsOrParentOrPlace, origin) {\n const message = new VFileMessage(\n // @ts-expect-error: the overloads are fine.\n causeOrReason,\n optionsOrParentOrPlace,\n origin\n )\n\n if (this.path) {\n message.name = this.path + ':' + message.name\n message.file = this.path\n }\n\n message.fatal = false\n\n this.messages.push(message)\n\n return message\n }\n\n /**\n * Serialize the file.\n *\n * > **Note**: which encodings are supported depends on the engine.\n * > For info on Node.js, see:\n * > .\n *\n * @param {string | null | undefined} [encoding='utf8']\n * Character encoding to understand `value` as when it\u2019s a `Uint8Array`\n * (default: `'utf-8'`).\n * @returns {string}\n * Serialized file.\n */\n toString(encoding) {\n if (this.value === undefined) {\n return ''\n }\n\n if (typeof this.value === 'string') {\n return this.value\n }\n\n const decoder = new TextDecoder(encoding || undefined)\n return decoder.decode(this.value)\n }\n}\n\n/**\n * Assert that `part` is not a path (as in, does not contain `path.sep`).\n *\n * @param {string | null | undefined} part\n * File path part.\n * @param {string} name\n * Part name.\n * @returns {undefined}\n * Nothing.\n */\nfunction assertPart(part, name) {\n if (part && part.includes(minpath.sep)) {\n throw new Error(\n '`' + name + '` cannot be a path: did not expect `' + minpath.sep + '`'\n )\n }\n}\n\n/**\n * Assert that `part` is not empty.\n *\n * @param {string | undefined} part\n * Thing.\n * @param {string} name\n * Part name.\n * @returns {asserts part is string}\n * Nothing.\n */\nfunction assertNonEmpty(part, name) {\n if (!part) {\n throw new Error('`' + name + '` cannot be empty')\n }\n}\n\n/**\n * Assert `path` exists.\n *\n * @param {string | undefined} path\n * Path.\n * @param {string} name\n * Dependency name.\n * @returns {asserts path is string}\n * Nothing.\n */\nfunction assertPath(path, name) {\n if (!path) {\n throw new Error('Setting `' + name + '` requires `path` to be set too')\n }\n}\n\n/**\n * Assert `value` is an `Uint8Array`.\n *\n * @param {unknown} value\n * thing.\n * @returns {value is Uint8Array}\n * Whether `value` is an `Uint8Array`.\n */\nfunction isUint8Array(value) {\n return Boolean(\n value &&\n typeof value === 'object' &&\n 'byteLength' in value &&\n 'byteOffset' in value\n )\n}\n", "// More types exposed from `index.d.ts`.\nexport {VFile} from './lib/index.js'\n", "export const CallableInstance =\n /**\n * @type {new , Result>(property: string | symbol) => (...parameters: Parameters) => Result}\n */\n (\n /** @type {unknown} */\n (\n /**\n * @this {Function}\n * @param {string | symbol} property\n * @returns {(...parameters: Array) => unknown}\n */\n function (property) {\n const self = this\n const constr = self.constructor\n const proto = /** @type {Record} */ (\n // Prototypes do exist.\n // type-coverage:ignore-next-line\n constr.prototype\n )\n const value = proto[property]\n /** @type {(...parameters: Array) => unknown} */\n const apply = function () {\n return value.apply(apply, arguments)\n }\n\n Object.setPrototypeOf(apply, proto)\n\n // Not needed for us in `unified`: we only call this on the `copy`\n // function,\n // and we don't need to add its fields (`length`, `name`)\n // over.\n // See also: GH-246.\n // const names = Object.getOwnPropertyNames(value)\n //\n // for (const p of names) {\n // const descriptor = Object.getOwnPropertyDescriptor(value, p)\n // if (descriptor) Object.defineProperty(apply, p, descriptor)\n // }\n\n return apply\n }\n )\n )\n", "/**\n * @typedef {import('trough').Pipeline} Pipeline\n *\n * @typedef {import('unist').Node} Node\n *\n * @typedef {import('vfile').Compatible} Compatible\n * @typedef {import('vfile').Value} Value\n *\n * @typedef {import('../index.js').CompileResultMap} CompileResultMap\n * @typedef {import('../index.js').Data} Data\n * @typedef {import('../index.js').Settings} Settings\n */\n\n/**\n * @typedef {CompileResultMap[keyof CompileResultMap]} CompileResults\n * Acceptable results from compilers.\n *\n * To register custom results, add them to\n * {@linkcode CompileResultMap}.\n */\n\n/**\n * @template {Node} [Tree=Node]\n * The node that the compiler receives (default: `Node`).\n * @template {CompileResults} [Result=CompileResults]\n * The thing that the compiler yields (default: `CompileResults`).\n * @callback Compiler\n * A **compiler** handles the compiling of a syntax tree to something else\n * (in most cases, text) (TypeScript type).\n *\n * It is used in the stringify phase and called with a {@linkcode Node}\n * and {@linkcode VFile} representation of the document to compile.\n * It should return the textual representation of the given tree (typically\n * `string`).\n *\n * > **Note**: unified typically compiles by serializing: most compilers\n * > return `string` (or `Uint8Array`).\n * > Some compilers, such as the one configured with\n * > [`rehype-react`][rehype-react], return other values (in this case, a\n * > React tree).\n * > If you\u2019re using a compiler that doesn\u2019t serialize, expect different\n * > result values.\n * >\n * > To register custom results in TypeScript, add them to\n * > {@linkcode CompileResultMap}.\n *\n * [rehype-react]: https://github.com/rehypejs/rehype-react\n * @param {Tree} tree\n * Tree to compile.\n * @param {VFile} file\n * File associated with `tree`.\n * @returns {Result}\n * New content: compiled text (`string` or `Uint8Array`, for `file.value`) or\n * something else (for `file.result`).\n */\n\n/**\n * @template {Node} [Tree=Node]\n * The node that the parser yields (default: `Node`)\n * @callback Parser\n * A **parser** handles the parsing of text to a syntax tree.\n *\n * It is used in the parse phase and is called with a `string` and\n * {@linkcode VFile} of the document to parse.\n * It must return the syntax tree representation of the given file\n * ({@linkcode Node}).\n * @param {string} document\n * Document to parse.\n * @param {VFile} file\n * File associated with `document`.\n * @returns {Tree}\n * Node representing the given file.\n */\n\n/**\n * @typedef {(\n * Plugin, any, any> |\n * PluginTuple, any, any> |\n * Preset\n * )} Pluggable\n * Union of the different ways to add plugins and settings.\n */\n\n/**\n * @typedef {Array} PluggableList\n * List of plugins and presets.\n */\n\n// Note: we can\u2019t use `callback` yet as it messes up `this`:\n// .\n/**\n * @template {Array} [PluginParameters=[]]\n * Arguments passed to the plugin (default: `[]`, the empty tuple).\n * @template {Node | string | undefined} [Input=Node]\n * Value that is expected as input (default: `Node`).\n *\n * * If the plugin returns a {@linkcode Transformer}, this\n * should be the node it expects.\n * * If the plugin sets a {@linkcode Parser}, this should be\n * `string`.\n * * If the plugin sets a {@linkcode Compiler}, this should be the\n * node it expects.\n * @template [Output=Input]\n * Value that is yielded as output (default: `Input`).\n *\n * * If the plugin returns a {@linkcode Transformer}, this\n * should be the node that that yields.\n * * If the plugin sets a {@linkcode Parser}, this should be the\n * node that it yields.\n * * If the plugin sets a {@linkcode Compiler}, this should be\n * result it yields.\n * @typedef {(\n * (this: Processor, ...parameters: PluginParameters) =>\n * Input extends string ? // Parser.\n * Output extends Node | undefined ? undefined | void : never :\n * Output extends CompileResults ? // Compiler.\n * Input extends Node | undefined ? undefined | void : never :\n * Transformer<\n * Input extends Node ? Input : Node,\n * Output extends Node ? Output : Node\n * > | undefined | void\n * )} Plugin\n * Single plugin.\n *\n * Plugins configure the processors they are applied on in the following\n * ways:\n *\n * * they change the processor, such as the parser, the compiler, or by\n * configuring data\n * * they specify how to handle trees and files\n *\n * In practice, they are functions that can receive options and configure the\n * processor (`this`).\n *\n * > **Note**: plugins are called when the processor is *frozen*, not when\n * > they are applied.\n */\n\n/**\n * Tuple of a plugin and its configuration.\n *\n * The first item is a plugin, the rest are its parameters.\n *\n * @template {Array} [TupleParameters=[]]\n * Arguments passed to the plugin (default: `[]`, the empty tuple).\n * @template {Node | string | undefined} [Input=undefined]\n * Value that is expected as input (optional).\n *\n * * If the plugin returns a {@linkcode Transformer}, this\n * should be the node it expects.\n * * If the plugin sets a {@linkcode Parser}, this should be\n * `string`.\n * * If the plugin sets a {@linkcode Compiler}, this should be the\n * node it expects.\n * @template [Output=undefined] (optional).\n * Value that is yielded as output.\n *\n * * If the plugin returns a {@linkcode Transformer}, this\n * should be the node that that yields.\n * * If the plugin sets a {@linkcode Parser}, this should be the\n * node that it yields.\n * * If the plugin sets a {@linkcode Compiler}, this should be\n * result it yields.\n * @typedef {(\n * [\n * plugin: Plugin,\n * ...parameters: TupleParameters\n * ]\n * )} PluginTuple\n */\n\n/**\n * @typedef Preset\n * Sharable configuration.\n *\n * They can contain plugins and settings.\n * @property {PluggableList | undefined} [plugins]\n * List of plugins and presets (optional).\n * @property {Settings | undefined} [settings]\n * Shared settings for parsers and compilers (optional).\n */\n\n/**\n * @template {VFile} [File=VFile]\n * The file that the callback receives (default: `VFile`).\n * @callback ProcessCallback\n * Callback called when the process is done.\n *\n * Called with either an error or a result.\n * @param {Error | undefined} [error]\n * Fatal error (optional).\n * @param {File | undefined} [file]\n * Processed file (optional).\n * @returns {undefined}\n * Nothing.\n */\n\n/**\n * @template {Node} [Tree=Node]\n * The tree that the callback receives (default: `Node`).\n * @callback RunCallback\n * Callback called when transformers are done.\n *\n * Called with either an error or results.\n * @param {Error | undefined} [error]\n * Fatal error (optional).\n * @param {Tree | undefined} [tree]\n * Transformed tree (optional).\n * @param {VFile | undefined} [file]\n * File (optional).\n * @returns {undefined}\n * Nothing.\n */\n\n/**\n * @template {Node} [Output=Node]\n * Node type that the transformer yields (default: `Node`).\n * @callback TransformCallback\n * Callback passed to transforms.\n *\n * If the signature of a `transformer` accepts a third argument, the\n * transformer may perform asynchronous operations, and must call it.\n * @param {Error | undefined} [error]\n * Fatal error to stop the process (optional).\n * @param {Output | undefined} [tree]\n * New, changed, tree (optional).\n * @param {VFile | undefined} [file]\n * New, changed, file (optional).\n * @returns {undefined}\n * Nothing.\n */\n\n/**\n * @template {Node} [Input=Node]\n * Node type that the transformer expects (default: `Node`).\n * @template {Node} [Output=Input]\n * Node type that the transformer yields (default: `Input`).\n * @callback Transformer\n * Transformers handle syntax trees and files.\n *\n * They are functions that are called each time a syntax tree and file are\n * passed through the run phase.\n * When an error occurs in them (either because it\u2019s thrown, returned,\n * rejected, or passed to `next`), the process stops.\n *\n * The run phase is handled by [`trough`][trough], see its documentation for\n * the exact semantics of these functions.\n *\n * > **Note**: you should likely ignore `next`: don\u2019t accept it.\n * > it supports callback-style async work.\n * > But promises are likely easier to reason about.\n *\n * [trough]: https://github.com/wooorm/trough#function-fninput-next\n * @param {Input} tree\n * Tree to handle.\n * @param {VFile} file\n * File to handle.\n * @param {TransformCallback} next\n * Callback.\n * @returns {(\n * Promise |\n * Promise | // For some reason this is needed separately.\n * Output |\n * Error |\n * undefined |\n * void\n * )}\n * If you accept `next`, nothing.\n * Otherwise:\n *\n * * `Error` \u2014 fatal error to stop the process\n * * `Promise` or `undefined` \u2014 the next transformer keeps using\n * same tree\n * * `Promise` or `Node` \u2014 new, changed, tree\n */\n\n/**\n * @template {Node | undefined} ParseTree\n * Output of `parse`.\n * @template {Node | undefined} HeadTree\n * Input for `run`.\n * @template {Node | undefined} TailTree\n * Output for `run`.\n * @template {Node | undefined} CompileTree\n * Input of `stringify`.\n * @template {CompileResults | undefined} CompileResult\n * Output of `stringify`.\n * @template {Node | string | undefined} Input\n * Input of plugin.\n * @template Output\n * Output of plugin (optional).\n * @typedef {(\n * Input extends string\n * ? Output extends Node | undefined\n * ? // Parser.\n * Processor<\n * Output extends undefined ? ParseTree : Output,\n * HeadTree,\n * TailTree,\n * CompileTree,\n * CompileResult\n * >\n * : // Unknown.\n * Processor\n * : Output extends CompileResults\n * ? Input extends Node | undefined\n * ? // Compiler.\n * Processor<\n * ParseTree,\n * HeadTree,\n * TailTree,\n * Input extends undefined ? CompileTree : Input,\n * Output extends undefined ? CompileResult : Output\n * >\n * : // Unknown.\n * Processor\n * : Input extends Node | undefined\n * ? Output extends Node | undefined\n * ? // Transform.\n * Processor<\n * ParseTree,\n * HeadTree extends undefined ? Input : HeadTree,\n * Output extends undefined ? TailTree : Output,\n * CompileTree,\n * CompileResult\n * >\n * : // Unknown.\n * Processor\n * : // Unknown.\n * Processor\n * )} UsePlugin\n * Create a processor based on the input/output of a {@link Plugin plugin}.\n */\n\n/**\n * @template {CompileResults | undefined} Result\n * Node type that the transformer yields.\n * @typedef {(\n * Result extends Value | undefined ?\n * VFile :\n * VFile & {result: Result}\n * )} VFileWithOutput\n * Type to generate a {@linkcode VFile} corresponding to a compiler result.\n *\n * If a result that is not acceptable on a `VFile` is used, that will\n * be stored on the `result` field of {@linkcode VFile}.\n */\n\nimport {bail} from 'bail'\nimport extend from 'extend'\nimport {ok as assert} from 'devlop'\nimport isPlainObj from 'is-plain-obj'\nimport {trough} from 'trough'\nimport {VFile} from 'vfile'\nimport {CallableInstance} from './callable-instance.js'\n\n// To do: next major: drop `Compiler`, `Parser`: prefer lowercase.\n\n// To do: we could start yielding `never` in TS when a parser is missing and\n// `parse` is called.\n// Currently, we allow directly setting `processor.parser`, which is untyped.\n\nconst own = {}.hasOwnProperty\n\n/**\n * @template {Node | undefined} [ParseTree=undefined]\n * Output of `parse` (optional).\n * @template {Node | undefined} [HeadTree=undefined]\n * Input for `run` (optional).\n * @template {Node | undefined} [TailTree=undefined]\n * Output for `run` (optional).\n * @template {Node | undefined} [CompileTree=undefined]\n * Input of `stringify` (optional).\n * @template {CompileResults | undefined} [CompileResult=undefined]\n * Output of `stringify` (optional).\n * @extends {CallableInstance<[], Processor>}\n */\nexport class Processor extends CallableInstance {\n /**\n * Create a processor.\n */\n constructor() {\n // If `Processor()` is called (w/o new), `copy` is called instead.\n super('copy')\n\n /**\n * Compiler to use (deprecated).\n *\n * @deprecated\n * Use `compiler` instead.\n * @type {(\n * Compiler<\n * CompileTree extends undefined ? Node : CompileTree,\n * CompileResult extends undefined ? CompileResults : CompileResult\n * > |\n * undefined\n * )}\n */\n this.Compiler = undefined\n\n /**\n * Parser to use (deprecated).\n *\n * @deprecated\n * Use `parser` instead.\n * @type {(\n * Parser |\n * undefined\n * )}\n */\n this.Parser = undefined\n\n // Note: the following fields are considered private.\n // However, they are needed for tests, and TSC generates an untyped\n // `private freezeIndex` field for, which trips `type-coverage` up.\n // Instead, we use `@deprecated` to visualize that they shouldn\u2019t be used.\n /**\n * Internal list of configured plugins.\n *\n * @deprecated\n * This is a private internal property and should not be used.\n * @type {Array>>}\n */\n this.attachers = []\n\n /**\n * Compiler to use.\n *\n * @type {(\n * Compiler<\n * CompileTree extends undefined ? Node : CompileTree,\n * CompileResult extends undefined ? CompileResults : CompileResult\n * > |\n * undefined\n * )}\n */\n this.compiler = undefined\n\n /**\n * Internal state to track where we are while freezing.\n *\n * @deprecated\n * This is a private internal property and should not be used.\n * @type {number}\n */\n this.freezeIndex = -1\n\n /**\n * Internal state to track whether we\u2019re frozen.\n *\n * @deprecated\n * This is a private internal property and should not be used.\n * @type {boolean | undefined}\n */\n this.frozen = undefined\n\n /**\n * Internal state.\n *\n * @deprecated\n * This is a private internal property and should not be used.\n * @type {Data}\n */\n this.namespace = {}\n\n /**\n * Parser to use.\n *\n * @type {(\n * Parser |\n * undefined\n * )}\n */\n this.parser = undefined\n\n /**\n * Internal list of configured transformers.\n *\n * @deprecated\n * This is a private internal property and should not be used.\n * @type {Pipeline}\n */\n this.transformers = trough()\n }\n\n /**\n * Copy a processor.\n *\n * @deprecated\n * This is a private internal method and should not be used.\n * @returns {Processor}\n * New *unfrozen* processor ({@linkcode Processor}) that is\n * configured to work the same as its ancestor.\n * When the descendant processor is configured in the future it does not\n * affect the ancestral processor.\n */\n copy() {\n // Cast as the type parameters will be the same after attaching.\n const destination =\n /** @type {Processor} */ (\n new Processor()\n )\n let index = -1\n\n while (++index < this.attachers.length) {\n const attacher = this.attachers[index]\n destination.use(...attacher)\n }\n\n destination.data(extend(true, {}, this.namespace))\n\n return destination\n }\n\n /**\n * Configure the processor with info available to all plugins.\n * Information is stored in an object.\n *\n * Typically, options can be given to a specific plugin, but sometimes it\n * makes sense to have information shared with several plugins.\n * For example, a list of HTML elements that are self-closing, which is\n * needed during all phases.\n *\n * > **Note**: setting information cannot occur on *frozen* processors.\n * > Call the processor first to create a new unfrozen processor.\n *\n * > **Note**: to register custom data in TypeScript, augment the\n * > {@linkcode Data} interface.\n *\n * @example\n * This example show how to get and set info:\n *\n * ```js\n * import {unified} from 'unified'\n *\n * const processor = unified().data('alpha', 'bravo')\n *\n * processor.data('alpha') // => 'bravo'\n *\n * processor.data() // => {alpha: 'bravo'}\n *\n * processor.data({charlie: 'delta'})\n *\n * processor.data() // => {charlie: 'delta'}\n * ```\n *\n * @template {keyof Data} Key\n *\n * @overload\n * @returns {Data}\n *\n * @overload\n * @param {Data} dataset\n * @returns {Processor}\n *\n * @overload\n * @param {Key} key\n * @returns {Data[Key]}\n *\n * @overload\n * @param {Key} key\n * @param {Data[Key]} value\n * @returns {Processor}\n *\n * @param {Data | Key} [key]\n * Key to get or set, or entire dataset to set, or nothing to get the\n * entire dataset (optional).\n * @param {Data[Key]} [value]\n * Value to set (optional).\n * @returns {unknown}\n * The current processor when setting, the value at `key` when getting, or\n * the entire dataset when getting without key.\n */\n data(key, value) {\n if (typeof key === 'string') {\n // Set `key`.\n if (arguments.length === 2) {\n assertUnfrozen('data', this.frozen)\n this.namespace[key] = value\n return this\n }\n\n // Get `key`.\n return (own.call(this.namespace, key) && this.namespace[key]) || undefined\n }\n\n // Set space.\n if (key) {\n assertUnfrozen('data', this.frozen)\n this.namespace = key\n return this\n }\n\n // Get space.\n return this.namespace\n }\n\n /**\n * Freeze a processor.\n *\n * Frozen processors are meant to be extended and not to be configured\n * directly.\n *\n * When a processor is frozen it cannot be unfrozen.\n * New processors working the same way can be created by calling the\n * processor.\n *\n * It\u2019s possible to freeze processors explicitly by calling `.freeze()`.\n * Processors freeze automatically when `.parse()`, `.run()`, `.runSync()`,\n * `.stringify()`, `.process()`, or `.processSync()` are called.\n *\n * @returns {Processor}\n * The current processor.\n */\n freeze() {\n if (this.frozen) {\n return this\n }\n\n // Cast so that we can type plugins easier.\n // Plugins are supposed to be usable on different processors, not just on\n // this exact processor.\n const self = /** @type {Processor} */ (/** @type {unknown} */ (this))\n\n while (++this.freezeIndex < this.attachers.length) {\n const [attacher, ...options] = this.attachers[this.freezeIndex]\n\n if (options[0] === false) {\n continue\n }\n\n if (options[0] === true) {\n options[0] = undefined\n }\n\n const transformer = attacher.call(self, ...options)\n\n if (typeof transformer === 'function') {\n this.transformers.use(transformer)\n }\n }\n\n this.frozen = true\n this.freezeIndex = Number.POSITIVE_INFINITY\n\n return this\n }\n\n /**\n * Parse text to a syntax tree.\n *\n * > **Note**: `parse` freezes the processor if not already *frozen*.\n *\n * > **Note**: `parse` performs the parse phase, not the run phase or other\n * > phases.\n *\n * @param {Compatible | undefined} [file]\n * file to parse (optional); typically `string` or `VFile`; any value\n * accepted as `x` in `new VFile(x)`.\n * @returns {ParseTree extends undefined ? Node : ParseTree}\n * Syntax tree representing `file`.\n */\n parse(file) {\n this.freeze()\n const realFile = vfile(file)\n const parser = this.parser || this.Parser\n assertParser('parse', parser)\n return parser(String(realFile), realFile)\n }\n\n /**\n * Process the given file as configured on the processor.\n *\n * > **Note**: `process` freezes the processor if not already *frozen*.\n *\n * > **Note**: `process` performs the parse, run, and stringify phases.\n *\n * @overload\n * @param {Compatible | undefined} file\n * @param {ProcessCallback>} done\n * @returns {undefined}\n *\n * @overload\n * @param {Compatible | undefined} [file]\n * @returns {Promise>}\n *\n * @param {Compatible | undefined} [file]\n * File (optional); typically `string` or `VFile`]; any value accepted as\n * `x` in `new VFile(x)`.\n * @param {ProcessCallback> | undefined} [done]\n * Callback (optional).\n * @returns {Promise | undefined}\n * Nothing if `done` is given.\n * Otherwise a promise, rejected with a fatal error or resolved with the\n * processed file.\n *\n * The parsed, transformed, and compiled value is available at\n * `file.value` (see note).\n *\n * > **Note**: unified typically compiles by serializing: most\n * > compilers return `string` (or `Uint8Array`).\n * > Some compilers, such as the one configured with\n * > [`rehype-react`][rehype-react], return other values (in this case, a\n * > React tree).\n * > If you\u2019re using a compiler that doesn\u2019t serialize, expect different\n * > result values.\n * >\n * > To register custom results in TypeScript, add them to\n * > {@linkcode CompileResultMap}.\n *\n * [rehype-react]: https://github.com/rehypejs/rehype-react\n */\n process(file, done) {\n const self = this\n\n this.freeze()\n assertParser('process', this.parser || this.Parser)\n assertCompiler('process', this.compiler || this.Compiler)\n\n return done ? executor(undefined, done) : new Promise(executor)\n\n // Note: `void`s needed for TS.\n /**\n * @param {((file: VFileWithOutput) => undefined | void) | undefined} resolve\n * @param {(error: Error | undefined) => undefined | void} reject\n * @returns {undefined}\n */\n function executor(resolve, reject) {\n const realFile = vfile(file)\n // Assume `ParseTree` (the result of the parser) matches `HeadTree` (the\n // input of the first transform).\n const parseTree =\n /** @type {HeadTree extends undefined ? Node : HeadTree} */ (\n /** @type {unknown} */ (self.parse(realFile))\n )\n\n self.run(parseTree, realFile, function (error, tree, file) {\n if (error || !tree || !file) {\n return realDone(error)\n }\n\n // Assume `TailTree` (the output of the last transform) matches\n // `CompileTree` (the input of the compiler).\n const compileTree =\n /** @type {CompileTree extends undefined ? Node : CompileTree} */ (\n /** @type {unknown} */ (tree)\n )\n\n const compileResult = self.stringify(compileTree, file)\n\n if (looksLikeAValue(compileResult)) {\n file.value = compileResult\n } else {\n file.result = compileResult\n }\n\n realDone(error, /** @type {VFileWithOutput} */ (file))\n })\n\n /**\n * @param {Error | undefined} error\n * @param {VFileWithOutput | undefined} [file]\n * @returns {undefined}\n */\n function realDone(error, file) {\n if (error || !file) {\n reject(error)\n } else if (resolve) {\n resolve(file)\n } else {\n assert(done, '`done` is defined if `resolve` is not')\n done(undefined, file)\n }\n }\n }\n }\n\n /**\n * Process the given file as configured on the processor.\n *\n * An error is thrown if asynchronous transforms are configured.\n *\n * > **Note**: `processSync` freezes the processor if not already *frozen*.\n *\n * > **Note**: `processSync` performs the parse, run, and stringify phases.\n *\n * @param {Compatible | undefined} [file]\n * File (optional); typically `string` or `VFile`; any value accepted as\n * `x` in `new VFile(x)`.\n * @returns {VFileWithOutput}\n * The processed file.\n *\n * The parsed, transformed, and compiled value is available at\n * `file.value` (see note).\n *\n * > **Note**: unified typically compiles by serializing: most\n * > compilers return `string` (or `Uint8Array`).\n * > Some compilers, such as the one configured with\n * > [`rehype-react`][rehype-react], return other values (in this case, a\n * > React tree).\n * > If you\u2019re using a compiler that doesn\u2019t serialize, expect different\n * > result values.\n * >\n * > To register custom results in TypeScript, add them to\n * > {@linkcode CompileResultMap}.\n *\n * [rehype-react]: https://github.com/rehypejs/rehype-react\n */\n processSync(file) {\n /** @type {boolean} */\n let complete = false\n /** @type {VFileWithOutput | undefined} */\n let result\n\n this.freeze()\n assertParser('processSync', this.parser || this.Parser)\n assertCompiler('processSync', this.compiler || this.Compiler)\n\n this.process(file, realDone)\n assertDone('processSync', 'process', complete)\n assert(result, 'we either bailed on an error or have a tree')\n\n return result\n\n /**\n * @type {ProcessCallback>}\n */\n function realDone(error, file) {\n complete = true\n bail(error)\n result = file\n }\n }\n\n /**\n * Run *transformers* on a syntax tree.\n *\n * > **Note**: `run` freezes the processor if not already *frozen*.\n *\n * > **Note**: `run` performs the run phase, not other phases.\n *\n * @overload\n * @param {HeadTree extends undefined ? Node : HeadTree} tree\n * @param {RunCallback} done\n * @returns {undefined}\n *\n * @overload\n * @param {HeadTree extends undefined ? Node : HeadTree} tree\n * @param {Compatible | undefined} file\n * @param {RunCallback} done\n * @returns {undefined}\n *\n * @overload\n * @param {HeadTree extends undefined ? Node : HeadTree} tree\n * @param {Compatible | undefined} [file]\n * @returns {Promise}\n *\n * @param {HeadTree extends undefined ? Node : HeadTree} tree\n * Tree to transform and inspect.\n * @param {(\n * RunCallback |\n * Compatible\n * )} [file]\n * File associated with `node` (optional); any value accepted as `x` in\n * `new VFile(x)`.\n * @param {RunCallback} [done]\n * Callback (optional).\n * @returns {Promise | undefined}\n * Nothing if `done` is given.\n * Otherwise, a promise rejected with a fatal error or resolved with the\n * transformed tree.\n */\n run(tree, file, done) {\n assertNode(tree)\n this.freeze()\n\n const transformers = this.transformers\n\n if (!done && typeof file === 'function') {\n done = file\n file = undefined\n }\n\n return done ? executor(undefined, done) : new Promise(executor)\n\n // Note: `void`s needed for TS.\n /**\n * @param {(\n * ((tree: TailTree extends undefined ? Node : TailTree) => undefined | void) |\n * undefined\n * )} resolve\n * @param {(error: Error) => undefined | void} reject\n * @returns {undefined}\n */\n function executor(resolve, reject) {\n assert(\n typeof file !== 'function',\n '`file` can\u2019t be a `done` anymore, we checked'\n )\n const realFile = vfile(file)\n transformers.run(tree, realFile, realDone)\n\n /**\n * @param {Error | undefined} error\n * @param {Node} outputTree\n * @param {VFile} file\n * @returns {undefined}\n */\n function realDone(error, outputTree, file) {\n const resultingTree =\n /** @type {TailTree extends undefined ? Node : TailTree} */ (\n outputTree || tree\n )\n\n if (error) {\n reject(error)\n } else if (resolve) {\n resolve(resultingTree)\n } else {\n assert(done, '`done` is defined if `resolve` is not')\n done(undefined, resultingTree, file)\n }\n }\n }\n }\n\n /**\n * Run *transformers* on a syntax tree.\n *\n * An error is thrown if asynchronous transforms are configured.\n *\n * > **Note**: `runSync` freezes the processor if not already *frozen*.\n *\n * > **Note**: `runSync` performs the run phase, not other phases.\n *\n * @param {HeadTree extends undefined ? Node : HeadTree} tree\n * Tree to transform and inspect.\n * @param {Compatible | undefined} [file]\n * File associated with `node` (optional); any value accepted as `x` in\n * `new VFile(x)`.\n * @returns {TailTree extends undefined ? Node : TailTree}\n * Transformed tree.\n */\n runSync(tree, file) {\n /** @type {boolean} */\n let complete = false\n /** @type {(TailTree extends undefined ? Node : TailTree) | undefined} */\n let result\n\n this.run(tree, file, realDone)\n\n assertDone('runSync', 'run', complete)\n assert(result, 'we either bailed on an error or have a tree')\n return result\n\n /**\n * @type {RunCallback}\n */\n function realDone(error, tree) {\n bail(error)\n result = tree\n complete = true\n }\n }\n\n /**\n * Compile a syntax tree.\n *\n * > **Note**: `stringify` freezes the processor if not already *frozen*.\n *\n * > **Note**: `stringify` performs the stringify phase, not the run phase\n * > or other phases.\n *\n * @param {CompileTree extends undefined ? Node : CompileTree} tree\n * Tree to compile.\n * @param {Compatible | undefined} [file]\n * File associated with `node` (optional); any value accepted as `x` in\n * `new VFile(x)`.\n * @returns {CompileResult extends undefined ? Value : CompileResult}\n * Textual representation of the tree (see note).\n *\n * > **Note**: unified typically compiles by serializing: most compilers\n * > return `string` (or `Uint8Array`).\n * > Some compilers, such as the one configured with\n * > [`rehype-react`][rehype-react], return other values (in this case, a\n * > React tree).\n * > If you\u2019re using a compiler that doesn\u2019t serialize, expect different\n * > result values.\n * >\n * > To register custom results in TypeScript, add them to\n * > {@linkcode CompileResultMap}.\n *\n * [rehype-react]: https://github.com/rehypejs/rehype-react\n */\n stringify(tree, file) {\n this.freeze()\n const realFile = vfile(file)\n const compiler = this.compiler || this.Compiler\n assertCompiler('stringify', compiler)\n assertNode(tree)\n\n return compiler(tree, realFile)\n }\n\n /**\n * Configure the processor to use a plugin, a list of usable values, or a\n * preset.\n *\n * If the processor is already using a plugin, the previous plugin\n * configuration is changed based on the options that are passed in.\n * In other words, the plugin is not added a second time.\n *\n * > **Note**: `use` cannot be called on *frozen* processors.\n * > Call the processor first to create a new unfrozen processor.\n *\n * @example\n * There are many ways to pass plugins to `.use()`.\n * This example gives an overview:\n *\n * ```js\n * import {unified} from 'unified'\n *\n * unified()\n * // Plugin with options:\n * .use(pluginA, {x: true, y: true})\n * // Passing the same plugin again merges configuration (to `{x: true, y: false, z: true}`):\n * .use(pluginA, {y: false, z: true})\n * // Plugins:\n * .use([pluginB, pluginC])\n * // Two plugins, the second with options:\n * .use([pluginD, [pluginE, {}]])\n * // Preset with plugins and settings:\n * .use({plugins: [pluginF, [pluginG, {}]], settings: {position: false}})\n * // Settings only:\n * .use({settings: {position: false}})\n * ```\n *\n * @template {Array} [Parameters=[]]\n * @template {Node | string | undefined} [Input=undefined]\n * @template [Output=Input]\n *\n * @overload\n * @param {Preset | null | undefined} [preset]\n * @returns {Processor}\n *\n * @overload\n * @param {PluggableList} list\n * @returns {Processor}\n *\n * @overload\n * @param {Plugin} plugin\n * @param {...(Parameters | [boolean])} parameters\n * @returns {UsePlugin}\n *\n * @param {PluggableList | Plugin | Preset | null | undefined} value\n * Usable value.\n * @param {...unknown} parameters\n * Parameters, when a plugin is given as a usable value.\n * @returns {Processor}\n * Current processor.\n */\n use(value, ...parameters) {\n const attachers = this.attachers\n const namespace = this.namespace\n\n assertUnfrozen('use', this.frozen)\n\n if (value === null || value === undefined) {\n // Empty.\n } else if (typeof value === 'function') {\n addPlugin(value, parameters)\n } else if (typeof value === 'object') {\n if (Array.isArray(value)) {\n addList(value)\n } else {\n addPreset(value)\n }\n } else {\n throw new TypeError('Expected usable value, not `' + value + '`')\n }\n\n return this\n\n /**\n * @param {Pluggable} value\n * @returns {undefined}\n */\n function add(value) {\n if (typeof value === 'function') {\n addPlugin(value, [])\n } else if (typeof value === 'object') {\n if (Array.isArray(value)) {\n const [plugin, ...parameters] =\n /** @type {PluginTuple>} */ (value)\n addPlugin(plugin, parameters)\n } else {\n addPreset(value)\n }\n } else {\n throw new TypeError('Expected usable value, not `' + value + '`')\n }\n }\n\n /**\n * @param {Preset} result\n * @returns {undefined}\n */\n function addPreset(result) {\n if (!('plugins' in result) && !('settings' in result)) {\n throw new Error(\n 'Expected usable value but received an empty preset, which is probably a mistake: presets typically come with `plugins` and sometimes with `settings`, but this has neither'\n )\n }\n\n addList(result.plugins)\n\n if (result.settings) {\n namespace.settings = extend(true, namespace.settings, result.settings)\n }\n }\n\n /**\n * @param {PluggableList | null | undefined} plugins\n * @returns {undefined}\n */\n function addList(plugins) {\n let index = -1\n\n if (plugins === null || plugins === undefined) {\n // Empty.\n } else if (Array.isArray(plugins)) {\n while (++index < plugins.length) {\n const thing = plugins[index]\n add(thing)\n }\n } else {\n throw new TypeError('Expected a list of plugins, not `' + plugins + '`')\n }\n }\n\n /**\n * @param {Plugin} plugin\n * @param {Array} parameters\n * @returns {undefined}\n */\n function addPlugin(plugin, parameters) {\n let index = -1\n let entryIndex = -1\n\n while (++index < attachers.length) {\n if (attachers[index][0] === plugin) {\n entryIndex = index\n break\n }\n }\n\n if (entryIndex === -1) {\n attachers.push([plugin, ...parameters])\n }\n // Only set if there was at least a `primary` value, otherwise we\u2019d change\n // `arguments.length`.\n else if (parameters.length > 0) {\n let [primary, ...rest] = parameters\n const currentPrimary = attachers[entryIndex][1]\n if (isPlainObj(currentPrimary) && isPlainObj(primary)) {\n primary = extend(true, currentPrimary, primary)\n }\n\n attachers[entryIndex] = [plugin, primary, ...rest]\n }\n }\n }\n}\n\n// Note: this returns a *callable* instance.\n// That\u2019s why it\u2019s documented as a function.\n/**\n * Create a new processor.\n *\n * @example\n * This example shows how a new processor can be created (from `remark`) and linked\n * to **stdin**(4) and **stdout**(4).\n *\n * ```js\n * import process from 'node:process'\n * import concatStream from 'concat-stream'\n * import {remark} from 'remark'\n *\n * process.stdin.pipe(\n * concatStream(function (buf) {\n * process.stdout.write(String(remark().processSync(buf)))\n * })\n * )\n * ```\n *\n * @returns\n * New *unfrozen* processor (`processor`).\n *\n * This processor is configured to work the same as its ancestor.\n * When the descendant processor is configured in the future it does not\n * affect the ancestral processor.\n */\nexport const unified = new Processor().freeze()\n\n/**\n * Assert a parser is available.\n *\n * @param {string} name\n * @param {unknown} value\n * @returns {asserts value is Parser}\n */\nfunction assertParser(name, value) {\n if (typeof value !== 'function') {\n throw new TypeError('Cannot `' + name + '` without `parser`')\n }\n}\n\n/**\n * Assert a compiler is available.\n *\n * @param {string} name\n * @param {unknown} value\n * @returns {asserts value is Compiler}\n */\nfunction assertCompiler(name, value) {\n if (typeof value !== 'function') {\n throw new TypeError('Cannot `' + name + '` without `compiler`')\n }\n}\n\n/**\n * Assert the processor is not frozen.\n *\n * @param {string} name\n * @param {unknown} frozen\n * @returns {asserts frozen is false}\n */\nfunction assertUnfrozen(name, frozen) {\n if (frozen) {\n throw new Error(\n 'Cannot call `' +\n name +\n '` on a frozen processor.\\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.'\n )\n }\n}\n\n/**\n * Assert `node` is a unist node.\n *\n * @param {unknown} node\n * @returns {asserts node is Node}\n */\nfunction assertNode(node) {\n // `isPlainObj` unfortunately uses `any` instead of `unknown`.\n // type-coverage:ignore-next-line\n if (!isPlainObj(node) || typeof node.type !== 'string') {\n throw new TypeError('Expected node, got `' + node + '`')\n // Fine.\n }\n}\n\n/**\n * Assert that `complete` is `true`.\n *\n * @param {string} name\n * @param {string} asyncName\n * @param {unknown} complete\n * @returns {asserts complete is true}\n */\nfunction assertDone(name, asyncName, complete) {\n if (!complete) {\n throw new Error(\n '`' + name + '` finished async. Use `' + asyncName + '` instead'\n )\n }\n}\n\n/**\n * @param {Compatible | undefined} [value]\n * @returns {VFile}\n */\nfunction vfile(value) {\n return looksLikeAVFile(value) ? value : new VFile(value)\n}\n\n/**\n * @param {Compatible | undefined} [value]\n * @returns {value is VFile}\n */\nfunction looksLikeAVFile(value) {\n return Boolean(\n value &&\n typeof value === 'object' &&\n 'message' in value &&\n 'messages' in value\n )\n}\n\n/**\n * @param {unknown} [value]\n * @returns {value is Value}\n */\nfunction looksLikeAValue(value) {\n return typeof value === 'string' || isUint8Array(value)\n}\n\n/**\n * Assert `value` is an `Uint8Array`.\n *\n * @param {unknown} value\n * thing.\n * @returns {value is Uint8Array}\n * Whether `value` is an `Uint8Array`.\n */\nfunction isUint8Array(value) {\n return Boolean(\n value &&\n typeof value === 'object' &&\n 'byteLength' in value &&\n 'byteOffset' in value\n )\n}\n", "// Note: types exposed from `index.d.ts`.\nexport {unified} from './lib/index.js'\n", "/**\n * @import {Element, Nodes, Parents, Root} from 'hast'\n * @import {Root as MdastRoot} from 'mdast'\n * @import {ComponentType, JSX, ReactElement, ReactNode} from 'react'\n * @import {Options as RemarkRehypeOptions} from 'remark-rehype'\n * @import {BuildVisitor} from 'unist-util-visit'\n * @import {PluggableList, Processor} from 'unified'\n */\n\n/**\n * @callback AllowElement\n * Filter elements.\n * @param {Readonly} element\n * Element to check.\n * @param {number} index\n * Index of `element` in `parent`.\n * @param {Readonly | undefined} parent\n * Parent of `element`.\n * @returns {boolean | null | undefined}\n * Whether to allow `element` (default: `false`).\n */\n\n/**\n * @typedef ExtraProps\n * Extra fields we pass.\n * @property {Element | undefined} [node]\n * passed when `passNode` is on.\n */\n\n/**\n * @typedef {{\n * [Key in keyof JSX.IntrinsicElements]?: ComponentType | keyof JSX.IntrinsicElements\n * }} Components\n * Map tag names to components.\n */\n\n/**\n * @typedef Deprecation\n * Deprecation.\n * @property {string} from\n * Old field.\n * @property {string} id\n * ID in readme.\n * @property {keyof Options} [to]\n * New field.\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {AllowElement | null | undefined} [allowElement]\n * Filter elements (optional);\n * `allowedElements` / `disallowedElements` is used first.\n * @property {ReadonlyArray | null | undefined} [allowedElements]\n * Tag names to allow (default: all tag names);\n * cannot combine w/ `disallowedElements`.\n * @property {string | null | undefined} [children]\n * Markdown.\n * @property {Components | null | undefined} [components]\n * Map tag names to components.\n * @property {ReadonlyArray | null | undefined} [disallowedElements]\n * Tag names to disallow (default: `[]`);\n * cannot combine w/ `allowedElements`.\n * @property {PluggableList | null | undefined} [rehypePlugins]\n * List of rehype plugins to use.\n * @property {PluggableList | null | undefined} [remarkPlugins]\n * List of remark plugins to use.\n * @property {Readonly | null | undefined} [remarkRehypeOptions]\n * Options to pass through to `remark-rehype`.\n * @property {boolean | null | undefined} [skipHtml=false]\n * Ignore HTML in markdown completely (default: `false`).\n * @property {boolean | null | undefined} [unwrapDisallowed=false]\n * Extract (unwrap) what\u2019s in disallowed elements (default: `false`);\n * normally when say `strong` is not allowed, it and it\u2019s children are dropped,\n * with `unwrapDisallowed` the element itself is replaced by its children.\n * @property {UrlTransform | null | undefined} [urlTransform]\n * Change URLs (default: `defaultUrlTransform`)\n */\n\n/**\n * @typedef HooksOptionsOnly\n * Configuration specifically for {@linkcode MarkdownHooks}.\n * @property {ReactNode | null | undefined} [fallback]\n * Content to render while the processor processing the markdown (optional).\n */\n\n/**\n * @typedef {Options & HooksOptionsOnly} HooksOptions\n * Configuration for {@linkcode MarkdownHooks};\n * extends the regular {@linkcode Options} with a `fallback` prop.\n */\n\n/**\n * @callback UrlTransform\n * Transform all URLs.\n * @param {string} url\n * URL.\n * @param {string} key\n * Property name (example: `'href'`).\n * @param {Readonly} node\n * Node.\n * @returns {string | null | undefined}\n * Transformed URL (optional).\n */\n\nimport {unreachable} from 'devlop'\nimport {toJsxRuntime} from 'hast-util-to-jsx-runtime'\nimport {urlAttributes} from 'html-url-attributes'\nimport {Fragment, jsx, jsxs} from 'react/jsx-runtime'\nimport {useEffect, useState} from 'react'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport {unified} from 'unified'\nimport {visit} from 'unist-util-visit'\nimport {VFile} from 'vfile'\n\nconst changelog =\n 'https://github.com/remarkjs/react-markdown/blob/main/changelog.md'\n\n/** @type {PluggableList} */\nconst emptyPlugins = []\n/** @type {Readonly} */\nconst emptyRemarkRehypeOptions = {allowDangerousHtml: true}\nconst safeProtocol = /^(https?|ircs?|mailto|xmpp)$/i\n\n// Mutable because we `delete` any time it\u2019s used and a message is sent.\n/** @type {ReadonlyArray>} */\nconst deprecations = [\n {from: 'astPlugins', id: 'remove-buggy-html-in-markdown-parser'},\n {from: 'allowDangerousHtml', id: 'remove-buggy-html-in-markdown-parser'},\n {\n from: 'allowNode',\n id: 'replace-allownode-allowedtypes-and-disallowedtypes',\n to: 'allowElement'\n },\n {\n from: 'allowedTypes',\n id: 'replace-allownode-allowedtypes-and-disallowedtypes',\n to: 'allowedElements'\n },\n {from: 'className', id: 'remove-classname'},\n {\n from: 'disallowedTypes',\n id: 'replace-allownode-allowedtypes-and-disallowedtypes',\n to: 'disallowedElements'\n },\n {from: 'escapeHtml', id: 'remove-buggy-html-in-markdown-parser'},\n {from: 'includeElementIndex', id: '#remove-includeelementindex'},\n {\n from: 'includeNodeIndex',\n id: 'change-includenodeindex-to-includeelementindex'\n },\n {from: 'linkTarget', id: 'remove-linktarget'},\n {from: 'plugins', id: 'change-plugins-to-remarkplugins', to: 'remarkPlugins'},\n {from: 'rawSourcePos', id: '#remove-rawsourcepos'},\n {from: 'renderers', id: 'change-renderers-to-components', to: 'components'},\n {from: 'source', id: 'change-source-to-children', to: 'children'},\n {from: 'sourcePos', id: '#remove-sourcepos'},\n {from: 'transformImageUri', id: '#add-urltransform', to: 'urlTransform'},\n {from: 'transformLinkUri', id: '#add-urltransform', to: 'urlTransform'}\n]\n\n/**\n * Component to render markdown.\n *\n * This is a synchronous component.\n * When using async plugins,\n * see {@linkcode MarkdownAsync} or {@linkcode MarkdownHooks}.\n *\n * @param {Readonly} options\n * Props.\n * @returns {ReactElement}\n * React element.\n */\nexport function Markdown(options) {\n const processor = createProcessor(options)\n const file = createFile(options)\n return post(processor.runSync(processor.parse(file), file), options)\n}\n\n/**\n * Component to render markdown with support for async plugins\n * through async/await.\n *\n * Components returning promises are supported on the server.\n * For async support on the client,\n * see {@linkcode MarkdownHooks}.\n *\n * @param {Readonly} options\n * Props.\n * @returns {Promise}\n * Promise to a React element.\n */\nexport async function MarkdownAsync(options) {\n const processor = createProcessor(options)\n const file = createFile(options)\n const tree = await processor.run(processor.parse(file), file)\n return post(tree, options)\n}\n\n/**\n * Component to render markdown with support for async plugins through hooks.\n *\n * This uses `useEffect` and `useState` hooks.\n * Hooks run on the client and do not immediately render something.\n * For async support on the server,\n * see {@linkcode MarkdownAsync}.\n *\n * @param {Readonly} options\n * Props.\n * @returns {ReactNode}\n * React node.\n */\nexport function MarkdownHooks(options) {\n const processor = createProcessor(options)\n const [error, setError] = useState(\n /** @type {Error | undefined} */ (undefined)\n )\n const [tree, setTree] = useState(/** @type {Root | undefined} */ (undefined))\n\n useEffect(\n function () {\n let cancelled = false\n const file = createFile(options)\n\n processor.run(processor.parse(file), file, function (error, tree) {\n if (!cancelled) {\n setError(error)\n setTree(tree)\n }\n })\n\n /**\n * @returns {undefined}\n * Nothing.\n */\n return function () {\n cancelled = true\n }\n },\n [\n options.children,\n options.rehypePlugins,\n options.remarkPlugins,\n options.remarkRehypeOptions\n ]\n )\n\n if (error) throw error\n\n return tree ? post(tree, options) : options.fallback\n}\n\n/**\n * Set up the `unified` processor.\n *\n * @param {Readonly} options\n * Props.\n * @returns {Processor}\n * Result.\n */\nfunction createProcessor(options) {\n const rehypePlugins = options.rehypePlugins || emptyPlugins\n const remarkPlugins = options.remarkPlugins || emptyPlugins\n const remarkRehypeOptions = options.remarkRehypeOptions\n ? {...options.remarkRehypeOptions, ...emptyRemarkRehypeOptions}\n : emptyRemarkRehypeOptions\n\n const processor = unified()\n .use(remarkParse)\n .use(remarkPlugins)\n .use(remarkRehype, remarkRehypeOptions)\n .use(rehypePlugins)\n\n return processor\n}\n\n/**\n * Set up the virtual file.\n *\n * @param {Readonly} options\n * Props.\n * @returns {VFile}\n * Result.\n */\nfunction createFile(options) {\n const children = options.children || ''\n const file = new VFile()\n\n if (typeof children === 'string') {\n file.value = children\n } else {\n unreachable(\n 'Unexpected value `' +\n children +\n '` for `children` prop, expected `string`'\n )\n }\n\n return file\n}\n\n/**\n * Process the result from unified some more.\n *\n * @param {Nodes} tree\n * Tree.\n * @param {Readonly} options\n * Props.\n * @returns {ReactElement}\n * React element.\n */\nfunction post(tree, options) {\n const allowedElements = options.allowedElements\n const allowElement = options.allowElement\n const components = options.components\n const disallowedElements = options.disallowedElements\n const skipHtml = options.skipHtml\n const unwrapDisallowed = options.unwrapDisallowed\n const urlTransform = options.urlTransform || defaultUrlTransform\n\n for (const deprecation of deprecations) {\n if (Object.hasOwn(options, deprecation.from)) {\n unreachable(\n 'Unexpected `' +\n deprecation.from +\n '` prop, ' +\n (deprecation.to\n ? 'use `' + deprecation.to + '` instead'\n : 'remove it') +\n ' (see <' +\n changelog +\n '#' +\n deprecation.id +\n '> for more info)'\n )\n }\n }\n\n if (allowedElements && disallowedElements) {\n unreachable(\n 'Unexpected combined `allowedElements` and `disallowedElements`, expected one or the other'\n )\n }\n\n visit(tree, transform)\n\n return toJsxRuntime(tree, {\n Fragment,\n components,\n ignoreInvalidStyle: true,\n jsx,\n jsxs,\n passKeys: true,\n passNode: true\n })\n\n /** @type {BuildVisitor} */\n function transform(node, index, parent) {\n if (node.type === 'raw' && parent && typeof index === 'number') {\n if (skipHtml) {\n parent.children.splice(index, 1)\n } else {\n parent.children[index] = {type: 'text', value: node.value}\n }\n\n return index\n }\n\n if (node.type === 'element') {\n /** @type {string} */\n let key\n\n for (key in urlAttributes) {\n if (\n Object.hasOwn(urlAttributes, key) &&\n Object.hasOwn(node.properties, key)\n ) {\n const value = node.properties[key]\n const test = urlAttributes[key]\n if (test === null || test.includes(node.tagName)) {\n node.properties[key] = urlTransform(String(value || ''), key, node)\n }\n }\n }\n }\n\n if (node.type === 'element') {\n let remove = allowedElements\n ? !allowedElements.includes(node.tagName)\n : disallowedElements\n ? disallowedElements.includes(node.tagName)\n : false\n\n if (!remove && allowElement && typeof index === 'number') {\n remove = !allowElement(node, index, parent)\n }\n\n if (remove && parent && typeof index === 'number') {\n if (unwrapDisallowed && node.children) {\n parent.children.splice(index, 1, ...node.children)\n } else {\n parent.children.splice(index, 1)\n }\n\n return index\n }\n }\n }\n}\n\n/**\n * Make a URL safe.\n *\n * @satisfies {UrlTransform}\n * @param {string} value\n * URL.\n * @returns {string}\n * Safe URL.\n */\nexport function defaultUrlTransform(value) {\n // Same as:\n // \n // But without the `encode` part.\n const colon = value.indexOf(':')\n const questionMark = value.indexOf('?')\n const numberSign = value.indexOf('#')\n const slash = value.indexOf('/')\n\n if (\n // If there is no protocol, it\u2019s relative.\n colon === -1 ||\n // If the first colon is after a `?`, `#`, or `/`, it\u2019s not a protocol.\n (slash !== -1 && colon > slash) ||\n (questionMark !== -1 && colon > questionMark) ||\n (numberSign !== -1 && colon > numberSign) ||\n // It is a protocol, it should be allowed.\n safeProtocol.test(value.slice(0, colon))\n ) {\n return value\n }\n\n return ''\n}\n", "/**\n * @typedef {import('./lib/index.js').AllowElement} AllowElement\n * @typedef {import('./lib/index.js').Components} Components\n * @typedef {import('./lib/index.js').ExtraProps} ExtraProps\n * @typedef {import('./lib/index.js').HooksOptions} HooksOptions\n * @typedef {import('./lib/index.js').Options} Options\n * @typedef {import('./lib/index.js').UrlTransform} UrlTransform\n */\n\nexport {\n MarkdownAsync,\n MarkdownHooks,\n Markdown as default,\n defaultUrlTransform\n} from './lib/index.js'\n", "/**\n * Count how often a character (or substring) is used in a string.\n *\n * @param {string} value\n * Value to search in.\n * @param {string} character\n * Character (or substring) to look for.\n * @return {number}\n * Number of times `character` occurred in `value`.\n */\nexport function ccount(value, character) {\n const source = String(value)\n\n if (typeof character !== 'string') {\n throw new TypeError('Expected character')\n }\n\n let count = 0\n let index = source.indexOf(character)\n\n while (index !== -1) {\n count++\n index = source.indexOf(character, index + character.length)\n }\n\n return count\n}\n", "export default function escapeStringRegexp(string) {\n\tif (typeof string !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\t// Escape characters with special meaning either inside or outside character sets.\n\t// Use a simple backslash escape when it\u2019s always valid, and a `\\xnn` escape when the simpler form would be disallowed by Unicode patterns\u2019 stricter grammar.\n\treturn string\n\t\t.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&')\n\t\t.replace(/-/g, '\\\\x2d');\n}\n", "/**\n * @import {Nodes, Parents, PhrasingContent, Root, Text} from 'mdast'\n * @import {BuildVisitor, Test, VisitorResult} from 'unist-util-visit-parents'\n */\n\n/**\n * @typedef RegExpMatchObject\n * Info on the match.\n * @property {number} index\n * The index of the search at which the result was found.\n * @property {string} input\n * A copy of the search string in the text node.\n * @property {[...Array, Text]} stack\n * All ancestors of the text node, where the last node is the text itself.\n *\n * @typedef {RegExp | string} Find\n * Pattern to find.\n *\n * Strings are escaped and then turned into global expressions.\n *\n * @typedef {Array} FindAndReplaceList\n * Several find and replaces, in array form.\n *\n * @typedef {[Find, Replace?]} FindAndReplaceTuple\n * Find and replace in tuple form.\n *\n * @typedef {ReplaceFunction | string | null | undefined} Replace\n * Thing to replace with.\n *\n * @callback ReplaceFunction\n * Callback called when a search matches.\n * @param {...any} parameters\n * The parameters are the result of corresponding search expression:\n *\n * * `value` (`string`) \u2014 whole match\n * * `...capture` (`Array`) \u2014 matches from regex capture groups\n * * `match` (`RegExpMatchObject`) \u2014 info on the match\n * @returns {Array | PhrasingContent | string | false | null | undefined}\n * Thing to replace with.\n *\n * * when `null`, `undefined`, `''`, remove the match\n * * \u2026or when `false`, do not replace at all\n * * \u2026or when `string`, replace with a text node of that value\n * * \u2026or when `Node` or `Array`, replace with those nodes\n *\n * @typedef {[RegExp, ReplaceFunction]} Pair\n * Normalized find and replace.\n *\n * @typedef {Array} Pairs\n * All find and replaced.\n *\n * @typedef Options\n * Configuration.\n * @property {Test | null | undefined} [ignore]\n * Test for which nodes to ignore (optional).\n */\n\nimport escape from 'escape-string-regexp'\nimport {visitParents} from 'unist-util-visit-parents'\nimport {convert} from 'unist-util-is'\n\n/**\n * Find patterns in a tree and replace them.\n *\n * The algorithm searches the tree in *preorder* for complete values in `Text`\n * nodes.\n * Partial matches are not supported.\n *\n * @param {Nodes} tree\n * Tree to change.\n * @param {FindAndReplaceList | FindAndReplaceTuple} list\n * Patterns to find.\n * @param {Options | null | undefined} [options]\n * Configuration (when `find` is not `Find`).\n * @returns {undefined}\n * Nothing.\n */\nexport function findAndReplace(tree, list, options) {\n const settings = options || {}\n const ignored = convert(settings.ignore || [])\n const pairs = toPairs(list)\n let pairIndex = -1\n\n while (++pairIndex < pairs.length) {\n visitParents(tree, 'text', visitor)\n }\n\n /** @type {BuildVisitor} */\n function visitor(node, parents) {\n let index = -1\n /** @type {Parents | undefined} */\n let grandparent\n\n while (++index < parents.length) {\n const parent = parents[index]\n /** @type {Array | undefined} */\n const siblings = grandparent ? grandparent.children : undefined\n\n if (\n ignored(\n parent,\n siblings ? siblings.indexOf(parent) : undefined,\n grandparent\n )\n ) {\n return\n }\n\n grandparent = parent\n }\n\n if (grandparent) {\n return handler(node, parents)\n }\n }\n\n /**\n * Handle a text node which is not in an ignored parent.\n *\n * @param {Text} node\n * Text node.\n * @param {Array} parents\n * Parents.\n * @returns {VisitorResult}\n * Result.\n */\n function handler(node, parents) {\n const parent = parents[parents.length - 1]\n const find = pairs[pairIndex][0]\n const replace = pairs[pairIndex][1]\n let start = 0\n /** @type {Array} */\n const siblings = parent.children\n const index = siblings.indexOf(node)\n let change = false\n /** @type {Array} */\n let nodes = []\n\n find.lastIndex = 0\n\n let match = find.exec(node.value)\n\n while (match) {\n const position = match.index\n /** @type {RegExpMatchObject} */\n const matchObject = {\n index: match.index,\n input: match.input,\n stack: [...parents, node]\n }\n let value = replace(...match, matchObject)\n\n if (typeof value === 'string') {\n value = value.length > 0 ? {type: 'text', value} : undefined\n }\n\n // It wasn\u2019t a match after all.\n if (value === false) {\n // False acts as if there was no match.\n // So we need to reset `lastIndex`, which currently being at the end of\n // the current match, to the beginning.\n find.lastIndex = position + 1\n } else {\n if (start !== position) {\n nodes.push({\n type: 'text',\n value: node.value.slice(start, position)\n })\n }\n\n if (Array.isArray(value)) {\n nodes.push(...value)\n } else if (value) {\n nodes.push(value)\n }\n\n start = position + match[0].length\n change = true\n }\n\n if (!find.global) {\n break\n }\n\n match = find.exec(node.value)\n }\n\n if (change) {\n if (start < node.value.length) {\n nodes.push({type: 'text', value: node.value.slice(start)})\n }\n\n parent.children.splice(index, 1, ...nodes)\n } else {\n nodes = [node]\n }\n\n return index + nodes.length\n }\n}\n\n/**\n * Turn a tuple or a list of tuples into pairs.\n *\n * @param {FindAndReplaceList | FindAndReplaceTuple} tupleOrList\n * Schema.\n * @returns {Pairs}\n * Clean pairs.\n */\nfunction toPairs(tupleOrList) {\n /** @type {Pairs} */\n const result = []\n\n if (!Array.isArray(tupleOrList)) {\n throw new TypeError('Expected find and replace tuple or list of tuples')\n }\n\n /** @type {FindAndReplaceList} */\n // @ts-expect-error: correct.\n const list =\n !tupleOrList[0] || Array.isArray(tupleOrList[0])\n ? tupleOrList\n : [tupleOrList]\n\n let index = -1\n\n while (++index < list.length) {\n const tuple = list[index]\n result.push([toExpression(tuple[0]), toFunction(tuple[1])])\n }\n\n return result\n}\n\n/**\n * Turn a find into an expression.\n *\n * @param {Find} find\n * Find.\n * @returns {RegExp}\n * Expression.\n */\nfunction toExpression(find) {\n return typeof find === 'string' ? new RegExp(escape(find), 'g') : find\n}\n\n/**\n * Turn a replace into a function.\n *\n * @param {Replace} replace\n * Replace.\n * @returns {ReplaceFunction}\n * Function.\n */\nfunction toFunction(replace) {\n return typeof replace === 'function'\n ? replace\n : function () {\n return replace\n }\n}\n", "/**\n * @typedef {import('./lib/index.js').FindAndReplaceList} FindAndReplaceList\n * @typedef {import('./lib/index.js').FindAndReplaceTuple} FindAndReplaceTuple\n * @typedef {import('./lib/index.js').Find} Find\n * @typedef {import('./lib/index.js').Options} Options\n * @typedef {import('./lib/index.js').RegExpMatchObject} RegExpMatchObject\n * @typedef {import('./lib/index.js').ReplaceFunction} ReplaceFunction\n * @typedef {import('./lib/index.js').Replace} Replace\n */\n\nexport {findAndReplace} from './lib/index.js'\n", "/**\n * @import {RegExpMatchObject, ReplaceFunction} from 'mdast-util-find-and-replace'\n * @import {CompileContext, Extension as FromMarkdownExtension, Handle as FromMarkdownHandle, Transform as FromMarkdownTransform} from 'mdast-util-from-markdown'\n * @import {ConstructName, Options as ToMarkdownExtension} from 'mdast-util-to-markdown'\n * @import {Link, PhrasingContent} from 'mdast'\n */\n\nimport {ccount} from 'ccount'\nimport {ok as assert} from 'devlop'\nimport {unicodePunctuation, unicodeWhitespace} from 'micromark-util-character'\nimport {findAndReplace} from 'mdast-util-find-and-replace'\n\n/** @type {ConstructName} */\nconst inConstruct = 'phrasing'\n/** @type {Array} */\nconst notInConstruct = ['autolink', 'link', 'image', 'label']\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM autolink\n * literals in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM autolink literals.\n */\nexport function gfmAutolinkLiteralFromMarkdown() {\n return {\n transforms: [transformGfmAutolinkLiterals],\n enter: {\n literalAutolink: enterLiteralAutolink,\n literalAutolinkEmail: enterLiteralAutolinkValue,\n literalAutolinkHttp: enterLiteralAutolinkValue,\n literalAutolinkWww: enterLiteralAutolinkValue\n },\n exit: {\n literalAutolink: exitLiteralAutolink,\n literalAutolinkEmail: exitLiteralAutolinkEmail,\n literalAutolinkHttp: exitLiteralAutolinkHttp,\n literalAutolinkWww: exitLiteralAutolinkWww\n }\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM autolink\n * literals in markdown.\n *\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM autolink literals.\n */\nexport function gfmAutolinkLiteralToMarkdown() {\n return {\n unsafe: [\n {\n character: '@',\n before: '[+\\\\-.\\\\w]',\n after: '[\\\\-.\\\\w]',\n inConstruct,\n notInConstruct\n },\n {\n character: '.',\n before: '[Ww]',\n after: '[\\\\-.\\\\w]',\n inConstruct,\n notInConstruct\n },\n {\n character: ':',\n before: '[ps]',\n after: '\\\\/',\n inConstruct,\n notInConstruct\n }\n ]\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterLiteralAutolink(token) {\n this.enter({type: 'link', title: null, url: '', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterLiteralAutolinkValue(token) {\n this.config.enter.autolinkProtocol.call(this, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitLiteralAutolinkHttp(token) {\n this.config.exit.autolinkProtocol.call(this, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitLiteralAutolinkWww(token) {\n this.config.exit.data.call(this, token)\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'link')\n node.url = 'http://' + this.sliceSerialize(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitLiteralAutolinkEmail(token) {\n this.config.exit.autolinkEmail.call(this, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitLiteralAutolink(token) {\n this.exit(token)\n}\n\n/** @type {FromMarkdownTransform} */\nfunction transformGfmAutolinkLiterals(tree) {\n findAndReplace(\n tree,\n [\n [/(https?:\\/\\/|www(?=\\.))([-.\\w]+)([^ \\t\\r\\n]*)/gi, findUrl],\n [/(?<=^|\\s|\\p{P}|\\p{S})([-.\\w+]+)@([-\\w]+(?:\\.[-\\w]+)+)/gu, findEmail]\n ],\n {ignore: ['link', 'linkReference']}\n )\n}\n\n/**\n * @type {ReplaceFunction}\n * @param {string} _\n * @param {string} protocol\n * @param {string} domain\n * @param {string} path\n * @param {RegExpMatchObject} match\n * @returns {Array | Link | false}\n */\n// eslint-disable-next-line max-params\nfunction findUrl(_, protocol, domain, path, match) {\n let prefix = ''\n\n // Not an expected previous character.\n if (!previous(match)) {\n return false\n }\n\n // Treat `www` as part of the domain.\n if (/^w/i.test(protocol)) {\n domain = protocol + domain\n protocol = ''\n prefix = 'http://'\n }\n\n if (!isCorrectDomain(domain)) {\n return false\n }\n\n const parts = splitUrl(domain + path)\n\n if (!parts[0]) return false\n\n /** @type {Link} */\n const result = {\n type: 'link',\n title: null,\n url: prefix + protocol + parts[0],\n children: [{type: 'text', value: protocol + parts[0]}]\n }\n\n if (parts[1]) {\n return [result, {type: 'text', value: parts[1]}]\n }\n\n return result\n}\n\n/**\n * @type {ReplaceFunction}\n * @param {string} _\n * @param {string} atext\n * @param {string} label\n * @param {RegExpMatchObject} match\n * @returns {Link | false}\n */\nfunction findEmail(_, atext, label, match) {\n if (\n // Not an expected previous character.\n !previous(match, true) ||\n // Label ends in not allowed character.\n /[-\\d_]$/.test(label)\n ) {\n return false\n }\n\n return {\n type: 'link',\n title: null,\n url: 'mailto:' + atext + '@' + label,\n children: [{type: 'text', value: atext + '@' + label}]\n }\n}\n\n/**\n * @param {string} domain\n * @returns {boolean}\n */\nfunction isCorrectDomain(domain) {\n const parts = domain.split('.')\n\n if (\n parts.length < 2 ||\n (parts[parts.length - 1] &&\n (/_/.test(parts[parts.length - 1]) ||\n !/[a-zA-Z\\d]/.test(parts[parts.length - 1]))) ||\n (parts[parts.length - 2] &&\n (/_/.test(parts[parts.length - 2]) ||\n !/[a-zA-Z\\d]/.test(parts[parts.length - 2])))\n ) {\n return false\n }\n\n return true\n}\n\n/**\n * @param {string} url\n * @returns {[string, string | undefined]}\n */\nfunction splitUrl(url) {\n const trailExec = /[!\"&'),.:;<>?\\]}]+$/.exec(url)\n\n if (!trailExec) {\n return [url, undefined]\n }\n\n url = url.slice(0, trailExec.index)\n\n let trail = trailExec[0]\n let closingParenIndex = trail.indexOf(')')\n const openingParens = ccount(url, '(')\n let closingParens = ccount(url, ')')\n\n while (closingParenIndex !== -1 && openingParens > closingParens) {\n url += trail.slice(0, closingParenIndex + 1)\n trail = trail.slice(closingParenIndex + 1)\n closingParenIndex = trail.indexOf(')')\n closingParens++\n }\n\n return [url, trail]\n}\n\n/**\n * @param {RegExpMatchObject} match\n * @param {boolean | null | undefined} [email=false]\n * @returns {boolean}\n */\nfunction previous(match, email) {\n const code = match.input.charCodeAt(match.index - 1)\n\n return (\n (match.index === 0 ||\n unicodeWhitespace(code) ||\n unicodePunctuation(code)) &&\n // If it\u2019s an email, the previous character should not be a slash.\n (!email || code !== 47)\n )\n}\n", "export {\n gfmAutolinkLiteralFromMarkdown,\n gfmAutolinkLiteralToMarkdown\n} from './lib/index.js'\n", "/**\n * @import {\n * CompileContext,\n * Extension as FromMarkdownExtension,\n * Handle as FromMarkdownHandle\n * } from 'mdast-util-from-markdown'\n * @import {ToMarkdownOptions} from 'mdast-util-gfm-footnote'\n * @import {\n * Handle as ToMarkdownHandle,\n * Map,\n * Options as ToMarkdownExtension\n * } from 'mdast-util-to-markdown'\n * @import {FootnoteDefinition, FootnoteReference} from 'mdast'\n */\n\nimport {ok as assert} from 'devlop'\nimport {normalizeIdentifier} from 'micromark-util-normalize-identifier'\n\nfootnoteReference.peek = footnoteReferencePeek\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteCallString() {\n this.buffer()\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteCall(token) {\n this.enter({type: 'footnoteReference', identifier: '', label: ''}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteDefinitionLabelString() {\n this.buffer()\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteDefinition(token) {\n this.enter(\n {type: 'footnoteDefinition', identifier: '', label: '', children: []},\n token\n )\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteCallString(token) {\n const label = this.resume()\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'footnoteReference')\n node.identifier = normalizeIdentifier(\n this.sliceSerialize(token)\n ).toLowerCase()\n node.label = label\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteCall(token) {\n this.exit(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteDefinitionLabelString(token) {\n const label = this.resume()\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'footnoteDefinition')\n node.identifier = normalizeIdentifier(\n this.sliceSerialize(token)\n ).toLowerCase()\n node.label = label\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteDefinition(token) {\n this.exit(token)\n}\n\n/** @type {ToMarkdownHandle} */\nfunction footnoteReferencePeek() {\n return '['\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {FootnoteReference} node\n */\nfunction footnoteReference(node, _, state, info) {\n const tracker = state.createTracker(info)\n let value = tracker.move('[^')\n const exit = state.enter('footnoteReference')\n const subexit = state.enter('reference')\n value += tracker.move(\n state.safe(state.associationId(node), {after: ']', before: value})\n )\n subexit()\n exit()\n value += tracker.move(']')\n return value\n}\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM footnotes\n * in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown`.\n */\nexport function gfmFootnoteFromMarkdown() {\n return {\n enter: {\n gfmFootnoteCallString: enterFootnoteCallString,\n gfmFootnoteCall: enterFootnoteCall,\n gfmFootnoteDefinitionLabelString: enterFootnoteDefinitionLabelString,\n gfmFootnoteDefinition: enterFootnoteDefinition\n },\n exit: {\n gfmFootnoteCallString: exitFootnoteCallString,\n gfmFootnoteCall: exitFootnoteCall,\n gfmFootnoteDefinitionLabelString: exitFootnoteDefinitionLabelString,\n gfmFootnoteDefinition: exitFootnoteDefinition\n }\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM footnotes\n * in markdown.\n *\n * @param {ToMarkdownOptions | null | undefined} [options]\n * Configuration (optional).\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown`.\n */\nexport function gfmFootnoteToMarkdown(options) {\n // To do: next major: change default.\n let firstLineBlank = false\n\n if (options && options.firstLineBlank) {\n firstLineBlank = true\n }\n\n return {\n handlers: {footnoteDefinition, footnoteReference},\n // This is on by default already.\n unsafe: [{character: '[', inConstruct: ['label', 'phrasing', 'reference']}]\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {FootnoteDefinition} node\n */\n function footnoteDefinition(node, _, state, info) {\n const tracker = state.createTracker(info)\n let value = tracker.move('[^')\n const exit = state.enter('footnoteDefinition')\n const subexit = state.enter('label')\n value += tracker.move(\n state.safe(state.associationId(node), {before: value, after: ']'})\n )\n subexit()\n\n value += tracker.move(']:')\n\n if (node.children && node.children.length > 0) {\n tracker.shift(4)\n\n value += tracker.move(\n (firstLineBlank ? '\\n' : ' ') +\n state.indentLines(\n state.containerFlow(node, tracker.current()),\n firstLineBlank ? mapAll : mapExceptFirst\n )\n )\n }\n\n exit()\n\n return value\n }\n}\n\n/** @type {Map} */\nfunction mapExceptFirst(line, index, blank) {\n return index === 0 ? line : mapAll(line, index, blank)\n}\n\n/** @type {Map} */\nfunction mapAll(line, index, blank) {\n return (blank ? '' : ' ') + line\n}\n", "// Note: extra types exported from `index.d.ts`.\nexport {gfmFootnoteFromMarkdown, gfmFootnoteToMarkdown} from './lib/index.js'\n", "/**\n * @typedef {import('mdast').Delete} Delete\n *\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n *\n * @typedef {import('mdast-util-to-markdown').ConstructName} ConstructName\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n */\n\n/**\n * List of constructs that occur in phrasing (paragraphs, headings), but cannot\n * contain strikethrough.\n * So they sort of cancel each other out.\n * Note: could use a better name.\n *\n * Note: keep in sync with: \n *\n * @type {Array}\n */\nconst constructsWithoutStrikethrough = [\n 'autolink',\n 'destinationLiteral',\n 'destinationRaw',\n 'reference',\n 'titleQuote',\n 'titleApostrophe'\n]\n\nhandleDelete.peek = peekDelete\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM\n * strikethrough in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM strikethrough.\n */\nexport function gfmStrikethroughFromMarkdown() {\n return {\n canContainEols: ['delete'],\n enter: {strikethrough: enterStrikethrough},\n exit: {strikethrough: exitStrikethrough}\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM\n * strikethrough in markdown.\n *\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM strikethrough.\n */\nexport function gfmStrikethroughToMarkdown() {\n return {\n unsafe: [\n {\n character: '~',\n inConstruct: 'phrasing',\n notInConstruct: constructsWithoutStrikethrough\n }\n ],\n handlers: {delete: handleDelete}\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterStrikethrough(token) {\n this.enter({type: 'delete', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitStrikethrough(token) {\n this.exit(token)\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {Delete} node\n */\nfunction handleDelete(node, _, state, info) {\n const tracker = state.createTracker(info)\n const exit = state.enter('strikethrough')\n let value = tracker.move('~~')\n value += state.containerPhrasing(node, {\n ...tracker.current(),\n before: value,\n after: '~'\n })\n value += tracker.move('~~')\n exit()\n return value\n}\n\n/** @type {ToMarkdownHandle} */\nfunction peekDelete() {\n return '~'\n}\n", "// Note: extra types in `index.d.ts`.\nexport {\n gfmStrikethroughFromMarkdown,\n gfmStrikethroughToMarkdown\n} from './lib/index.js'\n", "// To do: next major: remove.\n/**\n * @typedef {Options} MarkdownTableOptions\n * Configuration.\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {boolean | null | undefined} [alignDelimiters=true]\n * Whether to align the delimiters (default: `true`);\n * they are aligned by default:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * Pass `false` to make them staggered:\n *\n * ```markdown\n * | Alpha | B |\n * | - | - |\n * | C | Delta |\n * ```\n * @property {ReadonlyArray | string | null | undefined} [align]\n * How to align columns (default: `''`);\n * one style for all columns or styles for their respective columns;\n * each style is either `'l'` (left), `'r'` (right), or `'c'` (center);\n * other values are treated as `''`, which doesn\u2019t place the colon in the\n * alignment row but does align left;\n * *only the lowercased first character is used, so `Right` is fine.*\n * @property {boolean | null | undefined} [delimiterEnd=true]\n * Whether to end each row with the delimiter (default: `true`).\n *\n * > \uD83D\uDC49 **Note**: please don\u2019t use this: it could create fragile structures\n * > that aren\u2019t understandable to some markdown parsers.\n *\n * When `true`, there are ending delimiters:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there are no ending delimiters:\n *\n * ```markdown\n * | Alpha | B\n * | ----- | -----\n * | C | Delta\n * ```\n * @property {boolean | null | undefined} [delimiterStart=true]\n * Whether to begin each row with the delimiter (default: `true`).\n *\n * > \uD83D\uDC49 **Note**: please don\u2019t use this: it could create fragile structures\n * > that aren\u2019t understandable to some markdown parsers.\n *\n * When `true`, there are starting delimiters:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there are no starting delimiters:\n *\n * ```markdown\n * Alpha | B |\n * ----- | ----- |\n * C | Delta |\n * ```\n * @property {boolean | null | undefined} [padding=true]\n * Whether to add a space of padding between delimiters and cells\n * (default: `true`).\n *\n * When `true`, there is padding:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there is no padding:\n *\n * ```markdown\n * |Alpha|B |\n * |-----|-----|\n * |C |Delta|\n * ```\n * @property {((value: string) => number) | null | undefined} [stringLength]\n * Function to detect the length of table cell content (optional);\n * this is used when aligning the delimiters (`|`) between table cells;\n * full-width characters and emoji mess up delimiter alignment when viewing\n * the markdown source;\n * to fix this, you can pass this function,\n * which receives the cell content and returns its \u201Cvisible\u201D size;\n * note that what is and isn\u2019t visible depends on where the text is displayed.\n *\n * Without such a function, the following:\n *\n * ```js\n * markdownTable([\n * ['Alpha', 'Bravo'],\n * ['\u4E2D\u6587', 'Charlie'],\n * ['\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69', 'Delta']\n * ])\n * ```\n *\n * Yields:\n *\n * ```markdown\n * | Alpha | Bravo |\n * | - | - |\n * | \u4E2D\u6587 | Charlie |\n * | \uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69 | Delta |\n * ```\n *\n * With [`string-width`](https://github.com/sindresorhus/string-width):\n *\n * ```js\n * import stringWidth from 'string-width'\n *\n * markdownTable(\n * [\n * ['Alpha', 'Bravo'],\n * ['\u4E2D\u6587', 'Charlie'],\n * ['\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69', 'Delta']\n * ],\n * {stringLength: stringWidth}\n * )\n * ```\n *\n * Yields:\n *\n * ```markdown\n * | Alpha | Bravo |\n * | ----- | ------- |\n * | \u4E2D\u6587 | Charlie |\n * | \uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69 | Delta |\n * ```\n */\n\n/**\n * @param {string} value\n * Cell value.\n * @returns {number}\n * Cell size.\n */\nfunction defaultStringLength(value) {\n return value.length\n}\n\n/**\n * Generate a markdown\n * ([GFM](https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/organizing-information-with-tables))\n * table.\n *\n * @param {ReadonlyArray>} table\n * Table data (matrix of strings).\n * @param {Readonly | null | undefined} [options]\n * Configuration (optional).\n * @returns {string}\n * Result.\n */\nexport function markdownTable(table, options) {\n const settings = options || {}\n // To do: next major: change to spread.\n const align = (settings.align || []).concat()\n const stringLength = settings.stringLength || defaultStringLength\n /** @type {Array} Character codes as symbols for alignment per column. */\n const alignments = []\n /** @type {Array>} Cells per row. */\n const cellMatrix = []\n /** @type {Array>} Sizes of each cell per row. */\n const sizeMatrix = []\n /** @type {Array} */\n const longestCellByColumn = []\n let mostCellsPerRow = 0\n let rowIndex = -1\n\n // This is a superfluous loop if we don\u2019t align delimiters, but otherwise we\u2019d\n // do superfluous work when aligning, so optimize for aligning.\n while (++rowIndex < table.length) {\n /** @type {Array} */\n const row = []\n /** @type {Array} */\n const sizes = []\n let columnIndex = -1\n\n if (table[rowIndex].length > mostCellsPerRow) {\n mostCellsPerRow = table[rowIndex].length\n }\n\n while (++columnIndex < table[rowIndex].length) {\n const cell = serialize(table[rowIndex][columnIndex])\n\n if (settings.alignDelimiters !== false) {\n const size = stringLength(cell)\n sizes[columnIndex] = size\n\n if (\n longestCellByColumn[columnIndex] === undefined ||\n size > longestCellByColumn[columnIndex]\n ) {\n longestCellByColumn[columnIndex] = size\n }\n }\n\n row.push(cell)\n }\n\n cellMatrix[rowIndex] = row\n sizeMatrix[rowIndex] = sizes\n }\n\n // Figure out which alignments to use.\n let columnIndex = -1\n\n if (typeof align === 'object' && 'length' in align) {\n while (++columnIndex < mostCellsPerRow) {\n alignments[columnIndex] = toAlignment(align[columnIndex])\n }\n } else {\n const code = toAlignment(align)\n\n while (++columnIndex < mostCellsPerRow) {\n alignments[columnIndex] = code\n }\n }\n\n // Inject the alignment row.\n columnIndex = -1\n /** @type {Array} */\n const row = []\n /** @type {Array} */\n const sizes = []\n\n while (++columnIndex < mostCellsPerRow) {\n const code = alignments[columnIndex]\n let before = ''\n let after = ''\n\n if (code === 99 /* `c` */) {\n before = ':'\n after = ':'\n } else if (code === 108 /* `l` */) {\n before = ':'\n } else if (code === 114 /* `r` */) {\n after = ':'\n }\n\n // There *must* be at least one hyphen-minus in each alignment cell.\n let size =\n settings.alignDelimiters === false\n ? 1\n : Math.max(\n 1,\n longestCellByColumn[columnIndex] - before.length - after.length\n )\n\n const cell = before + '-'.repeat(size) + after\n\n if (settings.alignDelimiters !== false) {\n size = before.length + size + after.length\n\n if (size > longestCellByColumn[columnIndex]) {\n longestCellByColumn[columnIndex] = size\n }\n\n sizes[columnIndex] = size\n }\n\n row[columnIndex] = cell\n }\n\n // Inject the alignment row.\n cellMatrix.splice(1, 0, row)\n sizeMatrix.splice(1, 0, sizes)\n\n rowIndex = -1\n /** @type {Array} */\n const lines = []\n\n while (++rowIndex < cellMatrix.length) {\n const row = cellMatrix[rowIndex]\n const sizes = sizeMatrix[rowIndex]\n columnIndex = -1\n /** @type {Array} */\n const line = []\n\n while (++columnIndex < mostCellsPerRow) {\n const cell = row[columnIndex] || ''\n let before = ''\n let after = ''\n\n if (settings.alignDelimiters !== false) {\n const size =\n longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0)\n const code = alignments[columnIndex]\n\n if (code === 114 /* `r` */) {\n before = ' '.repeat(size)\n } else if (code === 99 /* `c` */) {\n if (size % 2) {\n before = ' '.repeat(size / 2 + 0.5)\n after = ' '.repeat(size / 2 - 0.5)\n } else {\n before = ' '.repeat(size / 2)\n after = before\n }\n } else {\n after = ' '.repeat(size)\n }\n }\n\n if (settings.delimiterStart !== false && !columnIndex) {\n line.push('|')\n }\n\n if (\n settings.padding !== false &&\n // Don\u2019t add the opening space if we\u2019re not aligning and the cell is\n // empty: there will be a closing space.\n !(settings.alignDelimiters === false && cell === '') &&\n (settings.delimiterStart !== false || columnIndex)\n ) {\n line.push(' ')\n }\n\n if (settings.alignDelimiters !== false) {\n line.push(before)\n }\n\n line.push(cell)\n\n if (settings.alignDelimiters !== false) {\n line.push(after)\n }\n\n if (settings.padding !== false) {\n line.push(' ')\n }\n\n if (\n settings.delimiterEnd !== false ||\n columnIndex !== mostCellsPerRow - 1\n ) {\n line.push('|')\n }\n }\n\n lines.push(\n settings.delimiterEnd === false\n ? line.join('').replace(/ +$/, '')\n : line.join('')\n )\n }\n\n return lines.join('\\n')\n}\n\n/**\n * @param {string | null | undefined} [value]\n * Value to serialize.\n * @returns {string}\n * Result.\n */\nfunction serialize(value) {\n return value === null || value === undefined ? '' : String(value)\n}\n\n/**\n * @param {string | null | undefined} value\n * Value.\n * @returns {number}\n * Alignment.\n */\nfunction toAlignment(value) {\n const code = typeof value === 'string' ? value.codePointAt(0) : 0\n\n return code === 67 /* `C` */ || code === 99 /* `c` */\n ? 99 /* `c` */\n : code === 76 /* `L` */ || code === 108 /* `l` */\n ? 108 /* `l` */\n : code === 82 /* `R` */ || code === 114 /* `r` */\n ? 114 /* `r` */\n : 0\n}\n", "/**\n * @import {Blockquote, Parents} from 'mdast'\n * @import {Info, Map, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {Blockquote} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function blockquote(node, _, state, info) {\n const exit = state.enter('blockquote')\n const tracker = state.createTracker(info)\n tracker.move('> ')\n tracker.shift(2)\n const value = state.indentLines(\n state.containerFlow(node, tracker.current()),\n map\n )\n exit()\n return value\n}\n\n/** @type {Map} */\nfunction map(line, _, blank) {\n return '>' + (blank ? '' : ' ') + line\n}\n", "/**\n * @import {ConstructName, Unsafe} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {Array} stack\n * @param {Unsafe} pattern\n * @returns {boolean}\n */\nexport function patternInScope(stack, pattern) {\n return (\n listInScope(stack, pattern.inConstruct, true) &&\n !listInScope(stack, pattern.notInConstruct, false)\n )\n}\n\n/**\n * @param {Array} stack\n * @param {Unsafe['inConstruct']} list\n * @param {boolean} none\n * @returns {boolean}\n */\nfunction listInScope(stack, list, none) {\n if (typeof list === 'string') {\n list = [list]\n }\n\n if (!list || list.length === 0) {\n return none\n }\n\n let index = -1\n\n while (++index < list.length) {\n if (stack.includes(list[index])) {\n return true\n }\n }\n\n return false\n}\n", "/**\n * @import {Break, Parents} from 'mdast'\n * @import {Info, State} from 'mdast-util-to-markdown'\n */\n\nimport {patternInScope} from '../util/pattern-in-scope.js'\n\n/**\n * @param {Break} _\n * @param {Parents | undefined} _1\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function hardBreak(_, _1, state, info) {\n let index = -1\n\n while (++index < state.unsafe.length) {\n // If we can\u2019t put eols in this construct (setext headings, tables), use a\n // space instead.\n if (\n state.unsafe[index].character === '\\n' &&\n patternInScope(state.stack, state.unsafe[index])\n ) {\n return /[ \\t]/.test(info.before) ? '' : ' '\n }\n }\n\n return '\\\\\\n'\n}\n", "/**\n * Get the count of the longest repeating streak of `substring` in `value`.\n *\n * @param {string} value\n * Content to search in.\n * @param {string} substring\n * Substring to look for, typically one character.\n * @returns {number}\n * Count of most frequent adjacent `substring`s in `value`.\n */\nexport function longestStreak(value, substring) {\n const source = String(value)\n let index = source.indexOf(substring)\n let expected = index\n let count = 0\n let max = 0\n\n if (typeof substring !== 'string') {\n throw new TypeError('Expected substring')\n }\n\n while (index !== -1) {\n if (index === expected) {\n if (++count > max) {\n max = count\n }\n } else {\n count = 1\n }\n\n expected = index + substring.length\n index = source.indexOf(substring, expected)\n }\n\n return max\n}\n", "/**\n * @import {State} from 'mdast-util-to-markdown'\n * @import {Code} from 'mdast'\n */\n\n/**\n * @param {Code} node\n * @param {State} state\n * @returns {boolean}\n */\nexport function formatCodeAsIndented(node, state) {\n return Boolean(\n state.options.fences === false &&\n node.value &&\n // If there\u2019s no info\u2026\n !node.lang &&\n // And there\u2019s a non-whitespace character\u2026\n /[^ \\r\\n]/.test(node.value) &&\n // And the value doesn\u2019t start or end in a blank\u2026\n !/^[\\t ]*(?:[\\r\\n]|$)|(?:^|[\\r\\n])[\\t ]*$/.test(node.value)\n )\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkFence(state) {\n const marker = state.options.fence || '`'\n\n if (marker !== '`' && marker !== '~') {\n throw new Error(\n 'Cannot serialize code with `' +\n marker +\n '` for `options.fence`, expected `` ` `` or `~`'\n )\n }\n\n return marker\n}\n", "/**\n * @import {Info, Map, State} from 'mdast-util-to-markdown'\n * @import {Code, Parents} from 'mdast'\n */\n\nimport {longestStreak} from 'longest-streak'\nimport {formatCodeAsIndented} from '../util/format-code-as-indented.js'\nimport {checkFence} from '../util/check-fence.js'\n\n/**\n * @param {Code} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function code(node, _, state, info) {\n const marker = checkFence(state)\n const raw = node.value || ''\n const suffix = marker === '`' ? 'GraveAccent' : 'Tilde'\n\n if (formatCodeAsIndented(node, state)) {\n const exit = state.enter('codeIndented')\n const value = state.indentLines(raw, map)\n exit()\n return value\n }\n\n const tracker = state.createTracker(info)\n const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3))\n const exit = state.enter('codeFenced')\n let value = tracker.move(sequence)\n\n if (node.lang) {\n const subexit = state.enter(`codeFencedLang${suffix}`)\n value += tracker.move(\n state.safe(node.lang, {\n before: value,\n after: ' ',\n encode: ['`'],\n ...tracker.current()\n })\n )\n subexit()\n }\n\n if (node.lang && node.meta) {\n const subexit = state.enter(`codeFencedMeta${suffix}`)\n value += tracker.move(' ')\n value += tracker.move(\n state.safe(node.meta, {\n before: value,\n after: '\\n',\n encode: ['`'],\n ...tracker.current()\n })\n )\n subexit()\n }\n\n value += tracker.move('\\n')\n\n if (raw) {\n value += tracker.move(raw + '\\n')\n }\n\n value += tracker.move(sequence)\n exit()\n return value\n}\n\n/** @type {Map} */\nfunction map(line, _, blank) {\n return (blank ? '' : ' ') + line\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkQuote(state) {\n const marker = state.options.quote || '\"'\n\n if (marker !== '\"' && marker !== \"'\") {\n throw new Error(\n 'Cannot serialize title with `' +\n marker +\n '` for `options.quote`, expected `\"`, or `\\'`'\n )\n }\n\n return marker\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Definition, Parents} from 'mdast'\n */\n\nimport {checkQuote} from '../util/check-quote.js'\n\n/**\n * @param {Definition} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function definition(node, _, state, info) {\n const quote = checkQuote(state)\n const suffix = quote === '\"' ? 'Quote' : 'Apostrophe'\n const exit = state.enter('definition')\n let subexit = state.enter('label')\n const tracker = state.createTracker(info)\n let value = tracker.move('[')\n value += tracker.move(\n state.safe(state.associationId(node), {\n before: value,\n after: ']',\n ...tracker.current()\n })\n )\n value += tracker.move(']: ')\n\n subexit()\n\n if (\n // If there\u2019s no url, or\u2026\n !node.url ||\n // If there are control characters or whitespace.\n /[\\0- \\u007F]/.test(node.url)\n ) {\n subexit = state.enter('destinationLiteral')\n value += tracker.move('<')\n value += tracker.move(\n state.safe(node.url, {before: value, after: '>', ...tracker.current()})\n )\n value += tracker.move('>')\n } else {\n // No whitespace, raw is prettier.\n subexit = state.enter('destinationRaw')\n value += tracker.move(\n state.safe(node.url, {\n before: value,\n after: node.title ? ' ' : '\\n',\n ...tracker.current()\n })\n )\n }\n\n subexit()\n\n if (node.title) {\n subexit = state.enter(`title${suffix}`)\n value += tracker.move(' ' + quote)\n value += tracker.move(\n state.safe(node.title, {\n before: value,\n after: quote,\n ...tracker.current()\n })\n )\n value += tracker.move(quote)\n subexit()\n }\n\n exit()\n\n return value\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkEmphasis(state) {\n const marker = state.options.emphasis || '*'\n\n if (marker !== '*' && marker !== '_') {\n throw new Error(\n 'Cannot serialize emphasis with `' +\n marker +\n '` for `options.emphasis`, expected `*`, or `_`'\n )\n }\n\n return marker\n}\n", "/**\n * Encode a code point as a character reference.\n *\n * @param {number} code\n * Code point to encode.\n * @returns {string}\n * Encoded character reference.\n */\nexport function encodeCharacterReference(code) {\n return '&#x' + code.toString(16).toUpperCase() + ';'\n}\n", "/**\n * @import {EncodeSides} from '../types.js'\n */\n\nimport {classifyCharacter} from 'micromark-util-classify-character'\n\n/**\n * Check whether to encode (as a character reference) the characters\n * surrounding an attention run.\n *\n * Which characters are around an attention run influence whether it works or\n * not.\n *\n * See for more info.\n * See this markdown in a particular renderer to see what works:\n *\n * ```markdown\n * | | A (letter inside) | B (punctuation inside) | C (whitespace inside) | D (nothing inside) |\n * | ----------------------- | ----------------- | ---------------------- | --------------------- | ------------------ |\n * | 1 (letter outside) | x*y*z | x*.*z | x* *z | x**z |\n * | 2 (punctuation outside) | .*y*. | .*.*. | .* *. | .**. |\n * | 3 (whitespace outside) | x *y* z | x *.* z | x * * z | x ** z |\n * | 4 (nothing outside) | *x* | *.* | * * | ** |\n * ```\n *\n * @param {number} outside\n * Code point on the outer side of the run.\n * @param {number} inside\n * Code point on the inner side of the run.\n * @param {'*' | '_'} marker\n * Marker of the run.\n * Underscores are handled more strictly (they form less often) than\n * asterisks.\n * @returns {EncodeSides}\n * Whether to encode characters.\n */\n// Important: punctuation must never be encoded.\n// Punctuation is solely used by markdown constructs.\n// And by encoding itself.\n// Encoding them will break constructs or double encode things.\nexport function encodeInfo(outside, inside, marker) {\n const outsideKind = classifyCharacter(outside)\n const insideKind = classifyCharacter(inside)\n\n // Letter outside:\n if (outsideKind === undefined) {\n return insideKind === undefined\n ? // Letter inside:\n // we have to encode *both* letters for `_` as it is looser.\n // it already forms for `*` (and GFMs `~`).\n marker === '_'\n ? {inside: true, outside: true}\n : {inside: false, outside: false}\n : insideKind === 1\n ? // Whitespace inside: encode both (letter, whitespace).\n {inside: true, outside: true}\n : // Punctuation inside: encode outer (letter)\n {inside: false, outside: true}\n }\n\n // Whitespace outside:\n if (outsideKind === 1) {\n return insideKind === undefined\n ? // Letter inside: already forms.\n {inside: false, outside: false}\n : insideKind === 1\n ? // Whitespace inside: encode both (whitespace).\n {inside: true, outside: true}\n : // Punctuation inside: already forms.\n {inside: false, outside: false}\n }\n\n // Punctuation outside:\n return insideKind === undefined\n ? // Letter inside: already forms.\n {inside: false, outside: false}\n : insideKind === 1\n ? // Whitespace inside: encode inner (whitespace).\n {inside: true, outside: false}\n : // Punctuation inside: already forms.\n {inside: false, outside: false}\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Emphasis, Parents} from 'mdast'\n */\n\nimport {checkEmphasis} from '../util/check-emphasis.js'\nimport {encodeCharacterReference} from '../util/encode-character-reference.js'\nimport {encodeInfo} from '../util/encode-info.js'\n\nemphasis.peek = emphasisPeek\n\n/**\n * @param {Emphasis} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function emphasis(node, _, state, info) {\n const marker = checkEmphasis(state)\n const exit = state.enter('emphasis')\n const tracker = state.createTracker(info)\n const before = tracker.move(marker)\n\n let between = tracker.move(\n state.containerPhrasing(node, {\n after: marker,\n before,\n ...tracker.current()\n })\n )\n const betweenHead = between.charCodeAt(0)\n const open = encodeInfo(\n info.before.charCodeAt(info.before.length - 1),\n betweenHead,\n marker\n )\n\n if (open.inside) {\n between = encodeCharacterReference(betweenHead) + between.slice(1)\n }\n\n const betweenTail = between.charCodeAt(between.length - 1)\n const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker)\n\n if (close.inside) {\n between = between.slice(0, -1) + encodeCharacterReference(betweenTail)\n }\n\n const after = tracker.move(marker)\n\n exit()\n\n state.attentionEncodeSurroundingInfo = {\n after: close.outside,\n before: open.outside\n }\n return before + between + after\n}\n\n/**\n * @param {Emphasis} _\n * @param {Parents | undefined} _1\n * @param {State} state\n * @returns {string}\n */\nfunction emphasisPeek(_, _1, state) {\n return state.options.emphasis || '*'\n}\n", "/**\n * @import {State} from 'mdast-util-to-markdown'\n * @import {Heading} from 'mdast'\n */\n\nimport {EXIT, visit} from 'unist-util-visit'\nimport {toString} from 'mdast-util-to-string'\n\n/**\n * @param {Heading} node\n * @param {State} state\n * @returns {boolean}\n */\nexport function formatHeadingAsSetext(node, state) {\n let literalWithBreak = false\n\n // Look for literals with a line break.\n // Note that this also\n visit(node, function (node) {\n if (\n ('value' in node && /\\r?\\n|\\r/.test(node.value)) ||\n node.type === 'break'\n ) {\n literalWithBreak = true\n return EXIT\n }\n })\n\n return Boolean(\n (!node.depth || node.depth < 3) &&\n toString(node) &&\n (state.options.setext || literalWithBreak)\n )\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Heading, Parents} from 'mdast'\n */\n\nimport {encodeCharacterReference} from '../util/encode-character-reference.js'\nimport {formatHeadingAsSetext} from '../util/format-heading-as-setext.js'\n\n/**\n * @param {Heading} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function heading(node, _, state, info) {\n const rank = Math.max(Math.min(6, node.depth || 1), 1)\n const tracker = state.createTracker(info)\n\n if (formatHeadingAsSetext(node, state)) {\n const exit = state.enter('headingSetext')\n const subexit = state.enter('phrasing')\n const value = state.containerPhrasing(node, {\n ...tracker.current(),\n before: '\\n',\n after: '\\n'\n })\n subexit()\n exit()\n\n return (\n value +\n '\\n' +\n (rank === 1 ? '=' : '-').repeat(\n // The whole size\u2026\n value.length -\n // Minus the position of the character after the last EOL (or\n // 0 if there is none)\u2026\n (Math.max(value.lastIndexOf('\\r'), value.lastIndexOf('\\n')) + 1)\n )\n )\n }\n\n const sequence = '#'.repeat(rank)\n const exit = state.enter('headingAtx')\n const subexit = state.enter('phrasing')\n\n // Note: for proper tracking, we should reset the output positions when there\n // is no content returned, because then the space is not output.\n // Practically, in that case, there is no content, so it doesn\u2019t matter that\n // we\u2019ve tracked one too many characters.\n tracker.move(sequence + ' ')\n\n let value = state.containerPhrasing(node, {\n before: '# ',\n after: '\\n',\n ...tracker.current()\n })\n\n if (/^[\\t ]/.test(value)) {\n // To do: what effect has the character reference on tracking?\n value = encodeCharacterReference(value.charCodeAt(0)) + value.slice(1)\n }\n\n value = value ? sequence + ' ' + value : sequence\n\n if (state.options.closeAtx) {\n value += ' ' + sequence\n }\n\n subexit()\n exit()\n\n return value\n}\n", "/**\n * @import {Html} from 'mdast'\n */\n\nhtml.peek = htmlPeek\n\n/**\n * @param {Html} node\n * @returns {string}\n */\nexport function html(node) {\n return node.value || ''\n}\n\n/**\n * @returns {string}\n */\nfunction htmlPeek() {\n return '<'\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Image, Parents} from 'mdast'\n */\n\nimport {checkQuote} from '../util/check-quote.js'\n\nimage.peek = imagePeek\n\n/**\n * @param {Image} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function image(node, _, state, info) {\n const quote = checkQuote(state)\n const suffix = quote === '\"' ? 'Quote' : 'Apostrophe'\n const exit = state.enter('image')\n let subexit = state.enter('label')\n const tracker = state.createTracker(info)\n let value = tracker.move('![')\n value += tracker.move(\n state.safe(node.alt, {before: value, after: ']', ...tracker.current()})\n )\n value += tracker.move('](')\n\n subexit()\n\n if (\n // If there\u2019s no url but there is a title\u2026\n (!node.url && node.title) ||\n // If there are control characters or whitespace.\n /[\\0- \\u007F]/.test(node.url)\n ) {\n subexit = state.enter('destinationLiteral')\n value += tracker.move('<')\n value += tracker.move(\n state.safe(node.url, {before: value, after: '>', ...tracker.current()})\n )\n value += tracker.move('>')\n } else {\n // No whitespace, raw is prettier.\n subexit = state.enter('destinationRaw')\n value += tracker.move(\n state.safe(node.url, {\n before: value,\n after: node.title ? ' ' : ')',\n ...tracker.current()\n })\n )\n }\n\n subexit()\n\n if (node.title) {\n subexit = state.enter(`title${suffix}`)\n value += tracker.move(' ' + quote)\n value += tracker.move(\n state.safe(node.title, {\n before: value,\n after: quote,\n ...tracker.current()\n })\n )\n value += tracker.move(quote)\n subexit()\n }\n\n value += tracker.move(')')\n exit()\n\n return value\n}\n\n/**\n * @returns {string}\n */\nfunction imagePeek() {\n return '!'\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {ImageReference, Parents} from 'mdast'\n */\n\nimageReference.peek = imageReferencePeek\n\n/**\n * @param {ImageReference} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function imageReference(node, _, state, info) {\n const type = node.referenceType\n const exit = state.enter('imageReference')\n let subexit = state.enter('label')\n const tracker = state.createTracker(info)\n let value = tracker.move('![')\n const alt = state.safe(node.alt, {\n before: value,\n after: ']',\n ...tracker.current()\n })\n value += tracker.move(alt + '][')\n\n subexit()\n // Hide the fact that we\u2019re in phrasing, because escapes don\u2019t work.\n const stack = state.stack\n state.stack = []\n subexit = state.enter('reference')\n // Note: for proper tracking, we should reset the output positions when we end\n // up making a `shortcut` reference, because then there is no brace output.\n // Practically, in that case, there is no content, so it doesn\u2019t matter that\n // we\u2019ve tracked one too many characters.\n const reference = state.safe(state.associationId(node), {\n before: value,\n after: ']',\n ...tracker.current()\n })\n subexit()\n state.stack = stack\n exit()\n\n if (type === 'full' || !alt || alt !== reference) {\n value += tracker.move(reference + ']')\n } else if (type === 'shortcut') {\n // Remove the unwanted `[`.\n value = value.slice(0, -1)\n } else {\n value += tracker.move(']')\n }\n\n return value\n}\n\n/**\n * @returns {string}\n */\nfunction imageReferencePeek() {\n return '!'\n}\n", "/**\n * @import {State} from 'mdast-util-to-markdown'\n * @import {InlineCode, Parents} from 'mdast'\n */\n\ninlineCode.peek = inlineCodePeek\n\n/**\n * @param {InlineCode} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @returns {string}\n */\nexport function inlineCode(node, _, state) {\n let value = node.value || ''\n let sequence = '`'\n let index = -1\n\n // If there is a single grave accent on its own in the code, use a fence of\n // two.\n // If there are two in a row, use one.\n while (new RegExp('(^|[^`])' + sequence + '([^`]|$)').test(value)) {\n sequence += '`'\n }\n\n // If this is not just spaces or eols (tabs don\u2019t count), and either the\n // first or last character are a space, eol, or tick, then pad with spaces.\n if (\n /[^ \\r\\n]/.test(value) &&\n ((/^[ \\r\\n]/.test(value) && /[ \\r\\n]$/.test(value)) || /^`|`$/.test(value))\n ) {\n value = ' ' + value + ' '\n }\n\n // We have a potential problem: certain characters after eols could result in\n // blocks being seen.\n // For example, if someone injected the string `'\\n# b'`, then that would\n // result in an ATX heading.\n // We can\u2019t escape characters in `inlineCode`, but because eols are\n // transformed to spaces when going from markdown to HTML anyway, we can swap\n // them out.\n while (++index < state.unsafe.length) {\n const pattern = state.unsafe[index]\n const expression = state.compilePattern(pattern)\n /** @type {RegExpExecArray | null} */\n let match\n\n // Only look for `atBreak`s.\n // Btw: note that `atBreak` patterns will always start the regex at LF or\n // CR.\n if (!pattern.atBreak) continue\n\n while ((match = expression.exec(value))) {\n let position = match.index\n\n // Support CRLF (patterns only look for one of the characters).\n if (\n value.charCodeAt(position) === 10 /* `\\n` */ &&\n value.charCodeAt(position - 1) === 13 /* `\\r` */\n ) {\n position--\n }\n\n value = value.slice(0, position) + ' ' + value.slice(match.index + 1)\n }\n }\n\n return sequence + value + sequence\n}\n\n/**\n * @returns {string}\n */\nfunction inlineCodePeek() {\n return '`'\n}\n", "/**\n * @import {State} from 'mdast-util-to-markdown'\n * @import {Link} from 'mdast'\n */\n\nimport {toString} from 'mdast-util-to-string'\n\n/**\n * @param {Link} node\n * @param {State} state\n * @returns {boolean}\n */\nexport function formatLinkAsAutolink(node, state) {\n const raw = toString(node)\n\n return Boolean(\n !state.options.resourceLink &&\n // If there\u2019s a url\u2026\n node.url &&\n // And there\u2019s a no title\u2026\n !node.title &&\n // And the content of `node` is a single text node\u2026\n node.children &&\n node.children.length === 1 &&\n node.children[0].type === 'text' &&\n // And if the url is the same as the content\u2026\n (raw === node.url || 'mailto:' + raw === node.url) &&\n // And that starts w/ a protocol\u2026\n /^[a-z][a-z+.-]+:/i.test(node.url) &&\n // And that doesn\u2019t contain ASCII control codes (character escapes and\n // references don\u2019t work), space, or angle brackets\u2026\n !/[\\0- <>\\u007F]/.test(node.url)\n )\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Link, Parents} from 'mdast'\n * @import {Exit} from '../types.js'\n */\n\nimport {checkQuote} from '../util/check-quote.js'\nimport {formatLinkAsAutolink} from '../util/format-link-as-autolink.js'\n\nlink.peek = linkPeek\n\n/**\n * @param {Link} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function link(node, _, state, info) {\n const quote = checkQuote(state)\n const suffix = quote === '\"' ? 'Quote' : 'Apostrophe'\n const tracker = state.createTracker(info)\n /** @type {Exit} */\n let exit\n /** @type {Exit} */\n let subexit\n\n if (formatLinkAsAutolink(node, state)) {\n // Hide the fact that we\u2019re in phrasing, because escapes don\u2019t work.\n const stack = state.stack\n state.stack = []\n exit = state.enter('autolink')\n let value = tracker.move('<')\n value += tracker.move(\n state.containerPhrasing(node, {\n before: value,\n after: '>',\n ...tracker.current()\n })\n )\n value += tracker.move('>')\n exit()\n state.stack = stack\n return value\n }\n\n exit = state.enter('link')\n subexit = state.enter('label')\n let value = tracker.move('[')\n value += tracker.move(\n state.containerPhrasing(node, {\n before: value,\n after: '](',\n ...tracker.current()\n })\n )\n value += tracker.move('](')\n subexit()\n\n if (\n // If there\u2019s no url but there is a title\u2026\n (!node.url && node.title) ||\n // If there are control characters or whitespace.\n /[\\0- \\u007F]/.test(node.url)\n ) {\n subexit = state.enter('destinationLiteral')\n value += tracker.move('<')\n value += tracker.move(\n state.safe(node.url, {before: value, after: '>', ...tracker.current()})\n )\n value += tracker.move('>')\n } else {\n // No whitespace, raw is prettier.\n subexit = state.enter('destinationRaw')\n value += tracker.move(\n state.safe(node.url, {\n before: value,\n after: node.title ? ' ' : ')',\n ...tracker.current()\n })\n )\n }\n\n subexit()\n\n if (node.title) {\n subexit = state.enter(`title${suffix}`)\n value += tracker.move(' ' + quote)\n value += tracker.move(\n state.safe(node.title, {\n before: value,\n after: quote,\n ...tracker.current()\n })\n )\n value += tracker.move(quote)\n subexit()\n }\n\n value += tracker.move(')')\n\n exit()\n return value\n}\n\n/**\n * @param {Link} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @returns {string}\n */\nfunction linkPeek(node, _, state) {\n return formatLinkAsAutolink(node, state) ? '<' : '['\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {LinkReference, Parents} from 'mdast'\n */\n\nlinkReference.peek = linkReferencePeek\n\n/**\n * @param {LinkReference} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function linkReference(node, _, state, info) {\n const type = node.referenceType\n const exit = state.enter('linkReference')\n let subexit = state.enter('label')\n const tracker = state.createTracker(info)\n let value = tracker.move('[')\n const text = state.containerPhrasing(node, {\n before: value,\n after: ']',\n ...tracker.current()\n })\n value += tracker.move(text + '][')\n\n subexit()\n // Hide the fact that we\u2019re in phrasing, because escapes don\u2019t work.\n const stack = state.stack\n state.stack = []\n subexit = state.enter('reference')\n // Note: for proper tracking, we should reset the output positions when we end\n // up making a `shortcut` reference, because then there is no brace output.\n // Practically, in that case, there is no content, so it doesn\u2019t matter that\n // we\u2019ve tracked one too many characters.\n const reference = state.safe(state.associationId(node), {\n before: value,\n after: ']',\n ...tracker.current()\n })\n subexit()\n state.stack = stack\n exit()\n\n if (type === 'full' || !text || text !== reference) {\n value += tracker.move(reference + ']')\n } else if (type === 'shortcut') {\n // Remove the unwanted `[`.\n value = value.slice(0, -1)\n } else {\n value += tracker.move(']')\n }\n\n return value\n}\n\n/**\n * @returns {string}\n */\nfunction linkReferencePeek() {\n return '['\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkBullet(state) {\n const marker = state.options.bullet || '*'\n\n if (marker !== '*' && marker !== '+' && marker !== '-') {\n throw new Error(\n 'Cannot serialize items with `' +\n marker +\n '` for `options.bullet`, expected `*`, `+`, or `-`'\n )\n }\n\n return marker\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\nimport {checkBullet} from './check-bullet.js'\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkBulletOther(state) {\n const bullet = checkBullet(state)\n const bulletOther = state.options.bulletOther\n\n if (!bulletOther) {\n return bullet === '*' ? '-' : '*'\n }\n\n if (bulletOther !== '*' && bulletOther !== '+' && bulletOther !== '-') {\n throw new Error(\n 'Cannot serialize items with `' +\n bulletOther +\n '` for `options.bulletOther`, expected `*`, `+`, or `-`'\n )\n }\n\n if (bulletOther === bullet) {\n throw new Error(\n 'Expected `bullet` (`' +\n bullet +\n '`) and `bulletOther` (`' +\n bulletOther +\n '`) to be different'\n )\n }\n\n return bulletOther\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkBulletOrdered(state) {\n const marker = state.options.bulletOrdered || '.'\n\n if (marker !== '.' && marker !== ')') {\n throw new Error(\n 'Cannot serialize items with `' +\n marker +\n '` for `options.bulletOrdered`, expected `.` or `)`'\n )\n }\n\n return marker\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkRule(state) {\n const marker = state.options.rule || '*'\n\n if (marker !== '*' && marker !== '-' && marker !== '_') {\n throw new Error(\n 'Cannot serialize rules with `' +\n marker +\n '` for `options.rule`, expected `*`, `-`, or `_`'\n )\n }\n\n return marker\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {List, Parents} from 'mdast'\n */\n\nimport {checkBullet} from '../util/check-bullet.js'\nimport {checkBulletOther} from '../util/check-bullet-other.js'\nimport {checkBulletOrdered} from '../util/check-bullet-ordered.js'\nimport {checkRule} from '../util/check-rule.js'\n\n/**\n * @param {List} node\n * @param {Parents | undefined} parent\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function list(node, parent, state, info) {\n const exit = state.enter('list')\n const bulletCurrent = state.bulletCurrent\n /** @type {string} */\n let bullet = node.ordered ? checkBulletOrdered(state) : checkBullet(state)\n /** @type {string} */\n const bulletOther = node.ordered\n ? bullet === '.'\n ? ')'\n : '.'\n : checkBulletOther(state)\n let useDifferentMarker =\n parent && state.bulletLastUsed ? bullet === state.bulletLastUsed : false\n\n if (!node.ordered) {\n const firstListItem = node.children ? node.children[0] : undefined\n\n // If there\u2019s an empty first list item directly in two list items,\n // we have to use a different bullet:\n //\n // ```markdown\n // * - *\n // ```\n //\n // \u2026because otherwise it would become one big thematic break.\n if (\n // Bullet could be used as a thematic break marker:\n (bullet === '*' || bullet === '-') &&\n // Empty first list item:\n firstListItem &&\n (!firstListItem.children || !firstListItem.children[0]) &&\n // Directly in two other list items:\n state.stack[state.stack.length - 1] === 'list' &&\n state.stack[state.stack.length - 2] === 'listItem' &&\n state.stack[state.stack.length - 3] === 'list' &&\n state.stack[state.stack.length - 4] === 'listItem' &&\n // That are each the first child.\n state.indexStack[state.indexStack.length - 1] === 0 &&\n state.indexStack[state.indexStack.length - 2] === 0 &&\n state.indexStack[state.indexStack.length - 3] === 0\n ) {\n useDifferentMarker = true\n }\n\n // If there\u2019s a thematic break at the start of the first list item,\n // we have to use a different bullet:\n //\n // ```markdown\n // * ---\n // ```\n //\n // \u2026because otherwise it would become one big thematic break.\n if (checkRule(state) === bullet && firstListItem) {\n let index = -1\n\n while (++index < node.children.length) {\n const item = node.children[index]\n\n if (\n item &&\n item.type === 'listItem' &&\n item.children &&\n item.children[0] &&\n item.children[0].type === 'thematicBreak'\n ) {\n useDifferentMarker = true\n break\n }\n }\n }\n }\n\n if (useDifferentMarker) {\n bullet = bulletOther\n }\n\n state.bulletCurrent = bullet\n const value = state.containerFlow(node, info)\n state.bulletLastUsed = bullet\n state.bulletCurrent = bulletCurrent\n exit()\n return value\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkListItemIndent(state) {\n const style = state.options.listItemIndent || 'one'\n\n if (style !== 'tab' && style !== 'one' && style !== 'mixed') {\n throw new Error(\n 'Cannot serialize items with `' +\n style +\n '` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`'\n )\n }\n\n return style\n}\n", "/**\n * @import {Info, Map, State} from 'mdast-util-to-markdown'\n * @import {ListItem, Parents} from 'mdast'\n */\n\nimport {checkBullet} from '../util/check-bullet.js'\nimport {checkListItemIndent} from '../util/check-list-item-indent.js'\n\n/**\n * @param {ListItem} node\n * @param {Parents | undefined} parent\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function listItem(node, parent, state, info) {\n const listItemIndent = checkListItemIndent(state)\n let bullet = state.bulletCurrent || checkBullet(state)\n\n // Add the marker value for ordered lists.\n if (parent && parent.type === 'list' && parent.ordered) {\n bullet =\n (typeof parent.start === 'number' && parent.start > -1\n ? parent.start\n : 1) +\n (state.options.incrementListMarker === false\n ? 0\n : parent.children.indexOf(node)) +\n bullet\n }\n\n let size = bullet.length + 1\n\n if (\n listItemIndent === 'tab' ||\n (listItemIndent === 'mixed' &&\n ((parent && parent.type === 'list' && parent.spread) || node.spread))\n ) {\n size = Math.ceil(size / 4) * 4\n }\n\n const tracker = state.createTracker(info)\n tracker.move(bullet + ' '.repeat(size - bullet.length))\n tracker.shift(size)\n const exit = state.enter('listItem')\n const value = state.indentLines(\n state.containerFlow(node, tracker.current()),\n map\n )\n exit()\n\n return value\n\n /** @type {Map} */\n function map(line, index, blank) {\n if (index) {\n return (blank ? '' : ' '.repeat(size)) + line\n }\n\n return (blank ? bullet : bullet + ' '.repeat(size - bullet.length)) + line\n }\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Paragraph, Parents} from 'mdast'\n */\n\n/**\n * @param {Paragraph} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function paragraph(node, _, state, info) {\n const exit = state.enter('paragraph')\n const subexit = state.enter('phrasing')\n const value = state.containerPhrasing(node, info)\n subexit()\n exit()\n return value\n}\n", "/**\n * @typedef {import('mdast').Html} Html\n * @typedef {import('mdast').PhrasingContent} PhrasingContent\n */\n\nimport {convert} from 'unist-util-is'\n\n/**\n * Check if the given value is *phrasing content*.\n *\n * > \uD83D\uDC49 **Note**: Excludes `html`, which can be both phrasing or flow.\n *\n * @param node\n * Thing to check, typically `Node`.\n * @returns\n * Whether `value` is phrasing content.\n */\n\nexport const phrasing =\n /** @type {(node?: unknown) => node is Exclude} */\n (\n convert([\n 'break',\n 'delete',\n 'emphasis',\n // To do: next major: removed since footnotes were added to GFM.\n 'footnote',\n 'footnoteReference',\n 'image',\n 'imageReference',\n 'inlineCode',\n // Enabled by `mdast-util-math`:\n 'inlineMath',\n 'link',\n 'linkReference',\n // Enabled by `mdast-util-mdx`:\n 'mdxJsxTextElement',\n // Enabled by `mdast-util-mdx`:\n 'mdxTextExpression',\n 'strong',\n 'text',\n // Enabled by `mdast-util-directive`:\n 'textDirective'\n ])\n )\n", "export {phrasing} from './lib/index.js'\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Parents, Root} from 'mdast'\n */\n\nimport {phrasing} from 'mdast-util-phrasing'\n\n/**\n * @param {Root} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function root(node, _, state, info) {\n // Note: `html` nodes are ambiguous.\n const hasPhrasing = node.children.some(function (d) {\n return phrasing(d)\n })\n\n const container = hasPhrasing ? state.containerPhrasing : state.containerFlow\n return container.call(state, node, info)\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkStrong(state) {\n const marker = state.options.strong || '*'\n\n if (marker !== '*' && marker !== '_') {\n throw new Error(\n 'Cannot serialize strong with `' +\n marker +\n '` for `options.strong`, expected `*`, or `_`'\n )\n }\n\n return marker\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Parents, Strong} from 'mdast'\n */\n\nimport {checkStrong} from '../util/check-strong.js'\nimport {encodeCharacterReference} from '../util/encode-character-reference.js'\nimport {encodeInfo} from '../util/encode-info.js'\n\nstrong.peek = strongPeek\n\n/**\n * @param {Strong} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function strong(node, _, state, info) {\n const marker = checkStrong(state)\n const exit = state.enter('strong')\n const tracker = state.createTracker(info)\n const before = tracker.move(marker + marker)\n\n let between = tracker.move(\n state.containerPhrasing(node, {\n after: marker,\n before,\n ...tracker.current()\n })\n )\n const betweenHead = between.charCodeAt(0)\n const open = encodeInfo(\n info.before.charCodeAt(info.before.length - 1),\n betweenHead,\n marker\n )\n\n if (open.inside) {\n between = encodeCharacterReference(betweenHead) + between.slice(1)\n }\n\n const betweenTail = between.charCodeAt(between.length - 1)\n const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker)\n\n if (close.inside) {\n between = between.slice(0, -1) + encodeCharacterReference(betweenTail)\n }\n\n const after = tracker.move(marker + marker)\n\n exit()\n\n state.attentionEncodeSurroundingInfo = {\n after: close.outside,\n before: open.outside\n }\n return before + between + after\n}\n\n/**\n * @param {Strong} _\n * @param {Parents | undefined} _1\n * @param {State} state\n * @returns {string}\n */\nfunction strongPeek(_, _1, state) {\n return state.options.strong || '*'\n}\n", "/**\n * @import {Info, State} from 'mdast-util-to-markdown'\n * @import {Parents, Text} from 'mdast'\n */\n\n/**\n * @param {Text} node\n * @param {Parents | undefined} _\n * @param {State} state\n * @param {Info} info\n * @returns {string}\n */\nexport function text(node, _, state, info) {\n return state.safe(node.value, info)\n}\n", "/**\n * @import {Options, State} from 'mdast-util-to-markdown'\n */\n\n/**\n * @param {State} state\n * @returns {Exclude}\n */\nexport function checkRuleRepetition(state) {\n const repetition = state.options.ruleRepetition || 3\n\n if (repetition < 3) {\n throw new Error(\n 'Cannot serialize rules with repetition `' +\n repetition +\n '` for `options.ruleRepetition`, expected `3` or more'\n )\n }\n\n return repetition\n}\n", "/**\n * @import {State} from 'mdast-util-to-markdown'\n * @import {Parents, ThematicBreak} from 'mdast'\n */\n\nimport {checkRuleRepetition} from '../util/check-rule-repetition.js'\nimport {checkRule} from '../util/check-rule.js'\n\n/**\n * @param {ThematicBreak} _\n * @param {Parents | undefined} _1\n * @param {State} state\n * @returns {string}\n */\nexport function thematicBreak(_, _1, state) {\n const value = (\n checkRule(state) + (state.options.ruleSpaces ? ' ' : '')\n ).repeat(checkRuleRepetition(state))\n\n return state.options.ruleSpaces ? value.slice(0, -1) : value\n}\n", "import {blockquote} from './blockquote.js'\nimport {hardBreak} from './break.js'\nimport {code} from './code.js'\nimport {definition} from './definition.js'\nimport {emphasis} from './emphasis.js'\nimport {heading} from './heading.js'\nimport {html} from './html.js'\nimport {image} from './image.js'\nimport {imageReference} from './image-reference.js'\nimport {inlineCode} from './inline-code.js'\nimport {link} from './link.js'\nimport {linkReference} from './link-reference.js'\nimport {list} from './list.js'\nimport {listItem} from './list-item.js'\nimport {paragraph} from './paragraph.js'\nimport {root} from './root.js'\nimport {strong} from './strong.js'\nimport {text} from './text.js'\nimport {thematicBreak} from './thematic-break.js'\n\n/**\n * Default (CommonMark) handlers.\n */\nexport const handle = {\n blockquote,\n break: hardBreak,\n code,\n definition,\n emphasis,\n hardBreak,\n heading,\n html,\n image,\n imageReference,\n inlineCode,\n link,\n linkReference,\n list,\n listItem,\n paragraph,\n root,\n strong,\n text,\n thematicBreak\n}\n", "// Note: extra types exposed from `index.d.ts`.\nexport {toMarkdown} from './lib/index.js'\nexport {handle as defaultHandlers} from './lib/handle/index.js'\n", "/**\n * @typedef {import('mdast').InlineCode} InlineCode\n * @typedef {import('mdast').Table} Table\n * @typedef {import('mdast').TableCell} TableCell\n * @typedef {import('mdast').TableRow} TableRow\n *\n * @typedef {import('markdown-table').Options} MarkdownTableOptions\n *\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n *\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').State} State\n * @typedef {import('mdast-util-to-markdown').Info} Info\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {boolean | null | undefined} [tableCellPadding=true]\n * Whether to add a space of padding between delimiters and cells (default:\n * `true`).\n * @property {boolean | null | undefined} [tablePipeAlign=true]\n * Whether to align the delimiters (default: `true`).\n * @property {MarkdownTableOptions['stringLength'] | null | undefined} [stringLength]\n * Function to detect the length of table cell content, used when aligning\n * the delimiters between cells (optional).\n */\n\nimport {ok as assert} from 'devlop'\nimport {markdownTable} from 'markdown-table'\nimport {defaultHandlers} from 'mdast-util-to-markdown'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM tables in\n * markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM tables.\n */\nexport function gfmTableFromMarkdown() {\n return {\n enter: {\n table: enterTable,\n tableData: enterCell,\n tableHeader: enterCell,\n tableRow: enterRow\n },\n exit: {\n codeText: exitCodeText,\n table: exitTable,\n tableData: exit,\n tableHeader: exit,\n tableRow: exit\n }\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterTable(token) {\n const align = token._align\n assert(align, 'expected `_align` on table')\n this.enter(\n {\n type: 'table',\n align: align.map(function (d) {\n return d === 'none' ? null : d\n }),\n children: []\n },\n token\n )\n this.data.inTable = true\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitTable(token) {\n this.exit(token)\n this.data.inTable = undefined\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterRow(token) {\n this.enter({type: 'tableRow', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exit(token) {\n this.exit(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterCell(token) {\n this.enter({type: 'tableCell', children: []}, token)\n}\n\n// Overwrite the default code text data handler to unescape escaped pipes when\n// they are in tables.\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitCodeText(token) {\n let value = this.resume()\n\n if (this.data.inTable) {\n value = value.replace(/\\\\([\\\\|])/g, replace)\n }\n\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'inlineCode')\n node.value = value\n this.exit(token)\n}\n\n/**\n * @param {string} $0\n * @param {string} $1\n * @returns {string}\n */\nfunction replace($0, $1) {\n // Pipes work, backslashes don\u2019t (but can\u2019t escape pipes).\n return $1 === '|' ? $1 : $0\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM tables in\n * markdown.\n *\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM tables.\n */\nexport function gfmTableToMarkdown(options) {\n const settings = options || {}\n const padding = settings.tableCellPadding\n const alignDelimiters = settings.tablePipeAlign\n const stringLength = settings.stringLength\n const around = padding ? ' ' : '|'\n\n return {\n unsafe: [\n {character: '\\r', inConstruct: 'tableCell'},\n {character: '\\n', inConstruct: 'tableCell'},\n // A pipe, when followed by a tab or space (padding), or a dash or colon\n // (unpadded delimiter row), could result in a table.\n {atBreak: true, character: '|', after: '[\\t :-]'},\n // A pipe in a cell must be encoded.\n {character: '|', inConstruct: 'tableCell'},\n // A colon must be followed by a dash, in which case it could start a\n // delimiter row.\n {atBreak: true, character: ':', after: '-'},\n // A delimiter row can also start with a dash, when followed by more\n // dashes, a colon, or a pipe.\n // This is a stricter version than the built in check for lists, thematic\n // breaks, and setex heading underlines though:\n // \n {atBreak: true, character: '-', after: '[:|-]'}\n ],\n handlers: {\n inlineCode: inlineCodeWithTable,\n table: handleTable,\n tableCell: handleTableCell,\n tableRow: handleTableRow\n }\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {Table} node\n */\n function handleTable(node, _, state, info) {\n return serializeData(handleTableAsData(node, state, info), node.align)\n }\n\n /**\n * This function isn\u2019t really used normally, because we handle rows at the\n * table level.\n * But, if someone passes in a table row, this ensures we make somewhat sense.\n *\n * @type {ToMarkdownHandle}\n * @param {TableRow} node\n */\n function handleTableRow(node, _, state, info) {\n const row = handleTableRowAsData(node, state, info)\n const value = serializeData([row])\n // `markdown-table` will always add an align row\n return value.slice(0, value.indexOf('\\n'))\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {TableCell} node\n */\n function handleTableCell(node, _, state, info) {\n const exit = state.enter('tableCell')\n const subexit = state.enter('phrasing')\n const value = state.containerPhrasing(node, {\n ...info,\n before: around,\n after: around\n })\n subexit()\n exit()\n return value\n }\n\n /**\n * @param {Array>} matrix\n * @param {Array | null | undefined} [align]\n */\n function serializeData(matrix, align) {\n return markdownTable(matrix, {\n align,\n // @ts-expect-error: `markdown-table` types should support `null`.\n alignDelimiters,\n // @ts-expect-error: `markdown-table` types should support `null`.\n padding,\n // @ts-expect-error: `markdown-table` types should support `null`.\n stringLength\n })\n }\n\n /**\n * @param {Table} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array>} */\n const result = []\n const subexit = state.enter('table')\n\n while (++index < children.length) {\n result[index] = handleTableRowAsData(children[index], state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @param {TableRow} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableRowAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array} */\n const result = []\n const subexit = state.enter('tableRow')\n\n while (++index < children.length) {\n // Note: the positional info as used here is incorrect.\n // Making it correct would be impossible due to aligning cells?\n // And it would need copy/pasting `markdown-table` into this project.\n result[index] = handleTableCell(children[index], node, state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {InlineCode} node\n */\n function inlineCodeWithTable(node, parent, state) {\n let value = defaultHandlers.inlineCode(node, parent, state)\n\n if (state.stack.includes('tableCell')) {\n value = value.replace(/\\|/g, '\\\\$&')\n }\n\n return value\n }\n}\n", "// Note: types exposed from `index.d.ts`.\nexport {gfmTableFromMarkdown, gfmTableToMarkdown} from './lib/index.js'\n", "/**\n * @typedef {import('mdast').ListItem} ListItem\n * @typedef {import('mdast').Paragraph} Paragraph\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n */\n\nimport {ok as assert} from 'devlop'\nimport {defaultHandlers} from 'mdast-util-to-markdown'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM task\n * list items in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM task list items.\n */\nexport function gfmTaskListItemFromMarkdown() {\n return {\n exit: {\n taskListCheckValueChecked: exitCheck,\n taskListCheckValueUnchecked: exitCheck,\n paragraph: exitParagraphWithTaskListItem\n }\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM task list\n * items in markdown.\n *\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM task list items.\n */\nexport function gfmTaskListItemToMarkdown() {\n return {\n unsafe: [{atBreak: true, character: '-', after: '[:|-]'}],\n handlers: {listItem: listItemWithTaskListItem}\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitCheck(token) {\n // We\u2019re always in a paragraph, in a list item.\n const node = this.stack[this.stack.length - 2]\n assert(node.type === 'listItem')\n node.checked = token.type === 'taskListCheckValueChecked'\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitParagraphWithTaskListItem(token) {\n const parent = this.stack[this.stack.length - 2]\n\n if (\n parent &&\n parent.type === 'listItem' &&\n typeof parent.checked === 'boolean'\n ) {\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'paragraph')\n const head = node.children[0]\n\n if (head && head.type === 'text') {\n const siblings = parent.children\n let index = -1\n /** @type {Paragraph | undefined} */\n let firstParaghraph\n\n while (++index < siblings.length) {\n const sibling = siblings[index]\n if (sibling.type === 'paragraph') {\n firstParaghraph = sibling\n break\n }\n }\n\n if (firstParaghraph === node) {\n // Must start with a space or a tab.\n head.value = head.value.slice(1)\n\n if (head.value.length === 0) {\n node.children.shift()\n } else if (\n node.position &&\n head.position &&\n typeof head.position.start.offset === 'number'\n ) {\n head.position.start.column++\n head.position.start.offset++\n node.position.start = Object.assign({}, head.position.start)\n }\n }\n }\n }\n\n this.exit(token)\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {ListItem} node\n */\nfunction listItemWithTaskListItem(node, parent, state, info) {\n const head = node.children[0]\n const checkable =\n typeof node.checked === 'boolean' && head && head.type === 'paragraph'\n const checkbox = '[' + (node.checked ? 'x' : ' ') + '] '\n const tracker = state.createTracker(info)\n\n if (checkable) {\n tracker.move(checkbox)\n }\n\n let value = defaultHandlers.listItem(node, parent, state, {\n ...info,\n ...tracker.current()\n })\n\n if (checkable) {\n value = value.replace(/^(?:[*+-]|\\d+\\.)([\\r\\n]| {1,3})/, check)\n }\n\n return value\n\n /**\n * @param {string} $0\n * @returns {string}\n */\n function check($0) {\n return $0 + checkbox\n }\n}\n", "export {\n gfmTaskListItemFromMarkdown,\n gfmTaskListItemToMarkdown\n} from './lib/index.js'\n", "/**\n * @import {Extension as FromMarkdownExtension} from 'mdast-util-from-markdown'\n * @import {Options} from 'mdast-util-gfm'\n * @import {Options as ToMarkdownExtension} from 'mdast-util-to-markdown'\n */\n\nimport {\n gfmAutolinkLiteralFromMarkdown,\n gfmAutolinkLiteralToMarkdown\n} from 'mdast-util-gfm-autolink-literal'\nimport {\n gfmFootnoteFromMarkdown,\n gfmFootnoteToMarkdown\n} from 'mdast-util-gfm-footnote'\nimport {\n gfmStrikethroughFromMarkdown,\n gfmStrikethroughToMarkdown\n} from 'mdast-util-gfm-strikethrough'\nimport {gfmTableFromMarkdown, gfmTableToMarkdown} from 'mdast-util-gfm-table'\nimport {\n gfmTaskListItemFromMarkdown,\n gfmTaskListItemToMarkdown\n} from 'mdast-util-gfm-task-list-item'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM (autolink\n * literals, footnotes, strikethrough, tables, tasklists).\n *\n * @returns {Array}\n * Extension for `mdast-util-from-markdown` to enable GFM (autolink literals,\n * footnotes, strikethrough, tables, tasklists).\n */\nexport function gfmFromMarkdown() {\n return [\n gfmAutolinkLiteralFromMarkdown(),\n gfmFootnoteFromMarkdown(),\n gfmStrikethroughFromMarkdown(),\n gfmTableFromMarkdown(),\n gfmTaskListItemFromMarkdown()\n ]\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM (autolink\n * literals, footnotes, strikethrough, tables, tasklists).\n *\n * @param {Options | null | undefined} [options]\n * Configuration (optional).\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM (autolink literals,\n * footnotes, strikethrough, tables, tasklists).\n */\nexport function gfmToMarkdown(options) {\n return {\n extensions: [\n gfmAutolinkLiteralToMarkdown(),\n gfmFootnoteToMarkdown(options),\n gfmStrikethroughToMarkdown(),\n gfmTableToMarkdown(options),\n gfmTaskListItemToMarkdown()\n ]\n }\n}\n", "// Note: types exposed from `index.d.ts`.\nexport {gfmFromMarkdown, gfmToMarkdown} from './lib/index.js'\n", "/**\n * @import {Code, ConstructRecord, Event, Extension, Previous, State, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { asciiAlpha, asciiAlphanumeric, asciiControl, markdownLineEndingOrSpace, unicodePunctuation, unicodeWhitespace } from 'micromark-util-character';\nconst wwwPrefix = {\n tokenize: tokenizeWwwPrefix,\n partial: true\n};\nconst domain = {\n tokenize: tokenizeDomain,\n partial: true\n};\nconst path = {\n tokenize: tokenizePath,\n partial: true\n};\nconst trail = {\n tokenize: tokenizeTrail,\n partial: true\n};\nconst emailDomainDotTrail = {\n tokenize: tokenizeEmailDomainDotTrail,\n partial: true\n};\nconst wwwAutolink = {\n name: 'wwwAutolink',\n tokenize: tokenizeWwwAutolink,\n previous: previousWww\n};\nconst protocolAutolink = {\n name: 'protocolAutolink',\n tokenize: tokenizeProtocolAutolink,\n previous: previousProtocol\n};\nconst emailAutolink = {\n name: 'emailAutolink',\n tokenize: tokenizeEmailAutolink,\n previous: previousEmail\n};\n\n/** @type {ConstructRecord} */\nconst text = {};\n\n/**\n * Create an extension for `micromark` to support GitHub autolink literal\n * syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions` to enable GFM\n * autolink literal syntax.\n */\nexport function gfmAutolinkLiteral() {\n return {\n text\n };\n}\n\n/** @type {Code} */\nlet code = 48;\n\n// Add alphanumerics.\nwhile (code < 123) {\n text[code] = emailAutolink;\n code++;\n if (code === 58) code = 65;else if (code === 91) code = 97;\n}\ntext[43] = emailAutolink;\ntext[45] = emailAutolink;\ntext[46] = emailAutolink;\ntext[95] = emailAutolink;\ntext[72] = [emailAutolink, protocolAutolink];\ntext[104] = [emailAutolink, protocolAutolink];\ntext[87] = [emailAutolink, wwwAutolink];\ntext[119] = [emailAutolink, wwwAutolink];\n\n// To do: perform email autolink literals on events, afterwards.\n// That\u2019s where `markdown-rs` and `cmark-gfm` perform it.\n// It should look for `@`, then for atext backwards, and then for a label\n// forwards.\n// To do: `mailto:`, `xmpp:` protocol as prefix.\n\n/**\n * Email autolink literal.\n *\n * ```markdown\n * > | a contact@example.org b\n * ^^^^^^^^^^^^^^^^^^^\n * ```\n *\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeEmailAutolink(effects, ok, nok) {\n const self = this;\n /** @type {boolean | undefined} */\n let dot;\n /** @type {boolean} */\n let data;\n return start;\n\n /**\n * Start of email autolink literal.\n *\n * ```markdown\n * > | a contact@example.org b\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n if (!gfmAtext(code) || !previousEmail.call(self, self.previous) || previousUnbalanced(self.events)) {\n return nok(code);\n }\n effects.enter('literalAutolink');\n effects.enter('literalAutolinkEmail');\n return atext(code);\n }\n\n /**\n * In email atext.\n *\n * ```markdown\n * > | a contact@example.org b\n * ^\n * ```\n *\n * @type {State}\n */\n function atext(code) {\n if (gfmAtext(code)) {\n effects.consume(code);\n return atext;\n }\n if (code === 64) {\n effects.consume(code);\n return emailDomain;\n }\n return nok(code);\n }\n\n /**\n * In email domain.\n *\n * The reference code is a bit overly complex as it handles the `@`, of which\n * there may be just one.\n * Source: \n *\n * ```markdown\n * > | a contact@example.org b\n * ^\n * ```\n *\n * @type {State}\n */\n function emailDomain(code) {\n // Dot followed by alphanumerical (not `-` or `_`).\n if (code === 46) {\n return effects.check(emailDomainDotTrail, emailDomainAfter, emailDomainDot)(code);\n }\n\n // Alphanumerical, `-`, and `_`.\n if (code === 45 || code === 95 || asciiAlphanumeric(code)) {\n data = true;\n effects.consume(code);\n return emailDomain;\n }\n\n // To do: `/` if xmpp.\n\n // Note: normally we\u2019d truncate trailing punctuation from the link.\n // However, email autolink literals cannot contain any of those markers,\n // except for `.`, but that can only occur if it isn\u2019t trailing.\n // So we can ignore truncating!\n return emailDomainAfter(code);\n }\n\n /**\n * In email domain, on dot that is not a trail.\n *\n * ```markdown\n * > | a contact@example.org b\n * ^\n * ```\n *\n * @type {State}\n */\n function emailDomainDot(code) {\n effects.consume(code);\n dot = true;\n return emailDomain;\n }\n\n /**\n * After email domain.\n *\n * ```markdown\n * > | a contact@example.org b\n * ^\n * ```\n *\n * @type {State}\n */\n function emailDomainAfter(code) {\n // Domain must not be empty, must include a dot, and must end in alphabetical.\n // Source: .\n if (data && dot && asciiAlpha(self.previous)) {\n effects.exit('literalAutolinkEmail');\n effects.exit('literalAutolink');\n return ok(code);\n }\n return nok(code);\n }\n}\n\n/**\n * `www` autolink literal.\n *\n * ```markdown\n * > | a www.example.org b\n * ^^^^^^^^^^^^^^^\n * ```\n *\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeWwwAutolink(effects, ok, nok) {\n const self = this;\n return wwwStart;\n\n /**\n * Start of www autolink literal.\n *\n * ```markdown\n * > | www.example.com/a?b#c\n * ^\n * ```\n *\n * @type {State}\n */\n function wwwStart(code) {\n if (code !== 87 && code !== 119 || !previousWww.call(self, self.previous) || previousUnbalanced(self.events)) {\n return nok(code);\n }\n effects.enter('literalAutolink');\n effects.enter('literalAutolinkWww');\n // Note: we *check*, so we can discard the `www.` we parsed.\n // If it worked, we consider it as a part of the domain.\n return effects.check(wwwPrefix, effects.attempt(domain, effects.attempt(path, wwwAfter), nok), nok)(code);\n }\n\n /**\n * After a www autolink literal.\n *\n * ```markdown\n * > | www.example.com/a?b#c\n * ^\n * ```\n *\n * @type {State}\n */\n function wwwAfter(code) {\n effects.exit('literalAutolinkWww');\n effects.exit('literalAutolink');\n return ok(code);\n }\n}\n\n/**\n * Protocol autolink literal.\n *\n * ```markdown\n * > | a https://example.org b\n * ^^^^^^^^^^^^^^^^^^^\n * ```\n *\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeProtocolAutolink(effects, ok, nok) {\n const self = this;\n let buffer = '';\n let seen = false;\n return protocolStart;\n\n /**\n * Start of protocol autolink literal.\n *\n * ```markdown\n * > | https://example.com/a?b#c\n * ^\n * ```\n *\n * @type {State}\n */\n function protocolStart(code) {\n if ((code === 72 || code === 104) && previousProtocol.call(self, self.previous) && !previousUnbalanced(self.events)) {\n effects.enter('literalAutolink');\n effects.enter('literalAutolinkHttp');\n buffer += String.fromCodePoint(code);\n effects.consume(code);\n return protocolPrefixInside;\n }\n return nok(code);\n }\n\n /**\n * In protocol.\n *\n * ```markdown\n * > | https://example.com/a?b#c\n * ^^^^^\n * ```\n *\n * @type {State}\n */\n function protocolPrefixInside(code) {\n // `5` is size of `https`\n if (asciiAlpha(code) && buffer.length < 5) {\n // @ts-expect-error: definitely number.\n buffer += String.fromCodePoint(code);\n effects.consume(code);\n return protocolPrefixInside;\n }\n if (code === 58) {\n const protocol = buffer.toLowerCase();\n if (protocol === 'http' || protocol === 'https') {\n effects.consume(code);\n return protocolSlashesInside;\n }\n }\n return nok(code);\n }\n\n /**\n * In slashes.\n *\n * ```markdown\n * > | https://example.com/a?b#c\n * ^^\n * ```\n *\n * @type {State}\n */\n function protocolSlashesInside(code) {\n if (code === 47) {\n effects.consume(code);\n if (seen) {\n return afterProtocol;\n }\n seen = true;\n return protocolSlashesInside;\n }\n return nok(code);\n }\n\n /**\n * After protocol, before domain.\n *\n * ```markdown\n * > | https://example.com/a?b#c\n * ^\n * ```\n *\n * @type {State}\n */\n function afterProtocol(code) {\n // To do: this is different from `markdown-rs`:\n // https://github.com/wooorm/markdown-rs/blob/b3a921c761309ae00a51fe348d8a43adbc54b518/src/construct/gfm_autolink_literal.rs#L172-L182\n return code === null || asciiControl(code) || markdownLineEndingOrSpace(code) || unicodeWhitespace(code) || unicodePunctuation(code) ? nok(code) : effects.attempt(domain, effects.attempt(path, protocolAfter), nok)(code);\n }\n\n /**\n * After a protocol autolink literal.\n *\n * ```markdown\n * > | https://example.com/a?b#c\n * ^\n * ```\n *\n * @type {State}\n */\n function protocolAfter(code) {\n effects.exit('literalAutolinkHttp');\n effects.exit('literalAutolink');\n return ok(code);\n }\n}\n\n/**\n * `www` prefix.\n *\n * ```markdown\n * > | a www.example.org b\n * ^^^^\n * ```\n *\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeWwwPrefix(effects, ok, nok) {\n let size = 0;\n return wwwPrefixInside;\n\n /**\n * In www prefix.\n *\n * ```markdown\n * > | www.example.com\n * ^^^^\n * ```\n *\n * @type {State}\n */\n function wwwPrefixInside(code) {\n if ((code === 87 || code === 119) && size < 3) {\n size++;\n effects.consume(code);\n return wwwPrefixInside;\n }\n if (code === 46 && size === 3) {\n effects.consume(code);\n return wwwPrefixAfter;\n }\n return nok(code);\n }\n\n /**\n * After www prefix.\n *\n * ```markdown\n * > | www.example.com\n * ^\n * ```\n *\n * @type {State}\n */\n function wwwPrefixAfter(code) {\n // If there is *anything*, we can link.\n return code === null ? nok(code) : ok(code);\n }\n}\n\n/**\n * Domain.\n *\n * ```markdown\n * > | a https://example.org b\n * ^^^^^^^^^^^\n * ```\n *\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeDomain(effects, ok, nok) {\n /** @type {boolean | undefined} */\n let underscoreInLastSegment;\n /** @type {boolean | undefined} */\n let underscoreInLastLastSegment;\n /** @type {boolean | undefined} */\n let seen;\n return domainInside;\n\n /**\n * In domain.\n *\n * ```markdown\n * > | https://example.com/a\n * ^^^^^^^^^^^\n * ```\n *\n * @type {State}\n */\n function domainInside(code) {\n // Check whether this marker, which is a trailing punctuation\n // marker, optionally followed by more trailing markers, and then\n // followed by an end.\n if (code === 46 || code === 95) {\n return effects.check(trail, domainAfter, domainAtPunctuation)(code);\n }\n\n // GH documents that only alphanumerics (other than `-`, `.`, and `_`) can\n // occur, which sounds like ASCII only, but they also support `www.\u9EDE\u770B.com`,\n // so that\u2019s Unicode.\n // Instead of some new production for Unicode alphanumerics, markdown\n // already has that for Unicode punctuation and whitespace, so use those.\n // Source: .\n if (code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code) || code !== 45 && unicodePunctuation(code)) {\n return domainAfter(code);\n }\n seen = true;\n effects.consume(code);\n return domainInside;\n }\n\n /**\n * In domain, at potential trailing punctuation, that was not trailing.\n *\n * ```markdown\n * > | https://example.com\n * ^\n * ```\n *\n * @type {State}\n */\n function domainAtPunctuation(code) {\n // There is an underscore in the last segment of the domain\n if (code === 95) {\n underscoreInLastSegment = true;\n }\n // Otherwise, it\u2019s a `.`: save the last segment underscore in the\n // penultimate segment slot.\n else {\n underscoreInLastLastSegment = underscoreInLastSegment;\n underscoreInLastSegment = undefined;\n }\n effects.consume(code);\n return domainInside;\n }\n\n /**\n * After domain.\n *\n * ```markdown\n * > | https://example.com/a\n * ^\n * ```\n *\n * @type {State} */\n function domainAfter(code) {\n // Note: that\u2019s GH says a dot is needed, but it\u2019s not true:\n // \n if (underscoreInLastLastSegment || underscoreInLastSegment || !seen) {\n return nok(code);\n }\n return ok(code);\n }\n}\n\n/**\n * Path.\n *\n * ```markdown\n * > | a https://example.org/stuff b\n * ^^^^^^\n * ```\n *\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizePath(effects, ok) {\n let sizeOpen = 0;\n let sizeClose = 0;\n return pathInside;\n\n /**\n * In path.\n *\n * ```markdown\n * > | https://example.com/a\n * ^^\n * ```\n *\n * @type {State}\n */\n function pathInside(code) {\n if (code === 40) {\n sizeOpen++;\n effects.consume(code);\n return pathInside;\n }\n\n // To do: `markdown-rs` also needs this.\n // If this is a paren, and there are less closings than openings,\n // we don\u2019t check for a trail.\n if (code === 41 && sizeClose < sizeOpen) {\n return pathAtPunctuation(code);\n }\n\n // Check whether this trailing punctuation marker is optionally\n // followed by more trailing markers, and then followed\n // by an end.\n if (code === 33 || code === 34 || code === 38 || code === 39 || code === 41 || code === 42 || code === 44 || code === 46 || code === 58 || code === 59 || code === 60 || code === 63 || code === 93 || code === 95 || code === 126) {\n return effects.check(trail, ok, pathAtPunctuation)(code);\n }\n if (code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) {\n return ok(code);\n }\n effects.consume(code);\n return pathInside;\n }\n\n /**\n * In path, at potential trailing punctuation, that was not trailing.\n *\n * ```markdown\n * > | https://example.com/a\"b\n * ^\n * ```\n *\n * @type {State}\n */\n function pathAtPunctuation(code) {\n // Count closing parens.\n if (code === 41) {\n sizeClose++;\n }\n effects.consume(code);\n return pathInside;\n }\n}\n\n/**\n * Trail.\n *\n * This calls `ok` if this *is* the trail, followed by an end, which means\n * the entire trail is not part of the link.\n * It calls `nok` if this *is* part of the link.\n *\n * ```markdown\n * > | https://example.com\").\n * ^^^\n * ```\n *\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeTrail(effects, ok, nok) {\n return trail;\n\n /**\n * In trail of domain or path.\n *\n * ```markdown\n * > | https://example.com\").\n * ^\n * ```\n *\n * @type {State}\n */\n function trail(code) {\n // Regular trailing punctuation.\n if (code === 33 || code === 34 || code === 39 || code === 41 || code === 42 || code === 44 || code === 46 || code === 58 || code === 59 || code === 63 || code === 95 || code === 126) {\n effects.consume(code);\n return trail;\n }\n\n // `&` followed by one or more alphabeticals and then a `;`, is\n // as a whole considered as trailing punctuation.\n // In all other cases, it is considered as continuation of the URL.\n if (code === 38) {\n effects.consume(code);\n return trailCharacterReferenceStart;\n }\n\n // Needed because we allow literals after `[`, as we fix:\n // .\n // Check that it is not followed by `(` or `[`.\n if (code === 93) {\n effects.consume(code);\n return trailBracketAfter;\n }\n if (\n // `<` is an end.\n code === 60 ||\n // So is whitespace.\n code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) {\n return ok(code);\n }\n return nok(code);\n }\n\n /**\n * In trail, after `]`.\n *\n * > \uD83D\uDC49 **Note**: this deviates from `cmark-gfm` to fix a bug.\n * > See end of for more.\n *\n * ```markdown\n * > | https://example.com](\n * ^\n * ```\n *\n * @type {State}\n */\n function trailBracketAfter(code) {\n // Whitespace or something that could start a resource or reference is the end.\n // Switch back to trail otherwise.\n if (code === null || code === 40 || code === 91 || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) {\n return ok(code);\n }\n return trail(code);\n }\n\n /**\n * In character-reference like trail, after `&`.\n *\n * ```markdown\n * > | https://example.com&).\n * ^\n * ```\n *\n * @type {State}\n */\n function trailCharacterReferenceStart(code) {\n // When non-alpha, it\u2019s not a trail.\n return asciiAlpha(code) ? trailCharacterReferenceInside(code) : nok(code);\n }\n\n /**\n * In character-reference like trail.\n *\n * ```markdown\n * > | https://example.com&).\n * ^\n * ```\n *\n * @type {State}\n */\n function trailCharacterReferenceInside(code) {\n // Switch back to trail if this is well-formed.\n if (code === 59) {\n effects.consume(code);\n return trail;\n }\n if (asciiAlpha(code)) {\n effects.consume(code);\n return trailCharacterReferenceInside;\n }\n\n // It\u2019s not a trail.\n return nok(code);\n }\n}\n\n/**\n * Dot in email domain trail.\n *\n * This calls `ok` if this *is* the trail, followed by an end, which means\n * the trail is not part of the link.\n * It calls `nok` if this *is* part of the link.\n *\n * ```markdown\n * > | contact@example.org.\n * ^\n * ```\n *\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeEmailDomainDotTrail(effects, ok, nok) {\n return start;\n\n /**\n * Dot.\n *\n * ```markdown\n * > | contact@example.org.\n * ^ ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n // Must be dot.\n effects.consume(code);\n return after;\n }\n\n /**\n * After dot.\n *\n * ```markdown\n * > | contact@example.org.\n * ^ ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n // Not a trail if alphanumeric.\n return asciiAlphanumeric(code) ? nok(code) : ok(code);\n }\n}\n\n/**\n * See:\n * .\n *\n * @type {Previous}\n */\nfunction previousWww(code) {\n return code === null || code === 40 || code === 42 || code === 95 || code === 91 || code === 93 || code === 126 || markdownLineEndingOrSpace(code);\n}\n\n/**\n * See:\n * .\n *\n * @type {Previous}\n */\nfunction previousProtocol(code) {\n return !asciiAlpha(code);\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Previous}\n */\nfunction previousEmail(code) {\n // Do not allow a slash \u201Cinside\u201D atext.\n // The reference code is a bit weird, but that\u2019s what it results in.\n // Source: .\n // Other than slash, every preceding character is allowed.\n return !(code === 47 || gfmAtext(code));\n}\n\n/**\n * @param {Code} code\n * @returns {boolean}\n */\nfunction gfmAtext(code) {\n return code === 43 || code === 45 || code === 46 || code === 95 || asciiAlphanumeric(code);\n}\n\n/**\n * @param {Array} events\n * @returns {boolean}\n */\nfunction previousUnbalanced(events) {\n let index = events.length;\n let result = false;\n while (index--) {\n const token = events[index][1];\n if ((token.type === 'labelLink' || token.type === 'labelImage') && !token._balanced) {\n result = true;\n break;\n }\n\n // If we\u2019ve seen this token, and it was marked as not having any unbalanced\n // bracket before it, we can exit.\n if (token._gfmAutolinkLiteralWalkedInto) {\n result = false;\n break;\n }\n }\n if (events.length > 0 && !result) {\n // Mark the last token as \u201Cwalked into\u201D w/o finding\n // anything.\n events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true;\n }\n return result;\n}", "export { gfmAutolinkLiteral } from './lib/syntax.js';\nexport { gfmAutolinkLiteralHtml } from './lib/html.js';", "/**\n * @import {Event, Exiter, Extension, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { blankLine } from 'micromark-core-commonmark';\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEndingOrSpace } from 'micromark-util-character';\nimport { normalizeIdentifier } from 'micromark-util-normalize-identifier';\nconst indent = {\n tokenize: tokenizeIndent,\n partial: true\n};\n\n// To do: micromark should support a `_hiddenGfmFootnoteSupport`, which only\n// affects label start (image).\n// That will let us drop `tokenizePotentialGfmFootnote*`.\n// It currently has a `_hiddenFootnoteSupport`, which affects that and more.\n// That can be removed when `micromark-extension-footnote` is archived.\n\n/**\n * Create an extension for `micromark` to enable GFM footnote syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions` to\n * enable GFM footnote syntax.\n */\nexport function gfmFootnote() {\n /** @type {Extension} */\n return {\n document: {\n [91]: {\n name: 'gfmFootnoteDefinition',\n tokenize: tokenizeDefinitionStart,\n continuation: {\n tokenize: tokenizeDefinitionContinuation\n },\n exit: gfmFootnoteDefinitionEnd\n }\n },\n text: {\n [91]: {\n name: 'gfmFootnoteCall',\n tokenize: tokenizeGfmFootnoteCall\n },\n [93]: {\n name: 'gfmPotentialFootnoteCall',\n add: 'after',\n tokenize: tokenizePotentialGfmFootnoteCall,\n resolveTo: resolveToPotentialGfmFootnoteCall\n }\n }\n };\n}\n\n// To do: remove after micromark update.\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizePotentialGfmFootnoteCall(effects, ok, nok) {\n const self = this;\n let index = self.events.length;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n /** @type {Token} */\n let labelStart;\n\n // Find an opening.\n while (index--) {\n const token = self.events[index][1];\n if (token.type === \"labelImage\") {\n labelStart = token;\n break;\n }\n\n // Exit if we\u2019ve walked far enough.\n if (token.type === 'gfmFootnoteCall' || token.type === \"labelLink\" || token.type === \"label\" || token.type === \"image\" || token.type === \"link\") {\n break;\n }\n }\n return start;\n\n /**\n * @type {State}\n */\n function start(code) {\n if (!labelStart || !labelStart._balanced) {\n return nok(code);\n }\n const id = normalizeIdentifier(self.sliceSerialize({\n start: labelStart.end,\n end: self.now()\n }));\n if (id.codePointAt(0) !== 94 || !defined.includes(id.slice(1))) {\n return nok(code);\n }\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n return ok(code);\n }\n}\n\n// To do: remove after micromark update.\n/** @type {Resolver} */\nfunction resolveToPotentialGfmFootnoteCall(events, context) {\n let index = events.length;\n /** @type {Token | undefined} */\n let labelStart;\n\n // Find an opening.\n while (index--) {\n if (events[index][1].type === \"labelImage\" && events[index][0] === 'enter') {\n labelStart = events[index][1];\n break;\n }\n }\n // Change the `labelImageMarker` to a `data`.\n events[index + 1][1].type = \"data\";\n events[index + 3][1].type = 'gfmFootnoteCallLabelMarker';\n\n // The whole (without `!`):\n /** @type {Token} */\n const call = {\n type: 'gfmFootnoteCall',\n start: Object.assign({}, events[index + 3][1].start),\n end: Object.assign({}, events[events.length - 1][1].end)\n };\n // The `^` marker\n /** @type {Token} */\n const marker = {\n type: 'gfmFootnoteCallMarker',\n start: Object.assign({}, events[index + 3][1].end),\n end: Object.assign({}, events[index + 3][1].end)\n };\n // Increment the end 1 character.\n marker.end.column++;\n marker.end.offset++;\n marker.end._bufferIndex++;\n /** @type {Token} */\n const string = {\n type: 'gfmFootnoteCallString',\n start: Object.assign({}, marker.end),\n end: Object.assign({}, events[events.length - 1][1].start)\n };\n /** @type {Token} */\n const chunk = {\n type: \"chunkString\",\n contentType: 'string',\n start: Object.assign({}, string.start),\n end: Object.assign({}, string.end)\n };\n\n /** @type {Array} */\n const replacement = [\n // Take the `labelImageMarker` (now `data`, the `!`)\n events[index + 1], events[index + 2], ['enter', call, context],\n // The `[`\n events[index + 3], events[index + 4],\n // The `^`.\n ['enter', marker, context], ['exit', marker, context],\n // Everything in between.\n ['enter', string, context], ['enter', chunk, context], ['exit', chunk, context], ['exit', string, context],\n // The ending (`]`, properly parsed and labelled).\n events[events.length - 2], events[events.length - 1], ['exit', call, context]];\n events.splice(index, events.length - index + 1, ...replacement);\n return events;\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeGfmFootnoteCall(effects, ok, nok) {\n const self = this;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n let size = 0;\n /** @type {boolean} */\n let data;\n\n // Note: the implementation of `markdown-rs` is different, because it houses\n // core *and* extensions in one project.\n // Therefore, it can include footnote logic inside `label-end`.\n // We can\u2019t do that, but luckily, we can parse footnotes in a simpler way than\n // needed for labels.\n return start;\n\n /**\n * Start of footnote label.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter('gfmFootnoteCall');\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n return callStart;\n }\n\n /**\n * After `[`, at `^`.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function callStart(code) {\n if (code !== 94) return nok(code);\n effects.enter('gfmFootnoteCallMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallMarker');\n effects.enter('gfmFootnoteCallString');\n effects.enter('chunkString').contentType = 'string';\n return callData;\n }\n\n /**\n * In label.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function callData(code) {\n if (\n // Too long.\n size > 999 ||\n // Closing brace with nothing.\n code === 93 && !data ||\n // Space or tab is not supported by GFM for some reason.\n // `\\n` and `[` not being supported makes sense.\n code === null || code === 91 || markdownLineEndingOrSpace(code)) {\n return nok(code);\n }\n if (code === 93) {\n effects.exit('chunkString');\n const token = effects.exit('gfmFootnoteCallString');\n if (!defined.includes(normalizeIdentifier(self.sliceSerialize(token)))) {\n return nok(code);\n }\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n effects.exit('gfmFootnoteCall');\n return ok;\n }\n if (!markdownLineEndingOrSpace(code)) {\n data = true;\n }\n size++;\n effects.consume(code);\n return code === 92 ? callEscape : callData;\n }\n\n /**\n * On character after escape.\n *\n * ```markdown\n * > | a [^b\\c] d\n * ^\n * ```\n *\n * @type {State}\n */\n function callEscape(code) {\n if (code === 91 || code === 92 || code === 93) {\n effects.consume(code);\n size++;\n return callData;\n }\n return callData(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeDefinitionStart(effects, ok, nok) {\n const self = this;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n /** @type {string} */\n let identifier;\n let size = 0;\n /** @type {boolean | undefined} */\n let data;\n return start;\n\n /**\n * Start of GFM footnote definition.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter('gfmFootnoteDefinition')._container = true;\n effects.enter('gfmFootnoteDefinitionLabel');\n effects.enter('gfmFootnoteDefinitionLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionLabelMarker');\n return labelAtMarker;\n }\n\n /**\n * In label, at caret.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelAtMarker(code) {\n if (code === 94) {\n effects.enter('gfmFootnoteDefinitionMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionMarker');\n effects.enter('gfmFootnoteDefinitionLabelString');\n effects.enter('chunkString').contentType = 'string';\n return labelInside;\n }\n return nok(code);\n }\n\n /**\n * In label.\n *\n * > \uD83D\uDC49 **Note**: `cmark-gfm` prevents whitespace from occurring in footnote\n * > definition labels.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelInside(code) {\n if (\n // Too long.\n size > 999 ||\n // Closing brace with nothing.\n code === 93 && !data ||\n // Space or tab is not supported by GFM for some reason.\n // `\\n` and `[` not being supported makes sense.\n code === null || code === 91 || markdownLineEndingOrSpace(code)) {\n return nok(code);\n }\n if (code === 93) {\n effects.exit('chunkString');\n const token = effects.exit('gfmFootnoteDefinitionLabelString');\n identifier = normalizeIdentifier(self.sliceSerialize(token));\n effects.enter('gfmFootnoteDefinitionLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionLabelMarker');\n effects.exit('gfmFootnoteDefinitionLabel');\n return labelAfter;\n }\n if (!markdownLineEndingOrSpace(code)) {\n data = true;\n }\n size++;\n effects.consume(code);\n return code === 92 ? labelEscape : labelInside;\n }\n\n /**\n * After `\\`, at a special character.\n *\n * > \uD83D\uDC49 **Note**: `cmark-gfm` currently does not support escaped brackets:\n * > \n *\n * ```markdown\n * > | [^a\\*b]: c\n * ^\n * ```\n *\n * @type {State}\n */\n function labelEscape(code) {\n if (code === 91 || code === 92 || code === 93) {\n effects.consume(code);\n size++;\n return labelInside;\n }\n return labelInside(code);\n }\n\n /**\n * After definition label.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelAfter(code) {\n if (code === 58) {\n effects.enter('definitionMarker');\n effects.consume(code);\n effects.exit('definitionMarker');\n if (!defined.includes(identifier)) {\n defined.push(identifier);\n }\n\n // Any whitespace after the marker is eaten, forming indented code\n // is not possible.\n // No space is also fine, just like a block quote marker.\n return factorySpace(effects, whitespaceAfter, 'gfmFootnoteDefinitionWhitespace');\n }\n return nok(code);\n }\n\n /**\n * After definition prefix.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function whitespaceAfter(code) {\n // `markdown-rs` has a wrapping token for the prefix that is closed here.\n return ok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeDefinitionContinuation(effects, ok, nok) {\n /// Start of footnote definition continuation.\n ///\n /// ```markdown\n /// | [^a]: b\n /// > | c\n /// ^\n /// ```\n //\n // Either a blank line, which is okay, or an indented thing.\n return effects.check(blankLine, ok, effects.attempt(indent, ok, nok));\n}\n\n/** @type {Exiter} */\nfunction gfmFootnoteDefinitionEnd(effects) {\n effects.exit('gfmFootnoteDefinition');\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeIndent(effects, ok, nok) {\n const self = this;\n return factorySpace(effects, afterPrefix, 'gfmFootnoteDefinitionIndent', 4 + 1);\n\n /**\n * @type {State}\n */\n function afterPrefix(code) {\n const tail = self.events[self.events.length - 1];\n return tail && tail[1].type === 'gfmFootnoteDefinitionIndent' && tail[2].sliceSerialize(tail[1], true).length === 4 ? ok(code) : nok(code);\n }\n}", "// Note: types are exported from `dev/index.d.ts`.\nexport { gfmFootnote } from './lib/syntax.js';\nexport { gfmFootnoteHtml, defaultBackLabel } from './lib/html.js';", "/**\n * @import {Options} from 'micromark-extension-gfm-strikethrough'\n * @import {Event, Extension, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { splice } from 'micromark-util-chunked';\nimport { classifyCharacter } from 'micromark-util-classify-character';\nimport { resolveAll } from 'micromark-util-resolve-all';\n/**\n * Create an extension for `micromark` to enable GFM strikethrough syntax.\n *\n * @param {Options | null | undefined} [options={}]\n * Configuration.\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions`, to\n * enable GFM strikethrough syntax.\n */\nexport function gfmStrikethrough(options) {\n const options_ = options || {};\n let single = options_.singleTilde;\n const tokenizer = {\n name: 'strikethrough',\n tokenize: tokenizeStrikethrough,\n resolveAll: resolveAllStrikethrough\n };\n if (single === null || single === undefined) {\n single = true;\n }\n return {\n text: {\n [126]: tokenizer\n },\n insideSpan: {\n null: [tokenizer]\n },\n attentionMarkers: {\n null: [126]\n }\n };\n\n /**\n * Take events and resolve strikethrough.\n *\n * @type {Resolver}\n */\n function resolveAllStrikethrough(events, context) {\n let index = -1;\n\n // Walk through all events.\n while (++index < events.length) {\n // Find a token that can close.\n if (events[index][0] === 'enter' && events[index][1].type === 'strikethroughSequenceTemporary' && events[index][1]._close) {\n let open = index;\n\n // Now walk back to find an opener.\n while (open--) {\n // Find a token that can open the closer.\n if (events[open][0] === 'exit' && events[open][1].type === 'strikethroughSequenceTemporary' && events[open][1]._open &&\n // If the sizes are the same:\n events[index][1].end.offset - events[index][1].start.offset === events[open][1].end.offset - events[open][1].start.offset) {\n events[index][1].type = 'strikethroughSequence';\n events[open][1].type = 'strikethroughSequence';\n\n /** @type {Token} */\n const strikethrough = {\n type: 'strikethrough',\n start: Object.assign({}, events[open][1].start),\n end: Object.assign({}, events[index][1].end)\n };\n\n /** @type {Token} */\n const text = {\n type: 'strikethroughText',\n start: Object.assign({}, events[open][1].end),\n end: Object.assign({}, events[index][1].start)\n };\n\n // Opening.\n /** @type {Array} */\n const nextEvents = [['enter', strikethrough, context], ['enter', events[open][1], context], ['exit', events[open][1], context], ['enter', text, context]];\n const insideSpan = context.parser.constructs.insideSpan.null;\n if (insideSpan) {\n // Between.\n splice(nextEvents, nextEvents.length, 0, resolveAll(insideSpan, events.slice(open + 1, index), context));\n }\n\n // Closing.\n splice(nextEvents, nextEvents.length, 0, [['exit', text, context], ['enter', events[index][1], context], ['exit', events[index][1], context], ['exit', strikethrough, context]]);\n splice(events, open - 1, index - open + 3, nextEvents);\n index = open + nextEvents.length - 2;\n break;\n }\n }\n }\n }\n index = -1;\n while (++index < events.length) {\n if (events[index][1].type === 'strikethroughSequenceTemporary') {\n events[index][1].type = \"data\";\n }\n }\n return events;\n }\n\n /**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\n function tokenizeStrikethrough(effects, ok, nok) {\n const previous = this.previous;\n const events = this.events;\n let size = 0;\n return start;\n\n /** @type {State} */\n function start(code) {\n if (previous === 126 && events[events.length - 1][1].type !== \"characterEscape\") {\n return nok(code);\n }\n effects.enter('strikethroughSequenceTemporary');\n return more(code);\n }\n\n /** @type {State} */\n function more(code) {\n const before = classifyCharacter(previous);\n if (code === 126) {\n // If this is the third marker, exit.\n if (size > 1) return nok(code);\n effects.consume(code);\n size++;\n return more;\n }\n if (size < 2 && !single) return nok(code);\n const token = effects.exit('strikethroughSequenceTemporary');\n const after = classifyCharacter(code);\n token._open = !after || after === 2 && Boolean(before);\n token._close = !before || before === 2 && Boolean(after);\n return ok(code);\n }\n }\n}", "// Note: more types exposed from `index.d.ts`.\nexport { gfmStrikethroughHtml } from './lib/html.js';\nexport { gfmStrikethrough } from './lib/syntax.js';", "/**\n * @import {Event} from 'micromark-util-types'\n */\n\n// Port of `edit_map.rs` from `markdown-rs`.\n// This should move to `markdown-js` later.\n\n// Deal with several changes in events, batching them together.\n//\n// Preferably, changes should be kept to a minimum.\n// Sometimes, it\u2019s needed to change the list of events, because parsing can be\n// messy, and it helps to expose a cleaner interface of events to the compiler\n// and other users.\n// It can also help to merge many adjacent similar events.\n// And, in other cases, it\u2019s needed to parse subcontent: pass some events\n// through another tokenizer and inject the result.\n\n/**\n * @typedef {[number, number, Array]} Change\n * @typedef {[number, number, number]} Jump\n */\n\n/**\n * Tracks a bunch of edits.\n */\nexport class EditMap {\n /**\n * Create a new edit map.\n */\n constructor() {\n /**\n * Record of changes.\n *\n * @type {Array}\n */\n this.map = [];\n }\n\n /**\n * Create an edit: a remove and/or add at a certain place.\n *\n * @param {number} index\n * @param {number} remove\n * @param {Array} add\n * @returns {undefined}\n */\n add(index, remove, add) {\n addImplementation(this, index, remove, add);\n }\n\n // To do: add this when moving to `micromark`.\n // /**\n // * Create an edit: but insert `add` before existing additions.\n // *\n // * @param {number} index\n // * @param {number} remove\n // * @param {Array} add\n // * @returns {undefined}\n // */\n // addBefore(index, remove, add) {\n // addImplementation(this, index, remove, add, true)\n // }\n\n /**\n * Done, change the events.\n *\n * @param {Array} events\n * @returns {undefined}\n */\n consume(events) {\n this.map.sort(function (a, b) {\n return a[0] - b[0];\n });\n\n /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */\n if (this.map.length === 0) {\n return;\n }\n\n // To do: if links are added in events, like they are in `markdown-rs`,\n // this is needed.\n // // Calculate jumps: where items in the current list move to.\n // /** @type {Array} */\n // const jumps = []\n // let index = 0\n // let addAcc = 0\n // let removeAcc = 0\n // while (index < this.map.length) {\n // const [at, remove, add] = this.map[index]\n // removeAcc += remove\n // addAcc += add.length\n // jumps.push([at, removeAcc, addAcc])\n // index += 1\n // }\n //\n // . shiftLinks(events, jumps)\n\n let index = this.map.length;\n /** @type {Array>} */\n const vecs = [];\n while (index > 0) {\n index -= 1;\n vecs.push(events.slice(this.map[index][0] + this.map[index][1]), this.map[index][2]);\n\n // Truncate rest.\n events.length = this.map[index][0];\n }\n vecs.push(events.slice());\n events.length = 0;\n let slice = vecs.pop();\n while (slice) {\n for (const element of slice) {\n events.push(element);\n }\n slice = vecs.pop();\n }\n\n // Truncate everything.\n this.map.length = 0;\n }\n}\n\n/**\n * Create an edit.\n *\n * @param {EditMap} editMap\n * @param {number} at\n * @param {number} remove\n * @param {Array} add\n * @returns {undefined}\n */\nfunction addImplementation(editMap, at, remove, add) {\n let index = 0;\n\n /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */\n if (remove === 0 && add.length === 0) {\n return;\n }\n while (index < editMap.map.length) {\n if (editMap.map[index][0] === at) {\n editMap.map[index][1] += remove;\n\n // To do: before not used by tables, use when moving to micromark.\n // if (before) {\n // add.push(...editMap.map[index][2])\n // editMap.map[index][2] = add\n // } else {\n editMap.map[index][2].push(...add);\n // }\n\n return;\n }\n index += 1;\n }\n editMap.map.push([at, remove, add]);\n}\n\n// /**\n// * Shift `previous` and `next` links according to `jumps`.\n// *\n// * This fixes links in case there are events removed or added between them.\n// *\n// * @param {Array} events\n// * @param {Array} jumps\n// */\n// function shiftLinks(events, jumps) {\n// let jumpIndex = 0\n// let index = 0\n// let add = 0\n// let rm = 0\n\n// while (index < events.length) {\n// const rmCurr = rm\n\n// while (jumpIndex < jumps.length && jumps[jumpIndex][0] <= index) {\n// add = jumps[jumpIndex][2]\n// rm = jumps[jumpIndex][1]\n// jumpIndex += 1\n// }\n\n// // Ignore items that will be removed.\n// if (rm > rmCurr) {\n// index += rm - rmCurr\n// } else {\n// // ?\n// // if let Some(link) = &events[index].link {\n// // if let Some(next) = link.next {\n// // events[next].link.as_mut().unwrap().previous = Some(index + add - rm);\n// // while jumpIndex < jumps.len() && jumps[jumpIndex].0 <= next {\n// // add = jumps[jumpIndex].2;\n// // rm = jumps[jumpIndex].1;\n// // jumpIndex += 1;\n// // }\n// // events[index].link.as_mut().unwrap().next = Some(next + add - rm);\n// // index = next;\n// // continue;\n// // }\n// // }\n// index += 1\n// }\n// }\n// }", "/**\n * @import {Event} from 'micromark-util-types'\n */\n\n/**\n * @typedef {'center' | 'left' | 'none' | 'right'} Align\n */\n\n/**\n * Figure out the alignment of a GFM table.\n *\n * @param {Readonly>} events\n * List of events.\n * @param {number} index\n * Table enter event.\n * @returns {Array}\n * List of aligns.\n */\nexport function gfmTableAlign(events, index) {\n let inDelimiterRow = false;\n /** @type {Array} */\n const align = [];\n while (index < events.length) {\n const event = events[index];\n if (inDelimiterRow) {\n if (event[0] === 'enter') {\n // Start of alignment value: set a new column.\n // To do: `markdown-rs` uses `tableDelimiterCellValue`.\n if (event[1].type === 'tableContent') {\n align.push(events[index + 1][1].type === 'tableDelimiterMarker' ? 'left' : 'none');\n }\n }\n // Exits:\n // End of alignment value: change the column.\n // To do: `markdown-rs` uses `tableDelimiterCellValue`.\n else if (event[1].type === 'tableContent') {\n if (events[index - 1][1].type === 'tableDelimiterMarker') {\n const alignIndex = align.length - 1;\n align[alignIndex] = align[alignIndex] === 'left' ? 'center' : 'right';\n }\n }\n // Done!\n else if (event[1].type === 'tableDelimiterRow') {\n break;\n }\n } else if (event[0] === 'enter' && event[1].type === 'tableDelimiterRow') {\n inDelimiterRow = true;\n }\n index += 1;\n }\n return align;\n}", "/**\n * @import {Event, Extension, Point, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\n/**\n * @typedef {[number, number, number, number]} Range\n * Cell info.\n *\n * @typedef {0 | 1 | 2 | 3} RowKind\n * Where we are: `1` for head row, `2` for delimiter row, `3` for body row.\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownLineEndingOrSpace, markdownSpace } from 'micromark-util-character';\nimport { EditMap } from './edit-map.js';\nimport { gfmTableAlign } from './infer.js';\n\n/**\n * Create an HTML extension for `micromark` to support GitHub tables syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions` to enable GFM\n * table syntax.\n */\nexport function gfmTable() {\n return {\n flow: {\n null: {\n name: 'table',\n tokenize: tokenizeTable,\n resolveAll: resolveTable\n }\n }\n };\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeTable(effects, ok, nok) {\n const self = this;\n let size = 0;\n let sizeB = 0;\n /** @type {boolean | undefined} */\n let seen;\n return start;\n\n /**\n * Start of a GFM table.\n *\n * If there is a valid table row or table head before, then we try to parse\n * another row.\n * Otherwise, we try to parse a head.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * > | | b |\n * ^\n * ```\n * @type {State}\n */\n function start(code) {\n let index = self.events.length - 1;\n while (index > -1) {\n const type = self.events[index][1].type;\n if (type === \"lineEnding\" ||\n // Note: markdown-rs uses `whitespace` instead of `linePrefix`\n type === \"linePrefix\") index--;else break;\n }\n const tail = index > -1 ? self.events[index][1].type : null;\n const next = tail === 'tableHead' || tail === 'tableRow' ? bodyRowStart : headRowBefore;\n\n // Don\u2019t allow lazy body rows.\n if (next === bodyRowStart && self.parser.lazy[self.now().line]) {\n return nok(code);\n }\n return next(code);\n }\n\n /**\n * Before table head row.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowBefore(code) {\n effects.enter('tableHead');\n effects.enter('tableRow');\n return headRowStart(code);\n }\n\n /**\n * Before table head row, after whitespace.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowStart(code) {\n if (code === 124) {\n return headRowBreak(code);\n }\n\n // To do: micromark-js should let us parse our own whitespace in extensions,\n // like `markdown-rs`:\n //\n // ```js\n // // 4+ spaces.\n // if (markdownSpace(code)) {\n // return nok(code)\n // }\n // ```\n\n seen = true;\n // Count the first character, that isn\u2019t a pipe, double.\n sizeB += 1;\n return headRowBreak(code);\n }\n\n /**\n * At break in table head row.\n *\n * ```markdown\n * > | | a |\n * ^\n * ^\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowBreak(code) {\n if (code === null) {\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don\u2018t.\n return nok(code);\n }\n if (markdownLineEnding(code)) {\n // If anything other than one pipe (ignoring whitespace) was used, it\u2019s fine.\n if (sizeB > 1) {\n sizeB = 0;\n // To do: check if this works.\n // Feel free to interrupt:\n self.interrupt = true;\n effects.exit('tableRow');\n effects.enter(\"lineEnding\");\n effects.consume(code);\n effects.exit(\"lineEnding\");\n return headDelimiterStart;\n }\n\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don\u2018t.\n return nok(code);\n }\n if (markdownSpace(code)) {\n // To do: check if this is fine.\n // effects.attempt(State::Next(StateName::GfmTableHeadRowBreak), State::Nok)\n // State::Retry(space_or_tab(tokenizer))\n return factorySpace(effects, headRowBreak, \"whitespace\")(code);\n }\n sizeB += 1;\n if (seen) {\n seen = false;\n // Header cell count.\n size += 1;\n }\n if (code === 124) {\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n // Whether a delimiter was seen.\n seen = true;\n return headRowBreak;\n }\n\n // Anything else is cell data.\n effects.enter(\"data\");\n return headRowData(code);\n }\n\n /**\n * In table head row data.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowData(code) {\n if (code === null || code === 124 || markdownLineEndingOrSpace(code)) {\n effects.exit(\"data\");\n return headRowBreak(code);\n }\n effects.consume(code);\n return code === 92 ? headRowEscape : headRowData;\n }\n\n /**\n * In table head row escape.\n *\n * ```markdown\n * > | | a\\-b |\n * ^\n * | | ---- |\n * | | c |\n * ```\n *\n * @type {State}\n */\n function headRowEscape(code) {\n if (code === 92 || code === 124) {\n effects.consume(code);\n return headRowData;\n }\n return headRowData(code);\n }\n\n /**\n * Before delimiter row.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headDelimiterStart(code) {\n // Reset `interrupt`.\n self.interrupt = false;\n\n // Note: in `markdown-rs`, we need to handle piercing here too.\n if (self.parser.lazy[self.now().line]) {\n return nok(code);\n }\n effects.enter('tableDelimiterRow');\n // Track if we\u2019ve seen a `:` or `|`.\n seen = false;\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterBefore, \"linePrefix\", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code);\n }\n return headDelimiterBefore(code);\n }\n\n /**\n * Before delimiter row, after optional whitespace.\n *\n * Reused when a `|` is found later, to parse another cell.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headDelimiterBefore(code) {\n if (code === 45 || code === 58) {\n return headDelimiterValueBefore(code);\n }\n if (code === 124) {\n seen = true;\n // If we start with a pipe, we open a cell marker.\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n return headDelimiterCellBefore;\n }\n\n // More whitespace / empty row not allowed at start.\n return headDelimiterNok(code);\n }\n\n /**\n * After `|`, before delimiter cell.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterCellBefore(code) {\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterValueBefore, \"whitespace\")(code);\n }\n return headDelimiterValueBefore(code);\n }\n\n /**\n * Before delimiter cell value.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterValueBefore(code) {\n // Align: left.\n if (code === 58) {\n sizeB += 1;\n seen = true;\n effects.enter('tableDelimiterMarker');\n effects.consume(code);\n effects.exit('tableDelimiterMarker');\n return headDelimiterLeftAlignmentAfter;\n }\n\n // Align: none.\n if (code === 45) {\n sizeB += 1;\n // To do: seems weird that this *isn\u2019t* left aligned, but that state is used?\n return headDelimiterLeftAlignmentAfter(code);\n }\n if (code === null || markdownLineEnding(code)) {\n return headDelimiterCellAfter(code);\n }\n return headDelimiterNok(code);\n }\n\n /**\n * After delimiter cell left alignment marker.\n *\n * ```markdown\n * | | a |\n * > | | :- |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterLeftAlignmentAfter(code) {\n if (code === 45) {\n effects.enter('tableDelimiterFiller');\n return headDelimiterFiller(code);\n }\n\n // Anything else is not ok after the left-align colon.\n return headDelimiterNok(code);\n }\n\n /**\n * In delimiter cell filler.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterFiller(code) {\n if (code === 45) {\n effects.consume(code);\n return headDelimiterFiller;\n }\n\n // Align is `center` if it was `left`, `right` otherwise.\n if (code === 58) {\n seen = true;\n effects.exit('tableDelimiterFiller');\n effects.enter('tableDelimiterMarker');\n effects.consume(code);\n effects.exit('tableDelimiterMarker');\n return headDelimiterRightAlignmentAfter;\n }\n effects.exit('tableDelimiterFiller');\n return headDelimiterRightAlignmentAfter(code);\n }\n\n /**\n * After delimiter cell right alignment marker.\n *\n * ```markdown\n * | | a |\n * > | | -: |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterRightAlignmentAfter(code) {\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterCellAfter, \"whitespace\")(code);\n }\n return headDelimiterCellAfter(code);\n }\n\n /**\n * After delimiter cell.\n *\n * ```markdown\n * | | a |\n * > | | -: |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterCellAfter(code) {\n if (code === 124) {\n return headDelimiterBefore(code);\n }\n if (code === null || markdownLineEnding(code)) {\n // Exit when:\n // * there was no `:` or `|` at all (it\u2019s a thematic break or setext\n // underline instead)\n // * the header cell count is not the delimiter cell count\n if (!seen || size !== sizeB) {\n return headDelimiterNok(code);\n }\n\n // Note: in markdown-rs`, a reset is needed here.\n effects.exit('tableDelimiterRow');\n effects.exit('tableHead');\n // To do: in `markdown-rs`, resolvers need to be registered manually.\n // effects.register_resolver(ResolveName::GfmTable)\n return ok(code);\n }\n return headDelimiterNok(code);\n }\n\n /**\n * In delimiter row, at a disallowed byte.\n *\n * ```markdown\n * | | a |\n * > | | x |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterNok(code) {\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don\u2018t.\n return nok(code);\n }\n\n /**\n * Before table body row.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowStart(code) {\n // Note: in `markdown-rs` we need to manually take care of a prefix,\n // but in `micromark-js` that is done for us, so if we\u2019re here, we\u2019re\n // never at whitespace.\n effects.enter('tableRow');\n return bodyRowBreak(code);\n }\n\n /**\n * At break in table body row.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ^\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowBreak(code) {\n if (code === 124) {\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n return bodyRowBreak;\n }\n if (code === null || markdownLineEnding(code)) {\n effects.exit('tableRow');\n return ok(code);\n }\n if (markdownSpace(code)) {\n return factorySpace(effects, bodyRowBreak, \"whitespace\")(code);\n }\n\n // Anything else is cell content.\n effects.enter(\"data\");\n return bodyRowData(code);\n }\n\n /**\n * In table body row data.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowData(code) {\n if (code === null || code === 124 || markdownLineEndingOrSpace(code)) {\n effects.exit(\"data\");\n return bodyRowBreak(code);\n }\n effects.consume(code);\n return code === 92 ? bodyRowEscape : bodyRowData;\n }\n\n /**\n * In table body row escape.\n *\n * ```markdown\n * | | a |\n * | | ---- |\n * > | | b\\-c |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowEscape(code) {\n if (code === 92 || code === 124) {\n effects.consume(code);\n return bodyRowData;\n }\n return bodyRowData(code);\n }\n}\n\n/** @type {Resolver} */\n\nfunction resolveTable(events, context) {\n let index = -1;\n let inFirstCellAwaitingPipe = true;\n /** @type {RowKind} */\n let rowKind = 0;\n /** @type {Range} */\n let lastCell = [0, 0, 0, 0];\n /** @type {Range} */\n let cell = [0, 0, 0, 0];\n let afterHeadAwaitingFirstBodyRow = false;\n let lastTableEnd = 0;\n /** @type {Token | undefined} */\n let currentTable;\n /** @type {Token | undefined} */\n let currentBody;\n /** @type {Token | undefined} */\n let currentCell;\n const map = new EditMap();\n while (++index < events.length) {\n const event = events[index];\n const token = event[1];\n if (event[0] === 'enter') {\n // Start of head.\n if (token.type === 'tableHead') {\n afterHeadAwaitingFirstBodyRow = false;\n\n // Inject previous (body end and) table end.\n if (lastTableEnd !== 0) {\n flushTableEnd(map, context, lastTableEnd, currentTable, currentBody);\n currentBody = undefined;\n lastTableEnd = 0;\n }\n\n // Inject table start.\n currentTable = {\n type: 'table',\n start: Object.assign({}, token.start),\n // Note: correct end is set later.\n end: Object.assign({}, token.end)\n };\n map.add(index, 0, [['enter', currentTable, context]]);\n } else if (token.type === 'tableRow' || token.type === 'tableDelimiterRow') {\n inFirstCellAwaitingPipe = true;\n currentCell = undefined;\n lastCell = [0, 0, 0, 0];\n cell = [0, index + 1, 0, 0];\n\n // Inject table body start.\n if (afterHeadAwaitingFirstBodyRow) {\n afterHeadAwaitingFirstBodyRow = false;\n currentBody = {\n type: 'tableBody',\n start: Object.assign({}, token.start),\n // Note: correct end is set later.\n end: Object.assign({}, token.end)\n };\n map.add(index, 0, [['enter', currentBody, context]]);\n }\n rowKind = token.type === 'tableDelimiterRow' ? 2 : currentBody ? 3 : 1;\n }\n // Cell data.\n else if (rowKind && (token.type === \"data\" || token.type === 'tableDelimiterMarker' || token.type === 'tableDelimiterFiller')) {\n inFirstCellAwaitingPipe = false;\n\n // First value in cell.\n if (cell[2] === 0) {\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, undefined, currentCell);\n lastCell = [0, 0, 0, 0];\n }\n cell[2] = index;\n }\n } else if (token.type === 'tableCellDivider') {\n if (inFirstCellAwaitingPipe) {\n inFirstCellAwaitingPipe = false;\n } else {\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, undefined, currentCell);\n }\n lastCell = cell;\n cell = [lastCell[1], index, 0, 0];\n }\n }\n }\n // Exit events.\n else if (token.type === 'tableHead') {\n afterHeadAwaitingFirstBodyRow = true;\n lastTableEnd = index;\n } else if (token.type === 'tableRow' || token.type === 'tableDelimiterRow') {\n lastTableEnd = index;\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, index, currentCell);\n } else if (cell[1] !== 0) {\n currentCell = flushCell(map, context, cell, rowKind, index, currentCell);\n }\n rowKind = 0;\n } else if (rowKind && (token.type === \"data\" || token.type === 'tableDelimiterMarker' || token.type === 'tableDelimiterFiller')) {\n cell[3] = index;\n }\n }\n if (lastTableEnd !== 0) {\n flushTableEnd(map, context, lastTableEnd, currentTable, currentBody);\n }\n map.consume(context.events);\n\n // To do: move this into `html`, when events are exposed there.\n // That\u2019s what `markdown-rs` does.\n // That needs updates to `mdast-util-gfm-table`.\n index = -1;\n while (++index < context.events.length) {\n const event = context.events[index];\n if (event[0] === 'enter' && event[1].type === 'table') {\n event[1]._align = gfmTableAlign(context.events, index);\n }\n }\n return events;\n}\n\n/**\n * Generate a cell.\n *\n * @param {EditMap} map\n * @param {Readonly} context\n * @param {Readonly} range\n * @param {RowKind} rowKind\n * @param {number | undefined} rowEnd\n * @param {Token | undefined} previousCell\n * @returns {Token | undefined}\n */\n// eslint-disable-next-line max-params\nfunction flushCell(map, context, range, rowKind, rowEnd, previousCell) {\n // `markdown-rs` uses:\n // rowKind === 2 ? 'tableDelimiterCell' : 'tableCell'\n const groupName = rowKind === 1 ? 'tableHeader' : rowKind === 2 ? 'tableDelimiter' : 'tableData';\n // `markdown-rs` uses:\n // rowKind === 2 ? 'tableDelimiterCellValue' : 'tableCellText'\n const valueName = 'tableContent';\n\n // Insert an exit for the previous cell, if there is one.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- exit\n // ^^^^-- this cell\n // ```\n if (range[0] !== 0) {\n previousCell.end = Object.assign({}, getPoint(context.events, range[0]));\n map.add(range[0], 0, [['exit', previousCell, context]]);\n }\n\n // Insert enter of this cell.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- enter\n // ^^^^-- this cell\n // ```\n const now = getPoint(context.events, range[1]);\n previousCell = {\n type: groupName,\n start: Object.assign({}, now),\n // Note: correct end is set later.\n end: Object.assign({}, now)\n };\n map.add(range[1], 0, [['enter', previousCell, context]]);\n\n // Insert text start at first data start and end at last data end, and\n // remove events between.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- enter\n // ^-- exit\n // ^^^^-- this cell\n // ```\n if (range[2] !== 0) {\n const relatedStart = getPoint(context.events, range[2]);\n const relatedEnd = getPoint(context.events, range[3]);\n /** @type {Token} */\n const valueToken = {\n type: valueName,\n start: Object.assign({}, relatedStart),\n end: Object.assign({}, relatedEnd)\n };\n map.add(range[2], 0, [['enter', valueToken, context]]);\n if (rowKind !== 2) {\n // Fix positional info on remaining events\n const start = context.events[range[2]];\n const end = context.events[range[3]];\n start[1].end = Object.assign({}, end[1].end);\n start[1].type = \"chunkText\";\n start[1].contentType = \"text\";\n\n // Remove if needed.\n if (range[3] > range[2] + 1) {\n const a = range[2] + 1;\n const b = range[3] - range[2] - 1;\n map.add(a, b, []);\n }\n }\n map.add(range[3] + 1, 0, [['exit', valueToken, context]]);\n }\n\n // Insert an exit for the last cell, if at the row end.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- exit\n // ^^^^^^-- this cell (the last one contains two \u201Cbetween\u201D parts)\n // ```\n if (rowEnd !== undefined) {\n previousCell.end = Object.assign({}, getPoint(context.events, rowEnd));\n map.add(rowEnd, 0, [['exit', previousCell, context]]);\n previousCell = undefined;\n }\n return previousCell;\n}\n\n/**\n * Generate table end (and table body end).\n *\n * @param {Readonly} map\n * @param {Readonly} context\n * @param {number} index\n * @param {Token} table\n * @param {Token | undefined} tableBody\n */\n// eslint-disable-next-line max-params\nfunction flushTableEnd(map, context, index, table, tableBody) {\n /** @type {Array} */\n const exits = [];\n const related = getPoint(context.events, index);\n if (tableBody) {\n tableBody.end = Object.assign({}, related);\n exits.push(['exit', tableBody, context]);\n }\n table.end = Object.assign({}, related);\n exits.push(['exit', table, context]);\n map.add(index + 1, 0, exits);\n}\n\n/**\n * @param {Readonly>} events\n * @param {number} index\n * @returns {Readonly}\n */\nfunction getPoint(events, index) {\n const event = events[index];\n const side = event[0] === 'enter' ? 'start' : 'end';\n return event[1][side];\n}", "export { gfmTableHtml } from './lib/html.js';\nexport { gfmTable } from './lib/syntax.js';", "/**\n * @import {Extension, State, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownLineEndingOrSpace, markdownSpace } from 'micromark-util-character';\nconst tasklistCheck = {\n name: 'tasklistCheck',\n tokenize: tokenizeTasklistCheck\n};\n\n/**\n * Create an HTML extension for `micromark` to support GFM task list items\n * syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `htmlExtensions` to\n * support GFM task list items when serializing to HTML.\n */\nexport function gfmTaskListItem() {\n return {\n text: {\n [91]: tasklistCheck\n }\n };\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeTasklistCheck(effects, ok, nok) {\n const self = this;\n return open;\n\n /**\n * At start of task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function open(code) {\n if (\n // Exit if there\u2019s stuff before.\n self.previous !== null ||\n // Exit if not in the first content that is the first child of a list\n // item.\n !self._gfmTasklistFirstContentOfListItem) {\n return nok(code);\n }\n effects.enter('taskListCheck');\n effects.enter('taskListCheckMarker');\n effects.consume(code);\n effects.exit('taskListCheckMarker');\n return inside;\n }\n\n /**\n * In task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function inside(code) {\n // Currently we match how GH works in files.\n // To match how GH works in comments, use `markdownSpace` (`[\\t ]`) instead\n // of `markdownLineEndingOrSpace` (`[\\t\\n\\r ]`).\n if (markdownLineEndingOrSpace(code)) {\n effects.enter('taskListCheckValueUnchecked');\n effects.consume(code);\n effects.exit('taskListCheckValueUnchecked');\n return close;\n }\n if (code === 88 || code === 120) {\n effects.enter('taskListCheckValueChecked');\n effects.consume(code);\n effects.exit('taskListCheckValueChecked');\n return close;\n }\n return nok(code);\n }\n\n /**\n * At close of task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function close(code) {\n if (code === 93) {\n effects.enter('taskListCheckMarker');\n effects.consume(code);\n effects.exit('taskListCheckMarker');\n effects.exit('taskListCheck');\n return after;\n }\n return nok(code);\n }\n\n /**\n * @type {State}\n */\n function after(code) {\n // EOL in paragraph means there must be something else after it.\n if (markdownLineEnding(code)) {\n return ok(code);\n }\n\n // Space or tab?\n // Check what comes after.\n if (markdownSpace(code)) {\n return effects.check({\n tokenize: spaceThenNonSpace\n }, ok, nok)(code);\n }\n\n // EOF, or non-whitespace, both wrong.\n return nok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction spaceThenNonSpace(effects, ok, nok) {\n return factorySpace(effects, after, \"whitespace\");\n\n /**\n * After whitespace, after task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n // EOF means there was nothing, so bad.\n // EOL means there\u2019s content after it, so good.\n // Impossible to have more spaces.\n // Anything else is good.\n return code === null ? nok(code) : ok(code);\n }\n}", "export { gfmTaskListItemHtml } from './lib/html.js';\nexport { gfmTaskListItem } from './lib/syntax.js';", "/**\n * @typedef {import('micromark-extension-gfm-footnote').HtmlOptions} HtmlOptions\n * @typedef {import('micromark-extension-gfm-strikethrough').Options} Options\n * @typedef {import('micromark-util-types').Extension} Extension\n * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension\n */\n\nimport {\n combineExtensions,\n combineHtmlExtensions\n} from 'micromark-util-combine-extensions'\nimport {\n gfmAutolinkLiteral,\n gfmAutolinkLiteralHtml\n} from 'micromark-extension-gfm-autolink-literal'\nimport {gfmFootnote, gfmFootnoteHtml} from 'micromark-extension-gfm-footnote'\nimport {\n gfmStrikethrough,\n gfmStrikethroughHtml\n} from 'micromark-extension-gfm-strikethrough'\nimport {gfmTable, gfmTableHtml} from 'micromark-extension-gfm-table'\nimport {gfmTagfilterHtml} from 'micromark-extension-gfm-tagfilter'\nimport {\n gfmTaskListItem,\n gfmTaskListItemHtml\n} from 'micromark-extension-gfm-task-list-item'\n\n/**\n * Create an extension for `micromark` to enable GFM syntax.\n *\n * @param {Options | null | undefined} [options]\n * Configuration (optional).\n *\n * Passed to `micromark-extens-gfm-strikethrough`.\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions` to enable GFM\n * syntax.\n */\nexport function gfm(options) {\n return combineExtensions([\n gfmAutolinkLiteral(),\n gfmFootnote(),\n gfmStrikethrough(options),\n gfmTable(),\n gfmTaskListItem()\n ])\n}\n\n/**\n * Create an extension for `micromark` to support GFM when serializing to HTML.\n *\n * @param {HtmlOptions | null | undefined} [options]\n * Configuration (optional).\n *\n * Passed to `micromark-extens-gfm-footnote`.\n * @returns {HtmlExtension}\n * Extension for `micromark` that can be passed in `htmlExtensions` to\n * support GFM when serializing to HTML.\n */\nexport function gfmHtml(options) {\n return combineHtmlExtensions([\n gfmAutolinkLiteralHtml(),\n gfmFootnoteHtml(options),\n gfmStrikethroughHtml(),\n gfmTableHtml(),\n gfmTagfilterHtml(),\n gfmTaskListItemHtml()\n ])\n}\n", "/**\n * @import {Root} from 'mdast'\n * @import {Options} from 'remark-gfm'\n * @import {} from 'remark-parse'\n * @import {} from 'remark-stringify'\n * @import {Processor} from 'unified'\n */\n\nimport {gfmFromMarkdown, gfmToMarkdown} from 'mdast-util-gfm'\nimport {gfm} from 'micromark-extension-gfm'\n\n/** @type {Options} */\nconst emptyOptions = {}\n\n/**\n * Add support GFM (autolink literals, footnotes, strikethrough, tables,\n * tasklists).\n *\n * @param {Options | null | undefined} [options]\n * Configuration (optional).\n * @returns {undefined}\n * Nothing.\n */\nexport default function remarkGfm(options) {\n // @ts-expect-error: TS is wrong about `this`.\n // eslint-disable-next-line unicorn/no-this-assignment\n const self = /** @type {Processor} */ (this)\n const settings = options || emptyOptions\n const data = self.data()\n\n const micromarkExtensions =\n data.micromarkExtensions || (data.micromarkExtensions = [])\n const fromMarkdownExtensions =\n data.fromMarkdownExtensions || (data.fromMarkdownExtensions = [])\n const toMarkdownExtensions =\n data.toMarkdownExtensions || (data.toMarkdownExtensions = [])\n\n micromarkExtensions.push(gfm(settings))\n fromMarkdownExtensions.push(gfmFromMarkdown())\n toMarkdownExtensions.push(gfmToMarkdown(settings))\n}\n", "// Note: types exposed from `index.d.ts`.\nexport {default} from './lib/index.js'\n", "import React from \"react\";\nimport { Box, Typography } from \"@mui/material\";\nimport type { SxProps, Theme } from \"@mui/material/styles\";\nimport { File, Download } from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\n\nimport { Icon, type IconSize } from \"@/components/icons\";\n\nexport type AgentPrototypeDownloadFile = {\n filename: string;\n pageCount?: number;\n sizeBytes?: number;\n displayFileSize?: boolean;\n url: string;\n};\n\nexport function formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\ninterface AgentPrototypeDownloadCardProps {\n file: AgentPrototypeDownloadFile;\n onDownload?: (file: AgentPrototypeDownloadFile) => void;\n metadata?: React.ReactNode;\n icon?: LucideIcon;\n iconSize?: IconSize;\n iconColor?: string;\n downloadIcon?: LucideIcon;\n downloadIconSize?: IconSize;\n downloadIconColor?: string;\n sx?: SxProps;\n titleSx?: SxProps;\n metadataSx?: SxProps;\n dataComponent?: string;\n docketConnectArtifactLink?: boolean;\n}\n\nconst sxArray = (sx?: SxProps) => (Array.isArray(sx) ? sx : sx ? [sx] : []);\n\nconst AgentPrototypeDownloadCard = ({\n file,\n onDownload,\n metadata,\n icon = File,\n iconSize = \"md\",\n iconColor = \"primary.main\",\n downloadIcon = Download,\n downloadIconSize = \"md\",\n downloadIconColor = \"primary.main\",\n sx,\n titleSx,\n metadataSx,\n dataComponent = \"AgentPrototypeDownloadCard\",\n docketConnectArtifactLink,\n}: AgentPrototypeDownloadCardProps) => {\n const pageCount =\n typeof file.pageCount === \"number\" && Number.isFinite(file.pageCount) && file.pageCount > 0\n ? Math.floor(file.pageCount)\n : null;\n const secondaryText =\n metadata ??\n (pageCount\n ? `${pageCount} ${pageCount === 1 ? \"page\" : \"pages\"}`\n : file.displayFileSize !== false && typeof file.sizeBytes === \"number\"\n ? formatFileSize(file.sizeBytes)\n : null);\n\n return (\n onDownload?.(file)}\n sx={[\n (theme) => ({\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n p: 1.5,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n border: `1px solid ${theme.border.default}`,\n textDecoration: \"none\",\n color: \"inherit\",\n transition: \"background-color 0.15s ease, border-color 0.15s ease\",\n \"&:hover\": {\n borderColor: theme.palette.primary._states.outlinedBorder,\n },\n \"&:focus-visible\": {\n outline: `2px solid ${theme.palette.primary.main}`,\n outlineOffset: 1,\n },\n }),\n ...sxArray(sx),\n ]}\n >\n \n \n \n \n \n {file.filename}\n \n {secondaryText && (\n \n {secondaryText}\n \n )}\n \n \n \n \n \n );\n};\n\nexport default AgentPrototypeDownloadCard;\n", "import React from \"react\";\nimport { Typography } from \"@mui/material\";\n\n/** Persisted message time, displayed in the reader's local timezone. */\nexport default function MessageTimestamp({ createdAt }: { createdAt?: string }) {\n if (!createdAt) return null;\n const date = new Date(createdAt);\n if (Number.isNaN(date.getTime())) return null;\n return (\n \n {date.toLocaleString(\"en-US\", { month: \"short\", day: \"numeric\", hour: \"numeric\", minute: \"2-digit\" })}\n \n );\n}\n", "import React, { useState, useCallback } from \"react\";\nimport { Box, Tooltip, Dialog, Stack, Typography, CircularProgress } from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { BIQInputField } from \"@/components/atoms/BIQInputField\";\nimport type { AlertColor } from \"@mui/material/Alert\";\nimport { Copy, Split, ThumbsUp, ThumbsDown, X } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { submitMessageFeedback, deleteMessageFeedback } from \"../../api/agentPrototype\";\nimport { MODAL_WIDTH } from \"../../utils/constants\";\n\nimport { iconSize } from \"@/components/theme/tokens/iconSize\";\nimport MessageTimestamp from \"./MessageTimestamp\";\nimport SafeSpan from \"@/components/atoms/SafeSpan\";\n\ntype FeedbackState = \"none\" | \"up\" | \"down\";\n\ninterface MessageActionsProps {\n onFork?: () => void;\n forkPending?: boolean;\n createdAt?: string;\n sessionId?: number;\n sessionToken?: string;\n serverMessageId?: number;\n copyContent: string;\n hasCitations: boolean;\n downloadFileCount: number;\n initialFeedback?: { rating: boolean } | null;\n readOnly?: boolean;\n setAlertWithOptions: (error: string | null, severity?: AlertColor, displayTimeMs?: number | null) => void;\n}\n\nconst MessageActions: React.FC = ({\n onFork,\n forkPending = false,\n createdAt,\n sessionId,\n sessionToken,\n serverMessageId,\n copyContent,\n hasCitations,\n downloadFileCount,\n initialFeedback,\n readOnly = false,\n setAlertWithOptions,\n}) => {\n const [feedbackState, setFeedbackState] = useState(() => {\n if (initialFeedback?.rating === true) return \"up\";\n if (initialFeedback?.rating === false) return \"down\";\n return \"none\";\n });\n const [modalOpen, setModalOpen] = useState(false);\n const [comment, setComment] = useState(\"\");\n const [submitting, setSubmitting] = useState(false);\n\n const handleCopy = useCallback(async () => {\n await navigator.clipboard.writeText(copyContent);\n if (sessionId) {\n void recordUserEvent({\n event_name: \"copy_clerk_response_to_clipboard\",\n event_properties: {\n session_id: sessionId,\n has_citations: hasCitations,\n download_file_count: downloadFileCount,\n },\n });\n }\n setAlertWithOptions(\"Copied to clipboard\", \"success\", 3000);\n }, [copyContent, sessionId, hasCitations, downloadFileCount, setAlertWithOptions]);\n\n const handleRemoveFeedback = useCallback(async () => {\n if (!sessionToken || !serverMessageId) return;\n const previousState = feedbackState;\n setFeedbackState(\"none\");\n try {\n await deleteMessageFeedback(sessionToken, serverMessageId);\n } catch {\n setFeedbackState(previousState);\n }\n }, [sessionToken, serverMessageId, feedbackState]);\n\n const handleThumbsUp = useCallback(async () => {\n if (!sessionToken || !serverMessageId) return;\n if (feedbackState === \"up\") return handleRemoveFeedback();\n const previousState = feedbackState;\n setFeedbackState(\"up\");\n try {\n await submitMessageFeedback(sessionToken, serverMessageId, true);\n } catch {\n setFeedbackState(previousState);\n }\n }, [sessionToken, serverMessageId, feedbackState, handleRemoveFeedback]);\n\n const handleThumbsDown = useCallback(() => {\n if (feedbackState === \"down\") return handleRemoveFeedback();\n setModalOpen(true);\n }, [feedbackState, handleRemoveFeedback]);\n\n const handleModalClose = useCallback(() => {\n setModalOpen(false);\n setComment(\"\");\n }, []);\n\n const handleModalSubmit = useCallback(async () => {\n if (!sessionToken || !serverMessageId) return;\n setSubmitting(true);\n try {\n await submitMessageFeedback(sessionToken, serverMessageId, false, comment || undefined);\n setFeedbackState(\"down\");\n setModalOpen(false);\n setComment(\"\");\n } catch {\n // leave modal open on failure so user can retry\n } finally {\n setSubmitting(false);\n }\n }, [sessionToken, serverMessageId, comment]);\n\n return (\n <>\n \n \n \n \n\n {!readOnly && onFork && (\n \n \n : Split}\n onClick={onFork}\n disabled={forkPending}\n />\n \n \n )}\n\n {!readOnly && feedbackState !== \"up\" && (\n \n \n ) : (\n ThumbsDown\n )\n }\n />\n \n )}\n {!readOnly && feedbackState !== \"down\" && (\n \n : ThumbsUp\n }\n />\n \n )}\n\n \n \n\n {modalOpen && (\n ({\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n maxWidth: MODAL_WIDTH,\n width: \"100%\",\n }),\n }}\n >\n \n \n Share feedback\n \n \n\n setComment(e.target.value)}\n helper=\"Your conversation will be submitted with your feedback to help improve the agent.\"\n />\n\n \n \n Cancel\n \n \n Submit\n \n \n \n \n )}\n \n );\n};\n\nexport default MessageActions;\n", "import React from \"react\";\nimport { Box, Tooltip, CircularProgress } from \"@mui/material\";\nimport type { AlertColor } from \"@mui/material/Alert\";\nimport { Copy, Split, X } from \"lucide-react\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { iconSize } from \"@/components/theme/tokens/iconSize\";\nimport SafeSpan from \"@/components/atoms/SafeSpan\";\nimport MessageTimestamp from \"./MessageTimestamp\";\n\nexport interface UserMessageActionsProps {\n pending?: boolean;\n createdAt?: string;\n copyContent: string;\n busy?: boolean;\n pendingActionType?: \"fork\" | \"steer\" | \"cancel\" | null;\n onFork?: () => void;\n canSteer?: boolean;\n onSteer?: () => void;\n onCancelAndEdit?: () => void;\n setAlertWithOptions: (message: string | null, severity?: AlertColor, displayTimeMs?: number | null) => void;\n}\n\nexport default function UserMessageActions({\n pending,\n createdAt,\n copyContent,\n busy,\n pendingActionType,\n onFork,\n onSteer,\n canSteer = false,\n onCancelAndEdit,\n setAlertWithOptions,\n}: UserMessageActionsProps) {\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(copyContent);\n setAlertWithOptions(\"Copied to clipboard\", \"success\", 3000);\n } catch {\n setAlertWithOptions(\"Could not copy to clipboard\", \"error\", 3000);\n }\n };\n return (\n \n {!pending && }\n \n \n \n {pending && onFork && (\n \n \n : Split}\n onClick={onFork}\n disabled={busy}\n />\n \n \n )}\n {pending && onSteer && (\n \n Steer\n \n )}\n {pending && onCancelAndEdit && (\n \n \n \n \n \n )}\n \n );\n}\n", "/**\n * Highlight overlay for ReactMarkdown-rendered content (agent sessions).\n *\n * Uses the CSS Custom Highlight API (`CSS.highlights`) to visually mark text\n * ranges WITHOUT modifying the DOM. This avoids conflicts with React's\n * reconciler that caused blank lines and broken text when inserting ``\n * elements into React-owned DOM trees.\n *\n * For click handling on highlights, we listen for clicks on the container and\n * check if the click target falls within a highlight range.\n *\n * Falls back to no-op on browsers without CSS.highlights support (pre-Chrome 105).\n */\n\nimport { useLayoutEffect, useRef, useCallback } from \"react\";\nimport type { Highlight } from \"../api/queries/folders.types\";\nimport {\n supportsHighlightAPI,\n buildRangeFromOffsets,\n findHighlightAtPoint,\n type HighlightRangeInfo,\n} from \"../utils/highlightRangeUtils\";\nimport { anchorPositionFromRect, getNoteIndicatorEl } from \"../utils/highlightPopoverAnchor\";\n\nconst CSS_HIGHLIGHT_NAME = \"user-highlights\";\n\n/**\n * Every message mounts its own overlay, but `CSS.highlights` is page-global.\n * They share one registered Highlight, and each overlay adds and removes only\n * its own ranges.\n */\nfunction sharedCssHighlight(): globalThis.Highlight {\n let cssHighlight = CSS.highlights.get(CSS_HIGHLIGHT_NAME);\n if (!cssHighlight) {\n cssHighlight = new window.Highlight();\n CSS.highlights.set(CSS_HIGHLIGHT_NAME, cssHighlight);\n }\n return cssHighlight;\n}\n\nexport function useHighlightOverlay(\n containerRef: React.RefObject,\n highlights: Highlight[] | undefined,\n onHighlightClick: (\n highlight: Highlight,\n anchorEl: HTMLElement | null,\n anchorPosition?: { top: number; left: number },\n ) => void,\n enabled = true,\n): void {\n const onClickRef = useRef(onHighlightClick);\n onClickRef.current = onHighlightClick;\n const rangeInfosRef = useRef([]);\n\n // Click handler: check if click falls within a highlight range.\n // Uses the NoteIndicator margin element as the anchor if available,\n // otherwise falls back to the container element. No temporary DOM elements.\n //\n // Registered in capture phase (see useLayoutEffect below) so it fires before\n // any inner element's click handler. This is what lets us swallow clicks on\n // citations / links / buttons that happen to sit inside a highlighted range \u2014\n // the citation's own onClick calls stopPropagation, which would otherwise\n // prevent this handler from running in the bubble phase.\n const handleClick = useCallback(\n (e: MouseEvent) => {\n // Skip if user was drag-selecting text (not clicking). The mouseup handler\n // fires first to open the \"create\" popover; without this guard the click\n // handler would immediately overwrite it with the \"edit\" popover.\n const selection = window.getSelection();\n if (selection && selection.toString().trim().length > 0) return;\n\n const info = findHighlightAtPoint(rangeInfosRef.current, e.clientX, e.clientY);\n if (info) {\n e.stopPropagation();\n e.preventDefault();\n const indicatorEl = getNoteIndicatorEl(info.highlight.id);\n if (indicatorEl) {\n onClickRef.current(info.highlight, indicatorEl);\n } else {\n // No margin indicator \u2014 pass anchor position from the highlight range\n onClickRef.current(info.highlight, null, anchorPositionFromRect(info.range.getBoundingClientRect()));\n }\n }\n },\n [containerRef],\n );\n\n useLayoutEffect(() => {\n if (!supportsHighlightAPI) return;\n\n const container = containerRef.current;\n rangeInfosRef.current = [];\n\n if (!container || !enabled || !highlights?.length) {\n return;\n }\n\n const cssHighlight = sharedCssHighlight();\n const removeRanges = () => {\n rangeInfosRef.current.forEach(({ range }) => cssHighlight.delete(range));\n rangeInfosRef.current = [];\n };\n const applyRanges = () => {\n removeRanges();\n rangeInfosRef.current = highlights.flatMap((highlight) => {\n const range = buildRangeFromOffsets(container, highlight);\n return range ? [{ highlight, range }] : [];\n });\n rangeInfosRef.current.forEach(({ range }) => cssHighlight.add(range));\n };\n applyRanges();\n\n // A live Range collapses when React replaces the text nodes it points into,\n // so rebuild the ranges whenever the rendered content changes.\n const observer = new MutationObserver(applyRanges);\n observer.observe(container, { childList: true, characterData: true, subtree: true });\n\n // Capture-phase listener so highlight clicks beat any inner onClick that\n // calls stopPropagation (e.g. citation links inside Clerk responses).\n container.addEventListener(\"click\", handleClick, true);\n\n return () => {\n observer.disconnect();\n removeRanges();\n container.removeEventListener(\"click\", handleClick, true);\n };\n }, [containerRef, highlights, enabled, handleClick]);\n}\n", "import { useRef } from \"react\";\nimport lodash from \"lodash\";\n\n/**\n * Returns the previously seen reference while `value` stays deep-equal.\n *\n * Session refetches rebuild message data with fresh-but-equal arrays; feeding\n * those straight into `useMemo` deps would recompute on every poll.\n */\nexport function useStableValue(value: T): T {\n const ref = useRef(value);\n if (ref.current !== value && !lodash.isEqual(ref.current, value)) {\n ref.current = value;\n }\n return ref.current;\n}\n", "import React, { useCallback, useState } from \"react\";\nimport { Box, Collapse, Typography } from \"@mui/material\";\nimport { ChevronDown, ChevronUp, ExternalLink } from \"lucide-react\";\n\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { Icon } from \"@/components/icons\";\n\nimport type { CitationData, TranscriptCitationData } from \"../../../api/queries/agentPrototype.types\";\nimport { safeSourceHref, transcriptUrl } from \"./citationLinks\";\nimport type { ClerkCitationSource } from \"./citationLinks\";\nimport { isCourtRecordCitation, isTranscriptCitation, isUploadedDocumentCitation } from \"./types\";\n\ninterface AgentSourcesSectionProps {\n citations: CitationData[];\n onOpenCitation?: (citation: TranscriptCitationData, source: ClerkCitationSource) => void;\n openTranscript?: (transcriptId: number, excerpt?: string, location?: TranscriptCitationData[\"location\"]) => void;\n}\n\nconst months = [\"Jan.\", \"Feb.\", \"Mar.\", \"Apr.\", \"May\", \"Jun.\", \"Jul.\", \"Aug.\", \"Sep.\", \"Oct.\", \"Nov.\", \"Dec.\"];\n\nfunction formatCitationDate(dateStr: string): string {\n const match = dateStr.match(/^(\\d{4})-(\\d{2})-(\\d{2})/);\n if (match) {\n const [, year, month, day] = match;\n return `${months[parseInt(month, 10) - 1]} ${parseInt(day, 10)}, ${year}`;\n }\n const date = new Date(dateStr);\n if (isNaN(date.getTime())) return dateStr;\n return `${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;\n}\n\nfunction formatBluebook(citation: TranscriptCitationData): string {\n if (citation.citation) return citation.citation;\n let label = `In re ${citation.case_name}, No. ${citation.case_number}`;\n if (citation.judge_name) label += `, before Judge ${citation.judge_name}`;\n if (citation.date_of_hearing) label += ` (${formatCitationDate(citation.date_of_hearing)})`;\n return label;\n}\n\nfunction looksLikeUrl(value?: string): boolean {\n return !!value && /^(https?:|\\/|\\/\\/)/i.test(value.trim());\n}\n\nfunction isProviderFallbackCaseName(value?: string): boolean {\n return /^PACER Monitor case \\d+$/i.test(value ?? \"\");\n}\n\nfunction formatCourtRecordDate(dateValue?: string): string | undefined {\n if (!dateValue) return undefined;\n const date = new Date(dateValue);\n if (Number.isNaN(date.getTime())) return dateValue;\n\n const months = [\"Jan.\", \"Feb.\", \"Mar.\", \"Apr.\", \"May\", \"June\", \"July\", \"Aug.\", \"Sept.\", \"Oct.\", \"Nov.\", \"Dec.\"];\n return `${months[date.getUTCMonth()]} ${date.getUTCDate()}, ${date.getUTCFullYear()}`;\n}\n\nconst courtCitationLabelsByCode: Record = {\n cacb: \"Bankr. C.D. Cal.\",\n ctb: \"Bankr. D. Conn.\",\n ctd: \"D. Conn.\",\n deb: \"Bankr. D. Del.\",\n flsb: \"Bankr. S.D. Fla.\",\n ganb: \"Bankr. N.D. Ga.\",\n mad: \"D. Mass.\",\n moeb: \"Bankr. E.D. Mo.\",\n ncwb: \"Bankr. W.D.N.C.\",\n njb: \"Bankr. D.N.J.\",\n nysb: \"Bankr. S.D.N.Y.\",\n nysd: \"S.D.N.Y.\",\n txnb: \"Bankr. N.D. Tex.\",\n txsb: \"Bankr. S.D. Tex.\",\n txwd: \"W.D. Tex.\",\n};\n\nconst courtCitationLabelsByName: Record = {\n \"california central bankruptcy court\": \"Bankr. C.D. Cal.\",\n \"connecticut bankruptcy court\": \"Bankr. D. Conn.\",\n \"connecticut district court\": \"D. Conn.\",\n \"delaware bankruptcy court\": \"Bankr. D. Del.\",\n \"florida southern bankruptcy court\": \"Bankr. S.D. Fla.\",\n \"georgia northern bankruptcy court\": \"Bankr. N.D. Ga.\",\n \"massachusetts district court\": \"D. Mass.\",\n \"missouri eastern bankruptcy court\": \"Bankr. E.D. Mo.\",\n \"new jersey bankruptcy court\": \"Bankr. D.N.J.\",\n \"new york southern bankruptcy court\": \"Bankr. S.D.N.Y.\",\n \"new york southern district court\": \"S.D.N.Y.\",\n \"north carolina western bankruptcy court\": \"Bankr. W.D.N.C.\",\n \"texas northern bankruptcy court\": \"Bankr. N.D. Tex.\",\n \"texas southern bankruptcy court\": \"Bankr. S.D. Tex.\",\n \"texas western district court\": \"W.D. Tex.\",\n};\n\n// courtCitationLabelsByCode/ByName below are a legacy fallback for citations\n// persisted before the server started emitting court_citation_label.\nfunction formatCourtRecordCourt(citationLabel?: string, courtName?: string, courtCode?: string): string | undefined {\n if (citationLabel) return citationLabel;\n\n const codeKey = courtCode?.trim().toLowerCase();\n if (codeKey && courtCitationLabelsByCode[codeKey]) return courtCitationLabelsByCode[codeKey];\n\n const nameKey = courtName?.trim().toLowerCase();\n if (nameKey && courtCitationLabelsByName[nameKey]) return courtCitationLabelsByName[nameKey];\n\n return courtName || courtCode;\n}\n\nfunction sanitizedCourtRecordCitation(citation: CitationData): string | undefined {\n if (!isCourtRecordCitation(citation)) return undefined;\n if (!isProviderFallbackCaseName(citation.case_name) && !citation.citation?.includes(\"PACER Monitor case\")) {\n return citation.citation;\n }\n\n const title = [citation.title_for_citation, citation.document_title, citation.raw_docket_text].find(\n (candidate) => candidate && !looksLikeUrl(candidate),\n );\n if (!title) return undefined;\n\n const parentheticalParts = [\n formatCourtRecordCourt(citation.court_citation_label, citation.court_name, citation.court_code),\n formatCourtRecordDate(citation.filed_at),\n ].filter(Boolean);\n const docketPart = citation.docket_number ? `ECF No. ${citation.docket_number}` : undefined;\n const citationParts = [title, docketPart].filter(Boolean);\n if (parentheticalParts.length > 0) {\n const parenthetical = `(${parentheticalParts.join(\" \")})`;\n if (citationParts.length > 1) {\n citationParts[citationParts.length - 1] = `${citationParts[citationParts.length - 1]} ${parenthetical}`;\n } else {\n citationParts.push(parenthetical);\n }\n }\n\n const label = citationParts.join(\", \").replace(/\\s+/g, \" \").trim();\n return label.endsWith(\".\") ? label : `${label}.`;\n}\n\nfunction courtRecordLabel(citation: CitationData): string {\n if (!isCourtRecordCitation(citation)) return \"\";\n const candidates = [\n sanitizedCourtRecordCitation(citation),\n citation.title_for_citation,\n citation.document_title,\n citation.raw_docket_text,\n ];\n return candidates.find((candidate) => candidate && !looksLikeUrl(candidate)) ?? \"Court record\";\n}\n\nconst TranscriptSourceRow: React.FC<{\n citation: TranscriptCitationData;\n index: number;\n onOpenCitation?: (citation: TranscriptCitationData, source: ClerkCitationSource) => void;\n openTranscript?: (transcriptId: number, excerpt?: string, location?: TranscriptCitationData[\"location\"]) => void;\n}> = ({ citation, index, onOpenCitation, openTranscript }) => (\n \n \n [{index + 1}]\n \n \n {citation.citation_unavailable && (\n \n Details unavailable\n \n )}\n {\n e.stopPropagation();\n onOpenCitation?.(citation, \"footnotes_section\");\n if (openTranscript) {\n e.preventDefault();\n openTranscript(citation.transcript_id, citation.excerpt, citation.location);\n }\n }}\n sx={{\n color: \"text.primary\",\n textDecoration: \"none\",\n display: \"block\",\n \"&:hover\": { textDecoration: \"underline\", color: \"primary.main\" },\n }}\n >\n {citation.citation_unavailable\n ? \"Transcript available (citation details unavailable)\"\n : formatBluebook(citation)}\n \n \n \n \n {citation.citation_unavailable && (\n \n You can still open the transcript and review the quoted passage.\n \n )}\n {citation.excerpt && (\n \n “{citation.excerpt}”\n \n )}\n \n \n);\n\nconst DocumentSourceRow: React.FC<{ citation: CitationData; index: number }> = ({ citation, index }) => {\n if (!isCourtRecordCitation(citation) && !isUploadedDocumentCitation(citation)) return null;\n const href = safeSourceHref(citation.download_url);\n const label = isCourtRecordCitation(citation)\n ? courtRecordLabel(citation)\n : citation.citation || citation.filename || \"Uploaded document\";\n\n return (\n \n \n [{index + 1}]\n \n \n {href ? (\n e.stopPropagation()}\n sx={{\n color: \"text.primary\",\n textDecoration: \"none\",\n display: \"block\",\n \"&:hover\": { textDecoration: \"underline\", color: \"primary.main\" },\n }}\n >\n {label}\n \n \n \n \n ) : (\n \n {label}\n \n )}\n {citation.excerpt && (\n \n “{citation.excerpt}”\n \n )}\n \n \n );\n};\n\nexport const AgentSourcesSection: React.FC = ({\n citations,\n onOpenCitation,\n openTranscript,\n}) => {\n const [expanded, setExpanded] = useState(false);\n const toggleExpanded = useCallback(() => setExpanded((current) => !current), []);\n const items = citations.filter((citation) => citation.read !== false);\n const hasUnavailable = items.some((citation) => citation.citation_unavailable === true);\n const hasUnavailableDocument = items.some(\n (citation) => !isTranscriptCitation(citation) && citation.citation_unavailable === true,\n );\n\n if (items.length === 0) return null;\n\n return (\n \n \n \n Sources ({items.length})\n \n {\n e.stopPropagation();\n toggleExpanded();\n }}\n />\n \n \n \n {hasUnavailable && (\n \n {hasUnavailableDocument\n ? \"Some sources are currently unavailable.\"\n : \"Some sources are missing citation details, but transcript links are available.\"}\n \n )}\n {items.map((citation, index) => {\n return isTranscriptCitation(citation) ? (\n \n ) : (\n \n );\n })}\n \n \n \n );\n};\n", "const CITATION_MAP_MARKER_REGEX = /\", markerIndex);\n if (closeIndex === -1) return content.slice(0, markerIndex).trimEnd();\n\n return `${content.slice(0, markerIndex)}${content.slice(closeIndex + 3)}`.trimEnd();\n}\n\nexport function hasInlineFootnoteReferences(content: string): boolean {\n return /\\[\\d+\\]/.test(content);\n}\n", "import type { CitationData } from \"../../../api/queries/agentPrototype.types\";\nimport { isCourtRecordCitation, isUploadedDocumentCitation } from \"./types\";\n\ntype MarkdownNode = {\n type: string;\n value?: string;\n children?: MarkdownNode[];\n};\n\nfunction documentIdentities(citations: CitationData[]): Map {\n const identities = new Map();\n citations.forEach((citation, index) => {\n if (isCourtRecordCitation(citation)) {\n identities.set(index + 1, `court_record:${citation.court_document_id}`);\n } else if (isUploadedDocumentCitation(citation)) {\n identities.set(index + 1, `uploaded_document:${String(citation.document_id)}`);\n }\n });\n return identities;\n}\n\nfunction collapseBlock(block: string, identities: Map): string {\n const seenDocuments = new Set();\n let collapsed = \"\";\n const markers = /(\\s*)\\[(\\d+)\\]/g;\n let match: RegExpExecArray | null;\n\n while ((match = markers.exec(block)) !== null) {\n const number = Number.parseInt(match[2], 10);\n const identity = identities.get(number);\n if (identity && seenDocuments.has(identity)) continue;\n\n if (identity) seenDocuments.add(identity);\n collapsed += `${match[1]}[${number}]`;\n }\n\n return collapsed;\n}\n\nfunction transform(node: MarkdownNode, identities: Map): void {\n if (node.type === \"text\" && node.value) {\n node.value = node.value.replace(/\\[\\d+\\](?:\\s*\\[\\d+\\])+/g, (block) => collapseBlock(block, identities));\n }\n node.children?.forEach((child) => transform(child, identities));\n}\n\nexport function collapseDocumentCitationBlocks(citations: CitationData[]) {\n const identities = documentIdentities(citations);\n\n return () => (tree: MarkdownNode) => {\n if (identities.size > 0) transform(tree, identities);\n };\n}\n", "import AgentPrototypeNextSteps from \"./AgentPrototypeNextSteps\";\nimport type { NextStepSet, NextStepSuggestion } from \"./nextSteps\";\nimport React, { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { Alert, Box, Typography, Chip, Divider, Tooltip } from \"@mui/material\";\nimport { alpha } from \"@mui/material/styles\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { Citation } from \"@/components/atoms/Citation\";\nimport { styled } from \"@/utils/styled\";\nimport { AlertCircle, File as FileIcon } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport type { ChatMessage } from \"../../hooks/useAgentPrototypeSession\";\nimport { useGlobalAlert } from \"../../contexts/GlobalAlertContext\";\nimport type { CitationData, TranscriptCitationData } from \"../../api/queries/agentPrototype.types\";\nimport AgentPrototypeThinking from \"./AgentPrototypeThinking\";\nimport AgentPrototypeDownloadCard from \"./AgentPrototypeDownloadCard\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { clerkResponseFileSizeBucket, normalizeFileExtension } from \"../../utils/clerkAnalytics\";\nimport { CLERK_ERROR_COPY } from \"../../utils/clerkErrorCopy\";\nimport MessageActions from \"./MessageActions\";\nimport UserMessageActions from \"./UserMessageActions\";\nimport { colors } from \"../theme/tokens\";\nimport type { Highlight } from \"../../api/queries/folders.types\";\nimport type { SelectionOffsets } from \"../../utils/getSelectionOffsets\";\nimport { getSelectionOffsets } from \"../../utils/getSelectionOffsets\";\nimport { canRequestJudge } from \"../../utils/canRequestJudge\";\nimport { useHighlightOverlay } from \"../../hooks/useHighlightOverlay\";\nimport { useStableValue } from \"../../hooks/useStableValue\";\nimport { featureEnabled } from \"../../utils/featureFlags\";\nimport { NoteMarginIndicators } from \"../highlights/NoteMarginIndicators\";\nimport { AgentSourcesSection } from \"./citations/AgentSourcesSection\";\nimport {\n copyableCitationMarkdown,\n inlineCitationLinkNumber,\n resolveFootnote,\n safeSourceHref,\n transcriptUrl,\n} from \"./citations/citationLinks\";\nimport type { ClerkCitationSource } from \"./citations/citationLinks\";\nimport { hasInlineFootnoteReferences, stripCitationMapControlText } from \"./citations/citationControlText\";\nimport { collapseDocumentCitationBlocks } from \"./citations/collapseDocumentCitationBlocks\";\nimport { isCourtRecordCitation, isTranscriptCitation, isUploadedDocumentCitation } from \"./citations/types\";\n\n// TODO: Extract to shared component once rhythm is validated.\nconst ProseContainer = styled(\"div\")(({ theme }) => ({\n position: \"relative\",\n // Reset\n \"& > *\": { marginTop: 0, marginBottom: 0 },\n // Default sibling gap\n \"& > * + *\": { marginTop: theme.spacing(1.5) },\n // Headings (## \u2192 Typography variant=\"h4\", renders as

    )\n \"& > .MuiTypography-h4\": { marginTop: theme.spacing(4) },\n \"& > .MuiTypography-h4 + *\": { marginTop: theme.spacing(1.5) },\n // Sub-headings (### \u2192 body2 with component=\"h3\", #### \u2192 body2 with component=\"h4\")\n \"& > h3:not(.MuiTypography-h4), & > h4:not(.MuiTypography-h4)\": { marginTop: theme.spacing(3) },\n \"& > h3:not(.MuiTypography-h4) + *, & > h4:not(.MuiTypography-h4) + *\": { marginTop: theme.spacing(1) },\n // Lists\n \"& > ul, & > ol\": { marginTop: theme.spacing(1) },\n \"& li + li\": { marginTop: theme.spacing(0.75) },\n // First child\n \"& > *:first-child\": { marginTop: 0 },\n}));\n\ninterface AgentPrototypeMessageProps {\n onForkMessage?: () => void;\n canSteer?: boolean;\n onSteerMessage?: () => void;\n onCancelAndEditMessage?: () => void;\n messageActionPending?: boolean;\n pendingMessageActionType?: \"fork\" | \"steer\" | \"cancel\" | null;\n message: ChatMessage;\n nextSteps?: NextStepSet;\n onSelectNextStep?: (suggestion: NextStepSuggestion) => void;\n suppressLiveProgress?: boolean;\n sessionId?: number;\n sessionToken?: string;\n onRetry?: () => void;\n onRetryDownloadLoad?: () => void;\n downloadLoadRetryDisabled?: boolean;\n openTranscript?: (transcriptId: number, excerpt?: string, location?: TranscriptCitationData[\"location\"]) => void;\n onRequestJudge?: (judgeName: string) => void;\n readOnly?: boolean;\n /** Highlights for this specific message (filtered by sub_element_id). */\n highlights?: Highlight[];\n /** Called when user selects text in this message. */\n onTextSelected?: (offsets: SelectionOffsets, messageId: number) => void;\n /** Called when user clicks on an existing highlight mark. */\n onHighlightClick?: (\n highlight: Highlight,\n anchorEl: HTMLElement | null,\n anchorPosition?: { top: number; left: number },\n ) => void;\n /** Ref to the scroll container (chat list), used by margin note indicators. */\n scrollContainerRef?: React.RefObject;\n}\n\ntype DownloadCardFile = {\n filename: string;\n pageCount?: number;\n sizeBytes?: number;\n displayFileSize?: boolean;\n url: string;\n};\n\nfunction isUsableCitation(citation?: CitationData): boolean {\n if (!citation) return false;\n if (isTranscriptCitation(citation)) return true;\n return safeSourceHref(citation.download_url) !== undefined;\n}\n\nfunction withoutMarkdownCode(content: string): string {\n const visibleLines: string[] = [];\n let activeFence: { character: \"`\" | \"~\"; length: number } | undefined;\n\n for (const line of content.split(\"\\n\")) {\n if (activeFence) {\n const closingFence = line.match(/^\\s*(?:>\\s*)*(`+|~+)\\s*$/)?.[1];\n if (closingFence && closingFence[0] === activeFence.character && closingFence.length >= activeFence.length) {\n activeFence = undefined;\n }\n continue;\n }\n\n const openingFence = line.match(/^\\s*(?:>\\s*)*(?:(?:[-+*]|\\d+[.)])\\s+)?(`{3,}|~{3,})/)?.[1];\n if (openingFence) {\n activeFence = { character: openingFence[0] as \"`\" | \"~\", length: openingFence.length };\n continue;\n }\n\n visibleLines.push(line);\n }\n\n return visibleLines.join(\"\\n\").replace(/(`+)[\\s\\S]*?\\1/g, \"\");\n}\n\nfunction hasUnresolvedFootnotes(\n content: string,\n citations: CitationData[],\n footnoteRenumber?: Map,\n): boolean {\n const markerPattern = /\\[(\\d+)\\]/g;\n let match: RegExpExecArray | null;\n const visibleContent = withoutMarkdownCode(content);\n\n while ((match = markerPattern.exec(visibleContent)) !== null) {\n const { citation } = resolveFootnote(parseInt(match[1], 10), citations, footnoteRenumber);\n if (!isUsableCitation(citation)) return true;\n }\n\n return false;\n}\n\n/** Format date as \"Mon. DD, YYYY\" (no period after May) */\nfunction formatCitationDate(dateStr: string): string {\n const months = [\"Jan.\", \"Feb.\", \"Mar.\", \"Apr.\", \"May\", \"Jun.\", \"Jul.\", \"Aug.\", \"Sep.\", \"Oct.\", \"Nov.\", \"Dec.\"];\n // Parse YYYY-MM-DD directly to avoid UTC-to-local timezone shift\n const match = dateStr.match(/^(\\d{4})-(\\d{2})-(\\d{2})/);\n if (match) {\n const [, year, month, day] = match;\n return `${months[parseInt(month, 10) - 1]} ${parseInt(day, 10)}, ${year}`;\n }\n const date = new Date(dateStr);\n if (isNaN(date.getTime())) return dateStr;\n return `${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;\n}\n\n/** Rich citation hover popup matching Figma design */\nconst CitationPopup: React.FC<{\n citation: TranscriptCitationData;\n onOpenCitation?: (citation: TranscriptCitationData, source: ClerkCitationSource) => void;\n openTranscript?: (transcriptId: number, excerpt?: string, location?: TranscriptCitationData[\"location\"]) => void;\n}> = ({ citation, onOpenCitation, openTranscript }) => (\n ({\n bgcolor: \"common.white\",\n border: `1px solid ${theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n boxShadow: theme.tokens.shadows.md,\n maxWidth: 800,\n width: 340,\n p: 3,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n })}\n >\n \n \n \n {citation.judge_name}\n \n {citation.date_of_hearing && (\n \n {formatCitationDate(citation.date_of_hearing)}\n \n )}\n \n \n In re {citation.case_name},\n \n {citation.description && (\n \n {citation.description}\n \n )}\n {citation.excerpt && (\n \n ...{citation.excerpt}\n \n )}\n \n {\n e.stopPropagation();\n onOpenCitation?.(citation, \"citation_popup\");\n if (openTranscript) {\n openTranscript(citation.transcript_id, citation.excerpt, citation.location);\n }\n }}\n sx={{\n alignSelf: \"flex-start\",\n color: \"primary.main\",\n borderColor: \"primary.main\",\n fontSize: \"0.8125rem\",\n letterSpacing: \"0.46px\",\n }}\n >\n View in Transcript\n \n \n);\n\n/**\n * Process text nodes to make [N] footnote references clickable.\n * Returns an array of strings and React elements.\n */\nfunction processFootnoteRefs(\n text: string,\n citations: CitationData[],\n footnoteRenumber?: Map,\n onOpenCitation?: (citation: TranscriptCitationData, source: ClerkCitationSource) => void,\n openTranscript?: (transcriptId: number, excerpt?: string, location?: TranscriptCitationData[\"location\"]) => void,\n isStreaming = false,\n preserveUnresolvedMarkers = false,\n): (string | React.ReactElement)[] {\n // Place sentence-ending citations after the full stop rather than before it:\n // \"...the motion [1].\" -> \"...the motion. [1]\". Only markers directly before\n // sentence-ending punctuation move; mid-sentence citations stay put.\n if (!preserveUnresolvedMarkers) {\n text = text.replace(/\\s*((?:\\[\\d+\\])+)([.!?])/g, \"$2 $1\");\n }\n // Normalize spacing: a citation the agent placed flush after the punctuation\n // (\"approval.[2]\") gets a single space so it matches the reordered form\n // (\"approval. [2]\") \u2014 consistent gap between the full stop and the marker.\n if (!preserveUnresolvedMarkers) {\n text = text.replace(/([.!?])((?:\\[\\d+\\])+)/g, \"$1 $2\");\n }\n\n const parts: (string | React.ReactElement)[] = [];\n const regex = /\\[(\\d+)\\]/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n // Add text before the match\n if (match.index > lastIndex) {\n parts.push(text.slice(lastIndex, match.index));\n }\n\n const num = parseInt(match[1], 10);\n const footnoteMatchIndex = match.index;\n const { displayNumber: displayNum, citation } = resolveFootnote(num, citations, footnoteRenumber);\n const pendingCitationMarker = () => (\n \n \n \n );\n\n if (citation && isTranscriptCitation(citation)) {\n const isUnavailable = citation.citation_unavailable === true;\n // Inline footnote reference: primary citation (cube symbol). Unavailability\n // is conveyed via the tooltip copy rather than a separate marker color.\n parts.push(\n \n )\n }\n placement=\"bottom-start\"\n slotProps={{\n tooltip: {\n sx: (theme) => ({\n bgcolor: \"transparent\",\n color: \"text.primary\",\n p: 0,\n maxWidth: \"none\",\n boxShadow: theme.tokens.shadows.none,\n }),\n },\n }}\n >\n {\n e.stopPropagation();\n onOpenCitation?.(citation, \"inline_footnote\");\n if (openTranscript) {\n e.preventDefault();\n openTranscript(citation.transcript_id, citation.excerpt, citation.location);\n }\n }}\n />\n ,\n );\n } else if (citation && (isCourtRecordCitation(citation) || isUploadedDocumentCitation(citation))) {\n const href = safeSourceHref(citation.download_url);\n if (href) {\n parts.push(\n e.stopPropagation()}\n />,\n );\n } else {\n if (isStreaming) parts.push(pendingCitationMarker());\n else if (preserveUnresolvedMarkers) parts.push(match[0]);\n }\n } else {\n if (isStreaming) parts.push(pendingCitationMarker());\n else if (preserveUnresolvedMarkers) parts.push(match[0]);\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts;\n}\n\n/**\n * Process text nodes to make download filenames clickable.\n */\nfunction processDownloadRefs(\n parts: (string | React.ReactElement)[],\n downloadFiles: Array<{ filename: string; sizeBytes?: number; url: string }>,\n onDownloadFile?: (file: { filename: string; sizeBytes?: number }) => void,\n): (string | React.ReactElement)[] {\n if (downloadFiles.length === 0) return parts;\n\n const result: (string | React.ReactElement)[] = [];\n for (const part of parts) {\n if (typeof part !== \"string\") {\n result.push(part);\n continue;\n }\n let remaining = part;\n let found = false;\n for (const file of downloadFiles) {\n const idx = remaining.indexOf(file.filename);\n if (idx !== -1) {\n found = true;\n if (idx > 0) result.push(remaining.slice(0, idx));\n result.push(\n {\n e.stopPropagation();\n onDownloadFile?.(file);\n }}\n sx={{\n color: \"primary.main\",\n textDecoration: \"none\",\n fontWeight: 500,\n \"&:hover\": { textDecoration: \"underline\" },\n }}\n >\n {file.filename}\n ,\n );\n remaining = remaining.slice(idx + file.filename.length);\n break; // one match per text node is sufficient\n }\n }\n if (!found) {\n result.push(remaining);\n } else if (remaining) {\n result.push(remaining);\n }\n }\n return result;\n}\n\n/**\n * Enhanced text processing: footnotes + download file refs.\n */\nfunction withEnhancements(\n children: React.ReactNode,\n citations: CitationData[],\n downloadFiles: Array<{ filename: string; sizeBytes?: number; url: string }>,\n footnoteRenumber?: Map,\n onDownloadFile?: (file: { filename: string; sizeBytes?: number }) => void,\n onOpenCitation?: (citation: TranscriptCitationData, source: ClerkCitationSource) => void,\n openTranscript?: (transcriptId: number, excerpt?: string, location?: TranscriptCitationData[\"location\"]) => void,\n isStreaming = false,\n preserveUnresolvedMarkers = false,\n): React.ReactNode {\n return React.Children.map(children, (child) => {\n if (typeof child === \"string\") {\n let processed = processFootnoteRefs(\n child,\n citations,\n footnoteRenumber,\n onOpenCitation,\n openTranscript,\n isStreaming,\n preserveUnresolvedMarkers,\n );\n processed = processDownloadRefs(processed, downloadFiles, onDownloadFile);\n if (processed.length === 1 && processed[0] === child) {\n return child;\n }\n return <>{processed};\n }\n if (React.isValidElement(child)) {\n const props = child.props as {\n children?: React.ReactNode;\n component?: React.ElementType;\n node?: { tagName?: string };\n };\n if (\n child.type === \"code\" ||\n child.type === \"pre\" ||\n props.component === \"code\" ||\n props.component === \"pre\" ||\n props.node?.tagName === \"code\" ||\n props.node?.tagName === \"pre\"\n ) {\n return child;\n }\n if (!props.children) return child;\n return React.cloneElement(child as React.ReactElement, {\n children: withEnhancements(\n props.children,\n citations,\n downloadFiles,\n footnoteRenumber,\n onDownloadFile,\n onOpenCitation,\n openTranscript,\n isStreaming,\n preserveUnresolvedMarkers,\n ),\n });\n }\n return child;\n });\n}\n\n/** Build markdown components with footnote-aware text processing */\nexport function getMarkdownComponents(\n citations: CitationData[],\n downloadFiles: Array<{ filename: string; sizeBytes?: number; url: string }> = [],\n footnoteRenumber?: Map,\n onDownloadFile?: (file: { filename: string; sizeBytes?: number }) => void,\n onOpenCitation?: (citation: TranscriptCitationData, source: ClerkCitationSource) => void,\n openTranscript?: (transcriptId: number, excerpt?: string, location?: TranscriptCitationData[\"location\"]) => void,\n onRequestJudge?: (judgeName: string) => void,\n isStreaming = false,\n preserveUnresolvedMarkers = false,\n enableInlineCitationLinks = false,\n) {\n const linkSx = {\n color: \"text.secondary\",\n textDecoration: \"underline\",\n \"&:hover\": { color: \"text.primary\" },\n } as const;\n\n const fn = (c: React.ReactNode) =>\n withEnhancements(\n c,\n citations,\n downloadFiles,\n footnoteRenumber,\n onDownloadFile,\n onOpenCitation,\n openTranscript,\n isStreaming,\n preserveUnresolvedMarkers,\n );\n\n return {\n p: ({ children }: { children?: React.ReactNode }) => (\n \n {fn(children)}\n \n ),\n h1: ({ children }: { children?: React.ReactNode }) => {children},\n h2: ({ children }: { children?: React.ReactNode }) => {children},\n h3: ({ children }: { children?: React.ReactNode }) => (\n \n {children}\n \n ),\n h4: ({ children }: { children?: React.ReactNode }) => (\n \n {children}\n \n ),\n ul: ({ children }: { children?: React.ReactNode }) => (\n \n {children}\n \n ),\n ol: ({ children }: { children?: React.ReactNode }) => (\n \n {children}\n \n ),\n li: ({ children }: { children?: React.ReactNode }) => (\n \n {fn(children)}\n \n ),\n table: ({ children }: { children?: React.ReactNode }) => (\n \n ({\n width: \"100%\",\n borderCollapse: \"collapse\",\n fontSize: \"0.8rem\",\n \"& th, & td\": {\n border: `1px solid ${theme.border.default}`,\n px: 1.5,\n py: 0.75,\n textAlign: \"left\",\n },\n \"& th\": {\n fontWeight: 500,\n color: theme.palette.text.secondary,\n },\n })}\n >\n {fn(children)}\n \n \n ),\n code: ({ children, className }: { children?: React.ReactNode; className?: string }) => {\n const isBlock = className?.startsWith(\"language-\");\n if (isBlock) {\n return (\n ({\n bgcolor: \"snippet.background\",\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n p: 1.5,\n overflowX: \"auto\",\n ...theme.typography.mono,\n })}\n >\n {children}\n \n );\n }\n return (\n ({\n bgcolor: \"snippet.background\",\n borderRadius: 0.5,\n px: 0.5,\n py: 0.25,\n ...theme.typography.mono,\n })}\n >\n {children}\n \n );\n },\n pre: ({ children }: { children?: React.ReactNode }) => <>{children},\n blockquote: ({ children }: { children?: React.ReactNode }) => (\n ({\n // Matches the transcript-body Turn accent rule (2px solid primary.main).\n borderLeft: `2px solid ${theme.palette.primary.main}`,\n pl: 2,\n ml: 0.5,\n mb: 1.5,\n color: \"text.primary\",\n fontStyle: \"italic\",\n })}\n >\n {fn(children)}\n \n ),\n hr: () => ,\n a: ({ href, children }: { href?: string; children?: React.ReactNode }) => {\n const inlineCitationNumber = enableInlineCitationLinks ? inlineCitationLinkNumber(href) : undefined;\n if (inlineCitationNumber !== undefined) {\n const { citation } = resolveFootnote(inlineCitationNumber, citations, footnoteRenumber);\n if (!citation || !isTranscriptCitation(citation)) return <>{children};\n\n return (\n ) => {\n event.stopPropagation();\n onOpenCitation?.(citation, \"inline_case_link\");\n if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {\n return;\n }\n\n if (!openTranscript) return;\n\n event.preventDefault();\n openTranscript(citation.transcript_id, citation.excerpt, citation.location);\n }}\n sx={linkSx}\n >\n {children}\n \n );\n }\n\n if (href?.startsWith(\"action:request-judge\")) {\n const url = new URL(href, \"http://placeholder\");\n const judgeName = url.searchParams.get(\"name\") || \"\";\n if (!canRequestJudge()) return <>;\n if (!onRequestJudge) return <>{children};\n return (\n onRequestJudge?.(judgeName)}\n sx={{\n mt: 1.5,\n mb: 0.5,\n fontWeight: 600,\n letterSpacing: 0.5,\n bgcolor: \"primary.main\",\n \"&:hover\": { bgcolor: \"primary.dark\" },\n }}\n >\n Request Judge\n \n );\n }\n const safeHref = safeMarkdownHref(href);\n return (\n \n {children}\n \n );\n },\n img: ({ src, alt }: { src?: string; alt?: string }) => {\n if (inlineCitationLinkNumber(src) !== undefined) return <>{alt};\n\n const safeSrc = safeMarkdownHref(src);\n return safeSrc ? {alt : <>{alt};\n },\n strong: ({ children }: { children?: React.ReactNode }) => {children},\n em: ({ children }: { children?: React.ReactNode }) => {children},\n };\n}\n\nfunction safeMarkdownHref(href?: string): string | undefined {\n if (!href) return undefined;\n return /^(https?:|mailto:|\\/(?!\\/))/i.test(href) ? href : undefined;\n}\n\nexport function markdownUrlTransform(url: string): string {\n if (inlineCitationLinkNumber(url) !== undefined) return url;\n if (url.startsWith(\"action:request-judge\")) return url;\n return /^(https?:|mailto:|\\/(?!\\/))/i.test(url) ? url : \"\";\n}\n\nfunction looksLikeVisibleUrl(value?: string): boolean {\n return !!value && /^(https?:|\\/|\\/\\/)/i.test(value.trim());\n}\n\nfunction documentDownloadCardTitle(citation: CitationData): string {\n if (isUploadedDocumentCitation(citation)) return citation.filename || \"Uploaded document\";\n if (!isCourtRecordCitation(citation)) return \"Download court record\";\n\n const title = [\n citation.document_title,\n citation.title_for_citation,\n citation.citation,\n citation.raw_docket_text,\n ].find((candidate) => candidate && !looksLikeVisibleUrl(candidate));\n\n if (title) return title.trim();\n if (citation.docket_number) return `Download Dkt. ${citation.docket_number}`;\n return \"Download court record\";\n}\n\nfunction documentDownloadCardFilename(citation: CitationData): string {\n if (isCourtRecordCitation(citation) && citation.filename?.trim()) return citation.filename;\n\n const title = documentDownloadCardTitle(citation).replace(/\\s+/g, \" \").trim();\n if (/\\.[a-z0-9]{2,5}$/i.test(title)) return title;\n return `${title}.pdf`;\n}\n\nfunction documentDownloadCardSizeBytes(citation: CitationData): number | undefined {\n if (!isCourtRecordCitation(citation) && !isUploadedDocumentCitation(citation)) return undefined;\n\n const candidates = [\n citation.file_size_bytes,\n (citation as CitationData & { size_bytes?: number }).size_bytes,\n (citation as CitationData & { sizeBytes?: number }).sizeBytes,\n ];\n\n return candidates.find((candidate) => typeof candidate === \"number\" && Number.isFinite(candidate));\n}\n\nfunction documentDownloadCardPageCount(citation: CitationData): number | undefined {\n if (!isCourtRecordCitation(citation) && !isUploadedDocumentCitation(citation)) return undefined;\n\n const pageCount = citation.page_count;\n return typeof pageCount === \"number\" && Number.isFinite(pageCount) && pageCount > 0\n ? Math.floor(pageCount)\n : undefined;\n}\n\nfunction courtRecordDownloadCardFiles(citations: CitationData[]): DownloadCardFile[] {\n const seen = new Set();\n const files: DownloadCardFile[] = [];\n\n for (const citation of citations) {\n if ((!isCourtRecordCitation(citation) && !isUploadedDocumentCitation(citation)) || citation.read === false)\n continue;\n\n const url = safeSourceHref(citation.download_url);\n if (!url || seen.has(url)) continue;\n\n seen.add(url);\n files.push({\n filename: documentDownloadCardFilename(citation),\n pageCount: documentDownloadCardPageCount(citation),\n sizeBytes: documentDownloadCardSizeBytes(citation),\n displayFileSize: false,\n url,\n });\n }\n\n return files;\n}\n\nfunction mergeDownloadCardFiles(\n baseFiles: DownloadCardFile[],\n courtRecordFiles: DownloadCardFile[],\n): DownloadCardFile[] {\n const courtRecordFilesByKey = new Map(courtRecordFiles.map((file) => [file.url || file.filename, file]));\n const seen = new Set();\n const files: DownloadCardFile[] = [];\n\n for (const baseFile of baseFiles) {\n const key = baseFile.url || baseFile.filename;\n const courtRecordFile = courtRecordFilesByKey.get(key);\n const file = courtRecordFile ? { ...baseFile, ...courtRecordFile } : baseFile;\n if (seen.has(key)) continue;\n\n seen.add(key);\n files.push(file);\n }\n\n for (const file of courtRecordFiles) {\n const key = file.url || file.filename;\n if (seen.has(key)) continue;\n\n seen.add(key);\n files.push(file);\n }\n\n return files;\n}\n\ninterface InlineResponseErrorProps {\n children: React.ReactNode;\n hasContent: boolean;\n severity?: \"error\" | \"warning\";\n onRetry?: () => void;\n retrying?: boolean;\n retryDisabled?: boolean;\n}\n\nconst InlineResponseError: React.FC = ({\n children,\n hasContent,\n severity = \"error\",\n onRetry,\n retrying = false,\n retryDisabled = false,\n}) => (\n \n {retrying ? \"Retrying\u2026\" : \"Retry\"}\n \n ) : undefined\n }\n >\n {children}\n \n);\n\nconst AgentPrototypeMessage: React.FC = React.memo(\n ({\n message,\n onForkMessage,\n onSteerMessage,\n canSteer = false,\n onCancelAndEditMessage,\n messageActionPending,\n pendingMessageActionType,\n nextSteps,\n onSelectNextStep,\n suppressLiveProgress = false,\n sessionId,\n sessionToken,\n onRetry,\n onRetryDownloadLoad,\n downloadLoadRetryDisabled = false,\n openTranscript,\n onRequestJudge,\n readOnly = false,\n highlights,\n onTextSelected,\n onHighlightClick,\n scrollContainerRef,\n }) => {\n const isUser = message.role === \"user\";\n const messageQueueEnabled = featureEnabled(\"clerk_message_queue\");\n // Planning messages retain this identity after approval and when reopened.\n // A cycle token alone also belongs to research execution, so use the message role.\n const isPlanningMessage = Boolean(message.metadata?.planning_message_role);\n const hideProgress = isPlanningMessage || (suppressLiveProgress && message.isStreaming);\n const { setAlertWithOptions } = useGlobalAlert();\n const highlightsEnabled = featureEnabled(\"folders_and_annotations\");\n const contentRef = useRef(null);\n\n // Apply highlight overlay on rendered markdown content (agent sessions only)\n useHighlightOverlay(\n contentRef,\n highlightsEnabled ? highlights : undefined,\n onHighlightClick ?? (() => {}),\n highlightsEnabled && !message.isStreaming,\n );\n\n /**\n * Listen for mouseup at the document level so text selections that end\n * outside the message bubble (e.g. the user drags into the chat gutter)\n * still notify the parent. The native selection range is still clamped to\n * the bubble's text \u2014 getSelectionOffsets' containment check ignores\n * selections made elsewhere on the page.\n *\n * Highlight clicks are handled by useHighlightOverlay's own click\n * listeners, so this effect is purely the selection-detection branch.\n */\n useEffect(() => {\n const serverMessageId = message.serverMessageId;\n if (!highlightsEnabled || !onTextSelected || !serverMessageId) return;\n const handleDocumentMouseUp = () => {\n if (!contentRef.current) return;\n const selection = window.getSelection();\n if (!selection?.toString().trim()) return;\n const offsets = getSelectionOffsets(contentRef.current);\n if (!offsets) return;\n onTextSelected(offsets, serverMessageId);\n };\n document.addEventListener(\"mouseup\", handleDocumentMouseUp);\n return () => document.removeEventListener(\"mouseup\", handleDocumentMouseUp);\n }, [highlightsEnabled, onTextSelected, message.serverMessageId]);\n\n const handleOpenCitation = useCallback(\n (citation: TranscriptCitationData, source: ClerkCitationSource) => {\n if (!sessionId) return;\n\n void recordUserEvent({\n event_name: \"click_transcript_citation_from_clerk_response\",\n event_properties: {\n session_id: sessionId,\n transcript_id: citation.transcript_id,\n citation_source: source,\n citation_unavailable: citation.citation_unavailable === true,\n },\n });\n },\n [sessionId],\n );\n\n const handleResponseFileDownload = useCallback(\n (file: { filename: string; sizeBytes?: number }) => {\n if (!sessionId || typeof file.sizeBytes !== \"number\") return;\n\n void recordUserEvent({\n event_name: \"download_clerk_response_file\",\n event_properties: {\n session_id: sessionId,\n file_extension: normalizeFileExtension(file.filename),\n size_bucket: clerkResponseFileSizeBucket(file.sizeBytes),\n },\n });\n },\n [sessionId],\n );\n\n const cleanContent = useMemo(() => stripCitationMapControlText(message.content), [message.content]);\n // Session polling rebuilds these arrays even when nothing changed. Keeping\n // them stable keeps the markdown component types stable, so React doesn't\n // remount the rendered paragraphs (which would collapse highlight ranges\n // and clear the user's text selection).\n const orderedCitations = useStableValue(message.citations);\n const downloadFiles = useStableValue(message.downloadFiles);\n const courtRecordDownloadFiles = useMemo(() => courtRecordDownloadCardFiles(orderedCitations), [orderedCitations]);\n const downloadCardFiles = useMemo(\n () =>\n message.downloadSelectionExplicit || message.isStreaming\n ? downloadFiles\n : mergeDownloadCardFiles(downloadFiles, courtRecordDownloadFiles),\n [downloadFiles, message.downloadSelectionExplicit, message.isStreaming, courtRecordDownloadFiles],\n );\n // Unread citations retain their original array slot but do not consume a display number.\n const footnoteRenumber = useMemo(() => {\n const renumber = new Map();\n let seq = 0;\n for (let i = 0; i < orderedCitations.length; i++) {\n if (orderedCitations[i].read !== false) {\n seq++;\n renumber.set(i + 1, seq);\n }\n }\n return renumber;\n }, [orderedCitations]);\n const components = useMemo(\n () =>\n getMarkdownComponents(\n orderedCitations,\n downloadFiles,\n footnoteRenumber,\n handleResponseFileDownload,\n handleOpenCitation,\n openTranscript,\n onRequestJudge,\n message.isStreaming,\n isUser,\n !isUser,\n ),\n [\n orderedCitations,\n downloadFiles,\n footnoteRenumber,\n openTranscript,\n handleOpenCitation,\n handleResponseFileDownload,\n onRequestJudge,\n message.isStreaming,\n isUser,\n ],\n );\n const markdownRemarkPlugins = useMemo(\n () => [remarkGfm, collapseDocumentCitationBlocks(orderedCitations)],\n [orderedCitations],\n );\n const showSources = hasInlineFootnoteReferences(cleanContent);\n const copyContent = useMemo(\n () =>\n isUser\n ? cleanContent\n : copyableCitationMarkdown(\n cleanContent,\n orderedCitations,\n footnoteRenumber,\n typeof window === \"undefined\" ? \"http://localhost\" : window.location.origin,\n ),\n [cleanContent, orderedCitations, footnoteRenumber, isUser],\n );\n const hasUnavailableCitationDetails = useMemo(\n () =>\n !isUser &&\n !message.isStreaming &&\n !message.isError &&\n hasUnresolvedFootnotes(cleanContent, orderedCitations, footnoteRenumber),\n [cleanContent, orderedCitations, footnoteRenumber, isUser, message.isStreaming, message.isError],\n );\n\n const failedTurnMessage = message.errorMessage || CLERK_ERROR_COPY.genericRetry;\n const errorOnlyContent = !isUser && message.isError && cleanContent.trim() === failedTurnMessage.trim();\n const showContentAsProse = Boolean(cleanContent) && !errorOnlyContent;\n const showMessageActions = showContentAsProse && !message.isStreaming && !isPlanningMessage;\n\n if (isUser) {\n const showQueuedAppearance =\n message.queueState === \"pending\" &&\n !message.isStopAccepted &&\n !message.isSteerAccepted &&\n !message.steerRequestedAt;\n return (\n \n ({\n bgcolor: messageQueueEnabled\n ? colors.taupe[showQueuedAppearance ? 200 : 300]\n : theme.palette.userbubble.background,\n color: messageQueueEnabled && showQueuedAppearance ? theme.palette.text.secondary : undefined,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n p: 2,\n maxWidth: \"580px\",\n \"& p, & li\": {\n fontSize: theme.typography.body2.fontSize,\n lineHeight: theme.typography.body2.lineHeight,\n fontWeight: theme.typography.body2.fontWeight,\n },\n })}\n >\n {message.files && message.files.length > 0 && (\n \n {message.files.map((file, i) => {\n const downloadUrl = sessionToken\n ? `/api/agent-prototype/sessions/${sessionToken}/files/${encodeURIComponent(file.name)}`\n : undefined;\n return (\n }\n label={file.name}\n size=\"small\"\n variant=\"outlined\"\n clickable={!!downloadUrl}\n component={downloadUrl ? \"a\" : \"div\"}\n href={downloadUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n sx={(theme) => ({\n height: 22,\n fontSize: \"0.7rem\",\n borderColor: theme.border.default,\n color: \"primary.main\",\n textDecoration: \"none\",\n \"& .MuiChip-icon\": { color: \"primary.main\", opacity: 0.6 },\n ...(downloadUrl && {\n \"&:hover\": {\n borderColor: theme.palette.primary._states.outlinedBorder,\n },\n }),\n })}\n />\n );\n })}\n \n )}\n {cleanContent && (\n *:first-child\": { mt: 0 }, \"& > *:last-child\": { mb: 0 } }}>\n \n {cleanContent}\n \n \n )}\n \n {messageQueueEnabled && (\n \n )}\n \n );\n }\n\n return (\n \n \n {/* Attached files */}\n {isUser && message.files && message.files.length > 0 && (\n \n {message.files.map((file, i) => {\n const downloadUrl = sessionToken\n ? `/api/agent-prototype/sessions/${sessionToken}/files/${encodeURIComponent(file.name)}`\n : undefined;\n return (\n }\n label={file.name}\n size=\"small\"\n variant=\"outlined\"\n clickable={!!downloadUrl}\n component={downloadUrl ? \"a\" : \"div\"}\n href={downloadUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n sx={(theme) => ({\n height: 22,\n fontSize: \"0.7rem\",\n borderColor: theme.border.default,\n color: \"primary.main\",\n textDecoration: \"none\",\n \"& .MuiChip-icon\": { color: \"primary.main\", opacity: 0.6 },\n ...(downloadUrl && {\n \"&:hover\": {\n borderColor: theme.palette.primary._states.outlinedBorder,\n },\n }),\n })}\n />\n );\n })}\n \n )}\n\n {/* Message content */}\n {showContentAsProse && (\n \n \n {cleanContent}\n \n {message.isStreaming && (\n \n )}\n {highlightsEnabled && highlights && highlights.length > 0 && scrollContainerRef && (\n {\n if (onHighlightClick) onHighlightClick(highlight, anchorEl);\n }}\n />\n )}\n \n )}\n\n {hasUnavailableCitationDetails && (\n ({\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 0.5,\n mt: cleanContent ? 0.75 : 0,\n maxWidth: \"100%\",\n p: 1,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n backgroundColor: alpha(theme.palette.error.main, 0.08),\n border: `1px solid ${theme.palette.error.light}`,\n })}\n >\n \n \n \n \n {CLERK_ERROR_COPY.citationGenerationFailure}\n \n \n )}\n\n {/* Empty streaming state */}\n {!isUser && !hideProgress && message.isStreaming && !message.content && message.thinking.length === 0 && (\n \n {[0, 1, 2].map((i) => (\n \n ))}\n \n )}\n\n {/* Explicit failed-turn state */}\n {!isUser && message.isError && (\n \n {failedTurnMessage}\n \n )}\n\n {!isUser && (message.downloadLoadState === \"error\" || message.downloadLoadState === \"retrying\") && (\n \n {CLERK_ERROR_COPY.responseDetailsLoadFailure}\n \n )}\n\n {/* Download cards for output files */}\n {!isUser && downloadCardFiles.length > 0 && (\n \n {downloadCardFiles.map((file, i) => (\n \n ))}\n \n )}\n\n {/* Agent thinking steps \u2014 below message content */}\n {!isUser && !hideProgress && (\n \n )}\n\n {/* Numbered footnotes with Bluebook citations */}\n {!isUser && !message.isStreaming && showSources && (\n \n )}\n\n {/* Response actions and timestamp */}\n {showMessageActions && (\n 0}\n downloadFileCount={downloadCardFiles.length}\n initialFeedback={message.feedback}\n readOnly={readOnly}\n setAlertWithOptions={setAlertWithOptions}\n />\n )}\n {showMessageActions && !readOnly && nextSteps && onSelectNextStep && (\n \n )}\n \n \n );\n },\n);\n\nexport default AgentPrototypeMessage;\n", "/**\n * Dev-only sample Clerk session \u2014 a curated list of ChatMessage objects that\n * covers every typography / styling surface inside `AgentPrototypeMessage`:\n * paragraph copy, headings, bullet + numbered lists, inline + block code,\n * bold + italic, links, blockquote, GFM table, citation references, and\n * variant message shells (thinking, tool calls, file attachments, errors,\n * download-files, feedback state).\n *\n * Used by `injectClerkSession.ts` when `localStorage.devInjectClerkSession`\n * is `\"1\"`. Real session data is never overwritten \u2014 only empty sessions\n * (zero messages) get filled with these samples.\n */\n\nimport type { ChatMessage } from \"../hooks/useAgentPrototypeSession\";\n\nconst userMessage = (id: string, content: string): ChatMessage => ({\n id,\n role: \"user\",\n content,\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n});\n\nconst assistantMessage = (id: string, content: string, overrides: Partial = {}): ChatMessage => ({\n id,\n role: \"assistant\",\n content,\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n ...overrides,\n});\n\nexport const SAMPLE_CLERK_MESSAGES: ChatMessage[] = [\n // \u2500\u2500 1. Plain paragraph response \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-1\", \"What is a stalking horse bidder?\"),\n assistantMessage(\n \"sample-a-1\",\n `A **stalking horse bidder** is the initial bidder selected by a debtor in a section 363 sale to set a baseline for an asset auction. The stalking horse's offer establishes the floor price and the deal terms that competing bidders must beat.\n\nThe arrangement typically includes *bid protections* \u2014 a break-up fee and expense reimbursement \u2014 that incentivize the stalking horse to invest the time and resources in due diligence even though they may ultimately be outbid.`,\n ),\n\n // \u2500\u2500 2. Headings + lists + inline formatting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-2\", \"Walk me through the typical first-day motions in a Chapter 11 case.\"),\n assistantMessage(\n \"sample-a-2\",\n `## First-day motions overview\n\nIn a typical Chapter 11 case, debtors file a package of \"first-day motions\" on or shortly after the petition date to keep the business operating during the early days of the bankruptcy.\n\n### Operational relief\n\nThe most common operational motions include:\n\n- **Cash management** \u2014 authority to continue using existing bank accounts and treasury practices.\n- **Wages and benefits** \u2014 authority to pay pre-petition employee compensation up to the statutory cap.\n- **Utilities** \u2014 adequate-assurance procedures under section 366.\n- **Critical vendors** \u2014 authority to pay select pre-petition trade claims to avoid supply disruption.\n\n### Financing relief\n\nTwo financing motions usually run on parallel tracks:\n\n1. **Cash collateral** \u2014 if the debtor has consensual lender support to use existing collateral.\n2. **DIP financing** \u2014 a new-money facility, often with priming liens, to fund the case through confirmation.\n\nThe court usually enters interim orders on the first day and schedules a final hearing within 14\u201330 days.`,\n ),\n\n // \u2500\u2500 3. Code block + inline code \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-3\", \"Show me the section that defines the automatic stay.\"),\n assistantMessage(\n \"sample-a-3\",\n `The automatic stay lives in \\`11 U.S.C. \u00A7 362(a)\\`. The core operative paragraph reads:\n\n\\`\\`\\`\n(a) Except as provided in subsection (b) of this section, a petition filed\nunder section 301, 302, or 303 of this title... operates as a stay,\napplicable to all entities, of \u2014\n (1) the commencement or continuation, including the issuance or\n employment of process, of a judicial, administrative, or other\n action or proceeding against the debtor that was or could have\n been commenced before the commencement of the case under this\n title, or to recover a claim against the debtor that arose\n before the commencement of the case under this title;\n\\`\\`\\`\n\nSubsection \\`(b)\\` enumerates the exceptions \u2014 most notably criminal proceedings, certain tax assessments, and government regulatory actions.`,\n ),\n\n // \u2500\u2500 4. Citations (footnote-style markers) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-4\", \"Has Judge Walrath addressed the parameters of a KEIP recently?\"),\n assistantMessage(\n \"sample-a-4\",\n `Yes. Judge Mary F. Walrath has weighed in on KEIP structure and metrics in several recent cases, generally requiring that the program be **incentivizing rather than retentive** to satisfy section 503(c)(3).\n\nIn the *Enduro Resource Partners* case, the court approved the debtor's KEIP after reducing one performance metric the U.S. Trustee characterized as a layup [1]. The court emphasized that the metrics must require meaningful effort \u2014 pure tenure-based bonuses don't qualify [2].\n\nMore recently, in a 2024 hearing the court approved a KEIP for senior management while denying an analogous Key Employee Retention Plan (\"KERP\") for the same executives, citing the prohibition on retentive bonuses for insiders [3].`,\n {\n citations: [\n {\n transcript_id: 1001,\n excerpt:\n \"THE COURT: I'm prepared to approve the KEIP as modified \u2014 the modification being that we're going to remove the EBITDA performance hurdle that the U.S. Trustee correctly described as a layup. With that change, I find the program is sufficiently incentivizing under 503(c)(3).\",\n speaker: \"Judge Walrath\",\n speaker_role: \"judge\",\n case_name: \"Enduro Resource Partners LLC\",\n case_number: \"18-11243\",\n judge_name: \"Mary F. Walrath\",\n date_of_hearing: \"2018-06-14\",\n citation: \"Enduro Resource Partners LLC (Jun. 14, 2018)\",\n },\n {\n transcript_id: 1002,\n excerpt:\n \"THE COURT: Tenure-based bonuses for senior management \u2014 payable simply for staying through emergence \u2014 fall on the retentive side of the line and don't survive 503(c)(3). The plan needs hurdles that require meaningful effort.\",\n speaker: \"Judge Walrath\",\n speaker_role: \"judge\",\n case_name: \"Times Square JV LLC\",\n case_number: \"22-11715\",\n judge_name: \"Mary F. Walrath\",\n date_of_hearing: \"2022-12-30\",\n citation: \"Times Square JV LLC (Dec. 30, 2022)\",\n },\n {\n transcript_id: 1003,\n excerpt:\n \"THE COURT: I'm approving the KEIP for the named senior officers but I am not approving the parallel KERP for the same individuals. You can't carve up a single bonus pool into two programs and call half of it incentive.\",\n speaker: \"Judge Walrath\",\n speaker_role: \"judge\",\n case_name: \"Friedman v. Wellspring Capital Management, LLC et al\",\n case_number: \"20-50554\",\n judge_name: \"Mary F. Walrath\",\n date_of_hearing: \"2024-03-21\",\n citation: \"Friedman v. Wellspring (Mar. 21, 2024)\",\n },\n ],\n },\n ),\n\n // \u2500\u2500 5. Blockquote + link \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-5\", \"Quote me the standard for adequate protection.\"),\n assistantMessage(\n \"sample-a-5\",\n `The classic articulation comes from *In re Mosello*, where the court explained:\n\n> \"The purpose of adequate protection is to safeguard the secured creditor from diminution in the value of its interest during the chapter 11 reorganization.\"\n\nThe mechanism is rooted in [section 361 of the Bankruptcy Code](https://www.law.cornell.edu/uscode/text/11/361), which lists three non-exclusive forms: cash payments, additional or replacement liens, and the catch-all \"indubitable equivalent.\"`,\n ),\n\n // \u2500\u2500 6. GFM table \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-6\", \"Compare the priority of administrative claims under 503(b).\"),\n assistantMessage(\n \"sample-a-6\",\n `Section 503(b) priority for administrative expenses breaks down roughly like this:\n\n| Category | Code section | Typical example |\n|---|---|---|\n| Operating costs | 503(b)(1)(A) | Post-petition payroll, rent |\n| Tax claims | 503(b)(1)(B)\u2013(C) | Post-petition tax obligations |\n| Professional fees | 503(b)(2) | Counsel and financial advisors retained under 327 |\n| 503(b)(9) claims | 503(b)(9) | Goods received within 20 days pre-petition |\n| KEIP awards | 503(c)(3) | Performance bonuses for non-insiders |\n\nAll 503(b) claims share the same priority \u2014 there is no internal hierarchy between subsections.`,\n ),\n\n // \u2500\u2500 7. Streaming / in-progress \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-7\", \"Walk me through 363(m) mootness.\"),\n assistantMessage(\n \"sample-a-7\",\n `Section 363(m) protects a sale order from being undone on appeal once the assets have been transferred to a good-faith purchaser. The Supreme Court clarified in *MOAC Mall Holdings* that 363(m) is a`,\n {\n isStreaming: true,\n thinkingSinceLastTool:\n \"User wants the post-MOAC framework. I should acknowledge that 363(m) is no longer jurisdictional and walk through the new statutory-limit framing \u2014 equitable mootness vs statutory mootness distinction.\",\n },\n ),\n\n // \u2500\u2500 8. Tool call + tool result \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-8\", \"Have any judges in DE addressed crypto exchange Chapter 11 retention?\"),\n assistantMessage(\n \"sample-a-8\",\n `I searched the Delaware bankruptcy docket for retention rulings in crypto exchange Chapter 11 cases. Here's what came back from a sample of recent hearings.`,\n {\n toolCalls: [\n {\n tool: \"search_transcripts\",\n input: {\n query: \"crypto exchange retention\",\n district: \"DE\",\n date_range: \"2022-2025\",\n },\n },\n ],\n toolResults: [\n {\n tool: \"search_transcripts\",\n summary:\n \"Returned 12 transcripts across 4 cases (FTX, Genesis, Voyager, Celsius). Retention orders appear at the typical first-day window with KEIP follow-ons 30\u201360 days later.\",\n },\n ],\n },\n ),\n\n // \u2500\u2500 9. File attachments + thinking \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n ...userMessage(\"sample-u-9\", \"I'm attaching the proposed bidding procedures order \u2014 please flag anything unusual.\"),\n files: [\n {\n name: \"bidding_procedures_order_draft.docx\",\n size: 187400,\n type: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n },\n ],\n },\n assistantMessage(\n \"sample-a-9\",\n `I reviewed the bidding-procedures order you attached. Two provisions stand out:\n\n1. **Break-up fee size.** The 4.5% break-up fee is on the high end \u2014 most DE judges have approved 2\u20133% in comparably sized cases. Be ready to defend it on the record.\n2. **Bid deadline ahead of objection deadline.** Competing bidders must commit before the U.S. Trustee's objection deadline. That sequencing has drawn pushback in *In re Genesis Global*; consider flipping the order.\n\nOtherwise the structure tracks the standard form.`,\n {\n thinking: [\n \"User wants a substantive legal review. I should compare the break-up fee against the DE benchmarks and note the timing-mismatch issue if I see it.\",\n \"Confirmed timing issue: bid deadline at day 21, objection deadline at day 28. That's the inversion the U.S. Trustee flagged in Genesis. Worth raising.\",\n ],\n files: [\n {\n name: \"bidding_procedures_order.pdf\",\n size: 234112,\n type: \"application/pdf\",\n },\n ],\n },\n ),\n\n // \u2500\u2500 10. Download files + feedback (thumbs up) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\n \"sample-u-10\",\n \"Generate a redlined version with my proposed edits and a research memo summarizing your changes.\",\n ),\n assistantMessage(\n \"sample-a-10\",\n `I drafted both deliverables. The redline applies your three edits (break-up fee 4.5% \u2192 3%, bid/objection deadlines swapped, qualified-bidder definition tightened). The research memo summarizes the rationale and cites the comparable transcripts.`,\n {\n downloadFiles: [\n {\n filename: \"bidding_procedures_order_redlined.docx\",\n sizeBytes: 256000,\n url: \"#\",\n },\n {\n filename: \"research_memo.pdf\",\n sizeBytes: 184000,\n url: \"#\",\n },\n ],\n feedback: { rating: true },\n },\n ),\n\n // \u2500\u2500 11. Error state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n userMessage(\"sample-u-11\", \"Pull all hearings where the Wagner court addressed substantive consolidation.\"),\n assistantMessage(\"sample-a-11\", \"\", {\n isError: true,\n errorMessage:\n \"Transcript search failed unexpectedly. Please try again \u2014 if the issue persists, send us the prompt and we'll investigate.\",\n }),\n];\n", "/**\n * Dev-only transformer that swaps an empty Clerk session for the curated\n * `SAMPLE_CLERK_MESSAGES` fixture so designers can review every message-level\n * typography surface in one place without driving a real session end-to-end.\n *\n * Two layers of defense to prevent this from ever firing in production:\n * 1. `process.env.NODE_ENV !== \"production\"` \u2014 esbuild inlines this at build\n * time, so the prod bundle dead-code-eliminates the entire branch.\n * 2. `localStorage.devInjectClerkSession === \"1\"` \u2014 opt-in even in dev.\n *\n * Usage in the dev browser console:\n * localStorage.devInjectClerkSession = \"1\"; // turn on, then reload\n * delete localStorage.devInjectClerkSession; // turn off, then reload\n *\n * When the flag is on, the fixture replaces whatever messages the chat would\n * normally render \u2014 real session data is hidden from view but never deleted\n * from server storage. Toggle the flag off and reload to see real messages\n * again.\n */\n\nimport { SAMPLE_CLERK_MESSAGES } from \"./sampleClerkSession\";\nimport type { ChatMessage } from \"../hooks/useAgentPrototypeSession\";\n\nconst STORAGE_KEY = \"devInjectClerkSession\";\n\nconst isInjectionEnabled = (): boolean => {\n if (process.env.NODE_ENV === \"production\") return false;\n if (typeof window === \"undefined\") return false;\n try {\n return window.localStorage.getItem(STORAGE_KEY) === \"1\";\n } catch {\n return false;\n }\n};\n\nexport function maybeInjectClerkSession(messages: ChatMessage[]): ChatMessage[] {\n if (!isInjectionEnabled()) return messages;\n return SAMPLE_CLERK_MESSAGES;\n}\n", "const HTML_ENTITIES: Record = {\n \" \": \" \",\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n \""\": '\"',\n \"'\": \"'\",\n \"'\": \"'\",\n};\n\n/**\n * Reduce a markdown string to plain, single-line text for compact display\n * (e.g. conversation-history list rows). Removes inline/block markdown syntax\n * rather than rendering it \u2014 a one-line row can't host block elements, and the\n * goal is to avoid showing raw markers like `**bold**` or leading `- `.\n */\nexport function stripMarkdown(input: string | null | undefined): string {\n if (!input) return \"\";\n\n return (\n input\n // Images / links: keep the visible text, drop the URL.\n .replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]\\([^)]*\\)/g, \"$1\")\n // Inline code and fenced code: keep the inner text.\n .replace(/```[a-zA-Z]*\\n?([\\s\\S]*?)```/g, \"$1\")\n .replace(/`([^`]+)`/g, \"$1\")\n // Emphasis / bold / strikethrough markers.\n .replace(/(\\*\\*|__)(.*?)\\1/g, \"$2\")\n .replace(/(\\*|_)(.*?)\\1/g, \"$2\")\n .replace(/~~(.*?)~~/g, \"$1\")\n // Leading block markers per line: headings, blockquotes, list bullets.\n .replace(/^[ \\t]*#{1,6}[ \\t]+/gm, \"\")\n .replace(/^[ \\t]*>[ \\t]?/gm, \"\")\n .replace(/^[ \\t]*(?:[-*+]|\\d+\\.)[ \\t]+/gm, \"\")\n // Common HTML entities.\n .replace(/ |&|<|>|"|'|'/g, (m) => HTML_ENTITIES[m] ?? m)\n // Collapse all whitespace (including newlines) to single spaces.\n .replace(/\\s+/g, \" \")\n .trim()\n );\n}\n", "import React from \"react\";\nimport { Box, Typography } from \"@mui/material\";\nimport type { BranchOrigin } from \"../../api/queries/agentPrototype.types\";\nimport { stripMarkdown } from \"../../utils/stripMarkdown\";\n\nexport default function BranchOriginDivider({ origin }: { origin: BranchOrigin }) {\n return (\n \n `1px solid ${theme.border.default}` }} />\n \n {origin.source_token ? (\n <>\n Branched from{\" \"}\n \n {stripMarkdown(origin.source_title || \"\") || \"New conversation\"}\n \n \n ) : (\n \"Branched from another conversation\"\n )}\n \n `1px solid ${theme.border.default}` }} />\n \n );\n}\n", "import type { NextStepSet, NextStepSuggestion } from \"./nextSteps\";\nimport React, { useRef, useEffect, useState, useCallback, useMemo } from \"react\";\nimport { Box, Fab } from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { ChevronDown } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport type { ChatMessage } from \"../../hooks/useAgentPrototypeSession\";\nimport AgentPrototypeMessage from \"./AgentPrototypeMessage\";\nimport type { Highlight } from \"../../api/queries/folders.types\";\nimport type { SelectionOffsets } from \"../../utils/getSelectionOffsets\";\nimport { PAGE_CONTENT_MAX_WIDTH } from \"../../utils/constants\";\nimport { maybeInjectClerkSession } from \"../../dev/injectClerkSession\";\nimport BranchOriginDivider from \"./BranchOriginDivider\";\nimport type { BranchOrigin, TranscriptCitationData } from \"../../api/queries/agentPrototype.types\";\n\ninterface AgentPrototypeChatProps {\n branchOrigin?: BranchOrigin | null;\n onForkMessage?: (message: ChatMessage) => void;\n canSteer?: boolean;\n onSteerMessage?: (message: ChatMessage) => void;\n onCancelAndEditMessage?: (message: ChatMessage) => void;\n pendingMessageActionId?: string;\n pendingMessageActionType?: \"fork\" | \"steer\" | \"cancel\" | null;\n messages: ChatMessage[];\n nextSteps?: NextStepSet;\n onSelectNextStep?: (suggestion: NextStepSuggestion) => void;\n suppressLiveProgress?: boolean;\n sessionId?: number;\n sessionToken?: string;\n hasMoreMessages?: boolean;\n onLoadOlderMessages?: () => Promise | void;\n onRetryRun?: (runId: string) => Promise | void;\n onRetryDownloadLoad?: (assistantId: string) => Promise | void;\n openTranscript?: (transcriptId: number, excerpt?: string, location?: TranscriptCitationData[\"location\"]) => void;\n onRequestJudge?: (judgeName: string) => void;\n readOnly?: boolean;\n /** All highlights for this session (from folders_and_annotations feature). */\n highlights?: Highlight[];\n /** Called when user selects text in a message. */\n onTextSelected?: (offsets: SelectionOffsets, messageId: number) => void;\n /** Called when user clicks on an existing highlight mark. */\n onHighlightClick?: (\n highlight: Highlight,\n anchorEl: HTMLElement | null,\n anchorPosition?: { top: number; left: number },\n ) => void;\n /**\n * Optional content rendered AFTER the last message but inside the\n * chat's scrollable column \u2014 same `mx: auto`-centered max-width\n * container as the messages, so anything passed here visually stacks\n * under the assistant's response as if it were part of the\n * conversation. Currently used by the locked-Clerk session view to\n * render its post-response footer (Search transcripts CTA + example\n * cards) inline with the canned answer.\n */\n trailingContent?: React.ReactNode;\n renderPlanningMessage?: (message: ChatMessage) => React.ReactNode | undefined;\n}\n\nconst AgentPrototypeChat: React.FC = ({\n messages: realMessages,\n branchOrigin,\n onForkMessage,\n onSteerMessage,\n canSteer = false,\n onCancelAndEditMessage,\n pendingMessageActionId,\n pendingMessageActionType,\n nextSteps,\n onSelectNextStep,\n sessionId,\n sessionToken,\n hasMoreMessages = false,\n onLoadOlderMessages,\n onRetryRun,\n onRetryDownloadLoad,\n openTranscript,\n onRequestJudge,\n readOnly = false,\n highlights,\n onTextSelected,\n onHighlightClick,\n trailingContent,\n renderPlanningMessage,\n suppressLiveProgress = false,\n}) => {\n const bottomRef = useRef(null);\n const containerRef = useRef(null);\n const userScrolledUp = useRef(false);\n const [showScrollButton, setShowScrollButton] = useState(false);\n const [isLoadingOlder, setIsLoadingOlder] = useState(false);\n\n // Dev-only fixture injection. In production this is a no-op (the helper\n // dead-code-eliminates the branch); in dev it swaps an empty session for\n // the curated `SAMPLE_CLERK_MESSAGES` when `localStorage.devInjectClerkSession === \"1\"`.\n const messages = maybeInjectClerkSession(realMessages);\n\n const isStreaming = messages.some((m) => m.isStreaming);\n\n // Track user scroll position\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n const { scrollTop, scrollHeight, clientHeight } = container;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n const scrolledUp = distanceFromBottom > 100;\n userScrolledUp.current = scrolledUp;\n setShowScrollButton(scrolledUp && isStreaming);\n };\n\n container.addEventListener(\"scroll\", handleScroll);\n return () => container.removeEventListener(\"scroll\", handleScroll);\n }, [isStreaming]);\n\n // Auto-scroll to bottom only when user hasn't scrolled up\n useEffect(() => {\n if (!userScrolledUp.current && bottomRef.current) {\n bottomRef.current.scrollIntoView({ behavior: \"smooth\" });\n }\n }, [messages, trailingContent]);\n\n // Hide button when streaming ends\n useEffect(() => {\n if (!isStreaming) {\n setShowScrollButton(false);\n }\n }, [isStreaming]);\n\n const scrollToBottom = useCallback(() => {\n userScrolledUp.current = false;\n setShowScrollButton(false);\n bottomRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, []);\n\n const loadOlderMessages = useCallback(async () => {\n if (!onLoadOlderMessages || isLoadingOlder) return;\n setIsLoadingOlder(true);\n try {\n await onLoadOlderMessages();\n } finally {\n setIsLoadingOlder(false);\n }\n }, [isLoadingOlder, onLoadOlderMessages]);\n\n // Group highlights by sub_element_id (message's serverMessageId)\n const highlightsByMessage = useMemo(() => {\n const map = new Map();\n (highlights ?? []).forEach((h) => {\n if (h.sub_element_id != null) {\n const existing = map.get(h.sub_element_id) ?? [];\n existing.push(h);\n map.set(h.sub_element_id, existing);\n }\n });\n return map;\n }, [highlights]);\n\n if (messages.length === 0 && !branchOrigin) return null;\n\n return (\n \n \n {hasMoreMessages && (\n \n \n {isLoadingOlder ? \"Loading...\" : \"Load older messages\"}\n \n \n )}\n {branchOrigin && branchOrigin.after_message_id === null && }\n {messages.map((message) => {\n const planningMessage = renderPlanningMessage?.(message);\n\n return (\n \n {planningMessage !== undefined ? (\n planningMessage\n ) : (\n onRetryDownloadLoad(message.id) : undefined}\n downloadLoadRetryDisabled={isStreaming}\n message={message}\n nextSteps={\n !readOnly &&\n message === messages[messages.length - 1] &&\n message.serverMessageId === nextSteps?.source_message_id\n ? nextSteps\n : undefined\n }\n onSelectNextStep={onSelectNextStep}\n onForkMessage={onForkMessage ? () => onForkMessage(message) : undefined}\n canSteer={canSteer}\n onSteerMessage={onSteerMessage ? () => onSteerMessage(message) : undefined}\n onCancelAndEditMessage={onCancelAndEditMessage ? () => onCancelAndEditMessage(message) : undefined}\n messageActionPending={pendingMessageActionId === message.id}\n pendingMessageActionType={pendingMessageActionId === message.id ? pendingMessageActionType : null}\n sessionId={sessionId}\n sessionToken={sessionToken}\n onRetry={\n !readOnly && !isStreaming && message.retryableRunId && onRetryRun\n ? () => onRetryRun(message.retryableRunId as string)\n : undefined\n }\n openTranscript={openTranscript}\n onRequestJudge={onRequestJudge}\n readOnly={readOnly}\n highlights={highlightsByMessage.get(message.serverMessageId ?? -1)}\n onTextSelected={onTextSelected}\n onHighlightClick={onHighlightClick}\n scrollContainerRef={containerRef}\n />\n )}\n {branchOrigin &&\n branchOrigin.after_message_id !== null &&\n branchOrigin.after_message_id === message.serverMessageId && (\n \n )}\n \n );\n })}\n {/* Trailing content lives inside the same max-width column as\n the messages, so it visually stacks under the last assistant\n response. Empty by default; the locked-Clerk session view\n uses this slot for its post-response CTA + example cards. */}\n {trailingContent}\n
    \n \n {showScrollButton && (\n \n \n \n )}\n \n );\n};\n\nexport default AgentPrototypeChat;\n", "import { useQuery } from \"@tanstack/react-query\";\nimport { queries } from \"./queries\";\nimport { retryIfServerError } from \"./documents\";\n\nexport const useQueryJudgesList = () => {\n return useQuery({\n queryKey: queries.judges.list().queryKey,\n queryFn: queries.judges.list().queryFn,\n retry: retryIfServerError,\n staleTime: 30 * 60 * 1000,\n\n refetchOnMount: false, // Don't refetch when component mounts\n refetchOnWindowFocus: false, // Don't refetch when window regains focus\n });\n};\n", "import React, { createContext, useContext, useState, useCallback, useEffect, useMemo } from \"react\";\nimport { makeSelectorListMatcher } from \"@/utils/makeSelectorListMatcher\";\n\n// Legacy tab identifier \u2014 historically lived on Home.tsx when it had a tabbed\n// surface. After PR 3 Step 7's migration, Home is a single Clerk-focused\n// surface and this lives here, near its only remaining consumer.\nexport type TabId = \"ask-ai\" | \"keyword-boolean\" | \"none\" | \"clerk\";\n\n/**\n * SearchFilterControlContext - Provides centralized state management for search filter UI controls\n *\n * This context manages:\n * - Active tab state for search interface\n * - Filter drawer open/close state\n * - Registration and coordination of open UI elements (dropdowns, modals, etc.)\n * - Click-outside handling to prevent premature closing of filter components\n * - Filter validation state\n *\n * Sample Usage:\n *\n * // 1. Wrap your component tree with the TopBarProvider (not the provider exported here)\n * function App() {\n * return (\n * \n * \n * \n * );\n * }\n *\n * // 2. Use the state and/or dispatch contexts in filter components.\n * // State is for reading, Dispatch for writing. Splitting them means a heavy component\n * // which only writes state doesn't need to re-render every time state changes.\n * function DateFilterChip() {\n * const { registerOpenElement, unregisterOpenElement } = useSearchFilterDispatch();\n * const [isOpen, setIsOpen] = useState(false);\n *\n * useEffect(() => {\n * if (isOpen) {\n * registerOpenElement({\n * id: \"date-filter\",\n * type: \"dropdown\",\n * metadata: { component: \"DateFilterChip\" },\n * onClose: () => setIsOpen(false)\n * });\n * } else {\n * unregisterOpenElement(\"date-filter\");\n * }\n * }, [isOpen, registerOpenElement, unregisterOpenElement]);\n *\n * return
    Date Filter Component
    ;\n * }\n *\n * // 3. Another example\n * function FilterButton() {\n * const { filterDrawerOpen } = useSearchFilterState();\n * const { toggleFilterModal } = useSearchFilterDispatch();\n *\n * return (\n * \n * );\n * }\n */\n\n// Types for different UI elements that can be open\ntype OpenUIElement = {\n id: string;\n type: \"filter-drawer\" | \"judge-autocomplete\" | \"modal\" | \"dropdown\";\n // Optional metadata for debugging\n metadata?: Record;\n // Optional close handler for the element\n onClose?: () => void;\n};\n\n// These selectors (presence of an attribute) mark elements that should not close the\n// top bar even if they're clicked or scrolled.\nconst KEEP_OPEN_SELECTORS = [\n \"[data-top-bar-keep-open]\",\n \"[data-filter-button]\",\n \"[data-judge-button]\",\n \"[data-transcript-reader-autoscroll]\",\n] as const;\n\nconst hasKeepOpenAttr = makeSelectorListMatcher(KEEP_OPEN_SELECTORS);\n\ninterface SearchFilterState {\n // Active tab state\n activeTab: TabId;\n\n // Filter drawer state\n filterDrawerOpen: boolean;\n\n // Filter validation state\n isFiltersValid: boolean;\n\n // Open UI elements tracking (for click-outside behavior)\n openUIElements: OpenUIElement[];\n isAnyUIElementOpen: () => boolean;\n\n // Click-outside handling\n shouldPreventClose: (target: EventTarget | null) => boolean;\n}\n\ninterface SearchFilterDispatch {\n setActiveTab: (tab: TabId) => void;\n setFilterDrawerOpen: (open: boolean) => void;\n toggleFilterModal: () => void;\n setIsFiltersValid: (valid: boolean) => void;\n registerOpenElement: (element: OpenUIElement) => void;\n unregisterOpenElement: (id: string) => void;\n handleClickOutside: () => void;\n // Element closing (for components to close themselves without triggering top bar close)\n closeElement: (id: string, shouldTriggerSearch?: boolean) => void;\n}\n\nconst SearchFilterStateContext = createContext(null);\nconst SearchFilterDispatchContext = createContext(null);\n\ninterface SearchFilterControlProviderProps {\n children: React.ReactNode;\n}\n\nexport function SearchFilterControlProvider({ children }: SearchFilterControlProviderProps) {\n const [activeTab, setActiveTab] = useState(\"none\");\n // Filter drawer state\n const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);\n\n // Filter validation state\n const [isFiltersValid, setIsFiltersValid] = useState(true);\n\n // Track all open UI elements\n const [openUIElements, setOpenUIElements] = useState([]);\n\n // Click-outside handler\n const handleClickOutside = useCallback(() => {\n setActiveTab(\"none\");\n }, [setActiveTab]);\n\n // Toggle filter modal\n const toggleFilterModal = useCallback(() => {\n setFilterDrawerOpen((prev) => !prev);\n }, []);\n\n // Register an open UI element\n const registerOpenElement = useCallback((element: OpenUIElement) => {\n setOpenUIElements((prev) => {\n // Remove any existing element with the same ID, then add the new one\n const filtered = prev.filter((el) => el.id !== element.id);\n return [...filtered, element];\n });\n }, []);\n\n // Unregister an open UI element\n const unregisterOpenElement = useCallback((id: string) => {\n setOpenUIElements((prev) => prev.filter((el) => el.id !== id));\n }, []);\n\n // Check if any UI element is open\n const isAnyUIElementOpen = useCallback(() => {\n return openUIElements.length > 0 || filterDrawerOpen;\n }, [openUIElements.length, filterDrawerOpen]);\n\n // Close an element without triggering top bar close\n const closeElement = useCallback(\n (id: string, shouldTriggerSearch: boolean = false) => {\n unregisterOpenElement(id);\n\n // If shouldTriggerSearch is true, we can add logic here to trigger search\n // For now, the individual components handle their own search triggering\n if (shouldTriggerSearch) {\n // Components will handle their own onChange calls\n }\n },\n [unregisterOpenElement],\n );\n\n // Function to check if click-outside should be prevented\n const shouldPreventClose = useCallback(\n (target: EventTarget | null): boolean => {\n if (!target) return false;\n\n // If clicking on an element with keep-open attributes, prevent closing\n if (target instanceof Element && hasKeepOpenAttr(target)) {\n return true;\n }\n\n // If clicking outside all open elements, close them first\n if (openUIElements.length > 0) {\n // Close all registered elements\n openUIElements.forEach((element) => {\n if (element.onClose) {\n element.onClose();\n }\n });\n return true; // Prevent top bar from closing this time\n }\n\n return false;\n },\n [openUIElements],\n );\n\n // Auto-register filter drawer when it opens/closes\n useEffect(() => {\n if (filterDrawerOpen) {\n registerOpenElement({\n id: \"filter-drawer\",\n type: \"filter-drawer\",\n metadata: { timestamp: Date.now() },\n });\n } else {\n unregisterOpenElement(\"filter-drawer\");\n }\n }, [filterDrawerOpen, registerOpenElement, unregisterOpenElement]);\n\n const stateValue: SearchFilterState = {\n activeTab,\n filterDrawerOpen,\n isFiltersValid,\n openUIElements,\n isAnyUIElementOpen,\n shouldPreventClose,\n };\n\n const dispatchValue: SearchFilterDispatch = useMemo(\n () => ({\n setActiveTab,\n setFilterDrawerOpen,\n toggleFilterModal,\n setIsFiltersValid,\n registerOpenElement,\n unregisterOpenElement,\n handleClickOutside,\n closeElement,\n }),\n [\n setActiveTab,\n setFilterDrawerOpen,\n toggleFilterModal,\n setIsFiltersValid,\n registerOpenElement,\n unregisterOpenElement,\n handleClickOutside,\n closeElement,\n ],\n );\n\n return (\n \n {children}\n \n );\n}\n\nexport function useSearchFilterState() {\n const context = useContext(SearchFilterStateContext);\n if (!context) {\n throw new Error(\"useSearchFilterState must be used within SearchFilterControlProvider\");\n }\n return context;\n}\n\nexport function useSearchFilterDispatch() {\n const context = useContext(SearchFilterDispatchContext);\n if (!context) {\n throw new Error(\"useSearchFilterDispatch must be used within SearchFilterControlProvider\");\n }\n return context;\n}\n\n// Export the type for use in other components\nexport type { OpenUIElement };\n", "import React, { createContext, useContext, useState, useCallback, useEffect, useMemo } from \"react\";\nimport { useQueryJudgesList } from \"../../api/judges\";\nimport { useLocation, useSearchParams } from \"../../utils/urlHelpers\";\nimport { JudgesAPIJudge } from \"../../api/queries/judges.types\";\nimport { useSearchFilterDispatch } from \"./SearchFilterControlContext\";\n\ninterface BooleanSearchBarState {\n searchInput: string;\n additionalQueryInput: string | undefined;\n hearingDateFromInput: string | undefined;\n hearingDateToInput: string | undefined;\n caseNumberInput: string | undefined;\n caseNameInput: string | undefined;\n motionTypeInput: string | undefined;\n judgesFilterInput: string[];\n selectedJudges: JudgesAPIJudge[];\n getSelectedJudgeNames: () => string[];\n getSelectedJudgeNamesString: () => string;\n focusRequestCounter: number;\n overlayRequestCounter: number;\n}\n\ninterface BooleanSearchBarDispatch {\n setSearchInput: (q: string) => void;\n setAdditionalQueryInput: (q: string | undefined) => void;\n setHearingDateFromInput: (d: string | undefined) => void;\n setHearingDateToInput: (d: string | undefined) => void;\n setCaseNumberInput: (n: string | undefined) => void;\n setCaseNameInput: (n: string | undefined) => void;\n setMotionTypeInput: (n: string | undefined) => void;\n setJudgesFilterInput: (ids: string[]) => void;\n setSelectedJudges: (judges: JudgesAPIJudge[]) => void;\n clearBooleanSearchBar: () => void;\n expandAndFocusQueryText: () => void;\n requestQueryTextFocus: () => void;\n}\n\nconst BooleanSearchBarStateContext = createContext(null);\nconst BooleanSearchBarDispatchContext = createContext(null);\n\nexport function BooleanSearchBarProvider({ children }: { children: React.ReactNode }) {\n const [searchInput, setSearchInput] = useState(\"\");\n const [additionalQueryInput, setAdditionalQueryInput] = useState(undefined);\n const [hearingDateFromInput, setHearingDateFromInput] = useState(undefined);\n const [hearingDateToInput, setHearingDateToInput] = useState(undefined);\n const [caseNumberInput, setCaseNumberInput] = useState(undefined);\n const [caseNameInput, setCaseNameInput] = useState(undefined);\n const [motionTypeInput, setMotionTypeInput] = useState(undefined);\n const [judgesFilterInput, setJudgesFilterInput] = useState([]);\n const [selectedJudges, setSelectedJudges] = useState([]);\n const [previousPathname, setPreviousPathname] = useState(\"\");\n const judgesQuery = useQueryJudgesList();\n const searchParams = useSearchParams()[0];\n const location = useLocation();\n const [focusRequestCounter, setFocusRequestCounter] = useState(0);\n const [overlayRequestCounter, setOverlayRequestCounter] = useState(0);\n\n const { setActiveTab } = useSearchFilterDispatch();\n\n const requestQueryTextFocus = useCallback(() => {\n // The boolean search bar listens for a change in this value.\n setFocusRequestCounter((c) => c + 1);\n }, []);\n\n const expandAndFocusQueryText = useCallback(() => {\n setActiveTab(\"keyword-boolean\");\n\n // Open the overlay immediately so there's no perceived delay.\n setOverlayRequestCounter((c) => c + 1);\n\n // Request focus after a short delay so the overlay animation can start\n // before the input grabs focus (avoids visual stutter).\n setTimeout(requestQueryTextFocus, 200);\n }, [setActiveTab]);\n\n // Hydrate all fields from URL and judges whenever either changes\n useEffect(() => {\n const judgeIds = searchParams.get(\"judgeIds\")?.split(\",\")?.filter(Boolean) || [];\n\n // Batch state updates to prevent multiple re-renders\n React.startTransition(() => {\n setSearchInput(searchParams.get(\"queryText\") || \"\");\n setAdditionalQueryInput(searchParams.get(\"additionalQuery\") || undefined);\n setHearingDateFromInput(searchParams.get(\"hearingDateFrom\") || undefined);\n setHearingDateToInput(searchParams.get(\"hearingDateTo\") || undefined);\n setCaseNumberInput(searchParams.get(\"caseNumber\") || undefined);\n setCaseNameInput(searchParams.get(\"caseName\") || undefined);\n setMotionTypeInput(searchParams.get(\"motionType\") || undefined);\n setJudgesFilterInput(judgeIds);\n if (judgesQuery.data && judgesQuery.data.length > 0) {\n setSelectedJudges(judgesQuery.data.filter((judge) => judgeIds.indexOf(judge.name) !== -1));\n }\n });\n }, [searchParams, judgesQuery.data]);\n\n useEffect(() => {\n // Clear inputs on navigation\n if (location.pathname !== previousPathname && location.pathname !== \"/transcripts\") {\n // Batch state updates to prevent multiple re-renders\n React.startTransition(() => {\n setSearchInput(\"\");\n setAdditionalQueryInput(undefined);\n setHearingDateFromInput(undefined);\n setHearingDateToInput(undefined);\n setCaseNumberInput(undefined);\n setCaseNameInput(undefined);\n setMotionTypeInput(undefined);\n setJudgesFilterInput([]);\n setSelectedJudges([]);\n });\n }\n setPreviousPathname(location.pathname);\n }, [location.pathname, previousPathname]);\n\n // Remove syncToCurrentBoolean from the context API\n const clearBooleanSearchBar = useCallback(() => {\n // Batch state updates to prevent multiple re-renders\n React.startTransition(() => {\n setSearchInput(\"\");\n setAdditionalQueryInput(undefined);\n setHearingDateFromInput(undefined);\n setHearingDateToInput(undefined);\n setCaseNumberInput(undefined);\n setCaseNameInput(undefined);\n setMotionTypeInput(undefined);\n setJudgesFilterInput([]);\n setSelectedJudges([]);\n });\n }, []);\n\n // Add derived selector for selected judge names\n const getSelectedJudgeNames = useCallback(() => selectedJudges.map((judge) => judge.name), [selectedJudges]);\n\n const getSelectedJudgeNamesString = useCallback(() => {\n return getSelectedJudgeNames().join(\",\");\n }, [getSelectedJudgeNames]);\n\n const stateValue: BooleanSearchBarState = {\n searchInput,\n additionalQueryInput,\n hearingDateFromInput,\n hearingDateToInput,\n caseNumberInput,\n caseNameInput,\n motionTypeInput,\n judgesFilterInput,\n selectedJudges,\n getSelectedJudgeNames,\n getSelectedJudgeNamesString,\n focusRequestCounter,\n overlayRequestCounter,\n };\n\n const dispatchValue: BooleanSearchBarDispatch = useMemo(\n () => ({\n setSearchInput,\n setAdditionalQueryInput,\n setHearingDateFromInput,\n setHearingDateToInput,\n setCaseNumberInput,\n setCaseNameInput,\n setMotionTypeInput,\n setJudgesFilterInput,\n setSelectedJudges,\n clearBooleanSearchBar,\n expandAndFocusQueryText,\n requestQueryTextFocus,\n }),\n [\n setSearchInput,\n setAdditionalQueryInput,\n setHearingDateFromInput,\n setHearingDateToInput,\n setCaseNumberInput,\n setCaseNameInput,\n setMotionTypeInput,\n setJudgesFilterInput,\n setSelectedJudges,\n clearBooleanSearchBar,\n expandAndFocusQueryText,\n requestQueryTextFocus,\n ],\n );\n\n return (\n \n \n {children}\n \n \n );\n}\n\nexport function useBooleanSearchBarState() {\n const context = useContext(BooleanSearchBarStateContext);\n if (!context) throw new Error(\"Must be used within BooleanSearchBarControlProvider\");\n return context;\n}\n\nexport function useBooleanSearchBarDispatch() {\n const context = useContext(BooleanSearchBarDispatchContext);\n if (!context) throw new Error(\"Must be used within BooleanSearchBarControlProvider\");\n return context;\n}\n", "/**\n * When a locked Clerk user reaches `/agent?q=` and then opens\n * the transcript search (via the landing's \"Search transcripts\" CTA or the\n * topbar trigger), seed the Boolean search input with their carried-over\n * question so they don't have to retype it.\n *\n * No-op when there's no `q` param (every non-locked surface), so this is safe to\n * call from the shared search-overlay open handler.\n */\nexport function prefillSearchFromCarriedQuery(\n searchParams: URLSearchParams,\n setSearchInput: (value: string) => void,\n): void {\n const carriedQuery = searchParams.get(\"q\")?.trim();\n if (carriedQuery) {\n setSearchInput(carriedQuery);\n }\n}\n", "import { useCallback } from \"react\";\nimport { useSearchParams } from \"@/utils/urlHelpers\";\nimport { useBooleanSearchBarDispatch } from \"@/components/contexts/BooleanSearchBarControlContext\";\nimport { prefillSearchFromCarriedQuery } from \"@/utils/searchPrefill\";\n\n/**\n * Returns a callback that seeds the Boolean search input with a locked user's\n * carried-over question (`?q=`), if present. Call it right BEFORE opening the\n * search overlay \u2014 the overlay snapshots `searchInput` at open time, so the\n * value has to be set first. No-op when there's no `?q`.\n *\n * Shared by the locked landing's \"Search transcripts\" CTA and the topbar search\n * trigger so the prefill wiring (read `?q` + dispatch `setSearchInput`) lives in\n * one place instead of being copy-pasted into both click handlers.\n */\nexport function useCarriedQueryPrefill(): () => void {\n const [searchParams] = useSearchParams();\n const { setSearchInput } = useBooleanSearchBarDispatch();\n return useCallback(() => {\n prefillSearchFromCarriedQuery(searchParams, setSearchInput);\n }, [searchParams, setSearchInput]);\n}\n", "import { Gavel, Scale, UserSearch } from \"lucide-react\";\nimport type { UsecaseCardItem } from \"@/components/atoms/UsecaseCard\";\nimport type { ChatMessage } from \"@/hooks/useAgentPrototypeSession\";\n\n/**\n * Static fixtures for the \"Locked Clerk Experience\" example conversations.\n *\n * Each entry is a real, completed Clerk research session, harvested read-only\n * from production and frozen here as a static `ChatMessage[]`. The user\n * question, the assistant's markdown answer, the `[N]` citation footnotes, and\n * every citation's `transcript_id` / `case_name` / `judge_name` etc. are the\n * genuine values from that session \u2014 so clicking a `[N]` footnote opens the\n * real transcript in the sidepanel reader (transcript IDs resolve in\n * production, where locked customers live).\n *\n * Light curation only: the multi-turn sessions are trimmed to their first\n * user\u2192assistant exchange, the accumulated `thinking` blob is reshaped into a\n * short `string[]` of plan steps, and a handful of representative\n * `boolean_search` steps stand in for the hundreds the real agent ran. The\n * answer text and citations are verbatim.\n *\n * Each entry powers one of the three cards on `LockedClerkLanding` and the\n * corresponding `/agent/exampleN` page. The cards link out to the\n * matching slug; the conversation pages render `messages` through the real\n * `AgentPrototypeChat` so the locked preview looks identical to a live\n * Clerk session (same chip, same plan card, same body copy).\n *\n * NO API calls happen on these pages: the messages are plain JS objects,\n * and `AgentPrototypeChat` consumes them directly. The 3-second \"Clerk is\n * thinking\" delay is purely a UI fake (setTimeout in\n * `LockedClerkExampleSession`) so the locked experience demos the loading\n * state realistically.\n */\n\nexport type LockedClerkExampleSlug = \"example1\" | \"example2\" | \"example3\";\n\n/**\n * The card payload is exactly the `UsecaseCardItem` the live homepage uses,\n * so `` renders the same way on both surfaces. We add the\n * `slug` (for routing) and the static `ChatMessage[]` that powers the\n * read-only conversation page.\n */\nexport interface LockedClerkExample {\n slug: LockedClerkExampleSlug;\n card: UsecaseCardItem;\n /**\n * The full conversation as a static `ChatMessage[]`. Always at least one\n * user message + one assistant message. The assistant message's\n * `thinking` / `toolCalls` / `toolResults` populate the research-plan\n * card; its `content` is the agent's final answer.\n *\n * During the 3-second loading fake the rendering wrapper sets\n * `isStreaming: true` AND blanks `content` on the assistant entry, so\n * the user only sees the plan card with its steps in flight; once the\n * timer elapses we drop the flag, restore `content`, and the plan card\n * collapses to \"Took N steps\" with the answer below it.\n */\n messages: ChatMessage[];\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Defaults every optional field on ChatMessage so the fixtures stay readable\n// \u2014 only the fields that matter for each message need to be spelled out at\n// the call site.\n\nconst userMessage = (id: string, content: string, overrides: Partial = {}): ChatMessage => ({\n id,\n role: \"user\",\n content,\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n ...overrides,\n});\n\nconst assistantMessage = (id: string, content: string, overrides: Partial = {}): ChatMessage => ({\n id,\n role: \"assistant\",\n content,\n thinking: [],\n thinkingSinceLastTool: \"\",\n toolCalls: [],\n toolResults: [],\n citations: [],\n files: [],\n downloadFiles: [],\n ...overrides,\n});\n\n// \u2500\u2500 Fixtures \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst example1: LockedClerkExample = {\n slug: \"example1\",\n card: {\n label: \"SDNY vs. Delaware on third-party releases\",\n icon: Scale,\n description:\n \"Compared rulings from both benches to map where they diverge on approving nondebtor releases after Purdue.\",\n // `prompt` is unused for locked cards (they navigate by slug, not by\n // injecting a prompt into the input). Kept on the shape so the\n // `UsecaseCardItem` contract is satisfied.\n prompt: \"\",\n },\n messages: [\n userMessage(\n \"example1-u-1\",\n `When ruling on third party releases in Chapter 11 cases, what specific factors do bankruptcy judges in the Southern District of New York versus the District of Delaware cite when approving versus rejecting such releases? Conduct an exhaustive review of all available relevant hearing transcripts in both jurisdictions.\n\nFor each jurisdiction, identify the factors judges actually weigh when ruling on third-party releases, including but not limited to: different operative facts, different controlling precedent, different interpretation or application of the same precedent, and different evidentiary or procedural expectations. Then compare the two jurisdictions directly and explain where they diverge.\n\nPrioritize insights that are both (1) unpredictable, meaning patterns an experienced restructuring attorney would not anticipate from reading the Code, the rules, or the leading cases alone, and (2) actionable, meaning they would change how I frame a release provision, which arguments I lead with, what evidence or record I build, or whether I include the release at all.\n\nFor every factor or pattern you surface, cite the specific judge, case, and hearing date. Where a pattern is supported by multiple transcripts, note how consistent it is across judges versus driven by one judge's preferences. Flag explicitly where the transcript record is thin or where you are inferring a pattern from limited data.`,\n ),\n assistantMessage(\n \"example1-a-1\",\n `Bottom line: SDNY judges focus on Metromedia necessity, claim-specific scope, and consent mechanics; Delaware judges focus more sharply on Continental fairness/necessity, separate consideration for the released third-party claims, and whether the consent mechanism is judge-approved. The most actionable divergence is this: in SDNY, a carefully noticed opt-out or yes-vote structure may work before several judges, but Judge Wiles-style scrutiny demands claim-by-claim necessity; in Delaware, the same release can fail if the record shows only \u201Cfinality,\u201D \u201Cpeace,\u201D or financier demand rather than evidence that the release is fair and necessary to the releasing creditors.\n\n## Scope and record limits\n\nI reviewed available SDNY and Delaware Chapter 11 transcripts with judge-spoken rulings or meaningful analysis on third-party/nondebtor releases, including confirmation, disclosure-statement, solicitation, and post-Purdue hearings. I excluded Chapter 15 foreign-recognition releases, post-confirmation enforcement transcripts without original approval analysis, and attorney-only mentions.\n\nTwo limits matter. First, the available SDNY record is unusually Judge Glenn-heavy, though Judges Lane, Wiles, Garrity, Beckerman, Jones, Mastando, and Morris also appear. Second, some mass-tort reasoning\u2014especially Boy Scouts in Delaware\u2014is in written opinions or procedural transcripts rather than a full bench-ruling transcript; I treat those as thin where the transcript itself does not contain the final factor analysis.\n\n## Southern District of New York\n\n### SDNY approval turns on Metromedia plus a practical record, not labels\n\nSDNY judges repeatedly cite Metromedia\u2019s \u201Crare\u201D / \u201Ctruly unusual\u201D framework, but they do not apply it mechanically. The record must show why the particular release matters to the plan, not merely that the releasee was helpful.\n\nJudge Garrity rejected D&O releases in SquareTwo even though the release was narrowed and no economic party objected, because \u201CThe Court does not find truly unusual circumstances justifying the nondebtor third-party releases.\u201D In re SquareTwo Financial Services Corp., No. 17-10659, before Judge James L. Garrity Jr., Bankr. S.D.N.Y. (June 5, 2017) [1]. By contrast, Judge Lane approved lender releases in ARO where the term-loan lenders funded administrative and priority claims and enabled the plan; he found their releases were \u201Can integral part of the plan and material inducement to term loan lenders pledging their support and making the plan possible.\u201D In re ARO Liquidation, Inc., No. 16-11275, before Judge Sean H. Lane, Bankr. S.D.N.Y. (Mar. 28, 2018) [2].\n\nActionable point: lead with necessity tied to the specific plan transaction. Do not lead with \u201Cthe released parties contributed.\u201D In SDNY, that framing invites the Wiles objection.\n\n### Judge Wiles is the clearest anti-boilerplate voice\n\nJudge Wiles\u2019s SDNY transcripts are the most useful warning against routine release drafting. In Aegean, he rejected nonconsensual releases because the debtors could not identify the actual remaining claims and why barring them was necessary: \u201CThird party releases are not a merit badge \u2026 they are not a participation trophy.\u201D In re Aegean Marine Petroleum Network Inc., No. 18-13374, before Judge Michael E. Wiles, Bankr. S.D.N.Y. (Mar. 26, 2019) [3]. He added that a proponent must show \u201Csomething about the particular claim that you want released that has to be barred in order to make this reorganization workable.\u201D Id. [4].\n\nIn Fairway, he required live testimony for contested releases and wanted \u201Csomething specific\u201D tying the release to the concessions made. In re Fairway Group Holdings Corp., No. 16-11241, before Judge Michael E. Wiles, Bankr. S.D.N.Y. (June 7, 2016) [5]. That is the record to build if the release is contested: identify the claims, value them, connect them to the settlement consideration, and explain why narrower relief fails.\n\n### Consent mechanics are split, but the safe SDNY structure is separate, prominent, and no silent non-returners\n\nSDNY does not have one uniform transcript rule on opt-in versus opt-out. Judge Garrity said it directly in China Fishery: \u201Cin our district, there are two views.\u201D In re China Fishery Group Ltd., No. 16-11895, before Judge James L. Garrity Jr., Bankr. S.D.N.Y. (Feb. 16, 2022) [6].\n\nThe accepting line: Judges Glenn, Garrity, Lane, Mastando, and David Jones have approved opt-out or yes-vote structures where notice was prominent and the affected party had a real, separate way to withhold the release. Avianca is the clean Glenn example: the debtor used \u201Cvery prominent in-bold provisions,\u201D and those without opt-out rights were not bound. In re Avianca Holdings S.A., No. 20-11133, before Judge Martin Glenn, Bankr. S.D.N.Y. (Sept. 14, 2021) [7]. Acorda is the clean post-Purdue yes-vote example: Judge David Jones held that voters told \u201Cvoting yes means consenting\u201D made an informed, knowing decision. In re Acorda Therapeutics, Inc., No. 24-22284, before Judge David S. Jones, Bankr. S.D.N.Y. (Aug. 7, 2024) [8].\n\nThe limiting line: Judges Wiles and Lane are skeptical of silence. In Chassix, Judge Wiles held that \u201Cinaction just is not a sufficient manifestation of consent\u201D and that consent used to avoid Metromedia \u201Cshould be real consent.\u201D In re Chassix Holdings, Inc., No. 15-10578, before Judge Michael E. Wiles, Bankr. S.D.N.Y. (July 2, 2015) [9]. In TBAC, Judge Lane said \u201Cfailure to submit a ballot can\u2019t \u2026 be consent.\u201D In re TBAC Wind Down, Ltd., No. 16-13297, before Judge Sean H. Lane, Bankr. S.D.N.Y. (Oct. 31, 2017) [10].\n\nActionable point: if using opt-out in SDNY, do not bind non-returned ballots. Azul is the model: releases applied only to creditors who returned ballots and did not opt out; \u201CNo releases will be granted by voters who do not return a ballot.\u201D In re Azul S.A., No. 25-11176, before Judge Sean H. Lane, Bankr. S.D.N.Y. (Dec. 19, 2025) [11].\n\n### Disclosure-stage drafting matters more than lawyers expect\n\nSDNY judges often solve release problems before confirmation. Judge Glenn in Advance Watch would not treat changed release language as consensual where creditors had not seen it when voting: \u201Cthere has to be sufficient disclosure to the creditor when they cast their vote.\u201D In re Advance Watch Co. Ltd., No. 15-12690, before Judge Martin Glenn, Bankr. S.D.N.Y. (Jan. 20, 2016) [12]. In SVB, even after the debtor switched to opt-in, Judge Glenn insisted creditors were \u201Centitled to an understanding of why.\u201D In re SVB Financial Group, No. 23-10367, before Judge Martin Glenn, Bankr. S.D.N.Y. (May 16, 2024) [13].\n\nActionable point: the disclosure statement should say who is released, by category and preferably by list; what claims are released; what consideration supports each release; and why a creditor should grant it. An opt-in box does not cure thin disclosure.\n\n### SDNY mass-tort release expectations are unusually evidentiary\n\nJudge Glenn\u2019s Rockville Centre comments are the sharpest SDNY mass-tort guidance. He required public identification of proposed releasees and financial disclosure: \u201Cnot under seal\u201D and \u201Cpart of the public record.\u201D In re Roman Catholic Diocese of Rockville Centre, No. 20-12345, before Judge Martin Glenn, Bankr. S.D.N.Y. (July 10, 2023) [14]. The next day, he warned that releasees must \u201Copen the books\u201D or \u201Cacknowledge they\u2019re not going to get a release.\u201D In re Roman Catholic Diocese of Rockville Centre, No. 20-12345, before Judge Martin Glenn, Bankr. S.D.N.Y. (July 11, 2023) [15].\n\nPost-Purdue, he treated signed claimant releases differently from imposed plan releases, stating that \u201CPurdue has no bearing\u201D where there is a signed release document. In re Roman Catholic Diocese of Rockville Centre, No. 20-12345, before Judge Martin Glenn, Bankr. S.D.N.Y. (Oct. 30, 2024) [16]. But he still required clarity on direct versus derivative claims, insurer claims, and what claimants must sign.\n\n## District of Delaware\n\n### Delaware\u2019s nonconsensual standard is more factor-driven and more often fatal\n\nDelaware judges anchor nonconsensual releases in Continental: \u201CFairness, necessity to the reorganization, and specific factual findings.\u201D In re Millennium Lab Holdings II, LLC, No. 15-12284, before Judge Laurie Selber Silverstein, Bankr. D. Del. (Dec. 11, 2015) [17]. Millennium is the high-water mark for approval: Judge Silverstein found \u201CWithout the contributions, there is no reorganization,\u201D and approved the releases as \u201Cfair and necessary.\u201D Id. [18].\n\nNorth Texas is another approval, but it was fact-specific: Judge Gross found \u201Cno financial contribution, no plan,\u201D where directors made concrete monetary contributions. In re North Texas Bancshares of Delaware, Inc., No. 13-12699, before Judge Kevin Gross, Bankr. D. Del. (June 4, 2014) [19].\n\nThe rejection cases show what fails. In GT Real Estate, Judge Owens held that financier demand was not enough and the releases were \u201Cnice to have, but they\u2019re not a need to have.\u201D In re GT Real Estate Holdings, LLC, No. 22-10505, before Judge Karen B. Owens, Bankr. D. Del. (Dec. 14, 2022) [20]. In Amyris, Judge Horan found the consensual-release backstop itself proved the nonconsensual releases were unnecessary. In re Amyris, Inc., No. 23-11131, before Judge Thomas M. Horan, Bankr. D. Del. (Feb. 2, 2024) [21].\n\nActionable point: in Delaware, do not say \u201Cthe plan sponsor requires it\u201D unless you also prove why that demand is objectively necessary and fair to the releasing creditors.\n\n### Delaware courts ask whether releasing creditors got consideration for their own third-party claims\n\nGulf Coast is the key Delaware warning. Judge Owens held that creditors forced to release third-party claims must receive consideration \u201Con account of the third-party released claims,\u201D not merely a distribution on debtor claims. In re Gulf Coast Health Care, LLC, No. 21-11336, before Judge Karen B. Owens, Bankr. D. Del. (May 4, 2022) [22]. The debtors had done \u201Cno separate analysis\u201D of the value of the released third-party claims. Id. [23].\n\nActionable point: if the release affects direct creditor claims, prepare a valuation or at least a reasoned litigation-risk analysis of those claims. A liquidation analysis of debtor claims is not enough.\n\n### Delaware judges are especially skeptical of ordinary lender / D&O \u201Cthey helped\u201D releases\n\nJudge Walrath in Boomerang rejected the proposition that DIP financing or plan-support work earns a release: \u201CIf a DIP alone were sufficient, all DIP lenders would get a release,\u201D and co-sponsoring or negotiating a PSA was not enough. In re Boomerang Tube, LLC, No. 15-11247, before Judge Mary F. Walrath, Bankr. D. Del. (Nov. 9, 2015) [24]. Judge Owens in Kettner similarly found \u201Cno evidence of necessity or a substantial contribution to the plan\u201D and required the releases excised unless opt-ins were solicited. In re Kettner Investments, LLC, No. 20-12366, before Judge Karen B. Owens, Bankr. D. Del. (Feb. 15, 2022) [25].\n\nActionable point: if the releasee is a DIP lender, plan sponsor, D&O, employee, or affiliate, isolate what the releasee gave beyond self-interested case participation.\n\n### Delaware consent law is judge-specific\n\nThe Delaware split is sharper than SDNY because judges articulate different theories.\n\n- Judge Walrath / opt-in line: In Reverse Mortgage, Judge Walrath held that nondebtors seeking releases need creditors to \u201Copt into that release and take affirmative action,\u201D and even a favorable plan vote is not affirmative acceptance of nondebtor releases. In re Reverse Mortgage Investment Trust Inc., No. 22-11225, before Judge Mary F. Walrath, Bankr. D. Del. (Mar. 21, 2023) [26]. She said the same in Hertz, grounded partly in \u00A7 524. In re The Hertz Corp., No. 20-11218, before Judge Mary F. Walrath, Bankr. D. Del. (Apr. 16, 2021) [27].\n- Judge Owens / no silence, but returned ballots can work: In PREIT, she said, \u201CFailing to object in my court is not sufficient manifestation of consent,\u201D but accepted releases where voting creditors returned ballots, accepted the plan, and did not opt out. In re Pennsylvania Real Estate Investment Trust, No. 23-11974, before Judge Karen B. Owens, Bankr. D. Del. (Jan. 22, 2024) [28].\n- Judge Goldblatt / opt-out as objection shortcut: In Appgate, he viewed the opt-out box as \u201Ca shortcut for I object to the plan,\u201D conditioned on adequate disclosure. In re Appgate, Inc., No. 24-10956, before Judge Craig T. Goldblatt, Bankr. D. Del. (June 17, 2024) [29].\n- Judges Stickles, Dorsey, Shannon, and Horan have accepted opt-out or returned-ballot mechanics in the right case. Clovis approved opt-out where disclosure was prominent and conspicuous, but unserved holders were not bound. In re Clovis Oncology, Inc., No. 22-11292, before Judge J. Kate Stickles, Bankr. D. Del. (June 9, 2023) [30]. Molecular Templates held post-Purdue that properly implemented opt-out can still work. In re Molecular Templates, Inc., No. 25-10739, before Judge Brendan L. Shannon, Bankr. D. Del. (July 1, 2025) [31].\n\nActionable point: in Delaware, judge assignment should drive the solicitation structure. If uncertain, use opt-in or at least returned-ballot-plus-no-opt-out, never pure failure-to-object.\n\n### Delaware separates plan voting from release consent more rigorously\n\nJudges Goldblatt, Owens, and Stickles all treat plan voting and release consent as distinct. Judge Goldblatt put it plainly: \u201Cthe vote and the decision whether to be bound by the third party release or not are analytically distinct,\u201D so even yes-voters should be able to opt out. In re TPC Group Inc., No. 22-10493, before Judge Craig T. Goldblatt, Bankr. D. Del. (Sept. 6, 2022) [32]. Judge Owens sustained an objection where accepting the plan was tied to granting releases, reasoning that tying distributions to the release \u201Ccould be seen as coercive.\u201D In re Legacy IMBDS, Inc., No. 23-10852, before Judge Karen B. Owens, Bankr. D. Del. (Nov. 1, 2023) [33].\n\nActionable point: do not make \u201Cvote yes = release\u201D the only path. Add a separate release election, and allow a creditor to accept the plan while opting out of the third-party release.\n\n### Delaware judges police disguised injunctions and vague release architecture\n\nJudge Silverstein in PARTS iD flagged a plan injunction that enjoined all holders of discharged claims from suing released parties; she said it was \u201Cessentially a third-party release without everyone having given a third-party release.\u201D In re PARTS iD, Inc., No. 23-12098, before Judge Laurie Selber Silverstein, Bankr. D. Del. (Feb. 9, 2024) [34]. In Imerys/Cyprus, she required channeling-injunction disclosure to say exactly what is covered and what is not. In re Imerys Talc America, Inc., No. 19-10289, before Judge Laurie Selber Silverstein, Bankr. D. Del. (Nov. 4, 2024) [35].\n\nActionable point: separate the debtor discharge injunction, consensual release injunction, channeling injunction, and gatekeeper provision. Do not rely on a global injunction paragraph.\n\n## Direct comparison: where SDNY and Delaware diverge\n\n### 1. SDNY is more narrative; Delaware is more evidentiary-factor driven\n\nSDNY judges often ask whether the release is truly important under Metromedia, but their analysis can be practical and transaction-specific. Delaware judges more often require a record mapped to Continental/Master Mortgage/Zenith: identity of interest, contribution, necessity, creditor support, and compensation/payment.\n\nThe practical difference: a compelling SDNY story about exit financing, settlement, and feasibility may work before Judge Lane or Glenn; in Delaware, the same story may fail before Judges Owens, Walrath, or Goldblatt unless it includes valuation of released claims, affected-class support, and consideration to releasing creditors.\n\n### 2. Delaware is more hostile to \u201Cfinancier demanded it\u201D\n\nBoth districts reject \u201Cpeace of mind\u201D as a standalone basis. But Delaware\u2019s GT, Gulf Coast, Amyris, and Boomerang transcripts are especially explicit that a sponsor\u2019s demand is not necessity. SDNY is more mixed: Judge Lane approved lender releases where the financing and support made the plan possible; Judge Wiles would require much more claim-specific proof.\n\n### 3. SDNY opt-out may be safer than Delaware opt-out, depending on judge\n\nIn SDNY, opt-out has been approved by several judges when notice is prominent and non-returned ballots are not bound, though Wiles and Lane provide important limits. In Delaware, opt-out remains viable before some judges post-Purdue, but Walrath and Owens make opt-in or returned-ballot evidence much safer. Judge Stickles\u2019s Lumio ruling is the cautionary post-Purdue example: opt-out was not forbidden, but she required opt-in where impaired creditors had zero or unknown recoveries and did not know their consideration. In re Lumio Holdings, Inc., No. 24-11916, before Judge J. Kate Stickles, Bankr. D. Del. (Jan. 3, 2025) [36].\n\n### 4. SDNY mass-tort release scrutiny focuses on releasee finances; Delaware focuses on channeling mechanics and direct-claim clarity\n\nJudge Glenn\u2019s Rockville Centre comments focus on public identification and financial disclosure of parishes/releasees. Judge Silverstein\u2019s Imerys/Cyprus comments focus on whether direct insurer/extra-contractual claims are being channeled and whether future courts can tell what was enjoined.\n\n### 5. Post-Purdue, both districts preserve consensual releases, but Delaware judges say \u201Cnonconsensual\u201D is over except asbestos more directly\n\nJudge Shannon stated the point most directly: \u201CNonconsensual releases are forbidden absent Section 524(g) and the asbestos context,\u201D while Purdue left consensual releases to the lower courts. In re Molecular Templates, Inc., No. 25-10739, before Judge Brendan L. Shannon, Bankr. D. Del. (July 1, 2025) [37]. In SDNY, Judge Glenn similarly distinguished Purdue\u2019s rejection of nonconsensual releases from consensual releases in GOL. In re GOL Linhas Aereas Inteligentes S.A., No. 24-10118, before Judge Martin Glenn, Bankr. S.D.N.Y. (May 20, 2025) [38].\n\n## Most actionable drafting moves\n\n- Use opt-in if you can. If not, use returned-ballot-plus-no-opt-out, not pure silence.\n- Let yes-voters opt out. Especially in Delaware, tying acceptance to releases is risky.\n- Do not bind non-returned, undeliverable, publication-only, or no-notice parties unless the judge has expressly approved that structure.\n- Put the full release text beside the vote/release election, with a cover letter saying the creditor is making two choices: plan vote and release decision.\n- File the released-party list early enough for voting, not in a late plan supplement.\n- Build a releasee-by-releasee chart: contribution, claim exposure, indemnity/defense-cost exposure, direct versus derivative claims, consideration to releasing creditors, and why narrower relief is insufficient.\n- If the case is mass tort or insurance-heavy, disclose releasee finances and spell out direct, derivative, indirect, extra-contractual, SIR, channeling, and gatekeeper mechanics in plain English.\n- Avoid broad \u201Crelated parties,\u201D \u201Csuccessors,\u201D and omnibus injunction language. Judges in both districts will read those as disguised nonconsensual releases if they sweep beyond actual consent.`,\n {\n thinking: [\n \"Pulling SDNY and Delaware Chapter 11 transcripts with bench rulings on nondebtor third-party releases.\",\n \"Separating consent-mechanism rulings (opt-in / opt-out / silence) from necessity-and-fairness rulings.\",\n \"Flagging post-Purdue hearings to compare consensual vs. nonconsensual treatment.\",\n \"Comparing the two benches factor by factor and pulling the judge quotes where they diverge.\",\n ],\n toolCalls: [\n {\n tool: \"boolean_search\",\n input: {\n query:\n '(\"third-party release\" OR \"nondebtor release\" OR \"non-debtor release\") AND (\"District of Delaware\" OR Delaware)',\n },\n },\n {\n tool: \"boolean_search\",\n input: {\n query:\n '(\"nonconsensual release\" OR \"opt-out release\" OR \"deemed consent\") AND (\"Southern District of New York\" OR SDNY)',\n },\n },\n {\n tool: \"boolean_search\",\n input: {\n query:\n '(release! /10 (nondebtor OR \"third party\" OR opt-out OR consensual)) AND (confirm! OR \"plan injunction\" OR Purdue)',\n },\n },\n ],\n toolResults: [\n { tool: \"boolean_search\", summary: \"Found 490 transcripts in the District of Delaware\" },\n { tool: \"boolean_search\", summary: \"Found 1,482 transcripts in the Southern District of New York\" },\n { tool: \"boolean_search\", summary: \"Narrowed to 326 transcripts with bench rulings on third-party releases\" },\n ],\n citations: [\n {\n transcript_id: 10036,\n excerpt:\n \"The Court does not find truly unusual circumstances justifying the nondebtor third-party releases.\",\n case_name: \"SquareTwo Financial Services Corporation and SquareTwo Unsecured Creditor Distribution Trust\",\n case_number: \"17-10659\",\n judge_name: \"James L Garrity Jr\",\n date_of_hearing: \"2017-06-05\",\n },\n {\n transcript_id: 9239,\n excerpt:\n \"The term loan lenders\u2019 releases are an integral part of the plan and material inducement to term loan lenders pledging their support and making the plan possible.\",\n case_name: \"ARO Liquidation, Inc.\",\n case_number: \"16-11275\",\n judge_name: \"Sean H Lane\",\n date_of_hearing: \"2018-03-28\",\n },\n {\n transcript_id: 8922,\n excerpt:\n \"Third party releases are not a merit badge that somebody gets in return for making a positive contribution to a restructuring, they are not a participation trophy\",\n case_name: \"Aegean Marine Petroleum Network Inc.\",\n case_number: \"18-13374\",\n judge_name: \"Michael E Wiles\",\n date_of_hearing: \"2019-03-26\",\n },\n {\n transcript_id: 8922,\n excerpt:\n \"You have to show that there's something about the particular claim that you want released that has to be barred in order to make this reorganization workable.\",\n case_name: \"Aegean Marine Petroleum Network Inc.\",\n case_number: \"18-13374\",\n judge_name: \"Michael E Wiles\",\n date_of_hearing: \"2019-03-26\",\n },\n {\n transcript_id: 12475,\n excerpt:\n \"Well, as to the release provisions, if they\u2019re contested, I\u2019m going to want to hear live testimony by direct and by cross --\",\n case_name: \"Fairway Group Holdings Corp.\",\n case_number: \"16-11241\",\n judge_name: \"Michael E Wiles\",\n date_of_hearing: \"2016-06-07\",\n },\n {\n transcript_id: 6229,\n excerpt: \"in our district, there are two views\",\n case_name: \"China Fishery Group Limited (Cayman) and Pacific Andes Enterprises (Hong Kong) Ltd.\",\n case_number: \"16-11895\",\n judge_name: \"James L Garrity Jr\",\n date_of_hearing: \"2022-02-16\",\n },\n {\n transcript_id: 7329,\n excerpt:\n \"what the debtors here propose is a very prominent in-bold provisions that make it clear. If you want to opt out of the releases\",\n case_name: \"Avianca Holdings S.A.\",\n case_number: \"20-11133\",\n judge_name: \"Martin Glenn\",\n date_of_hearing: \"2021-09-14\",\n },\n {\n transcript_id: 41952,\n excerpt:\n \"Recipients of ballots were told that voting yes means consenting to these releases, and if they voted yes, it's fair to deem that decision\",\n case_name: \"Acorda Therapeutics, Inc.\",\n case_number: \"24-22284\",\n judge_name: \"David S Jones\",\n date_of_hearing: \"2024-08-07\",\n },\n {\n transcript_id: 12246,\n excerpt: \"inaction just is not a sufficient manifestation of consent in this particular context.\",\n case_name: \"Chassix Holdings, Inc., et al.,\",\n case_number: \"15-10578\",\n judge_name: \"Michael E Wiles\",\n date_of_hearing: \"2015-07-02\",\n },\n {\n transcript_id: 22805,\n excerpt:\n \"failure to submit a ballot can't -- by definition, can't be consent, because you haven't done anything\",\n case_name: \"TBAC Wind Down, Ltd.,\",\n case_number: \"16-13297\",\n judge_name: \"Sean H Lane\",\n date_of_hearing: \"2017-10-31\",\n },\n {\n transcript_id: 49045,\n excerpt: \"No releases will be granted by voters who do not return a ballot.\",\n case_name: \"Azul S.A.\",\n case_number: \"25-11176\",\n judge_name: \"Sean H Lane\",\n date_of_hearing: \"2025-12-19\",\n },\n {\n transcript_id: 10747,\n excerpt:\n \"To get to the opt in, opt out consent issue there has to be sufficient disclosure to the creditor when they cast their vote.\",\n case_name: \"Advance Watch Company Ltd.\",\n case_number: \"15-12690\",\n judge_name: \"Martin Glenn\",\n date_of_hearing: \"2016-01-20\",\n },\n {\n transcript_id: 40449,\n excerpt:\n \"I understand you've switched to opt-in. But creditors voting whether -- on a plan and deciding whether to opt in or not are entitled to an understanding of why.\",\n case_name: \"SVB Financial Group\",\n case_number: \"23-10367\",\n judge_name: \"Martin Glenn\",\n date_of_hearing: \"2024-05-16\",\n },\n {\n transcript_id: 5680,\n excerpt:\n \"I would need to know the identity -- and not under seal. This would need to be part of the public record -- the identity of each\",\n case_name: \"The Roman Catholic Diocese of Rockville Centre, Ne\",\n case_number: \"20-12345\",\n judge_name: \"Martin Glenn\",\n date_of_hearing: \"2023-07-10\",\n },\n {\n transcript_id: 5689,\n excerpt:\n \"if any party expects to get a release, they're going to have to -- if the case survives beyond this motion to dismiss, it may not\",\n case_name: \"The Roman Catholic Diocese of Rockville Centre, Ne\",\n case_number: \"20-12345\",\n judge_name: \"Martin Glenn\",\n date_of_hearing: \"2023-07-11\",\n },\n {\n transcript_id: 42487,\n excerpt:\n \"Purdue has no bearing on the availability of the third-party releases if there's a signed document with the release.\",\n case_name: \"The Roman Catholic Diocese of Rockville Centre, Ne\",\n case_number: \"20-12345\",\n judge_name: \"Martin Glenn\",\n date_of_hearing: \"2024-10-30\",\n },\n {\n transcript_id: 20895,\n excerpt:\n \"Fairness, necessity to the reorganization, and specific factual findings to support the conclusions.\",\n case_name: \"Millennium Lab Holdings II, LLC\",\n case_number: \"15-12284\",\n judge_name: \"Laurie Selber Silverstein\",\n date_of_hearing: \"2015-12-11\",\n },\n {\n transcript_id: 20895,\n excerpt: \"Without the contributions, there is no reorganization.\",\n case_name: \"Millennium Lab Holdings II, LLC\",\n case_number: \"15-12284\",\n judge_name: \"Laurie Selber Silverstein\",\n date_of_hearing: \"2015-12-11\",\n },\n {\n transcript_id: 21315,\n excerpt: \"no financial contribution, no plan, and the financial contribution was substantial.\",\n case_name: \"North Texas Bancshares of Delaware, Inc. and North Texas Bancshares Inc\",\n case_number: \"13-12699\",\n judge_name: \"Kevin Gross\",\n date_of_hearing: \"2014-06-04\",\n },\n {\n transcript_id: 15718,\n excerpt: \"the releases are \u2018nice to have, but they're not a need to have.\u2019\",\n case_name: \"GT Real Estate Holdings, LLC\",\n case_number: \"22-10505\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-12-14\",\n },\n {\n transcript_id: 41042,\n excerpt:\n \"the existence of the backstop proves that the nonconsensual releases are not necessary to the reorganization.\",\n case_name: \"Amyris, Inc.\",\n case_number: \"23-11131\",\n judge_name: \"Thomas M Horan\",\n date_of_hearing: \"2024-02-02\",\n },\n {\n transcript_id: 15900,\n excerpt:\n \"third-party releasing creditors must receive consideration on account of the third-party released claims they are forced to give up under a debtor's plan\",\n case_name: \"Gulf Coast Health Care, LLC\",\n case_number: \"21-11336\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-05-04\",\n },\n {\n transcript_id: 15900,\n excerpt:\n \"no separate analysis was performed by the debtors or the committee as to the value of the third-party released claims\",\n case_name: \"Gulf Coast Health Care, LLC\",\n case_number: \"21-11336\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-05-04\",\n },\n {\n transcript_id: 20799,\n excerpt: \"If a DIP alone were sufficient, all DIP lenders would get a release and that is not true.\",\n case_name: \"Boomerang Tube, LLC\",\n case_number: \"15-11247\",\n judge_name: \"Mary F Walrath\",\n date_of_hearing: \"2015-11-09\",\n },\n {\n transcript_id: 15510,\n excerpt: \"there's no evidence of necessity or a substantial contribution to the plan.\",\n case_name: \"Kettner Investments, LLC\",\n case_number: \"20-12366\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-02-15\",\n },\n {\n transcript_id: 15332,\n excerpt:\n \"if nondebtors want a third-party release by creditors, they need to have those creditors opt into that release and take affirmative action to\",\n case_name: \"Reverse Mortgage Investment Trust Inc.\",\n case_number: \"22-11225\",\n judge_name: \"Mary F Walrath\",\n date_of_hearing: \"2023-03-21\",\n },\n {\n transcript_id: 16517,\n excerpt:\n \"I really think this has to be an affirmative agreement by a creditor that they're willing to agree to release non-debtors.\",\n case_name: \"The Hertz Corporation\",\n case_number: \"20-11218\",\n judge_name: \"Mary F Walrath\",\n date_of_hearing: \"2021-04-16\",\n },\n {\n transcript_id: 41014,\n excerpt: \"Failing to object in my court is not sufficient manifestation of consent.\",\n case_name: \"Pennsylvania Real Estate Investment Trust\",\n case_number: \"23-11974\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2024-01-22\",\n },\n {\n transcript_id: 41615,\n excerpt:\n \"I view the opt-out box as essentially being a shortcut for I object to the plan, and the debtor responding by carving out the objector\",\n case_name: \"Appgate, Inc.\",\n case_number: \"24-10956\",\n judge_name: \"Craig T Goldblatt\",\n date_of_hearing: \"2024-06-17\",\n },\n {\n transcript_id: 14690,\n excerpt:\n \"where the disclosure is prominent and conspicuous, an opt-out mechanism is a valid means of obtaining consent.\",\n case_name: \"Clovis Oncology, Inc.\",\n case_number: \"22-11292\",\n judge_name: \"J Kate Stickles\",\n date_of_hearing: \"2023-06-09\",\n },\n {\n transcript_id: 45307,\n excerpt:\n \"the opt out structure is when properly implemented, is indeed effective to provide for releases under a confirmed chapter 11 plan.\",\n case_name: \"Molecular Templates, Inc.\",\n case_number: \"25-10739\",\n judge_name: \"Brendan Linehan Shannon\",\n date_of_hearing: \"2025-07-01\",\n },\n {\n transcript_id: 15692,\n excerpt:\n \"the vote and the decision whether to be bound by the third party release or not are analytically distinct\",\n case_name: \"TPC Group Inc.\",\n case_number: \"22-10493\",\n judge_name: \"Craig T Goldblatt\",\n date_of_hearing: \"2022-09-06\",\n },\n {\n transcript_id: 15151,\n excerpt:\n \"I don't think it's appropriate for the debtor to be able to tie the debtors' distribution to creditors to the third-party release\",\n case_name: \"Legacy IMBDS, Inc., et al.,\",\n case_number: \"23-10852\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2023-11-01\",\n },\n {\n transcript_id: 41054,\n excerpt: \"that's essentially a third-party release without everyone having given a third-party release.\",\n case_name: \"PARTS iD, Inc.\",\n case_number: \"23-12098\",\n judge_name: \"Laurie Selber Silverstein\",\n date_of_hearing: \"2024-02-09\",\n },\n {\n transcript_id: 42485,\n excerpt:\n \"If you are asking for a third party release people need to know what exactly it covers and what it doesn\u2019t cover\",\n case_name: \"Imerys Talc America, Inc.\",\n case_number: \"19-10289\",\n judge_name: \"Laurie Selber Silverstein\",\n date_of_hearing: \"2024-11-04\",\n },\n {\n transcript_id: 44061,\n excerpt:\n \"in light of Purdue, there's no prohibition on the use of opt-out releases, but that whether an opt-out is appropriate is subject to a\",\n case_name: \"Lumio Holdings, Inc.\",\n case_number: \"24-11916\",\n judge_name: \"J Kate Stickles\",\n date_of_hearing: \"2025-01-03\",\n },\n {\n transcript_id: 45307,\n excerpt: \"Nonconsensual releases are forbidden absent Section 524(g) and the asbestos context.\",\n case_name: \"Molecular Templates, Inc.\",\n case_number: \"25-10739\",\n judge_name: \"Brendan Linehan Shannon\",\n date_of_hearing: \"2025-07-01\",\n },\n {\n transcript_id: 44977,\n excerpt:\n \"Supreme Court said they couldn't find the authority in 1123(b)(6) to support nonconsensual releases. That's different -- than\",\n case_name: \"GOL Linhas Aereas Inteligentes S.A. and Gol Finance (Luxembourg)\",\n case_number: \"24-10118\",\n judge_name: \"Martin Glenn\",\n date_of_hearing: \"2025-05-20\",\n },\n ],\n },\n ),\n ],\n};\n\nconst example2: LockedClerkExample = {\n slug: \"example2\",\n card: {\n label: \"What makes Judge Owens sustain an objection\",\n icon: Gavel,\n description:\n \"Analyzed Judge Owens' transcripts for factors that flip her between sustaining and overruling confirmation objections.\",\n prompt: \"\",\n },\n messages: [\n userMessage(\n \"example2-u-1\",\n `When ruling on the issues in the attached objection, what specific factors has Judge Owens cited that differentiate their rulings sustaining versus denying? Conduct an exhaustive review of all available relevant transcripts. Factors could include, but not be limited to, different facts, different case law precedent, or different interpretation of case law precedent. Prioritize insights that are both unpredictable \u2014 patterns I, an attorney, wouldn't anticipate from the rules or general experience alone \u2014 and actionable enough to change how I'd frame my motion, what arguments I'd lead with, or whether I'd file one at all.`,\n {\n files: [{ name: \"UST Objection.pdf\", size: 850924, type: \"application/pdf\" }],\n },\n ),\n assistantMessage(\n \"example2-a-1\",\n `Bottom line: Judge Owens sustains these objections when the plan asks her to infer consent, bless broad finality, or alter jurisdiction without a tight factual record. She overrules them when the plan narrows the provision, preserves rights, gives clear notice, and leaves a real forum for later disputes.\n\nIn Akorn itself, the final ruling did not separately analyze the United States\u2019 tax/setoff/government-bar-date objections; by the time of ruling, Judge Owens confirmed the plan after modifications, stating she was \u201Cprepared to overrule the objection and confirm the plan.\u201D[1]\n\n## 1. Release consent: silence loses; accepting ballots can win\n\nThe non-obvious point: Judge Owens rejects \u201Cfailure to object\u201D as consent, but she has repeatedly accepted a returned ballot voting yes plus failure to opt out as affirmative consent.\n\nSustain factors:\n- unimpaired or non-voting parties are bound by inaction;\n- creditors must reject the plan to avoid the release;\n- released parties are not identified before voting;\n- \u201Crelated parties\u201D are swept in without proof the voter can bind them.\n\nIn PREIT, she was categorical: \u201CFailing to object in my court is not sufficient manifestation of consent.\u201D[2] In Legacy IMBDS, she required an opt-out because tying plan distributions to release consent \u201Cpotentially could be seen as coercive.\u201D[3]\n\nDeny/approve factors:\n- creditor received and returned a ballot;\n- voted to accept;\n- release language was conspicuous;\n- creditor had a clear opt-out;\n- releasing creditors also received reciprocal releases.\n\nIn Jambys, post-Purdue, she held the narrow question was whether \u201Ca vote in favor of the plan\u201D plus failure to opt out was enough; she held it was.[4] In True Value, she said Purdue had not changed her analysis and that the focus remains \u201Csufficient manifestation of affirmative consent.\u201D[5]\n\nActionable framing: if defending releases, lead with the mechanics, not Continental. Show who got ballots, who returned them, what box they checked, whether non-voters/rejectors are excluded or opt-in only, and whether releasing parties become released parties. If objecting, do not just say \u201Copt-out is bad\u201D; target the exact group whose only \u201Cconsent\u201D is silence.\n\n## 2. Nonconsensual releases: contributions help only if they are necessary and tied to affected creditor fairness\n\nJudge Owens has approved nonconsensual releases, but the approval record is narrow. In Quorum, she emphasized that releases were \u201Csignificantly scaled back,\u201D limited to voting Classes 4 and 5, and that no unsecured claimants or equity holders gave third-party releases.[6] She also cited substantial contributions through DIP financing, claim concessions, GUC recovery, and post-confirmation liquidity.[7]\n\nShe denied them where finality was merely valuable, not necessary. In GT Real Estate, she held \u201Cdemand from plan financiers is not sufficient to carry the day\u201D[8] and called the releases \u201Cnice to have, but they're not a need to have.\u201D[9] In Gulf Coast, she rejected peace/finality as the only justification.[10] In Kettner, she sustained the UST objection where there was \u201Cno evidence of necessity or a substantial contribution to the plan,\u201D and the settlement was not contingent on plan releases.[11]\n\nActionable framing: if seeking nonconsensual releases, build the record around affected creditors, not beneficiaries. Show affected class support, consideration for the released claims, participation by those creditors or a fiduciary representing them, and why the plan actually fails without the release. If objecting, the best attack is: \u201CThe plan still works if this release is excised.\u201D\n\n## 3. Debtor releases and exculpation are different animals\n\nJudge Owens will approve debtor releases as business judgment when supported by an estate fiduciary investigation, committee support, value-maximizing settlement, narrow carveouts, and weak claims. But insider releases in a liquidating case face much sharper scrutiny.\n\nIn Azzur, she rejected insider debtor releases, warning that broad releases \u201Care not a participation trophy or a merit badge for a job well done.\u201D[12] Her cumulative factors were stark: self-interested board, late cash offer, no independent testing, low creditor recovery, and plan-administrator concerns \u2014 \u201CEverything tilts in favor of denying the insider releases.\u201D[13]\n\nExculpation is more categorical. In Hygea, she stated that \u201Cexculpated parties are limited to estate fiduciaries in this district.\u201D[14] In Medley, she required Sierra and related parties removed because they \u201Ccannot be exculpated as a non-fiduciary.\u201D[15] She also limits exculpation temporally: no prepetition acts and no post-effective-date conduct.[16]\n\nActionable framing: do not argue \u201Csubstantial contribution\u201D to justify exculpation for lenders, sponsors, or other non-fiduciaries. Put them in release analysis, not exculpation. For debtor releases, lead with independent fiduciary process and specific claim investigation.\n\n## 4. Exclusive jurisdiction and gatekeeper provisions are a pressure point\n\nJudge Owens is skeptical of plan language that forces parties back to her before another court can interpret a plan or release.\n\nIn Gulf Coast, she sustained the UST\u2019s objection to an exclusive gatekeeper provision: \u201CI see no reason to retain exclusive jurisdiction.\u201D[17] In Hygea, she put the principle more broadly: \u201CI can't expand or contract my jurisdiction by language in any order, let alone a confirmation order.\u201D[18]\n\nActionable framing: make retained jurisdiction permissive and statutory. Avoid \u201Cexclusive,\u201D \u201Csole,\u201D or \u201Cmust return to this Court first\u201D language unless you have a very specific enforcement need.\n\n## 5. Setoff, recoupment, and estimation: she prefers preservation plus later adjudication\n\nOn unripe setoff, Judge Owens will often preserve rather than decide. In Zohar III, she declined to rule because the rights were not yet established and the issue was \u201Cun-ripe.\u201D[19] But she also insisted that preservation language not be used later \u201Cas a sword for stripping the setoff.\u201D[20]\n\nOn claim estimation, she polices unilateral trustee power. In Medley, she found plan language ambiguous because she did not think a liquidating trustee could estimate a claim \u201Cwithout my intervention.\u201D[21] In Silvergate, she bifurcated estimation because prejudice and threshold appropriateness had to be addressed first.[22]\n\nActionable framing: if defending a plan, remove any language suggesting a plan administrator may estimate, reserve, disallow, or compromise claims \u201Cfree of\u201D the Code or Rules. If objecting, lead with the loss of court oversight and opportunity to be heard.\n\n## 6. Government/tax/admin issues: few merits rulings, but clear practical pattern\n\nI found no Judge Owens transcript squarely deciding a contested \u00A7 511 interest, \u00A7 1129(a)(9)(C), Local Rule 3002-1, Anti-Assignment Act, or West Electronics issue on the merits. These issues were usually resolved by plan/confirmation-order language, full payment, reserves, or rights preservation.\n\nWhere she did rule, the differentiator was practical prejudice and record development. In Virgin Orbit, she overruled the UST\u2019s administrative-claim-treatment objection because later notice would explain the deadline,[23] but sustained the UST-fee/reporting objection because the UST briefed it and \u201Cno one responded with any substantive briefing in rebuttal.\u201D[24] In AeroCision, she struck language purporting to avoid dissolution taxes/fees as \u201Cbeyond my authority.\u201D[25]\n\nActionable framing: for government objections, propose specific order language early. If objecting, show what concrete right will be lost: unexpired government bar date, missing return, no reporting mechanism, interest not accruing, or lien/setoff language actually cut off.\n\n## 7. Speed, stay waiver, and dismissal: economics do not beat process\n\nJudge Owens will permit efficient end-of-case relief when priority rules and notice are clean. In Maurice Sporting Goods, she rejected the argument that distributions always require a plan, noting there is \u201Cno requirement under the Code that a plan is the only mechanism to make distributions.\u201D[26] But she refused to approve exculpation in that same structured dismissal because notice had not been given to all parties in interest.[27]\n\nIn One Table, she went the other way and sustained the UST\u2019s objection to structured dismissal because the proposed post-dismissal claims process lacked clarity, court supervision, and due process.[28] In Southland, when a creditor sought a reserve/stay-like protection, she balanced irreparable harm, likelihood of success, and prejudice to GUCs, then granted only a limited reserve.[29]\n\nActionable framing: if seeking immediate effectiveness or stay waiver, show no unresolved objector will lose a practical remedy. If objecting, identify the forum or process that disappears if the plan goes effective immediately.\n\n## Coverage\n\nI reviewed 49 Judge Owens transcripts identified through targeted searches on the attached objection\u2019s issues. The strongest merits record is on releases, exculpation, jurisdiction/gatekeeper language, setoff preservation, claim estimation, structured dismissal, and UST-fee/admin-claim mechanics. The tax-interest, Local Rule 3002-1, and federal-contract-assignment issues produced mostly resolved-objection records rather than contested bench rulings.`,\n {\n thinking: [\n \"Searching Judge Owens' transcripts for rulings on the issues in the objection.\",\n \"Splitting them into objections she sustained vs. overruled.\",\n \"Finding the factual and consent-mechanic patterns that flip her decision.\",\n \"Pulling her own language on releases, exculpation, jurisdiction, and setoff.\",\n ],\n toolCalls: [\n { tool: \"lookup_judge\", input: { query: \"Owens\" } },\n {\n tool: \"boolean_search\",\n input: {\n query: '(Akorn AND confirm! AND (\"United States Trustee\" OR UST) AND object!)',\n judge_names: [\"Karen B Owens\"],\n },\n },\n {\n tool: \"boolean_search\",\n input: {\n query:\n '(release! OR exculpat! OR \"third party release\" OR setoff OR jurisdiction) AND (sustain! OR overrul! OR object!)',\n judge_names: [\"Karen B Owens\"],\n },\n },\n ],\n toolResults: [\n {\n tool: \"lookup_judge\",\n summary: \"Matched Judge Karen B. Owens, U.S. Bankruptcy Court, District of Delaware\",\n },\n { tool: \"boolean_search\", summary: \"Found 11 transcripts in In re Akorn, Inc.\" },\n { tool: \"boolean_search\", summary: \"Reviewed 49 Judge Owens transcripts on point\" },\n ],\n citations: [\n {\n transcript_id: 17140,\n excerpt:\n \"With respect to confirmation of the plan, I am prepared to overrule the objection and confirm the plan.\",\n case_name: \"Akorn, Inc.\",\n case_number: \"20-11177\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2020-09-04\",\n },\n {\n transcript_id: 41014,\n excerpt: \"Failing to object in my court is not sufficient manifestation of consent.\",\n case_name: \"Pennsylvania Real Estate Investment Trust\",\n case_number: \"23-11974\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2024-01-22\",\n },\n {\n transcript_id: 15151,\n excerpt:\n \"I don't think it's appropriate for the debtor to be able to tie the debtors' distribution to creditors to the third-party release\",\n case_name: \"Legacy IMBDS, Inc., et al.,\",\n case_number: \"23-10852\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2023-11-01\",\n },\n {\n transcript_id: 42149,\n excerpt:\n \"The question here is narrow, I submit, and it's whether a vote in favor of the plan and the creditor who voted in favor\",\n case_name: \"Jambys, Inc.\",\n case_number: \"24-10913\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2024-09-10\",\n },\n {\n transcript_id: 44427,\n excerpt:\n \"Purdue has not changed my analysis that I have consistently had since taking the bench, that my decision-making on this issue is guided\",\n case_name: \"True Value Company, L.L.C.\",\n case_number: \"24-12337\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2025-02-11\",\n },\n {\n transcript_id: 17496,\n excerpt:\n \"First, they have been significantly scaled back from the releases originally proposed and are now limited to the members of the voting Classes 4\",\n case_name: \"Quorum Health Corporation\",\n case_number: \"20-10766\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2020-06-29\",\n },\n {\n transcript_id: 17496,\n excerpt:\n \"Third, the beneficiaries of third-party releases have made substantial contributions to the effected classes through and among other things the provision of the DIP\",\n case_name: \"Quorum Health Corporation\",\n case_number: \"20-10766\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2020-06-29\",\n },\n {\n transcript_id: 15718,\n excerpt: \"demand from plan financiers is not sufficient to carry the day.\",\n case_name: \"GT Real Estate Holdings, LLC\",\n case_number: \"22-10505\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-12-14\",\n },\n {\n transcript_id: 15718,\n excerpt: \"the releases are \u2018nice to have, but they're not a need to have.\u2019\",\n case_name: \"GT Real Estate Holdings, LLC\",\n case_number: \"22-10505\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-12-14\",\n },\n {\n transcript_id: 15900,\n excerpt:\n \"The only justification for the release is the desire by the contribution parties to achieve peace and finality in exchange for their contributions to the\",\n case_name: \"Gulf Coast Health Care, LLC\",\n case_number: \"21-11336\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-05-04\",\n },\n {\n transcript_id: 15510,\n excerpt: \"there's no evidence of necessity or a substantial contribution to the plan.\",\n case_name: \"Kettner Investments, LLC\",\n case_number: \"20-12366\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-02-15\",\n },\n {\n transcript_id: 44992,\n excerpt:\n \"broad releases like the ones here are not a participation trophy or a merit badge for a job well done.\",\n case_name: \"Azzur Group Holdings LLC\",\n case_number: \"25-10342\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2025-05-20\",\n },\n {\n transcript_id: 44992,\n excerpt: \"Everything tilts in favor of denying the insider releases.\",\n case_name: \"Azzur Group Holdings LLC\",\n case_number: \"25-10342\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2025-05-20\",\n },\n {\n transcript_id: 22596,\n excerpt: \"exculpated parties are limited to estate fiduciaries in this district.\",\n case_name: \"Hygea Holdings Corp.\",\n case_number: \"20-10361\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2020-06-12\",\n },\n {\n transcript_id: 22657,\n excerpt:\n \"Sierra and its related parties cannot be exculpated as a non-fiduciary and will require that they be removed\",\n case_name: \"Medley LLC\",\n case_number: \"21-10526\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2021-10-07\",\n },\n {\n transcript_id: 22596,\n excerpt:\n \"I will not prospectively exculpate actions not yet taken by a reorganization, following the effective date, nor will I expand\",\n case_name: \"Hygea Holdings Corp.\",\n case_number: \"20-10361\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2020-06-12\",\n },\n {\n transcript_id: 15900,\n excerpt:\n \"I will sustain the U.S. Trustee's objection on this point. I see no reason to retain exclusive jurisdiction for a determination that\",\n case_name: \"Gulf Coast Health Care, LLC\",\n case_number: \"21-11336\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-05-04\",\n },\n {\n transcript_id: 22596,\n excerpt:\n \"I can't expand or contract my jurisdiction by language in any order, let alone a confirmation order.\",\n case_name: \"Hygea Holdings Corp.\",\n case_number: \"20-10361\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2020-06-12\",\n },\n {\n transcript_id: 15797,\n excerpt:\n \"I am inclined to not rule on that issue today; I am inclined to preserve it because I don\u2019t think that the rights to the\",\n case_name: \"Zohar III, Corp.\",\n case_number: \"18-10512\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-06-21\",\n },\n {\n transcript_id: 15797,\n excerpt:\n \"the preservation or the language preserving the issues shouldn\u2019t be used as a sword for stripping the setoff or the arguments in the future\",\n case_name: \"Zohar III, Corp.\",\n case_number: \"18-10512\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2022-06-21\",\n },\n {\n transcript_id: 22657,\n excerpt:\n \"I don't think that the liquidating trustee could estimate a claim, of course, unless it was agreed to by the parties without my intervention\",\n case_name: \"Medley LLC\",\n case_number: \"21-10526\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2021-10-07\",\n },\n {\n transcript_id: 42662,\n excerpt:\n \"there is significant prejudice -- there could be significant prejudice, depending on how the estimation trial will need to proceed in substance, and that\",\n case_name: \"Silvergate Capital Corporation\",\n case_number: \"24-12158\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2024-11-26\",\n },\n {\n transcript_id: 14989,\n excerpt:\n \"subsequent notice will be provided in the notice of effective date explaining the deadline and providing notice of that deadline to effected parties.\",\n case_name: \"Virgin Orbit Holdings, Inc.\",\n case_number: \"23-10405\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2023-07-28\",\n },\n {\n transcript_id: 14989,\n excerpt:\n \"I am going to sustain the objection of the U.S. Trustee on this issue. The Trustee briefed it and no one responded with\",\n case_name: \"Virgin Orbit Holdings, Inc.\",\n case_number: \"23-10405\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2023-07-28\",\n },\n {\n transcript_id: 41069,\n excerpt: \"That's, I believe, beyond my authority.\",\n case_name: \"AeroCision Parent, LLC\",\n case_number: \"23-11032\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2024-03-04\",\n },\n {\n transcript_id: 22573,\n excerpt:\n \"There\u2019s no requirement under the Code that a plan is the only mechanism to make distributions to claimants\",\n case_name: \"Maurice Sporting Goods of Delaware, Inc.\",\n case_number: \"17-12481\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2020-04-23\",\n },\n {\n transcript_id: 22573,\n excerpt:\n \"With respect to the exculpation provision, I\u2019m not prepared to approve the exculpation provision. I don\u2019t think that\",\n case_name: \"Maurice Sporting Goods of Delaware, Inc.\",\n case_number: \"17-12481\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2020-04-23\",\n },\n {\n transcript_id: 45380,\n excerpt:\n \"there\u2019s another part of this, which is the integrity of the process and due process and that\u2019s where this idea or this proposed process\",\n case_name: \"One Table Restaurant Brands, LLC\",\n case_number: \"24-11553\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2025-07-17\",\n },\n {\n transcript_id: 16756,\n excerpt:\n \"And I think that I look at this issue similarly than I would look -- similarly to how I would look at a stay pending appeal and\",\n case_name: \"Southland Royalty Company LLC\",\n case_number: \"20-10158\",\n judge_name: \"Karen B Owens\",\n date_of_hearing: \"2021-05-20\",\n },\n ],\n },\n ),\n ],\n};\n\nconst example3: LockedClerkExample = {\n slug: \"example3\",\n card: {\n label: \"Which witnesses win a contested DIP before Judge Isgur\",\n icon: UserSearch,\n description:\n \"Read Judge Isgur's DIP hearings to map which witness type he credits on roll-up, cash need, and adequate protection.\",\n prompt: \"\",\n },\n messages: [\n userMessage(\n \"example3-u-1\",\n `When ruling on DIP related issues, what types of witnesses does Judge Isgur respond better to? Conduct an exhaustive review of all available relevant transcripts. Factors could include, but not be limited to, different facts, different case law precedent, or different interpretation of case law precedent. Prioritize insights that are both unpredictable \u2014 patterns I, an attorney, wouldn't anticipate from the rules or general experience alone \u2014 and actionable enough to change how I'd select a witness to best navigate a contested DIP.`,\n ),\n assistantMessage(\n \"example3-a-1\",\n `Bottom line: Judge Isgur responds best to the witness whose actual job matches the disputed DIP issue. For a contested DIP, the safest lineup is usually: market-facing banker for alternatives/roll-up/pricing; CFO/CRO/treasurer for immediate cash need and budget; independent fiduciary if conflicts or insider dynamics are present; and a collateral/waterfall witness for adequate protection.\n\n## The best witness for roll-up, pricing, or \u201Conly available financing\u201D is usually the banker who ran the market\n\nThe most actionable pattern is that Judge Isgur can be moved by a live, precise investment banker even when he starts skeptical. In California Pizza Kitchen, he opened with concern that the effective rate looked extreme, then approved after Guggenheim\u2019s Stuart Erickson explained DIP-to-exit economics, alternatives, and liquidity need:\n\n> \u201CI\u2019m persuaded by Mr. Erickson\u2019s testimony that my initial evaluation, which I\u2019m forced to do sort of without any notice, at this first day hearing was incorrect.\u201D In re California Pizza Kitchen, Inc. and CPK Parent Inc., 20-33752, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Jul. 30, 2020) [1].\n\nThe same pattern appeared in GWG. Judge Isgur discounted insider/model testimony, but credited the banker who tied valuation theory to actual market evidence:\n\n> \u201CI find Mr. Laurinaitis's testimony to be extraordinarily credible; and frankly, with that testimony, the business judgment gets sustained. But for what it's worth, without that, it wouldn't have been. But Mr. Laurinaitis carried the day for the debtor, and I'm going to approve it.\u201D In re GWG Holdings, Inc. and GWG Life USA, LLC, 22-90032, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Oct. 27, 2022) [2].\n\nUse that witness when the fight is: roll-up necessity, priming alternatives, pricing, competing DIP proposals, or whether a less onerous facility was realistically executable. The witness should personally know the outreach, bids, lender feedback, and why no unsecured/junior/pari/priming alternative exists.\n\n## But banker testimony fails if it lacks collateral and adequate-protection facts\n\nThe banker is not a cure-all. In SpeedCast, Judge Isgur credited finance professionals because they had investigated the marketplace and the proof was unchallenged:\n\n> \u201CThe testimony that the Debtors\u2019 extremely high-qualified professionals, who are very credible witnesses, concluded after investigating the marketplace that they couldn\u2019t obtain the credit otherwise is proof.\u201D In re SpeedCast International Limited and SpeedCast Communications, Inc., 20-32243, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (May 20, 2020) [3].\n\nBut in Pipeline, he stopped the hearing when the financing witness could not account for potentially unencumbered assets:\n\n> \u201CHow can we determine whether you meet the requirements of Section 364 unless we know whether there are substantial unencumbered assets that could generate these funds?\u201D In re Pipeline Health System, LLC, 22-90291, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Oct. 31, 2022) [4].\n\nThe debtors later cured that problem by re-running the market process treating the assets as unencumbered:\n\n> \u201CThe debtors have now revisited that. They have now gone back into the marketplace dealing with those as unencumbered assets, and once again can meet their burden of proof under the currently-known factual scenario.\u201D In re Pipeline Health System, LLC, 22-90291, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Nov. 16, 2022) [5].\n\nAction point: if collateral, priming, or unencumbered assets are in play, pair the banker with a lien/valuation witness. Do not let the banker say \u201Cbest available\u201D without knowing what collateral was assumed.\n\n## For emergency need, use the person who owns the 13-week cash forecast\n\nJudge Isgur distinguishes \u201Cwe need the announcement\u201D from \u201Cwe need the cash.\u201D The useful witness is the CFO, treasurer, CRO, or financial advisor who can walk the 13-week model and explain exactly what breaks.\n\nIn CEC, the budget testimony mattered directly:\n\n> \u201CThe fact is that on the 13 week budget which no one contests, next week the debtor will drop below its $25 million optimum cash reserves if the DIP isn\u2019t funded immediately.\u201D In re CEC Entertainment, Inc. and Official Committee Of Unsecured Creditors, 20-33163, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Oct. 8, 2020) [6].\n\nIn Linc, he began skeptical, then credited live testimony tying a delayed BP bond release to immediate cash failure:\n\n> \u201CI do think the evidence demonstrates a striking need to have the money.\u201D In re Linc USA GP and Official Committee Of Unsecured Creditors, 16-32689, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (May 31, 2016) [7].\n\nAction point: prepare the finance witness to answer account-by-account cash availability, restricted cash, foreign cash, payroll/rent/vendor timing, minimum liquidity, and what line items can be deferred.\n\n## For adequate protection and waivers, do not use a CRO who cannot do the waterfall\n\nThis is the most dangerous trap. Judge Isgur may find a CRO credible and still deny relief if the witness cannot explain adequate protection, diminution, 506(c), 552(b), or who benefits.\n\nIn BJ Services, he denied the motion because the CRO did not understand the economics:\n\n> \u201CI\u2019m denying the motion. I have a witness that doesn\u2019t understand what we\u2019re doing.\u201D In re BJ Services, LLC and BJ Services Management Holdings Corporation, 20-33627, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Oct. 19, 2020) [8].\n\nIn Griddy, the CFO proved cash need but not adequate-protection need:\n\n> \u201CUnder controlling Supreme Court precedent, adequate protection need not be provided to an oversecured secured creditor unless there is a substantial possibility of a diminution and the value of that collateral. I\u2019ve heard zero evidence of that, so I\u2019m denying the motion as pled.\u201D In re Griddy Energy LLC and Official Committee Of Unsecured Creditors, 21-30923, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Mar. 16, 2021) [9].\n\nAction point: for contested adequate protection, bring someone who can quantify diminution, collateral value, lien stack, replacement liens, unencumbered assets, and the unsecured-creditor impact. A budget witness alone is not enough.\n\n## For priming/valuation, use a real valuation or collateral witness\u2014not a CEO with reserve reports\n\nJudge Isgur polices expert boundaries. In Northstar, he would not let an operational executive become a valuation expert by force of familiarity:\n\n> \u201CDoes he know a lot more than I do? Absolutely. Does he know enough to qualify as an expert under the federal rules? No. Was he properly designated? No.\u201D In re Northstar Offshore Group, LLC and Official Committee of Unsecured Creditors, 16-34028, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Jan. 13, 2017) [10].\n\nTechnical witnesses can help, but only on their lane. In TMT, the broker was credible, but the debtor still failed because no management or financial-advisor witness explained the business judgment:\n\n> \u201CMr. Roberts is a man of high credibility, who answered every question, I think, honestly and to the best of his capability, but I think he doesn't have the experience required for me to say that anyone's business judgment should be sustained.\u201D In re TMT Procurement Corporation, 13-33763, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Feb. 19, 2014) [11].\n\nAction point: if the issue is collateral value, bring a qualified valuation witness. If the issue is business judgment, bring management/CRO. Do not confuse the two.\n\n## If conflicts, insider lenders, or lender-driven milestones are present, use an independent fiduciary\n\nWhen the DIP is entangled with insider dynamics, credit bids, milestones, or a CRO condition, Judge Isgur wants evidence that the debtor\u2019s decision is genuinely independent.\n\nIn Anagram, he separated the witness roles: the CRO for value-maximizing business judgment, the banker for process/milestones:\n\n> \u201CIt\u2019s whether the debtor believes it\u2019s going to maximize value. That\u2019s why I thought Mr. Frankum would be the witness under his declaration.\u201D In re Anagram Holdings, LLC and Anagram International, Inc., 23-90901, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Nov. 9, 2023) [12].\n\nIn Sanchez, where a CRO appointment was tied to DIP progress, he would not approve a cosmetic role:\n\n> \u201CI'm not inclined to appoint any CRO if it's a meaningless appointment.\u201D In re Sanchez Energy Corporation, 19-34508, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Dec. 6, 2019) [13].\n\nAction point: if independence is an issue, call the independent director, special committee chair, or empowered CRO. The testimony should cover reporting lines, authority, conflicts, advisor oversight, and why the process is not lender-captured.\n\n## The counterintuitive point: an ugly roll-up can pass if no one proves a live alternative\n\nJudge Isgur dislikes roll-ups, but he will not rewrite a lender\u2019s deal without evidence of an executable alternative. In Black Elk, objectors attacked the roll-up but did not cross-examine the affidavit witness or prove a viable no-rollup financing:\n\n> \u201CIf Option C isn\u2019t available, then I\u2019ve only got to pick between A and B and I can\u2019t say make B better. I can\u2019t make people lend money on terms they don\u2019t want to lend money on.\u201D In re Black Elk Energy Offshore Operations, LLC and Wood Group PSN, Inc., 15-34287, before Judge Marvin Isgur, Texas Southern Bankruptcy Court (Mar. 18, 2016) [14].\n\nAction point: for debtor\u2019s counsel, prove \u201Cthis or no deal\u201D with a cross-ready market witness. For objectors, do not just call the roll-up offensive\u2014put on evidence that another lender will actually close.\n\n## Recommended contested-DIP witness lineup\n\nFor a serious contested DIP before Judge Isgur, I would consider this order:\n\n- Lead witness if pricing/roll-up/alternatives are contested: banker or debt-advisory professional who ran the market.\n- Lead witness if emergency/interim need is contested: CFO/treasurer/CRO who owns the 13-week cash forecast.\n- Required add-on if adequate protection is contested: collateral/valuation/waterfall witness.\n- Required add-on if insider/conflict/milestones are contested: independent fiduciary or empowered CRO.\n- Supporting witness only: technical operator, broker, engineer, or asset specialist.\n\nThe theme is simple: do not bring the most senior witness; bring the witness Judge Isgur can use to make the specific finding he is struggling with.\n\n## Coverage\n\nI screened the full Judge Isgur DIP/cash-collateral universe identified by financing-related search terms and read 52 witness-heavy, contested, or otherwise probative transcripts from 2014\u20132024. Routine uncontested orders and duplicative hearings were screened but not treated as materially probative unless they showed a distinct witness-selection signal.`,\n {\n thinking: [\n \"Searching Judge Isgur's DIP and cash-collateral hearings for contested, witness-heavy records.\",\n \"Grouping rulings by disputed issue \u2014 pricing/roll-up, cash need, adequate protection, conflicts.\",\n \"Matching each issue to the witness type he credited or rejected.\",\n \"Pulling his bench quotes crediting or discounting each witness.\",\n ],\n toolCalls: [\n { tool: \"lookup_judge\", input: { query: \"Isgur\" } },\n {\n tool: \"boolean_search\",\n input: {\n query:\n '((DIP OR \"cash collateral\" OR \"debtor in possession financing\") AND (witness OR testimony OR declaration OR \"cross-examination\"))',\n judge_names: [\"Marvin Isgur\"],\n },\n },\n {\n tool: \"boolean_search\",\n input: {\n query:\n '(\"roll-up\" OR \"adequate protection\" OR \"priming lien\" OR \"section 364\") AND (CRO OR CFO OR \"investment banker\" OR \"financial advisor\")',\n judge_names: [\"Marvin Isgur\"],\n },\n },\n ],\n toolResults: [\n {\n tool: \"lookup_judge\",\n summary: \"Matched Judge Marvin Isgur, U.S. Bankruptcy Court, Southern District of Texas\",\n },\n { tool: \"boolean_search\", summary: \"Found 605 transcripts in contested DIP and cash-collateral hearings\" },\n { tool: \"boolean_search\", summary: \"Narrowed to 52 witness-heavy, contested DIP hearings from 2014\u20132024\" },\n ],\n citations: [\n {\n transcript_id: 1999,\n excerpt:\n \"I\u2019m persuaded by Mr. Erickson\u2019s testimony that my initial evaluation, which I\u2019m forced to do sort of without any notice, at this first day hearing was incorrect.\",\n case_name: \"California Pizza Kitchen, Inc. and CPK Parent Inc.\",\n case_number: \"20-33752\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2020-07-30\",\n },\n {\n transcript_id: 5177,\n excerpt:\n \"I find Mr. Laurinaitis's testimony to be extraordinarily credible; and frankly, with that testimony, the business judgment gets sustained.\",\n case_name: \"GWG Holdings, Inc. and GWG Life USA, LLC\",\n case_number: \"22-90032\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2022-10-27\",\n },\n {\n transcript_id: 2076,\n excerpt:\n \"The testimony that the Debtors\u2019 extremely high-qualified professionals, who are very credible witnesses, concluded after investigating the marketplace\",\n case_name: \"SpeedCast International Limited and SpeedCast Communications, Inc.\",\n case_number: \"20-32243\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2020-05-20\",\n },\n {\n transcript_id: 578,\n excerpt:\n \"How can we determine whether you meet the requirements of Section 364 unless we know whether there are substantial unencumbered assets\",\n case_name: \"Pipeline Health System, LLC and Official Committee of Unsecured Creditors of Pipel\",\n case_number: \"22-90291\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2022-10-31\",\n },\n {\n transcript_id: 5461,\n excerpt:\n \"The debtors have now revisited that. They have now gone back into the marketplace dealing with those as unencumbered assets\",\n case_name: \"Pipeline Health System, LLC and Official Committee of Unsecured Creditors of Pipel\",\n case_number: \"22-90291\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2022-11-16\",\n },\n {\n transcript_id: 5108,\n excerpt:\n \"The fact is that on the 13 week budget which no one contests, next week the debtor will drop below its $25 million optimum cash reserves\",\n case_name: \"CEC Entertainment, Inc. and Official Committee Of Unsecured Creditors\",\n case_number: \"20-33163\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2020-10-08\",\n },\n {\n transcript_id: 4184,\n excerpt: \"I do think the evidence demonstrates a striking need to have the money.\",\n case_name: \"Linc USA GP and Official Committee Of Unsecured Creditors\",\n case_number: \"16-32689\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2016-05-31\",\n },\n {\n transcript_id: 1807,\n excerpt: \"I\u2019m denying the motion. I have a witness that doesn\u2019t understand what we\u2019re doing.\",\n case_name: \"BJ Services, LLC and BJ Services Management Holdings Corporation\",\n case_number: \"20-33627\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2020-10-19\",\n },\n {\n transcript_id: 1252,\n excerpt:\n \"Under controlling Supreme Court precedent, adequate protection need not be provided to an oversecured secured creditor unless there is a substantial possibility\",\n case_name: \"Griddy Energy LLC and Official Committee Of Unsecured Creditors\",\n case_number: \"21-30923\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2021-03-16\",\n },\n {\n transcript_id: 3997,\n excerpt:\n \"Does he know a lot more than I do? Absolutely. Does he know enough to qualify as an expert under the federal rules?\",\n case_name: \"Northstar Offshore Group, LLC and Official Committee of Unsecured Creditors\",\n case_number: \"16-34028\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2017-01-13\",\n },\n {\n transcript_id: 5007,\n excerpt:\n \"Mr. Roberts is a man of high credibility, who answered every question, I think, honestly and to the best of his capability\",\n case_name: \"TMT Procurement Corporation and Official Committee of Unsecured Creditors of TMT P\",\n case_number: \"13-33763\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2014-02-19\",\n },\n {\n transcript_id: 22726,\n excerpt:\n \"It\u2019s whether the debtor believes it\u2019s going to maximize value. That\u2019s why I thought Mr. Frankum would be the witness\",\n case_name: \"Anagram Holdings, LLC and Anagram International, Inc.\",\n case_number: \"23-90901\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2023-11-09\",\n },\n {\n transcript_id: 2849,\n excerpt: \"I'm not inclined to appoint any CRO if it's a meaningless appointment.\",\n case_name: \"Sanchez Energy Corporation, et al\",\n case_number: \"19-34508\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2019-12-06\",\n },\n {\n transcript_id: 3042,\n excerpt:\n \"If Option C isn\u2019t available, then I\u2019ve only got to pick between A and B and I can\u2019t say make B better.\",\n case_name: \"Black Elk Energy Offshore Operations, LLC and Wood Group PSN, Inc.\",\n case_number: \"15-34287\",\n judge_name: \"Marvin Isgur\",\n date_of_hearing: \"2016-03-18\",\n },\n ],\n },\n ),\n ],\n};\n\nexport const LOCKED_CLERK_EXAMPLES: Record = {\n example1,\n example2,\n example3,\n};\n\nexport const LOCKED_CLERK_EXAMPLE_LIST: LockedClerkExample[] = [example1, example2, example3];\n", "import React from \"react\";\nimport { Box } from \"@mui/material\";\nimport { motion, type TargetAndTransition } from \"motion/react\";\nimport { useNavigate } from \"@/utils/urlHelpers\";\nimport { useBooleanSearchBarDispatch } from \"@/components/contexts/BooleanSearchBarControlContext\";\nimport { useCarriedQueryPrefill } from \"@/hooks/useCarriedQueryPrefill\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { UseCaseBlock } from \"@/components/molecules/UseCaseBlock\";\nimport { UsecaseCard } from \"@/components/atoms/UsecaseCard\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { isGenerativeAIDisabled } from \"@/utils/featureFlags\";\nimport { LOCKED_CLERK_EXAMPLE_LIST, type LockedClerkExample } from \"./lockedClerkExamples\";\nimport { AGENT_HELP_CENTER_URL } from \"./constants\";\n\n/**\n * Shared footer rendered below the locked Clerk surfaces \u2014 primarily the\n * `LockedClerkLanding` (and still referenced by the live session views in\n * `AgentPrototypeLayout` / `AgentPrototypeConversation` for the rare case a\n * locked account reaches a `:token` URL directly).\n *\n * Surfaces:\n * - Primary \"Search transcripts\" CTA \u2014 opens the topbar SearchOverlay\n * via `expandAndFocusQueryText()`, no navigation\n * - \"See an example conversation with Clerk\" header with the\n * Clerk-101 Intercom tooltip\n * - 3 example-conversation cards routing to `/agent/example{1|2|3}`\n *\n * `animateIn` gates a staggered reveal: when it flips true (the landing flips\n * it once the canned response finishes typing), the CTA fades in, then the\n * example section, then each card one by one. `initial={false}` means the\n * default (`animateIn` omitted \u2192 true) renders in the final state with no\n * entrance animation, so the live-session consumers are visually unchanged.\n * Honors `prefers-reduced-motion` via the app-level ``.\n *\n * Wrapping / max-width is the consumer's responsibility \u2014 the footer\n * just renders these blocks in a vertical flex column with the standard\n * 40px spacing the landing page uses.\n */\n\nconst SECTION_HEADER_COPY = \"See an example session:\";\n\n// Staggered-reveal timing (seconds). CTA first, then the example section, then\n// the cards one by one. While hidden, `visibility: hidden` + `pointerEvents:\n// none` keep the CTA + cards out of the tab order and off screen readers during\n// the typewriter window \u2014 `opacity: 0` alone leaves them focusable/announced.\nconst REVEAL_HIDDEN: TargetAndTransition = { opacity: 0, y: 8, visibility: \"hidden\", pointerEvents: \"none\" };\nconst REVEAL_VISIBLE: TargetAndTransition = { opacity: 1, y: 0, visibility: \"visible\", pointerEvents: \"auto\" };\nconst REVEAL_DURATION = 0.3;\nconst CTA_DELAY = 0;\nconst SECTION_DELAY = 0.15;\nconst CARD_BASE_DELAY = 0.3;\nconst CARD_STAGGER = 0.12;\n\n// Shared wrapper for the staggered reveal \u2014 identical fade+rise for the CTA, the\n// example section, and each card; `delay` drives the stagger. `initial={false}`\n// means the default (animateIn omitted \u2192 true) mounts in the final state.\nconst AnimatedReveal: React.FC<{ animateIn: boolean; delay: number; children: React.ReactNode }> = ({\n animateIn,\n delay,\n children,\n}) => (\n \n {children}\n \n);\n\ninterface LockedClerkFooterProps {\n /**\n * When false, the CTA + example cards sit hidden (in place, no layout shift)\n * until flipped true, at which point they reveal in a staggered sequence.\n * Defaults to true so non-animated consumers render the final state.\n */\n animateIn?: boolean;\n}\n\nconst LockedClerkFooter: React.FC = ({ animateIn = true }) => {\n const navigate = useNavigate();\n const { expandAndFocusQueryText } = useBooleanSearchBarDispatch();\n const prefillCarriedQuery = useCarriedQueryPrefill();\n\n const handleSearchTranscriptsClick = () => {\n // Seed the search box with the carried-over question (`?q=`) BEFORE opening \u2014\n // the overlay snapshots `searchInput` at open time, so it must be set first.\n prefillCarriedQuery();\n expandAndFocusQueryText();\n };\n\n const handleExampleClick = (example: LockedClerkExample, position: number) => {\n if (isGenerativeAIDisabled()) {\n void recordUserEvent({\n event_name: \"click_disabled_clerk_example_session\",\n event_properties: {\n example_slug: example.slug,\n example_label: example.card.label,\n position,\n },\n });\n }\n navigate({ pathname: `/agent/${example.slug}` });\n };\n\n const handleAgentHelpClick = () => {\n window.open(AGENT_HELP_CENTER_URL, \"_blank\", \"noopener,noreferrer\");\n };\n\n return (\n \n \n \n Search transcripts\n \n \n \n (\n \n handleExampleClick(example, i + 1)}\n maxDescriptionLines={4}\n />\n \n ))}\n />\n \n \n );\n};\n\nexport default LockedClerkFooter;\n", "import React, { useCallback, useEffect, useRef, useState } from \"react\";\n// eslint-disable-next-line no-restricted-imports -- the new-tab handoff uses a literal URL marker; removing it must preserve the hash used by incognito query routing.\nimport { useParams, useOutletContext, useLocation, useNavigate as useRouterNavigate } from \"react-router-dom\";\nimport { Box, CircularProgress, Stack, Typography } from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { useAgentPrototype } from \"./AgentPrototypeContext\";\nimport AgentPrototypeChat from \"./AgentPrototypeChat\";\nimport { RequestJudgeModal } from \"../molecules/RequestJudgeModal\";\nimport LockedClerkFooter from \"./LockedClerkFooter\";\nimport type { LayoutOutletContext } from \"./AgentPrototypeLayout\";\nimport { useNavigate } from \"../../utils/urlHelpers\";\nimport { CLERK_ERROR_COPY } from \"../../utils/clerkErrorCopy\";\nimport { featureEnabled, isClerkAvailable } from \"../../utils/featureFlags\";\nimport { useGlobalAlert } from \"../../contexts/GlobalAlertContext\";\nimport type { ChatMessage } from \"../../hooks/useAgentPrototypeSession\";\nimport { useOptionalClientMatter } from \"@/contexts/ClientMatterContext\";\nimport { isCreditBillingLive } from \"@/utils/creditBilling\";\n\nimport { getBranchDraft, type MessageDraft } from \"../../api/agentPrototype\";\n\nconst EMPTY_CONVERSATION_RETRY_LIMIT = 6;\nconst EMPTY_CONVERSATION_RETRY_DELAY_MS = 500;\n\nconst AgentPrototypeConversation: React.FC = () => {\n const navigate = useNavigate();\n const routerNavigate = useRouterNavigate();\n const location = useLocation();\n const branchInFlight = useRef(false);\n const draftRequests = useRef(new Map>());\n const { token: urlToken } = useParams<{ token: string }>();\n const {\n openTranscript,\n nextSteps,\n onSelectNextStep,\n highlights,\n onTextSelected,\n onHighlightClick,\n renderPlanningMessage,\n planningTrailingContent,\n } = useOutletContext();\n const {\n sessionId,\n isFreshEmptySession,\n branchOrigin,\n conversationDrafts,\n token: sessionToken,\n status,\n error,\n messages,\n hasMoreMessages,\n loadSession,\n loadOlderMessages,\n retryRun,\n retryDownloadLoad,\n injectRequestJudgeMessages,\n isStreaming,\n readOnly,\n clientMatterCode,\n steerMessage,\n canSteer,\n cancelAndEditMessage,\n forkMessage,\n pendingMessageActionId,\n pendingMessageActionType,\n pendingAction,\n activePlan,\n pendingPlanning,\n } = useAgentPrototype();\n const { setAlertWithOptions } = useGlobalAlert();\n const messageActionsEnabled = !readOnly && featureEnabled(\"clerk_message_queue\");\n const handleSteerMessage = useCallback(\n async (message: ChatMessage) => {\n try {\n await steerMessage(message);\n } catch (error) {\n setAlertWithOptions(error instanceof Error ? error.message : \"Could not steer. Please try again.\", \"error\");\n }\n },\n [steerMessage, setAlertWithOptions],\n );\n const handleCancelAndEditMessage = useCallback(\n async (message: ChatMessage) => {\n try {\n await cancelAndEditMessage(message);\n } catch (error) {\n setAlertWithOptions(\n error instanceof Error ? error.message : \"Could not restore this message. Please try again.\",\n \"error\",\n );\n }\n },\n [cancelAndEditMessage, setAlertWithOptions],\n );\n const handleForkMessage = useCallback(\n async (message: ChatMessage) => {\n if (branchInFlight.current) return;\n branchInFlight.current = true;\n const branchTab = window.open(\"about:blank\", \"_blank\");\n if (!branchTab) {\n branchInFlight.current = false;\n setAlertWithOptions(\"Could not branch this conversation. Please try again.\", \"error\");\n return;\n }\n branchTab.opener = null;\n try {\n const result = await forkMessage(message);\n if (!result?.session_token) {\n branchTab.close();\n return;\n }\n branchTab.location.replace(`/agent/${encodeURIComponent(result.session_token)}?branchDraft=1`);\n } catch (error) {\n branchTab.close();\n setAlertWithOptions(\n error instanceof Error ? error.message : \"Could not branch this conversation. Please try again.\",\n \"error\",\n );\n } finally {\n branchInFlight.current = false;\n }\n },\n [forkMessage, setAlertWithOptions],\n );\n\n useEffect(() => {\n if (!urlToken || new URLSearchParams(location.search).get(\"branchDraft\") !== \"1\") return;\n let active = true;\n let request = draftRequests.current.get(urlToken);\n if (!request) {\n request = getBranchDraft(urlToken);\n draftRequests.current.set(urlToken, request);\n }\n void request\n .then((draft) => {\n if (!active) return;\n conversationDrafts.restore(urlToken, `branch:${urlToken}`, { text: draft.message, files: draft.files });\n const query = new URLSearchParams(location.search);\n query.delete(\"branchDraft\");\n routerNavigate(\n { pathname: location.pathname, search: query.toString(), hash: location.hash },\n { replace: true },\n );\n })\n .catch((error) => {\n if (!active) return;\n draftRequests.current.delete(urlToken);\n setAlertWithOptions(\n error instanceof Error ? error.message : \"Could not restore this message. Please try again.\",\n \"error\",\n );\n });\n return () => {\n active = false;\n };\n }, [\n urlToken,\n location.pathname,\n location.search,\n location.hash,\n conversationDrafts,\n routerNavigate,\n setAlertWithOptions,\n ]);\n const clientMatter = useOptionalClientMatter();\n const loadedToken = useRef(null);\n const emptyRetryAttempts = useRef(0);\n const emptyRetryTimeout = useRef(null);\n const [emptyLoadFailed, setEmptyLoadFailed] = useState(false);\n const [requestJudgeOpen, setRequestJudgeOpen] = useState(false);\n const [requestJudgeQuery, setRequestJudgeQuery] = useState(\"\");\n const switchingConversation = Boolean(urlToken && sessionToken !== urlToken);\n const freshEmptyConversation = Boolean(isFreshEmptySession && urlToken === sessionToken);\n const switchFailed = switchingConversation && Boolean(error) && status !== \"creating\";\n\n const handleRequestJudge = useCallback((judgeName: string) => {\n setRequestJudgeQuery(judgeName);\n setRequestJudgeOpen(true);\n }, []);\n\n const handleRequestJudgeClose = useCallback(() => {\n setRequestJudgeOpen(false);\n }, []);\n\n const clearEmptyRetryTimeout = useCallback(() => {\n if (emptyRetryTimeout.current === null) return;\n window.clearTimeout(emptyRetryTimeout.current);\n emptyRetryTimeout.current = null;\n }, []);\n\n const retryConversationLoad = useCallback(() => {\n if (!urlToken || emptyRetryTimeout.current !== null) return;\n\n emptyRetryTimeout.current = window.setTimeout(() => {\n emptyRetryTimeout.current = null;\n emptyRetryAttempts.current += 1;\n void loadSession(urlToken);\n }, EMPTY_CONVERSATION_RETRY_DELAY_MS);\n }, [loadSession, urlToken]);\n\n // Load a changed URL unless its populated session has no load in progress.\n // Also retry an unexpectedly empty session for the current URL.\n useEffect(() => {\n if (!urlToken) return;\n\n if (urlToken !== loadedToken.current) {\n loadedToken.current = urlToken;\n emptyRetryAttempts.current = 0;\n setEmptyLoadFailed(false);\n clearEmptyRetryTimeout();\n if (urlToken === sessionToken && messages.length > 0 && status !== \"creating\") {\n return;\n }\n void loadSession(urlToken);\n return;\n }\n\n if (sessionToken === urlToken && (messages.length > 0 || branchOrigin || freshEmptyConversation)) {\n emptyRetryAttempts.current = 0;\n setEmptyLoadFailed(false);\n clearEmptyRetryTimeout();\n return;\n }\n\n if (status === \"creating\") return;\n\n // A settled mismatch needs recovery even if retained stream or poll updates\n // have already cleared the hook's load error.\n if (status === \"error\" || switchingConversation) {\n clearEmptyRetryTimeout();\n setEmptyLoadFailed(true);\n return;\n }\n\n if (emptyRetryAttempts.current >= EMPTY_CONVERSATION_RETRY_LIMIT) {\n clearEmptyRetryTimeout();\n setEmptyLoadFailed(true);\n return;\n }\n\n retryConversationLoad();\n }, [\n urlToken,\n sessionToken,\n status,\n messages.length,\n branchOrigin,\n freshEmptyConversation,\n switchingConversation,\n loadSession,\n clearEmptyRetryTimeout,\n retryConversationLoad,\n ]);\n\n useEffect(() => () => clearEmptyRetryTimeout(), [clearEmptyRetryTimeout]);\n\n const handleRetryConversation = useCallback(() => {\n if (!urlToken) return;\n\n clearEmptyRetryTimeout();\n emptyRetryAttempts.current = 0;\n setEmptyLoadFailed(false);\n void loadSession(urlToken);\n }, [clearEmptyRetryTimeout, loadSession, urlToken]);\n\n const handleRetryRun = useCallback(\n async (failedRunId: string) => {\n if (isCreditBillingLive()) {\n const matterCode = await clientMatter?.ensureMatter({\n lockedMatterCode: clientMatterCode || undefined,\n });\n if (!matterCode) return;\n }\n\n await retryRun(failedRunId);\n },\n [clientMatter, clientMatterCode, retryRun],\n );\n\n // Show loading spinner while session is being fetched\n if (switchingConversation || (messages.length === 0 && !branchOrigin && !freshEmptyConversation)) {\n if (!switchFailed && !emptyLoadFailed && status !== \"error\") {\n return (\n \n \n \n );\n }\n\n return (\n \n \n {CLERK_ERROR_COPY.emptyConversationRecoveryHeading}\n \n {error || CLERK_ERROR_COPY.emptyConversationRecoveryBody}\n \n \n Retry conversation\n navigate({ pathname: \"/agent\" })}>\n Back to home\n \n \n \n \n );\n }\n\n // Locked-Clerk session: once the canned response has finished\n // streaming, slot the LockedClerkFooter (Search transcripts CTA +\n // example cards) into the chat's trailing-content slot \u2014 same\n // mx:auto-centered column as the messages, so it visually stacks\n // under the assistant's response as if Clerk generated it.\n const isLocked = !isClerkAvailable();\n const lockedTrailingContent = isLocked && messages.length > 0 && !isStreaming ? : undefined;\n\n return (\n <>\n \n injectRequestJudgeMessages(judgeName)}\n query={requestJudgeQuery}\n />\n \n );\n};\n\nexport default AgentPrototypeConversation;\n", "import React from \"react\";\nimport Box from \"@mui/material/Box\";\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\n\nexport interface EmptyStateProps {\n /**\n * Icon shown in the 48px slot. Pass a lucide icon at size 24\n * (e.g. ``) or the brand logo mark. Lucide icons inherit\n * the muted `secondary.main` color via `currentColor`; image marks render\n * at their own color.\n */\n icon: React.ReactNode;\n /** Headline \u2014 rendered in the italic display (h3) variant. */\n title: string;\n /** Supporting copy under the title. ReactNode so callers can embed links. */\n description: React.ReactNode;\n /** Optional CTA (e.g. a ``). Rendered below the copy. */\n action?: React.ReactNode;\n /**\n * Top offset in px to push the block down from the top of the surface.\n * Defaults to 0 (no offset). Full-page empty states pass\n * `EMPTY_STATE_PAGE_TOP_OFFSET`.\n */\n topOffset?: number;\n}\n\n/** Top offset used by full-page empty states (History, Starred, Notes, \u2026). */\nexport const EMPTY_STATE_PAGE_TOP_OFFSET = 120;\n\n/**\n * EmptyState \u2014 the design-system empty/zero-state block (Figma node 784:6627).\n *\n * A centered icon (48px slot) over an italic display title, a muted description\n * (max 400px wide), and an optional CTA. Shared across History, Starred, Notes,\n * Folders, and the search no-results state so every empty surface reads the same.\n */\nexport const EmptyState: React.FC = ({ icon, title, description, action, topOffset = 0 }) => (\n \n \n {icon}\n \n \n \n {title}\n \n \n {description}\n \n \n {action}\n \n);\n\nexport default EmptyState;\n", "import React, { useEffect, useState } from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport Dialog from \"@mui/material/Dialog\";\nimport Typography from \"@mui/material/Typography\";\nimport { X } from \"lucide-react\";\nimport { updateSessionTitle } from \"@/api/agentPrototype\";\nimport { queryClient } from \"@/api/queryClient\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { BIQInputField } from \"@/components/atoms/BIQInputField\";\nimport { layout } from \"@/components/theme/tokens/layout\";\nimport type { RecentSession } from \"./mockSessions\";\n\ninterface RenameSessionDialogProps {\n open: boolean;\n session: RecentSession | null;\n onClose: () => void;\n}\n\nexport const RenameSessionDialog: FC = ({ open, session, onClose }) => {\n const [title, setTitle] = useState(\"\");\n const [error, setError] = useState(null);\n const [saving, setSaving] = useState(false);\n\n useEffect(() => {\n if (!open) return;\n setTitle(session?.title ?? \"\");\n setError(null);\n setSaving(false);\n }, [open, session]);\n\n const save = async () => {\n if (saving || !session) return;\n const trimmed = title.trim();\n if (!trimmed) {\n setError(\"Enter a conversation name.\");\n return;\n }\n if (trimmed.length > 100) {\n setError(\"Conversation names can be up to 100 characters.\");\n return;\n }\n\n setSaving(true);\n setError(null);\n try {\n await updateSessionTitle(session.id, trimmed);\n await queryClient.invalidateQueries({ queryKey: [\"agentPrototypeSessions\", \"infinite\"] });\n onClose();\n } catch {\n setError(\"The conversation couldn't be renamed. Please try again.\");\n } finally {\n setSaving(false);\n }\n };\n\n return (\n ({\n width: layout.modalWidth,\n maxWidth: `calc(100% - ${theme.tokens.spacing[8]}px)`,\n boxSizing: \"border-box\",\n m: 0,\n p: `${theme.tokens.spacing[6]}px`,\n gap: `${theme.tokens.spacing[6]}px`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n border: `1px solid ${theme.border.default}`,\n boxShadow: theme.tokens.shadows.none,\n overflow: \"visible\",\n }),\n }}\n >\n \n \n Rename conversation\n \n \n \n \n setTitle(event.target.value)}\n inputProps={{ maxLength: 100, \"aria-label\": \"Conversation name\" }}\n error={Boolean(error)}\n helper={error}\n autoFocus\n fullWidth\n sx={(theme) => ({\n \"& .MuiInputBase-input\": {\n px: `${theme.tokens.spacing[3]}px`,\n py: `${theme.tokens.spacing[4]}px`,\n fontSize: theme.typography.body1.fontSize,\n lineHeight: \"24px\",\n letterSpacing: \"0.15px\",\n },\n })}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") void save();\n }}\n />\n \n \n \n Cancel\n \n void save()} disabled={saving}>\n Save\n \n \n \n );\n};\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport Menu from \"@mui/material/Menu\";\nimport MenuItem from \"@mui/material/MenuItem\";\nimport ListItemIcon from \"@mui/material/ListItemIcon\";\nimport ListItemText from \"@mui/material/ListItemText\";\nimport { PenLine } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport { ADD_TO_FOLDERS_ICON, ADD_TO_FOLDERS_LABEL } from \"@/components/molecules/addToFoldersAction\";\n\ninterface SessionActionsMenuProps {\n anchorEl: HTMLElement | null;\n open: boolean;\n onClose: () => void;\n onRename: () => void;\n onMoveToFolder: () => void;\n showMoveToFolder: boolean;\n}\n\nexport const SessionActionsMenu: FC = ({\n anchorEl,\n open,\n onClose,\n onRename,\n onMoveToFolder,\n showMoveToFolder,\n}) => (\n \n \n \n \n \n Rename\n \n {showMoveToFolder && (\n \n \n \n \n {ADD_TO_FOLDERS_LABEL}\n \n )}\n \n);\n", "import { useCallback, useEffect, useRef } from \"react\";\n\nexport const useContinuousScroll = (loadMore: () => void, hasNextPage: boolean | undefined) => {\n const observerRef = useRef(null);\n const loadMoreRef = useRef(loadMore);\n\n useEffect(() => {\n loadMoreRef.current = loadMore;\n }, [loadMore]);\n\n const lastElementRef = useCallback(\n (node: HTMLElement | null) => {\n if (observerRef.current) observerRef.current.disconnect();\n observerRef.current = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting && hasNextPage) {\n loadMoreRef.current();\n }\n });\n if (node) observerRef.current.observe(node);\n },\n [hasNextPage],\n );\n\n return lastElementRef;\n};\n", "import React, { useMemo, useState } from \"react\";\nimport { Box, Typography, CircularProgress } from \"@mui/material\";\nimport { EllipsisVertical } from \"lucide-react\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { EmptyState, EMPTY_STATE_PAGE_TOP_OFFSET } from \"@/components/molecules/EmptyState\";\nimport { SaveToFolderPopover } from \"@/components/molecules/SaveToFolderPopover\";\nimport { RenameSessionDialog } from \"@/components/SideNav/Recents/RenameSessionDialog\";\nimport { SessionActionsMenu } from \"@/components/SideNav/Recents/SessionActionsMenu\";\nimport type { RecentSession } from \"@/components/SideNav/Recents/mockSessions\";\nimport { colors } from \"@/components/theme/tokens/colors\";\nimport { useSaveToFolder } from \"@/hooks/useSaveToFolder\";\nimport { featureEnabled } from \"@/utils/featureFlags\";\nimport { useInfiniteClerkHistory } from \"../../api/queries/agentPrototype\";\nimport { useContinuousScroll } from \"../../utils/useContinuousScrollHook\";\nimport { useNavigate } from \"../../utils/urlHelpers\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { CLERK_ERROR_COPY } from \"../../utils/clerkErrorCopy\";\nimport { PAGE_CONTENT_MAX_WIDTH } from \"../../utils/constants\";\nimport { stripMarkdown } from \"../../utils/stripMarkdown\";\nimport type { SortDirection } from \"../organisms/ActivityHistoryPage\";\n\ninterface AgentPrototypeHistoryProps {\n sortDirection?: SortDirection;\n}\n\nconst AgentPrototypeHistory: React.FC = ({ sortDirection = \"desc\" }) => {\n const navigate = useNavigate();\n const foldersEnabled = featureEnabled(\"folders_and_annotations\");\n const [menuAnchor, setMenuAnchor] = useState(null);\n const [actionSession, setActionSession] = useState(null);\n const [renameOpen, setRenameOpen] = useState(false);\n const saveToFolder = useSaveToFolder({\n folderableType: \"AgentPrototypeSession\",\n folderableId: actionSession?.sessionId ?? 0,\n sourceType: \"clerk_session\",\n enabled: foldersEnabled && Boolean(actionSession?.sessionId),\n });\n const { data, fetchNextPage, hasNextPage, isError, isFetchNextPageError, isFetchingNextPage, isLoading } =\n useInfiniteClerkHistory(sortDirection);\n // Pause auto-load on error \u2014 a stuck sentinel at the bottom would otherwise\n // hammer fetchNextPage on every intersect. Clicking \"Retry\" resumes.\n const lastElementRef = useContinuousScroll(fetchNextPage, hasNextPage && !isFetchNextPageError);\n\n // Dedupe by token: a session whose updated_at gets bumped between page\n // fetches can appear in two adjacent pages, which would trigger a duplicate\n // key warning. Order is set by the backend per the sortDirection query param;\n // we don't sort client-side (would only re-order the loaded subset, not the\n // full result set).\n const sortedSessions = useMemo(() => {\n const seen = new Set();\n return (data?.pages ?? [])\n .flatMap((p) => p.data)\n .filter((s) => {\n if (seen.has(s.token)) return false;\n seen.add(s.token);\n return true;\n });\n }, [data]);\n\n // Group header label: \"Today\" for the current day, otherwise the full date\n // (\"Month D, YYYY\") \u2014 matching the Activity history grouping style.\n const formatGroupLabel = (date: Date, now: Date): string =>\n date.toDateString() === now.toDateString()\n ? \"Today\"\n : date.toLocaleDateString(\"en-US\", { year: \"numeric\", month: \"long\", day: \"numeric\" });\n\n // Per-row timestamp: time only (the calendar day lives in the group header).\n const formatTimestamp = (dateString: string): string =>\n new Date(dateString).toLocaleTimeString(\"en-US\", { hour: \"numeric\", minute: \"2-digit\", hour12: true });\n\n // Group the (backend-sorted) sessions by calendar day so each day gets a\n // header, mirroring ActivityHistoryPage's date grouping. `index` is the\n // session's position in the flat list \u2014 kept for the analytics event and the\n // infinite-scroll sentinel on the final row.\n const groupedSessions = useMemo(() => {\n const now = new Date();\n const groups: {\n key: string;\n label: string;\n items: { session: (typeof sortedSessions)[number]; index: number }[];\n }[] = [];\n let prevKey: string | null = null;\n sortedSessions.forEach((session, index) => {\n const date = new Date(session.updated_at);\n const key = date.toDateString();\n if (key !== prevKey) {\n groups.push({ key, label: formatGroupLabel(date, now), items: [] });\n prevKey = key;\n }\n groups[groups.length - 1].items.push({ session, index });\n });\n return groups;\n }, [sortedSessions]);\n\n const closeRename = () => {\n setRenameOpen(false);\n setActionSession(null);\n };\n\n const closeFolders = () => {\n saveToFolder.closePopover();\n setActionSession(null);\n };\n\n return (\n <>\n \n {isLoading ? (\n \n \n \n ) : isError && sortedSessions.length === 0 ? (\n \n \n {CLERK_ERROR_COPY.historyLoadFailure}\n \n \n ) : sortedSessions.length === 0 ? (\n }\n title=\"Begin with a question\"\n description=\"Ask about a judge, case, or filing. Bench IQ reads the record and answers with citations.\"\n action={\n navigate({ pathname: \"/agent\" })}>\n Ask a question\n \n }\n />\n ) : (\n ({\n padding: `${theme.tokens.spacing[6]}px max(${theme.tokens.spacing[6]}px, calc((100% - ${PAGE_CONTENT_MAX_WIDTH}px) / 2 + ${theme.tokens.spacing[6]}px))`,\n })}\n >\n {groupedSessions.map((group) => (\n \n \n {group.label}\n \n {/* The server owns title selection and word-safe limiting;\n this existing presentation helper only removes markup. */}\n {group.items.map(({ session, index }) => (\n {\n void recordUserEvent({\n event_name: \"click_clerk_history_session\",\n event_properties: {\n session_id: session.session_id,\n message_count: session.message_count,\n position: index + 1,\n },\n });\n navigate({ pathname: `/agent/${session.token}` });\n }}\n sx={(theme) => ({\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n p: `${theme.tokens.spacing[3]}px`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n cursor: \"pointer\",\n transition: \"background-color 0.15s ease\",\n \"& .history-row-actions\": {\n opacity: 0,\n transition: `opacity ${theme.transitions.duration.shortest}ms`,\n },\n \"&:hover\": {\n backgroundColor: colors.taupe[200],\n },\n \"&:hover .history-row-actions, &:focus-within .history-row-actions\": {\n opacity: 1,\n },\n \"@media (hover: none), (pointer: coarse)\": {\n \"& .history-row-actions\": {\n opacity: 1,\n },\n },\n })}\n >\n {/* Match the Activity tab text style: 14px / weight 300. */}\n \n {formatTimestamp(session.updated_at)}\n \n \n \n {stripMarkdown(session.display_title) || \"New conversation\"}\n \n \n \n {\n event.stopPropagation();\n setActionSession({\n id: session.token,\n sessionId: session.session_id,\n title: stripMarkdown(session.display_title) || \"New conversation\",\n status: session.sidenav_status ?? \"read\",\n });\n setMenuAnchor(event.currentTarget);\n }}\n />\n \n \n ))}\n \n ))}\n {isFetchingNextPage && (\n \n \n \n )}\n {isFetchNextPageError && !isFetchingNextPage && (\n \n \n {CLERK_ERROR_COPY.historyLoadFailure}\n \n void fetchNextPage()}>\n Retry\n \n \n )}\n \n )}\n \n {\n setMenuAnchor(null);\n setActionSession(null);\n }}\n showMoveToFolder={foldersEnabled}\n onRename={() => {\n setMenuAnchor(null);\n setRenameOpen(true);\n }}\n onMoveToFolder={() => {\n if (menuAnchor) saveToFolder.openPopover(menuAnchor);\n setMenuAnchor(null);\n }}\n />\n \n {foldersEnabled && actionSession?.sessionId ? (\n \n ) : null}\n \n );\n};\n\nexport default AgentPrototypeHistory;\n", "import React, { useEffect, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { Box, CircularProgress, Typography } from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { consumeShareLink } from \"../../api/agentPrototype\";\nimport { normalizeClerkErrorMessage } from \"../../utils/clerkErrorCopy\";\nimport { useNavigate } from \"../../utils/urlHelpers\";\n\nconst resolverShellStyles = {\n height: \"100%\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n px: 3,\n boxSizing: \"border-box\",\n} as const;\n\nconst AgentPrototypeShareResolver: React.FC = () => {\n const navigate = useNavigate();\n const { shareToken } = useParams<{ shareToken: string }>();\n const [error, setError] = useState(null);\n\n useEffect(() => {\n let cancelled = false;\n\n const resolveShareLink = async () => {\n if (!shareToken) {\n if (!cancelled) {\n setError(normalizeClerkErrorMessage(null, { fallbackKey: \"shareConversationUnavailable\" }));\n }\n return;\n }\n\n try {\n const response = await consumeShareLink(shareToken);\n if (cancelled) return;\n\n navigate({ pathname: `/agent/${response.token}` }, { replace: true });\n } catch (err) {\n if (!cancelled) {\n setError(\n normalizeClerkErrorMessage(err instanceof Error ? err.message : null, {\n fallbackKey: \"shareConversationUnavailable\",\n }),\n );\n }\n }\n };\n\n resolveShareLink();\n\n return () => {\n cancelled = true;\n };\n }, [navigate, shareToken]);\n\n if (!error) {\n return (\n \n \n \n \n Opening shared conversation...\n \n \n \n );\n }\n\n return (\n \n \n Unable to open this shared conversation\n \n {error}\n \n navigate({ pathname: \"/agent\" }, { replace: true })}>Back\n \n \n );\n};\n\nexport default AgentPrototypeShareResolver;\n", "import React from \"react\";\n// eslint-disable-next-line no-restricted-imports -- a backwards-compat redirect must use the literal URL, not the incognito-rewritten view from utils/urlHelpers (which folds the hash into search and can drop the query string).\nimport { Navigate, useLocation } from \"react-router-dom\";\n\n/**\n * Backwards-compat redirect for the legacy `/agent-prototype` prefix.\n *\n * Already-delivered links \u2014 bookmarks, previously-sent share links, emails, and\n * push notifications \u2014 point at the old `/agent-prototype` path. This bounces them\n * to the canonical `/agent` path, preserving the sub-path, query string, and hash\n * fragment verbatim so deep-link params survive the redirect. Newly-generated\n * backend URLs already use `/agent`, so this only serves pre-existing links.\n */\nconst RedirectToAgent = () => {\n const location = useLocation();\n const target = location.pathname.replace(/^\\/agent-prototype/, \"/agent\") + location.search + location.hash;\n return ;\n};\n\nexport default RedirectToAgent;\n", "import React, { useEffect, useState } from \"react\";\nimport { Box, Typography } from \"@mui/material\";\nimport { useReducedMotion } from \"motion/react\";\nimport { useSearchParams } from \"@/utils/urlHelpers\";\nimport ClerkDisabledBannerSlot from \"./ClerkDisabledBannerSlot\";\nimport LockedClerkFooter from \"./LockedClerkFooter\";\n\n/**\n * Locked Clerk landing page (`/agent` when `disable_generative_ai`\n * or `incognito_queries` is on).\n *\n * Locked accounts can't run a real Clerk session \u2014 the backend rejects\n * session creation for them \u2014 so the whole \"Clerk is responding\" experience\n * is faked client-side here, with zero network and zero LLM cost. The route\n * shell renders this for EVERY locked visit to `/agent` (see\n * `AgentPrototypeRouteShell` in `components/index.tsx`).\n *\n * The page animates in to feel like a real, quick Clerk turn:\n * 1. If the user submitted a question from Home, it's carried over in the URL\n * (`?q=...`) and echoed immediately as a user bubble \u2014 surviving refresh.\n * Cold/direct arrivals (no `q`) have no question, so no bubble.\n * 2. The canned \"limited access\" response streams in character-by-character\n * in gentle bursts (mimicking a live SSE response, not a word-by-word\n * metronome), as one continuous block \u2014 no pause between the two sentences.\n * 3. Once typing finishes, the footer reveals: the \"Search transcripts\" CTA\n * fades in, then the three example-conversation cards stagger in one by\n * one (`LockedClerkFooter`, gated by `animateIn`).\n *\n * Respects `prefers-reduced-motion`: when set, the full text + footer render\n * in their final state immediately (no typewriter, no staggered reveal).\n */\n\n// The canned \"limited access\" response shown on the locked landing. This used\n// to be duplicated by the agent service's `LOCKED_RESPONSE_TEXT`, but that\n// server-side canned-response path was removed in this PR, so this is now the\n// only copy.\nconst CANNED_RESPONSE =\n \"I can't run AI research tools in this workspace because AI access isn't enabled. You can ask your admin for access or search hearing transcripts with Boolean search. Open the search panel here, or access it anytime from the top of the page.\";\n\nconst CHAT_COLUMN_WIDTH = 760;\nconst USER_BUBBLE_MAX_WIDTH = 580;\n// Reveal cadence for the canned response. We advance a small, slightly variable\n// number of characters every ~animation frame, mid-word \u2014 this mirrors how a\n// live Clerk answer streams (rAF-flushed SSE token bursts) rather than a uniform\n// word-by-word metronome, which reads as mechanical.\nconst TYPEWRITER_TICK_MS = 16;\nconst TYPEWRITER_MIN_STEP = 2;\nconst TYPEWRITER_MAX_STEP = 5;\n\n/** Right-aligned user bubble \u2014 matches `AgentPrototypeMessage`'s user message. */\nconst UserBubble: React.FC<{ text: string }> = ({ text }) => (\n \n ({\n bgcolor: theme.palette.userbubble.background,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n p: 2,\n maxWidth: USER_BUBBLE_MAX_WIDTH,\n })}\n >\n \n {text}\n \n \n \n);\n\n/** Blinking caret shown at the end of the response while it types in. Mirrors\n * the streaming cursor `AgentPrototypeMessage` renders during a live run. */\nconst TypingCursor: React.FC = () => (\n \n);\n\nconst LockedClerkLanding: React.FC = () => {\n const prefersReducedMotion = useReducedMotion();\n\n // The question carried over from Home lives in the URL (`?q=...`). Cold\n // arrivals (no Home submit) have no `q`, so `userQuery` is null.\n const [searchParams] = useSearchParams();\n const userQuery = searchParams.get(\"q\")?.trim() || null;\n\n // Character-level reveal that simulates a live SSE stream: each tick advances\n // a small, variable number of characters (mid-word), so the text arrives in\n // gentle bursts rather than a uniform word-by-word beat.\n const [revealedChars, setRevealedChars] = useState(() => (prefersReducedMotion ? CANNED_RESPONSE.length : 0));\n\n useEffect(() => {\n if (prefersReducedMotion) {\n setRevealedChars(CANNED_RESPONSE.length);\n return;\n }\n if (revealedChars >= CANNED_RESPONSE.length) return;\n const timer = window.setTimeout(() => {\n const step = TYPEWRITER_MIN_STEP + Math.floor(Math.random() * (TYPEWRITER_MAX_STEP - TYPEWRITER_MIN_STEP + 1));\n setRevealedChars((n) => Math.min(CANNED_RESPONSE.length, n + step));\n }, TYPEWRITER_TICK_MS);\n return () => window.clearTimeout(timer);\n }, [prefersReducedMotion, revealedChars]);\n\n const typedText = CANNED_RESPONSE.slice(0, revealedChars);\n const typingDone = revealedChars >= CANNED_RESPONSE.length;\n\n return (\n <>\n \n\n {/* Chat column. `mx: auto` centers it horizontally within LayoutSlot\n (mirrors how AgentPrototypeChat centers its own content). */}\n \n {userQuery && }\n\n {/* Canned response \u2014 typography matches how `AgentPrototypeMessage`\n renders assistant markdown paragraphs (body2 + lineHeight 1.7), so\n this reads visually identical to the real agent's responses. */}\n \n {typedText}\n {!typingDone && }\n \n\n \n \n \n );\n};\n\nexport default LockedClerkLanding;\n", "import React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Navigate } from \"react-router-dom\";\nimport { useReaderPanelState } from \"../AppShell\";\nimport { SidepanelTranscriptReader } from \"../Reader\";\nimport { useTranscriptDisplayTitle } from \"../../hooks/useTranscriptDisplayTitle\";\nimport AgentPrototypeChat from \"./AgentPrototypeChat\";\nimport ClerkDisabledBannerSlot from \"./ClerkDisabledBannerSlot\";\nimport { LOCKED_CLERK_EXAMPLES, type LockedClerkExample, type LockedClerkExampleSlug } from \"./lockedClerkExamples\";\nimport type { ChatMessage } from \"@/hooks/useAgentPrototypeSession\";\n\n/**\n * Read-only sample conversation for a locked Clerk example (Figma 6056-5925\n * \u2192 6056-6154).\n *\n * The page lives at `/agent/{slug}` for slugs `example1`,\n * `example2`, `example3`. The static fixtures in `lockedClerkExamples.ts`\n * back every page; no API call is ever made.\n *\n * Two visual phases:\n * 1. **Loading** (first 3 seconds after mount) \u2014 the assistant message\n * renders with `isStreaming: true`, which makes `AgentPrototypeMessage`\n * show its in-progress research plan card with the curated `thinking`\n * entries + tool calls as plan steps. Mirrors Figma 6056-5925.\n * 2. **Loaded** (after 3 seconds) \u2014 `isStreaming` flips to `false`, the\n * plan card collapses to \"Took N steps\", and the agent's final\n * `content` paragraph appears below. Mirrors Figma 6056-6154.\n *\n * Clicking a citation in the assistant's response opens the cited\n * transcript in AppShell's column-3 sidepanel reader \u2014 same pattern\n * `AgentPrototypeLayout` uses for live sessions. Reuses\n * `useReaderPanelState` + `SidepanelTranscriptReader` directly.\n *\n * The 3-second delay is purely a UI fake \u2014 no network activity drives the\n * transition. Reusing `AgentPrototypeChat` (not a slim static renderer)\n * means the locked preview looks pixel-identical to a real Clerk session,\n * complete with citation footnotes the user can click into.\n */\n\nconst LOADING_DURATION_MS = 3000;\n\ninterface LockedClerkExampleSessionProps {\n slug: LockedClerkExampleSlug;\n}\n\nconst LockedClerkExampleSession: React.FC = ({ slug }) => {\n const example: LockedClerkExample | undefined = LOCKED_CLERK_EXAMPLES[slug];\n const [loaded, setLoaded] = useState(false);\n\n // Column-3 reader state. Mirrors AgentPrototypeLayout's wiring exactly \u2014\n // citation click \u2192 setReaderTranscriptId \u2192 useReaderPanelState bridges\n // it to AppShell's column-3 mode \u2192 SidepanelTranscriptReader renders\n // inside AppShell.SidePanel.\n const [readerTranscriptId, setReaderTranscriptId] = useState(null);\n const [readerOpenRequestCounter, setReaderOpenRequestCounter] = useState(0);\n const readerPanel = useReaderPanelState({\n isReaderOpen: readerTranscriptId !== null,\n onClose: () => setReaderTranscriptId(null),\n openRequestKey: readerOpenRequestCounter,\n });\n const readerTitle = useTranscriptDisplayTitle(readerTranscriptId);\n\n const handleOpenTranscript = useCallback((transcriptId: number) => {\n // Static demos don't have the layered excerpt-search-into-highlight\n // plumbing AgentPrototypeLayout has \u2014 citations just open the\n // transcript at top. The reader's own search-within-transcript can\n // still find the cited passage if the user wants.\n setReaderTranscriptId(transcriptId);\n setReaderOpenRequestCounter((current) => current + 1);\n }, []);\n\n useEffect(() => {\n if (!example) return;\n const timer = window.setTimeout(() => setLoaded(true), LOADING_DURATION_MS);\n return () => window.clearTimeout(timer);\n }, [example]);\n\n // Compute the displayed messages. Mirrors how a real Clerk session\n // renders during a live run:\n // - **While streaming (first 3s):** assistant message has\n // `isStreaming: true` AND its `content` is blanked out, so the user\n // ONLY sees the research-plan card with its in-progress steps \u2014\n // not the final answer prematurely. This matches how Clerk works\n // today (thinking first, then the answer text writes in once the\n // run completes).\n // - **After 5s:** `isStreaming` flips off and the original `content`\n // restores, so the plan card collapses to \"Took N steps\" and the\n // answer + citations render below it.\n //\n // Memoize so AgentPrototypeChat doesn't re-render the message list\n // unnecessarily \u2014 that component scrolls itself, so a new array\n // identity every render would fight its scroll logic.\n const displayedMessages = useMemo(() => {\n if (!example) return [];\n return example.messages.map((message) => {\n if (message.role !== \"assistant\") return message;\n if (loaded) return message; // Final state: real content + citations.\n // Loading state: keep the thinking + tool plan but hide the answer.\n return { ...message, isStreaming: true, content: \"\" };\n });\n }, [example, loaded]);\n\n // Defensive: an unknown slug means someone navigated to a URL we don't\n // recognize (e.g. mistyped). Bounce them back to the landing rather\n // than rendering nothing.\n if (!example) {\n return ;\n }\n\n return (\n <>\n \n {/* AgentPrototypeChat goes directly inside LayoutSlot (same shape as\n the live AgentPrototypeConversation) \u2014 its internal `mx: auto`\n handles the chat column's 808px centering. */}\n \n {/* Column-3 reader. Registers into AppShell.SidePanel via the\n SidepanelTranscriptReader compound; only mounts when a citation\n has been opened. */}\n {readerTranscriptId !== null && (\n \n )}\n \n );\n};\n\nexport default LockedClerkExampleSession;\n", "import React from \"react\";\nimport { Stack } from \"@mui/material\";\nimport { SearchX } from \"lucide-react\";\nimport { EmptyState } from \"../molecules/EmptyState\";\n\nconst NoTranscriptResults = () => {\n return (\n \n }\n title=\"No results found\"\n description=\"Try broadening your search, checking your Boolean syntax, or removing filters.\"\n />\n \n );\n};\n\nexport default NoTranscriptResults;\n", "/**\n * Counts at or above this are reported as \"10000+\" rather than an exact number,\n * matching the cap the (now-removed) result-type tab badges used.\n */\nconst COUNT_CAP = 10000;\n\n/**\n * Formats the quiet \"Transcripts (N)\" label shown in the sort row above the\n * results list \u2014 a label for the list, not a sentence.\n *\n * Returns null when there's nothing to show \u2014 the count isn't known yet\n * (undefined) or there are no results (the page's empty state covers zero).\n */\nexport function formatResultCountLabel(count: number | undefined, label: string): string | null {\n if (count === undefined || count <= 0) return null;\n const display = count >= COUNT_CAP ? `${COUNT_CAP}+` : `${count}`;\n return `${label} (${display})`;\n}\n", "'use strict';\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar React = require('react');\nvar React__default = _interopDefault(React);\n\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nfunction _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n}\n\nvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\nfunction withSideEffect(reducePropsToState, handleStateChangeOnClient, mapStateOnServer) {\n if (typeof reducePropsToState !== 'function') {\n throw new Error('Expected reducePropsToState to be a function.');\n }\n\n if (typeof handleStateChangeOnClient !== 'function') {\n throw new Error('Expected handleStateChangeOnClient to be a function.');\n }\n\n if (typeof mapStateOnServer !== 'undefined' && typeof mapStateOnServer !== 'function') {\n throw new Error('Expected mapStateOnServer to either be undefined or a function.');\n }\n\n function getDisplayName(WrappedComponent) {\n return WrappedComponent.displayName || WrappedComponent.name || 'Component';\n }\n\n return function wrap(WrappedComponent) {\n if (typeof WrappedComponent !== 'function') {\n throw new Error('Expected WrappedComponent to be a React component.');\n }\n\n var mountedInstances = [];\n var state;\n\n function emitChange() {\n state = reducePropsToState(mountedInstances.map(function (instance) {\n return instance.props;\n }));\n\n if (SideEffect.canUseDOM) {\n handleStateChangeOnClient(state);\n } else if (mapStateOnServer) {\n state = mapStateOnServer(state);\n }\n }\n\n var SideEffect =\n /*#__PURE__*/\n function (_PureComponent) {\n _inheritsLoose(SideEffect, _PureComponent);\n\n function SideEffect() {\n return _PureComponent.apply(this, arguments) || this;\n }\n\n // Try to use displayName of wrapped component\n // Expose canUseDOM so tests can monkeypatch it\n SideEffect.peek = function peek() {\n return state;\n };\n\n SideEffect.rewind = function rewind() {\n if (SideEffect.canUseDOM) {\n throw new Error('You may only call rewind() on the server. Call peek() to read the current state.');\n }\n\n var recordedState = state;\n state = undefined;\n mountedInstances = [];\n return recordedState;\n };\n\n var _proto = SideEffect.prototype;\n\n _proto.UNSAFE_componentWillMount = function UNSAFE_componentWillMount() {\n mountedInstances.push(this);\n emitChange();\n };\n\n _proto.componentDidUpdate = function componentDidUpdate() {\n emitChange();\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n var index = mountedInstances.indexOf(this);\n mountedInstances.splice(index, 1);\n emitChange();\n };\n\n _proto.render = function render() {\n return React__default.createElement(WrappedComponent, this.props);\n };\n\n return SideEffect;\n }(React.PureComponent);\n\n _defineProperty(SideEffect, \"displayName\", \"SideEffect(\" + getDisplayName(WrappedComponent) + \")\");\n\n _defineProperty(SideEffect, \"canUseDOM\", canUseDOM);\n\n return SideEffect;\n };\n}\n\nmodule.exports = withSideEffect;\n", "/* global Map:readonly, Set:readonly, ArrayBuffer:readonly */\n\nvar hasElementType = typeof Element !== 'undefined';\nvar hasMap = typeof Map === 'function';\nvar hasSet = typeof Set === 'function';\nvar hasArrayBuffer = typeof ArrayBuffer === 'function' && !!ArrayBuffer.isView;\n\n// Note: We **don't** need `envHasBigInt64Array` in fde es6/index.js\n\nfunction equal(a, b) {\n // START: fast-deep-equal es6/index.js 3.1.3\n if (a === b) return true;\n\n if (a && b && typeof a == 'object' && typeof b == 'object') {\n if (a.constructor !== b.constructor) return false;\n\n var length, i, keys;\n if (Array.isArray(a)) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (!equal(a[i], b[i])) return false;\n return true;\n }\n\n // START: Modifications:\n // 1. Extra `has &&` helpers in initial condition allow es6 code\n // to co-exist with es5.\n // 2. Replace `for of` with es5 compliant iteration using `for`.\n // Basically, take:\n //\n // ```js\n // for (i of a.entries())\n // if (!b.has(i[0])) return false;\n // ```\n //\n // ... and convert to:\n //\n // ```js\n // it = a.entries();\n // while (!(i = it.next()).done)\n // if (!b.has(i.value[0])) return false;\n // ```\n //\n // **Note**: `i` access switches to `i.value`.\n var it;\n if (hasMap && (a instanceof Map) && (b instanceof Map)) {\n if (a.size !== b.size) return false;\n it = a.entries();\n while (!(i = it.next()).done)\n if (!b.has(i.value[0])) return false;\n it = a.entries();\n while (!(i = it.next()).done)\n if (!equal(i.value[1], b.get(i.value[0]))) return false;\n return true;\n }\n\n if (hasSet && (a instanceof Set) && (b instanceof Set)) {\n if (a.size !== b.size) return false;\n it = a.entries();\n while (!(i = it.next()).done)\n if (!b.has(i.value[0])) return false;\n return true;\n }\n // END: Modifications\n\n if (hasArrayBuffer && ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (a[i] !== b[i]) return false;\n return true;\n }\n\n if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;\n // START: Modifications:\n // Apply guards for `Object.create(null)` handling. See:\n // - https://github.com/FormidableLabs/react-fast-compare/issues/64\n // - https://github.com/epoberezkin/fast-deep-equal/issues/49\n if (a.valueOf !== Object.prototype.valueOf && typeof a.valueOf === 'function' && typeof b.valueOf === 'function') return a.valueOf() === b.valueOf();\n if (a.toString !== Object.prototype.toString && typeof a.toString === 'function' && typeof b.toString === 'function') return a.toString() === b.toString();\n // END: Modifications\n\n keys = Object.keys(a);\n length = keys.length;\n if (length !== Object.keys(b).length) return false;\n\n for (i = length; i-- !== 0;)\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\n // END: fast-deep-equal\n\n // START: react-fast-compare\n // custom handling for DOM elements\n if (hasElementType && a instanceof Element) return false;\n\n // custom handling for React/Preact\n for (i = length; i-- !== 0;) {\n if ((keys[i] === '_owner' || keys[i] === '__v' || keys[i] === '__o') && a.$$typeof) {\n // React-specific: avoid traversing React elements' _owner\n // Preact-specific: avoid traversing Preact elements' __v and __o\n // __v = $_original / $_vnode\n // __o = $_owner\n // These properties contain circular references and are not needed when\n // comparing the actual elements (and not their owners)\n // .$$typeof and ._store on just reasonable markers of elements\n\n continue;\n }\n\n // all other properties should be traversed as usual\n if (!equal(a[keys[i]], b[keys[i]])) return false;\n }\n // END: react-fast-compare\n\n // START: fast-deep-equal\n return true;\n }\n\n return a !== a && b !== b;\n}\n// end fast-deep-equal\n\nmodule.exports = function isEqual(a, b) {\n try {\n return equal(a, b);\n } catch (error) {\n if (((error.message || '').match(/stack|recursion/i))) {\n // warn on circular references, don't crash\n // browsers give this different errors name and messages:\n // chrome/safari: \"RangeError\", \"Maximum call stack size exceeded\"\n // firefox: \"InternalError\", too much recursion\"\n // edge: \"Error\", \"Out of stack space\"\n console.warn('react-fast-compare cannot handle circular refs');\n return false;\n }\n // some other error. we should definitely know about these\n throw error;\n }\n};\n", "/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n", "import PropTypes from 'prop-types';\nimport withSideEffect from 'react-side-effect';\nimport isEqual from 'react-fast-compare';\nimport React from 'react';\nimport objectAssign from 'object-assign';\n\nvar ATTRIBUTE_NAMES = {\n BODY: \"bodyAttributes\",\n HTML: \"htmlAttributes\",\n TITLE: \"titleAttributes\"\n};\n\nvar TAG_NAMES = {\n BASE: \"base\",\n BODY: \"body\",\n HEAD: \"head\",\n HTML: \"html\",\n LINK: \"link\",\n META: \"meta\",\n NOSCRIPT: \"noscript\",\n SCRIPT: \"script\",\n STYLE: \"style\",\n TITLE: \"title\"\n};\n\nvar VALID_TAG_NAMES = Object.keys(TAG_NAMES).map(function (name) {\n return TAG_NAMES[name];\n});\n\nvar TAG_PROPERTIES = {\n CHARSET: \"charset\",\n CSS_TEXT: \"cssText\",\n HREF: \"href\",\n HTTPEQUIV: \"http-equiv\",\n INNER_HTML: \"innerHTML\",\n ITEM_PROP: \"itemprop\",\n NAME: \"name\",\n PROPERTY: \"property\",\n REL: \"rel\",\n SRC: \"src\",\n TARGET: \"target\"\n};\n\nvar REACT_TAG_MAP = {\n accesskey: \"accessKey\",\n charset: \"charSet\",\n class: \"className\",\n contenteditable: \"contentEditable\",\n contextmenu: \"contextMenu\",\n \"http-equiv\": \"httpEquiv\",\n itemprop: \"itemProp\",\n tabindex: \"tabIndex\"\n};\n\nvar HELMET_PROPS = {\n DEFAULT_TITLE: \"defaultTitle\",\n DEFER: \"defer\",\n ENCODE_SPECIAL_CHARACTERS: \"encodeSpecialCharacters\",\n ON_CHANGE_CLIENT_STATE: \"onChangeClientState\",\n TITLE_TEMPLATE: \"titleTemplate\"\n};\n\nvar HTML_TAG_MAP = Object.keys(REACT_TAG_MAP).reduce(function (obj, key) {\n obj[REACT_TAG_MAP[key]] = key;\n return obj;\n}, {});\n\nvar SELF_CLOSING_TAGS = [TAG_NAMES.NOSCRIPT, TAG_NAMES.SCRIPT, TAG_NAMES.STYLE];\n\nvar HELMET_ATTRIBUTE = \"data-react-helmet\";\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n} : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n};\n\nvar classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\nvar inherits = function (subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass);\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n};\n\nvar objectWithoutProperties = function (obj, keys) {\n var target = {};\n\n for (var i in obj) {\n if (keys.indexOf(i) >= 0) continue;\n if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;\n target[i] = obj[i];\n }\n\n return target;\n};\n\nvar possibleConstructorReturn = function (self, call) {\n if (!self) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self;\n};\n\nvar encodeSpecialCharacters = function encodeSpecialCharacters(str) {\n var encode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n if (encode === false) {\n return String(str);\n }\n\n return String(str).replace(/&/g, \"&\").replace(//g, \">\").replace(/\"/g, \""\").replace(/'/g, \"'\");\n};\n\nvar getTitleFromPropsList = function getTitleFromPropsList(propsList) {\n var innermostTitle = getInnermostProperty(propsList, TAG_NAMES.TITLE);\n var innermostTemplate = getInnermostProperty(propsList, HELMET_PROPS.TITLE_TEMPLATE);\n\n if (innermostTemplate && innermostTitle) {\n // use function arg to avoid need to escape $ characters\n return innermostTemplate.replace(/%s/g, function () {\n return Array.isArray(innermostTitle) ? innermostTitle.join(\"\") : innermostTitle;\n });\n }\n\n var innermostDefaultTitle = getInnermostProperty(propsList, HELMET_PROPS.DEFAULT_TITLE);\n\n return innermostTitle || innermostDefaultTitle || undefined;\n};\n\nvar getOnChangeClientState = function getOnChangeClientState(propsList) {\n return getInnermostProperty(propsList, HELMET_PROPS.ON_CHANGE_CLIENT_STATE) || function () {};\n};\n\nvar getAttributesFromPropsList = function getAttributesFromPropsList(tagType, propsList) {\n return propsList.filter(function (props) {\n return typeof props[tagType] !== \"undefined\";\n }).map(function (props) {\n return props[tagType];\n }).reduce(function (tagAttrs, current) {\n return _extends({}, tagAttrs, current);\n }, {});\n};\n\nvar getBaseTagFromPropsList = function getBaseTagFromPropsList(primaryAttributes, propsList) {\n return propsList.filter(function (props) {\n return typeof props[TAG_NAMES.BASE] !== \"undefined\";\n }).map(function (props) {\n return props[TAG_NAMES.BASE];\n }).reverse().reduce(function (innermostBaseTag, tag) {\n if (!innermostBaseTag.length) {\n var keys = Object.keys(tag);\n\n for (var i = 0; i < keys.length; i++) {\n var attributeKey = keys[i];\n var lowerCaseAttributeKey = attributeKey.toLowerCase();\n\n if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && tag[lowerCaseAttributeKey]) {\n return innermostBaseTag.concat(tag);\n }\n }\n }\n\n return innermostBaseTag;\n }, []);\n};\n\nvar getTagsFromPropsList = function getTagsFromPropsList(tagName, primaryAttributes, propsList) {\n // Calculate list of tags, giving priority innermost component (end of the propslist)\n var approvedSeenTags = {};\n\n return propsList.filter(function (props) {\n if (Array.isArray(props[tagName])) {\n return true;\n }\n if (typeof props[tagName] !== \"undefined\") {\n warn(\"Helmet: \" + tagName + \" should be of type \\\"Array\\\". Instead found type \\\"\" + _typeof(props[tagName]) + \"\\\"\");\n }\n return false;\n }).map(function (props) {\n return props[tagName];\n }).reverse().reduce(function (approvedTags, instanceTags) {\n var instanceSeenTags = {};\n\n instanceTags.filter(function (tag) {\n var primaryAttributeKey = void 0;\n var keys = Object.keys(tag);\n for (var i = 0; i < keys.length; i++) {\n var attributeKey = keys[i];\n var lowerCaseAttributeKey = attributeKey.toLowerCase();\n\n // Special rule with link tags, since rel and href are both primary tags, rel takes priority\n if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && !(primaryAttributeKey === TAG_PROPERTIES.REL && tag[primaryAttributeKey].toLowerCase() === \"canonical\") && !(lowerCaseAttributeKey === TAG_PROPERTIES.REL && tag[lowerCaseAttributeKey].toLowerCase() === \"stylesheet\")) {\n primaryAttributeKey = lowerCaseAttributeKey;\n }\n // Special case for innerHTML which doesn't work lowercased\n if (primaryAttributes.indexOf(attributeKey) !== -1 && (attributeKey === TAG_PROPERTIES.INNER_HTML || attributeKey === TAG_PROPERTIES.CSS_TEXT || attributeKey === TAG_PROPERTIES.ITEM_PROP)) {\n primaryAttributeKey = attributeKey;\n }\n }\n\n if (!primaryAttributeKey || !tag[primaryAttributeKey]) {\n return false;\n }\n\n var value = tag[primaryAttributeKey].toLowerCase();\n\n if (!approvedSeenTags[primaryAttributeKey]) {\n approvedSeenTags[primaryAttributeKey] = {};\n }\n\n if (!instanceSeenTags[primaryAttributeKey]) {\n instanceSeenTags[primaryAttributeKey] = {};\n }\n\n if (!approvedSeenTags[primaryAttributeKey][value]) {\n instanceSeenTags[primaryAttributeKey][value] = true;\n return true;\n }\n\n return false;\n }).reverse().forEach(function (tag) {\n return approvedTags.push(tag);\n });\n\n // Update seen tags with tags from this instance\n var keys = Object.keys(instanceSeenTags);\n for (var i = 0; i < keys.length; i++) {\n var attributeKey = keys[i];\n var tagUnion = objectAssign({}, approvedSeenTags[attributeKey], instanceSeenTags[attributeKey]);\n\n approvedSeenTags[attributeKey] = tagUnion;\n }\n\n return approvedTags;\n }, []).reverse();\n};\n\nvar getInnermostProperty = function getInnermostProperty(propsList, property) {\n for (var i = propsList.length - 1; i >= 0; i--) {\n var props = propsList[i];\n\n if (props.hasOwnProperty(property)) {\n return props[property];\n }\n }\n\n return null;\n};\n\nvar reducePropsToState = function reducePropsToState(propsList) {\n return {\n baseTag: getBaseTagFromPropsList([TAG_PROPERTIES.HREF, TAG_PROPERTIES.TARGET], propsList),\n bodyAttributes: getAttributesFromPropsList(ATTRIBUTE_NAMES.BODY, propsList),\n defer: getInnermostProperty(propsList, HELMET_PROPS.DEFER),\n encode: getInnermostProperty(propsList, HELMET_PROPS.ENCODE_SPECIAL_CHARACTERS),\n htmlAttributes: getAttributesFromPropsList(ATTRIBUTE_NAMES.HTML, propsList),\n linkTags: getTagsFromPropsList(TAG_NAMES.LINK, [TAG_PROPERTIES.REL, TAG_PROPERTIES.HREF], propsList),\n metaTags: getTagsFromPropsList(TAG_NAMES.META, [TAG_PROPERTIES.NAME, TAG_PROPERTIES.CHARSET, TAG_PROPERTIES.HTTPEQUIV, TAG_PROPERTIES.PROPERTY, TAG_PROPERTIES.ITEM_PROP], propsList),\n noscriptTags: getTagsFromPropsList(TAG_NAMES.NOSCRIPT, [TAG_PROPERTIES.INNER_HTML], propsList),\n onChangeClientState: getOnChangeClientState(propsList),\n scriptTags: getTagsFromPropsList(TAG_NAMES.SCRIPT, [TAG_PROPERTIES.SRC, TAG_PROPERTIES.INNER_HTML], propsList),\n styleTags: getTagsFromPropsList(TAG_NAMES.STYLE, [TAG_PROPERTIES.CSS_TEXT], propsList),\n title: getTitleFromPropsList(propsList),\n titleAttributes: getAttributesFromPropsList(ATTRIBUTE_NAMES.TITLE, propsList)\n };\n};\n\nvar rafPolyfill = function () {\n var clock = Date.now();\n\n return function (callback) {\n var currentTime = Date.now();\n\n if (currentTime - clock > 16) {\n clock = currentTime;\n callback(currentTime);\n } else {\n setTimeout(function () {\n rafPolyfill(callback);\n }, 0);\n }\n };\n}();\n\nvar cafPolyfill = function cafPolyfill(id) {\n return clearTimeout(id);\n};\n\nvar requestAnimationFrame = typeof window !== \"undefined\" ? window.requestAnimationFrame && window.requestAnimationFrame.bind(window) || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || rafPolyfill : global.requestAnimationFrame || rafPolyfill;\n\nvar cancelAnimationFrame = typeof window !== \"undefined\" ? window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || cafPolyfill : global.cancelAnimationFrame || cafPolyfill;\n\nvar warn = function warn(msg) {\n return console && typeof console.warn === \"function\" && console.warn(msg);\n};\n\nvar _helmetCallback = null;\n\nvar handleClientStateChange = function handleClientStateChange(newState) {\n if (_helmetCallback) {\n cancelAnimationFrame(_helmetCallback);\n }\n\n if (newState.defer) {\n _helmetCallback = requestAnimationFrame(function () {\n commitTagChanges(newState, function () {\n _helmetCallback = null;\n });\n });\n } else {\n commitTagChanges(newState);\n _helmetCallback = null;\n }\n};\n\nvar commitTagChanges = function commitTagChanges(newState, cb) {\n var baseTag = newState.baseTag,\n bodyAttributes = newState.bodyAttributes,\n htmlAttributes = newState.htmlAttributes,\n linkTags = newState.linkTags,\n metaTags = newState.metaTags,\n noscriptTags = newState.noscriptTags,\n onChangeClientState = newState.onChangeClientState,\n scriptTags = newState.scriptTags,\n styleTags = newState.styleTags,\n title = newState.title,\n titleAttributes = newState.titleAttributes;\n\n updateAttributes(TAG_NAMES.BODY, bodyAttributes);\n updateAttributes(TAG_NAMES.HTML, htmlAttributes);\n\n updateTitle(title, titleAttributes);\n\n var tagUpdates = {\n baseTag: updateTags(TAG_NAMES.BASE, baseTag),\n linkTags: updateTags(TAG_NAMES.LINK, linkTags),\n metaTags: updateTags(TAG_NAMES.META, metaTags),\n noscriptTags: updateTags(TAG_NAMES.NOSCRIPT, noscriptTags),\n scriptTags: updateTags(TAG_NAMES.SCRIPT, scriptTags),\n styleTags: updateTags(TAG_NAMES.STYLE, styleTags)\n };\n\n var addedTags = {};\n var removedTags = {};\n\n Object.keys(tagUpdates).forEach(function (tagType) {\n var _tagUpdates$tagType = tagUpdates[tagType],\n newTags = _tagUpdates$tagType.newTags,\n oldTags = _tagUpdates$tagType.oldTags;\n\n\n if (newTags.length) {\n addedTags[tagType] = newTags;\n }\n if (oldTags.length) {\n removedTags[tagType] = tagUpdates[tagType].oldTags;\n }\n });\n\n cb && cb();\n\n onChangeClientState(newState, addedTags, removedTags);\n};\n\nvar flattenArray = function flattenArray(possibleArray) {\n return Array.isArray(possibleArray) ? possibleArray.join(\"\") : possibleArray;\n};\n\nvar updateTitle = function updateTitle(title, attributes) {\n if (typeof title !== \"undefined\" && document.title !== title) {\n document.title = flattenArray(title);\n }\n\n updateAttributes(TAG_NAMES.TITLE, attributes);\n};\n\nvar updateAttributes = function updateAttributes(tagName, attributes) {\n var elementTag = document.getElementsByTagName(tagName)[0];\n\n if (!elementTag) {\n return;\n }\n\n var helmetAttributeString = elementTag.getAttribute(HELMET_ATTRIBUTE);\n var helmetAttributes = helmetAttributeString ? helmetAttributeString.split(\",\") : [];\n var attributesToRemove = [].concat(helmetAttributes);\n var attributeKeys = Object.keys(attributes);\n\n for (var i = 0; i < attributeKeys.length; i++) {\n var attribute = attributeKeys[i];\n var value = attributes[attribute] || \"\";\n\n if (elementTag.getAttribute(attribute) !== value) {\n elementTag.setAttribute(attribute, value);\n }\n\n if (helmetAttributes.indexOf(attribute) === -1) {\n helmetAttributes.push(attribute);\n }\n\n var indexToSave = attributesToRemove.indexOf(attribute);\n if (indexToSave !== -1) {\n attributesToRemove.splice(indexToSave, 1);\n }\n }\n\n for (var _i = attributesToRemove.length - 1; _i >= 0; _i--) {\n elementTag.removeAttribute(attributesToRemove[_i]);\n }\n\n if (helmetAttributes.length === attributesToRemove.length) {\n elementTag.removeAttribute(HELMET_ATTRIBUTE);\n } else if (elementTag.getAttribute(HELMET_ATTRIBUTE) !== attributeKeys.join(\",\")) {\n elementTag.setAttribute(HELMET_ATTRIBUTE, attributeKeys.join(\",\"));\n }\n};\n\nvar updateTags = function updateTags(type, tags) {\n var headElement = document.head || document.querySelector(TAG_NAMES.HEAD);\n var tagNodes = headElement.querySelectorAll(type + \"[\" + HELMET_ATTRIBUTE + \"]\");\n var oldTags = Array.prototype.slice.call(tagNodes);\n var newTags = [];\n var indexToDelete = void 0;\n\n if (tags && tags.length) {\n tags.forEach(function (tag) {\n var newElement = document.createElement(type);\n\n for (var attribute in tag) {\n if (tag.hasOwnProperty(attribute)) {\n if (attribute === TAG_PROPERTIES.INNER_HTML) {\n newElement.innerHTML = tag.innerHTML;\n } else if (attribute === TAG_PROPERTIES.CSS_TEXT) {\n if (newElement.styleSheet) {\n newElement.styleSheet.cssText = tag.cssText;\n } else {\n newElement.appendChild(document.createTextNode(tag.cssText));\n }\n } else {\n var value = typeof tag[attribute] === \"undefined\" ? \"\" : tag[attribute];\n newElement.setAttribute(attribute, value);\n }\n }\n }\n\n newElement.setAttribute(HELMET_ATTRIBUTE, \"true\");\n\n // Remove a duplicate tag from domTagstoRemove, so it isn't cleared.\n if (oldTags.some(function (existingTag, index) {\n indexToDelete = index;\n return newElement.isEqualNode(existingTag);\n })) {\n oldTags.splice(indexToDelete, 1);\n } else {\n newTags.push(newElement);\n }\n });\n }\n\n oldTags.forEach(function (tag) {\n return tag.parentNode.removeChild(tag);\n });\n newTags.forEach(function (tag) {\n return headElement.appendChild(tag);\n });\n\n return {\n oldTags: oldTags,\n newTags: newTags\n };\n};\n\nvar generateElementAttributesAsString = function generateElementAttributesAsString(attributes) {\n return Object.keys(attributes).reduce(function (str, key) {\n var attr = typeof attributes[key] !== \"undefined\" ? key + \"=\\\"\" + attributes[key] + \"\\\"\" : \"\" + key;\n return str ? str + \" \" + attr : attr;\n }, \"\");\n};\n\nvar generateTitleAsString = function generateTitleAsString(type, title, attributes, encode) {\n var attributeString = generateElementAttributesAsString(attributes);\n var flattenedTitle = flattenArray(title);\n return attributeString ? \"<\" + type + \" \" + HELMET_ATTRIBUTE + \"=\\\"true\\\" \" + attributeString + \">\" + encodeSpecialCharacters(flattenedTitle, encode) + \"\" : \"<\" + type + \" \" + HELMET_ATTRIBUTE + \"=\\\"true\\\">\" + encodeSpecialCharacters(flattenedTitle, encode) + \"\";\n};\n\nvar generateTagsAsString = function generateTagsAsString(type, tags, encode) {\n return tags.reduce(function (str, tag) {\n var attributeHtml = Object.keys(tag).filter(function (attribute) {\n return !(attribute === TAG_PROPERTIES.INNER_HTML || attribute === TAG_PROPERTIES.CSS_TEXT);\n }).reduce(function (string, attribute) {\n var attr = typeof tag[attribute] === \"undefined\" ? attribute : attribute + \"=\\\"\" + encodeSpecialCharacters(tag[attribute], encode) + \"\\\"\";\n return string ? string + \" \" + attr : attr;\n }, \"\");\n\n var tagContent = tag.innerHTML || tag.cssText || \"\";\n\n var isSelfClosing = SELF_CLOSING_TAGS.indexOf(type) === -1;\n\n return str + \"<\" + type + \" \" + HELMET_ATTRIBUTE + \"=\\\"true\\\" \" + attributeHtml + (isSelfClosing ? \"/>\" : \">\" + tagContent + \"\");\n }, \"\");\n};\n\nvar convertElementAttributestoReactProps = function convertElementAttributestoReactProps(attributes) {\n var initProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n return Object.keys(attributes).reduce(function (obj, key) {\n obj[REACT_TAG_MAP[key] || key] = attributes[key];\n return obj;\n }, initProps);\n};\n\nvar convertReactPropstoHtmlAttributes = function convertReactPropstoHtmlAttributes(props) {\n var initAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n return Object.keys(props).reduce(function (obj, key) {\n obj[HTML_TAG_MAP[key] || key] = props[key];\n return obj;\n }, initAttributes);\n};\n\nvar generateTitleAsReactComponent = function generateTitleAsReactComponent(type, title, attributes) {\n var _initProps;\n\n // assigning into an array to define toString function on it\n var initProps = (_initProps = {\n key: title\n }, _initProps[HELMET_ATTRIBUTE] = true, _initProps);\n var props = convertElementAttributestoReactProps(attributes, initProps);\n\n return [React.createElement(TAG_NAMES.TITLE, props, title)];\n};\n\nvar generateTagsAsReactComponent = function generateTagsAsReactComponent(type, tags) {\n return tags.map(function (tag, i) {\n var _mappedTag;\n\n var mappedTag = (_mappedTag = {\n key: i\n }, _mappedTag[HELMET_ATTRIBUTE] = true, _mappedTag);\n\n Object.keys(tag).forEach(function (attribute) {\n var mappedAttribute = REACT_TAG_MAP[attribute] || attribute;\n\n if (mappedAttribute === TAG_PROPERTIES.INNER_HTML || mappedAttribute === TAG_PROPERTIES.CSS_TEXT) {\n var content = tag.innerHTML || tag.cssText;\n mappedTag.dangerouslySetInnerHTML = { __html: content };\n } else {\n mappedTag[mappedAttribute] = tag[attribute];\n }\n });\n\n return React.createElement(type, mappedTag);\n });\n};\n\nvar getMethodsForTag = function getMethodsForTag(type, tags, encode) {\n switch (type) {\n case TAG_NAMES.TITLE:\n return {\n toComponent: function toComponent() {\n return generateTitleAsReactComponent(type, tags.title, tags.titleAttributes, encode);\n },\n toString: function toString() {\n return generateTitleAsString(type, tags.title, tags.titleAttributes, encode);\n }\n };\n case ATTRIBUTE_NAMES.BODY:\n case ATTRIBUTE_NAMES.HTML:\n return {\n toComponent: function toComponent() {\n return convertElementAttributestoReactProps(tags);\n },\n toString: function toString() {\n return generateElementAttributesAsString(tags);\n }\n };\n default:\n return {\n toComponent: function toComponent() {\n return generateTagsAsReactComponent(type, tags);\n },\n toString: function toString() {\n return generateTagsAsString(type, tags, encode);\n }\n };\n }\n};\n\nvar mapStateOnServer = function mapStateOnServer(_ref) {\n var baseTag = _ref.baseTag,\n bodyAttributes = _ref.bodyAttributes,\n encode = _ref.encode,\n htmlAttributes = _ref.htmlAttributes,\n linkTags = _ref.linkTags,\n metaTags = _ref.metaTags,\n noscriptTags = _ref.noscriptTags,\n scriptTags = _ref.scriptTags,\n styleTags = _ref.styleTags,\n _ref$title = _ref.title,\n title = _ref$title === undefined ? \"\" : _ref$title,\n titleAttributes = _ref.titleAttributes;\n return {\n base: getMethodsForTag(TAG_NAMES.BASE, baseTag, encode),\n bodyAttributes: getMethodsForTag(ATTRIBUTE_NAMES.BODY, bodyAttributes, encode),\n htmlAttributes: getMethodsForTag(ATTRIBUTE_NAMES.HTML, htmlAttributes, encode),\n link: getMethodsForTag(TAG_NAMES.LINK, linkTags, encode),\n meta: getMethodsForTag(TAG_NAMES.META, metaTags, encode),\n noscript: getMethodsForTag(TAG_NAMES.NOSCRIPT, noscriptTags, encode),\n script: getMethodsForTag(TAG_NAMES.SCRIPT, scriptTags, encode),\n style: getMethodsForTag(TAG_NAMES.STYLE, styleTags, encode),\n title: getMethodsForTag(TAG_NAMES.TITLE, { title: title, titleAttributes: titleAttributes }, encode)\n };\n};\n\nvar Helmet = function Helmet(Component) {\n var _class, _temp;\n\n return _temp = _class = function (_React$Component) {\n inherits(HelmetWrapper, _React$Component);\n\n function HelmetWrapper() {\n classCallCheck(this, HelmetWrapper);\n return possibleConstructorReturn(this, _React$Component.apply(this, arguments));\n }\n\n HelmetWrapper.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps) {\n return !isEqual(this.props, nextProps);\n };\n\n HelmetWrapper.prototype.mapNestedChildrenToProps = function mapNestedChildrenToProps(child, nestedChildren) {\n if (!nestedChildren) {\n return null;\n }\n\n switch (child.type) {\n case TAG_NAMES.SCRIPT:\n case TAG_NAMES.NOSCRIPT:\n return {\n innerHTML: nestedChildren\n };\n\n case TAG_NAMES.STYLE:\n return {\n cssText: nestedChildren\n };\n }\n\n throw new Error(\"<\" + child.type + \" /> elements are self-closing and can not contain children. Refer to our API for more information.\");\n };\n\n HelmetWrapper.prototype.flattenArrayTypeChildren = function flattenArrayTypeChildren(_ref) {\n var _babelHelpers$extends;\n\n var child = _ref.child,\n arrayTypeChildren = _ref.arrayTypeChildren,\n newChildProps = _ref.newChildProps,\n nestedChildren = _ref.nestedChildren;\n\n return _extends({}, arrayTypeChildren, (_babelHelpers$extends = {}, _babelHelpers$extends[child.type] = [].concat(arrayTypeChildren[child.type] || [], [_extends({}, newChildProps, this.mapNestedChildrenToProps(child, nestedChildren))]), _babelHelpers$extends));\n };\n\n HelmetWrapper.prototype.mapObjectTypeChildren = function mapObjectTypeChildren(_ref2) {\n var _babelHelpers$extends2, _babelHelpers$extends3;\n\n var child = _ref2.child,\n newProps = _ref2.newProps,\n newChildProps = _ref2.newChildProps,\n nestedChildren = _ref2.nestedChildren;\n\n switch (child.type) {\n case TAG_NAMES.TITLE:\n return _extends({}, newProps, (_babelHelpers$extends2 = {}, _babelHelpers$extends2[child.type] = nestedChildren, _babelHelpers$extends2.titleAttributes = _extends({}, newChildProps), _babelHelpers$extends2));\n\n case TAG_NAMES.BODY:\n return _extends({}, newProps, {\n bodyAttributes: _extends({}, newChildProps)\n });\n\n case TAG_NAMES.HTML:\n return _extends({}, newProps, {\n htmlAttributes: _extends({}, newChildProps)\n });\n }\n\n return _extends({}, newProps, (_babelHelpers$extends3 = {}, _babelHelpers$extends3[child.type] = _extends({}, newChildProps), _babelHelpers$extends3));\n };\n\n HelmetWrapper.prototype.mapArrayTypeChildrenToProps = function mapArrayTypeChildrenToProps(arrayTypeChildren, newProps) {\n var newFlattenedProps = _extends({}, newProps);\n\n Object.keys(arrayTypeChildren).forEach(function (arrayChildName) {\n var _babelHelpers$extends4;\n\n newFlattenedProps = _extends({}, newFlattenedProps, (_babelHelpers$extends4 = {}, _babelHelpers$extends4[arrayChildName] = arrayTypeChildren[arrayChildName], _babelHelpers$extends4));\n });\n\n return newFlattenedProps;\n };\n\n HelmetWrapper.prototype.warnOnInvalidChildren = function warnOnInvalidChildren(child, nestedChildren) {\n if (process.env.NODE_ENV !== \"production\") {\n if (!VALID_TAG_NAMES.some(function (name) {\n return child.type === name;\n })) {\n if (typeof child.type === \"function\") {\n return warn(\"You may be attempting to nest components within each other, which is not allowed. Refer to our API for more information.\");\n }\n\n return warn(\"Only elements types \" + VALID_TAG_NAMES.join(\", \") + \" are allowed. Helmet does not support rendering <\" + child.type + \"> elements. Refer to our API for more information.\");\n }\n\n if (nestedChildren && typeof nestedChildren !== \"string\" && (!Array.isArray(nestedChildren) || nestedChildren.some(function (nestedChild) {\n return typeof nestedChild !== \"string\";\n }))) {\n throw new Error(\"Helmet expects a string as a child of <\" + child.type + \">. Did you forget to wrap your children in braces? ( <\" + child.type + \">{``} ) Refer to our API for more information.\");\n }\n }\n\n return true;\n };\n\n HelmetWrapper.prototype.mapChildrenToProps = function mapChildrenToProps(children, newProps) {\n var _this2 = this;\n\n var arrayTypeChildren = {};\n\n React.Children.forEach(children, function (child) {\n if (!child || !child.props) {\n return;\n }\n\n var _child$props = child.props,\n nestedChildren = _child$props.children,\n childProps = objectWithoutProperties(_child$props, [\"children\"]);\n\n var newChildProps = convertReactPropstoHtmlAttributes(childProps);\n\n _this2.warnOnInvalidChildren(child, nestedChildren);\n\n switch (child.type) {\n case TAG_NAMES.LINK:\n case TAG_NAMES.META:\n case TAG_NAMES.NOSCRIPT:\n case TAG_NAMES.SCRIPT:\n case TAG_NAMES.STYLE:\n arrayTypeChildren = _this2.flattenArrayTypeChildren({\n child: child,\n arrayTypeChildren: arrayTypeChildren,\n newChildProps: newChildProps,\n nestedChildren: nestedChildren\n });\n break;\n\n default:\n newProps = _this2.mapObjectTypeChildren({\n child: child,\n newProps: newProps,\n newChildProps: newChildProps,\n nestedChildren: nestedChildren\n });\n break;\n }\n });\n\n newProps = this.mapArrayTypeChildrenToProps(arrayTypeChildren, newProps);\n return newProps;\n };\n\n HelmetWrapper.prototype.render = function render() {\n var _props = this.props,\n children = _props.children,\n props = objectWithoutProperties(_props, [\"children\"]);\n\n var newProps = _extends({}, props);\n\n if (children) {\n newProps = this.mapChildrenToProps(children, newProps);\n }\n\n return React.createElement(Component, newProps);\n };\n\n createClass(HelmetWrapper, null, [{\n key: \"canUseDOM\",\n\n\n // Component.peek comes from react-side-effect:\n // For testing, you may use a static peek() method available on the returned component.\n // It lets you get the current state without resetting the mounted instance stack.\n // Don\u2019t use it for anything other than testing.\n\n /**\n * @param {Object} base: {\"target\": \"_blank\", \"href\": \"http://mysite.com/\"}\n * @param {Object} bodyAttributes: {\"className\": \"root\"}\n * @param {String} defaultTitle: \"Default Title\"\n * @param {Boolean} defer: true\n * @param {Boolean} encodeSpecialCharacters: true\n * @param {Object} htmlAttributes: {\"lang\": \"en\", \"amp\": undefined}\n * @param {Array} link: [{\"rel\": \"canonical\", \"href\": \"http://mysite.com/example\"}]\n * @param {Array} meta: [{\"name\": \"description\", \"content\": \"Test description\"}]\n * @param {Array} noscript: [{\"innerHTML\": \" console.log(newState)\"\n * @param {Array} script: [{\"type\": \"text/javascript\", \"src\": \"http://mysite.com/js/test.js\"}]\n * @param {Array} style: [{\"type\": \"text/css\", \"cssText\": \"div { display: block; color: blue; }\"}]\n * @param {String} title: \"Title\"\n * @param {Object} titleAttributes: {\"itemprop\": \"name\"}\n * @param {String} titleTemplate: \"MySite.com - %s\"\n */\n set: function set$$1(canUseDOM) {\n Component.canUseDOM = canUseDOM;\n }\n }]);\n return HelmetWrapper;\n }(React.Component), _class.propTypes = {\n base: PropTypes.object,\n bodyAttributes: PropTypes.object,\n children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),\n defaultTitle: PropTypes.string,\n defer: PropTypes.bool,\n encodeSpecialCharacters: PropTypes.bool,\n htmlAttributes: PropTypes.object,\n link: PropTypes.arrayOf(PropTypes.object),\n meta: PropTypes.arrayOf(PropTypes.object),\n noscript: PropTypes.arrayOf(PropTypes.object),\n onChangeClientState: PropTypes.func,\n script: PropTypes.arrayOf(PropTypes.object),\n style: PropTypes.arrayOf(PropTypes.object),\n title: PropTypes.string,\n titleAttributes: PropTypes.object,\n titleTemplate: PropTypes.string\n }, _class.defaultProps = {\n defer: true,\n encodeSpecialCharacters: true\n }, _class.peek = Component.peek, _class.rewind = function () {\n var mappedState = Component.rewind();\n if (!mappedState) {\n // provide fallback if mappedState is undefined\n mappedState = mapStateOnServer({\n baseTag: [],\n bodyAttributes: {},\n encodeSpecialCharacters: true,\n htmlAttributes: {},\n linkTags: [],\n metaTags: [],\n noscriptTags: [],\n scriptTags: [],\n styleTags: [],\n title: \"\",\n titleAttributes: {}\n });\n }\n\n return mappedState;\n }, _temp;\n};\n\nvar NullComponent = function NullComponent() {\n return null;\n};\n\nvar HelmetSideEffects = withSideEffect(reducePropsToState, handleClientStateChange, mapStateOnServer)(NullComponent);\n\nvar HelmetExport = Helmet(HelmetSideEffects);\nHelmetExport.renderStatic = HelmetExport.rewind;\n\nexport default HelmetExport;\nexport { HelmetExport as Helmet };\n", "import React from \"react\";\nimport { Helmet } from \"react-helmet\";\n\ninterface TitleProps {\n title?: string;\n}\n\nconst WindowTitle: React.FC = ({ title }) => {\n const fullTitle = title ? `${title} - Bench IQ` : \"Bench IQ\";\n\n return (\n \n {fullTitle}\n \n );\n};\n\nexport default WindowTitle;\n", "import { Pagination } from \"@mui/material\";\nimport { styled } from \"@/utils/styled\";\n\n/**\n * Shared pagination control used by list pages (StarredPage, FoldersPage,\n * any future list view). Wraps MUI Pagination with a consistent `margin-top`\n * so the control sits with the same rhythm below its list content on every\n * page that uses it.\n *\n * Callers are expected to provide the standard props (`count`, `page`,\n * `onChange`, `color`, `shape`) and to wrap it in a centered container\n * (typically ``) per the existing\n * StarredPage pattern.\n */\nexport const StyledPagination = styled(Pagination)`\n margin-top: 10px;\n`;\n\nexport default StyledPagination;\n", "import Chip from \"@mui/material/Chip\";\nimport { styled } from \"@/utils/styled\";\n\nconst MotionTag = styled(Chip)`\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport default MotionTag;\n", "import { X, Ellipsis } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport { Box, Stack } from \"@mui/material\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport React, { MouseEvent, useEffect, useRef, useState } from \"react\";\n\nexport interface MotionTagsProps {\n /**\n * Motion tags.\n */\n children: React.ReactNode;\n}\n\n/**\n * A container of motion tags.\n *\n * This component displays a single line of tags by default and exposes controls\n * to show or hide additional tags that do not fit on the first line.\n */\nexport default function MotionTags({ children }: MotionTagsProps) {\n const self = useRef(null);\n const [measured, setMeasured] = useState(false);\n const [expanded, setExpanded] = useState(false);\n const [numVisibleTags, setNumVisibleTags] = useState(0);\n\n function onClickExpand(e: MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n setExpanded(true);\n }\n\n function onClickCollapse(e: MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n setExpanded(false);\n }\n\n // recalculate the number of visible tags when children change or the\n // container is resized\n useEffect(() => {\n const container = self.current!;\n const measure = () => {\n const buffer = 40;\n const gap = 8;\n const maxWidth = container.clientWidth - buffer;\n let usedWidth = 0;\n let numVisible = 0;\n\n for (const child of Array.from(container.children)) {\n const childWidth = child.getBoundingClientRect().width;\n if (usedWidth + childWidth > maxWidth) {\n break;\n }\n usedWidth += childWidth + gap;\n numVisible += 1;\n }\n\n setNumVisibleTags(numVisible);\n setMeasured(true);\n };\n\n measure();\n\n const observer = new ResizeObserver(measure);\n observer.observe(container);\n return () => observer.disconnect();\n }, [children]);\n\n const childrenArray = React.Children.toArray(children);\n const overflows = numVisibleTags < childrenArray.length;\n\n return (\n
    \n {/*\n Shadow view.\n Render all children so that we can measure their rendered widths and\n use that to determine which to show and which to hide in the real\n view. Hide them so that they do not appear on the screen or affect\n layout.\n */}\n
    \n {children}\n
    \n\n {/*\n Real view.\n Render children that fit in the container if it is collapsed or all\n children if the container is expanded.\n */}\n {measured && (\n \n {expanded ? children : childrenArray.slice(0, numVisibleTags)}\n\n {overflows && !expanded && (\n \n \n \n }\n />\n )}\n\n {overflows && expanded && }\n \n )}\n
    \n );\n}\n", "import React from \"react\";\nimport { styled } from \"@/utils/styled\";\nimport { Typography } from \"@mui/material\";\nimport { Citation } from \"./Citation\";\n\n// TODO Phase 2 review: border-radius 4px has no equivalent in new brand shape tokens (smallest = smallRadius/8px)\nconst PreserveWhitespace = styled(Typography)`\n white-space: pre-wrap;\n`;\n\nconst citationPatternSep = /(\\[\\d+\\])/;\nconst citationPattern = /\\[(\\d+)\\]/;\n\ninterface CitationTextProps {\n text: string;\n onClickCitation: (index: number) => void;\n}\n\n/**\n * Renders text with inline citation markers ([1], [2], etc.) as clickable spans.\n */\nexport function CitationText({ text, onClickCitation }: CitationTextProps) {\n const parts = text.split(citationPatternSep).filter((part) => part.length > 0);\n\n return (\n \n {parts.map((part, i) => {\n const match = part.match(citationPattern);\n\n if (!match) {\n return part;\n }\n\n const citationIdx = parseInt(match[1], 10);\n const prevPartHasCitation = Boolean(i > 0 && parts[i - 1].match(citationPattern));\n\n return (\n {\n e.stopPropagation();\n onClickCitation(citationIdx);\n }}\n // Consecutive citations (e.g. [1][2]) collapse spacing; isolated\n // ones keep 0.25em so the pill doesn't hug the adjacent text.\n sx={{ marginLeft: prevPartHasCitation ? 0 : \"0.25em\" }}\n >\n {citationIdx}\n \n );\n })}\n \n );\n}\n", "import React from \"react\";\nimport AISummaryUnavailable from \"./AISummaryUnavailable\";\nimport { Citation } from \"@/api/queries/transcripts.types\";\nimport { CitationText } from \"./CitationText\";\n\ntype Overview = { content: string; citations: Citation[] };\n\ninterface TranscriptOverviewProps {\n /**\n * The transcript overview.\n */\n overview: Overview | null | undefined;\n /**\n * Callback triggered when the user clicks on a citation marker. The payload\n * includes the citation index and the text string associated with that\n * citation.\n */\n onClickCitation?: (index: number, text: string) => void;\n}\n\n/**\n * An overview of a transcript.\n */\nexport function TranscriptOverview(props: TranscriptOverviewProps) {\n if (!props.overview) {\n return ;\n }\n\n const { content, citations } = props.overview;\n\n return (\n {\n const text = citations.find((citation) => citation.index === idx)?.transcript_citations[0];\n if (text === undefined) return;\n\n props.onClickCitation?.(idx, text);\n }}\n />\n );\n}\n", "import React, { MouseEvent, useState } from \"react\";\n\nimport { styled } from \"@/utils/styled\";\n\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\nimport Card from \"@mui/material/Card\";\nimport IconButton from \"@mui/material/IconButton\";\n\nimport MotionTag from \"../atoms/MotionTag\";\nimport convertDateToMMDDYYYY from \"../../utils/convertDateToMMDDYYYY\";\nimport { featureEnabled } from \"../../utils/featureFlags\";\nimport MotionTags from \"../atoms/MotionTags\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport Tooltip from \"@mui/material/Tooltip\";\nimport { TranscriptQueryResultType } from \"../../api/queries\";\nimport { TranscriptsAPIReadableContentPreview } from \"../../api/queries/transcripts.types\";\nimport { Excerpt } from \"../atoms/Excerpt\";\nimport { RESULTS_CARD_MAX_WIDTH, RESULTS_CARD_MIN_WIDTH } from \"../../utils/constants\";\nimport { TranscriptOverview } from \"../atoms/TranscriptOverview\";\nimport { sanitizeSearchResultHighlight } from \"../../utils/sanitizeSearchResultHighlight\";\n\nexport { sanitizeSearchResultHighlight } from \"../../utils/sanitizeSearchResultHighlight\";\n\n// Border thickness stays at 1px in every state (color changes for hover/selected).\n// See design-system.md rules C1 + S1. Hover and selected differ only in border color;\n// shadow and background never change.\nconst QueryResultsCard = styled(Card)<{ selected: boolean }>(({ theme, selected }) => ({\n boxShadow: theme.tokens.shadows.sm,\n cursor: \"pointer\",\n overflow: \"visible\",\n padding: theme.tokens.spacing[4],\n borderRadius: theme.tokens.radii.standardRadius,\n border: `1px solid ${selected ? theme.palette.secondary._states.outlinedBorder : theme.border.default}`,\n minWidth: `${RESULTS_CARD_MIN_WIDTH}px`,\n maxWidth: `${RESULTS_CARD_MAX_WIDTH}px`,\n transition: \"border-color 0.15s ease\",\n \"&:hover\": {\n borderColor: selected\n ? theme.palette.secondary._states.outlinedBorder\n : theme.palette.primary._states.outlinedBorder,\n },\n}));\n\nexport interface QueryResultCardProps {\n queryResult: TranscriptsAPIReadableContentPreview;\n queryResultType: TranscriptQueryResultType;\n setParentTranscriptHighlightIndex: React.Dispatch>;\n isSelected: boolean;\n handleExcerptClick: (transcriptSearchResultPreview: TranscriptsAPIReadableContentPreview, index: number) => any;\n queryText?: string;\n motionType?: string | null;\n /**\n * Callback triggered when the user clicks on a citation in the transcript\n * overview.\n */\n onClickOverviewCitation?: (citationIdx: number) => void;\n}\n\nconst QueryResultCard = (props: QueryResultCardProps) => {\n const theme = useTheme();\n const queryResult = props.queryResult;\n const queryResultType = props.queryResultType;\n const setParentTranscriptHighlightIndex = props.setParentTranscriptHighlightIndex;\n const isSelected = props.isSelected;\n const handleExcerptClick = props.handleExcerptClick;\n const queryText = props.queryText ?? \"\";\n const motionType = props.motionType;\n const onClickOverviewCitation = props.onClickOverviewCitation;\n\n const [currentHighlightIndex, setCurrentHighlightIndex] = useState(0);\n\n const isAIEnabled = !featureEnabled(\"disable_generative_ai\");\n const hasQuery = queryText.trim().length > 0;\n const showMotionTags = motionType != null && typeof motionType === \"string\" && motionType.trim().length > 0;\n const transcriptOverview = queryResult.transcript_overview;\n\n const handleNextHighlightNavigation = (event: MouseEvent) => {\n event.stopPropagation();\n\n setParentTranscriptHighlightIndex(currentHighlightIndex + 1);\n setCurrentHighlightIndex(currentHighlightIndex + 1);\n handleExcerptClick(queryResult, currentHighlightIndex + 1);\n };\n\n const handlePreviousHighlightNavigation = (event: MouseEvent) => {\n event.stopPropagation();\n\n setParentTranscriptHighlightIndex(currentHighlightIndex - 1);\n setCurrentHighlightIndex(currentHighlightIndex - 1);\n handleExcerptClick(queryResult, currentHighlightIndex - 1);\n };\n\n const renderHighlightedCaseName = () => {\n let highlightedCaseName = queryResult.court_case.name;\n\n if (queryResult.case_name_highlights.length !== 0) {\n highlightedCaseName = queryResult.case_name_highlights[0];\n }\n\n return ;\n };\n\n const removeEmHtmlTags = (str: string) => str.replace(/]*>(.*?)<\\/em>/g, \"$1\");\n\n function highlightMotionTypes(motionTypeHighlights: string[], allMotionTypes: string[]) {\n if (!!motionTypeHighlights && motionTypeHighlights.length > 0) {\n motionTypeHighlights.forEach((highlight) => {\n const cleanedHighlight = removeEmHtmlTags(highlight);\n const allMotionTypesIndex = allMotionTypes.findIndex(\n (allMotionTypesItem) => allMotionTypesItem === cleanedHighlight,\n );\n\n if (allMotionTypesIndex > -1) {\n allMotionTypes[allMotionTypesIndex] = highlight;\n }\n });\n }\n\n return allMotionTypes;\n }\n\n function renderMatchingMotionTags() {\n if (queryResult.motion_types) {\n const highlightedMotionTypes = highlightMotionTypes(queryResult.motion_type_highlights, queryResult.motion_types);\n return highlightedMotionTypes.map((motionType, index) => {\n const formattedMotionType = motionType\n .toLowerCase()\n .split(\" \")\n .map((word) => word[0].toUpperCase() + word.slice(1))\n .join(\" \");\n\n return (\n }\n placement=\"bottom\"\n >\n } />\n \n );\n });\n }\n return null;\n }\n\n function renderQueryResultJudge() {\n if (queryResult.judge.name) {\n return (\n \n {queryResult.judge.name}\n \n );\n }\n return null;\n }\n\n function renderQueryResultDateOfHearing() {\n if (queryResult.date_of_hearing) {\n return (\n \n {convertDateToMMDDYYYY(new Date(`${queryResult.date_of_hearing}T00:00:00`))}\n \n );\n }\n return null;\n }\n\n function renderResultExcerptNavigation() {\n if (queryResult.content_highlights.length > 1) {\n return (\n \n \n \n \n \n \n \n \n );\n }\n return null;\n }\n\n function removeHeadingTags(htmlString: string) {\n // All heading spans (h2, h3, h4) are structural/issue headers whose content is already in plaintext \u2014 strip entirely\n const structuralHeadingRegex = /.*?<\\/span>/gim;\n const benchOpinionFootnoteRegex =\n /\\s.*?<\\/span>/gim;\n const benchOpinionUncitedFootnoteRegex = /\\[\\d+\\]/gim;\n const benchOpinionDashRegex = /\\s*\\-\\s*/gim;\n const benchOpinionDoublePeriodRegex = /\\.\\s+\\./gim;\n\n return htmlString\n .replace(structuralHeadingRegex, \"\")\n .replace(benchOpinionFootnoteRegex, \"\")\n .replace(benchOpinionDashRegex, \" \")\n .replace(benchOpinionUncitedFootnoteRegex, \"\")\n .replace(benchOpinionDoublePeriodRegex, \".\");\n }\n\n // For bench opinions, compute the effective highlight index by skipping header-only fragments\n const effectiveHighlightIndex = (() => {\n if (queryResultType !== \"bench-opinion\" || queryResult.content_highlights.length === 0) {\n return currentHighlightIndex;\n }\n for (let i = 0; i < queryResult.content_highlights.length; i++) {\n const idx = (currentHighlightIndex + i) % queryResult.content_highlights.length;\n const candidate = removeHeadingTags(queryResult.content_highlights[idx]);\n const textOnly = candidate.replace(/<[^>]*>/g, \"\").trim();\n if (textOnly.length > 0) {\n return idx;\n }\n }\n return currentHighlightIndex;\n })();\n\n function renderHighlightedContent() {\n if (queryResult.content_highlights.length > 0) {\n let content_highlights = \"\";\n if (queryResultType === \"bench-opinion\") {\n const candidate = removeHeadingTags(queryResult.content_highlights[effectiveHighlightIndex]);\n const textOnly = candidate.replace(/<[^>]*>/g, \"\").trim();\n if (textOnly.length === 0) {\n return null;\n }\n content_highlights = candidate;\n } else {\n content_highlights = queryResult.content_highlights[currentHighlightIndex];\n }\n\n if (isAIEnabled) {\n const navigation = renderResultExcerptNavigation();\n const motionTagsContent = showMotionTags ? {renderMatchingMotionTags()} : null;\n\n return (\n \n );\n }\n\n const sanitizedContentHighlights = sanitizeSearchResultHighlight(content_highlights);\n return (\n ({\n width: \"100%\",\n // The whole snippet is a system highlight: underline all the text\n // (olive/300), keyword hits () just stay bold. Mirrors Excerpt.\n textDecorationLine: \"underline\",\n textDecorationColor: theme.palette.systemHighlight.main,\n textDecorationThickness: \"15%\",\n textUnderlineOffset: \"30%\",\n textDecorationSkipInk: \"none\",\n \"& em\": {\n fontStyle: \"normal\",\n fontWeight: 500,\n color: theme.palette.text.primary,\n },\n })}\n dangerouslySetInnerHTML={{ __html: `...${sanitizedContentHighlights}...` }}\n />\n );\n }\n }\n\n function renderMotionTagsInContainer() {\n if (!isAIEnabled || !showMotionTags) {\n return null;\n }\n\n return {renderMatchingMotionTags()}} />;\n }\n\n return (\n {\n handleExcerptClick(\n queryResult,\n queryResultType === \"bench-opinion\" ? effectiveHighlightIndex : currentHighlightIndex,\n );\n }}\n >\n \n \n \n {renderQueryResultJudge()}\n \n \n {queryResult.court_case.number}\n \n {renderQueryResultDateOfHearing()}\n \n \n \n {renderHighlightedCaseName()}\n {isAIEnabled ? !hasQuery && renderResultExcerptNavigation() : renderResultExcerptNavigation()}\n \n \n {isAIEnabled ? (\n <>\n \n {hasQuery && renderHighlightedContent()}\n {!hasQuery && renderMotionTagsInContainer()}\n \n ) : (\n <>\n {renderHighlightedContent()}\n {showMotionTags && {renderMatchingMotionTags()}}\n \n )}\n \n \n );\n};\n\nexport default QueryResultCard;\n", "import { z } from \"zod\";\n\nexport const AutoCorrectionsResponseSchema = z.object({\n corrected_query: z.string(),\n});\n\nexport type AutoCorrectionsResponse = z.infer;\n", "import { useState } from \"react\";\nimport { fetchHelper } from \"../utils/fetchHelpers\";\nimport { AutoCorrectionsResponse, AutoCorrectionsResponseSchema } from \"./queries/autoCorrections.types\";\n\nconst useQueryAutoCorrections = () => {\n const [isLoading, setIsLoading] = useState(false);\n const [data, setData] = useState(null);\n const [error, setError] = useState(null);\n\n const correctQuery = async (query: string): Promise => {\n setIsLoading(true);\n setError(null);\n setData(null);\n\n try {\n const url = new URL(\"/api/queries/auto_corrections/create\", window.location.origin);\n const rawResponse = await fetchHelper(url.toString(), {\n method: \"POST\",\n body: { query },\n });\n\n if (!rawResponse.ok) {\n const errorData = await rawResponse.json().catch(() => ({}));\n throw new Error(errorData.error || `HTTP ${rawResponse.status}: ${rawResponse.statusText}`);\n }\n\n const json = await rawResponse.json();\n const parsed = AutoCorrectionsResponseSchema.safeParse(json);\n if (!parsed.success) {\n throw new Error(\"Invalid auto corrections response\");\n }\n\n setData(parsed.data);\n return parsed.data;\n } catch (err: unknown) {\n setError(err);\n return null;\n } finally {\n setIsLoading(false);\n }\n };\n\n const clearData = () => {\n setData(null);\n setError(null);\n };\n\n return { correctQuery, isLoading, data, error, clearData };\n};\n\nexport default useQueryAutoCorrections;\n", "import React, { useState, useRef, useEffect } from \"react\";\nimport { Typography, TypographyProps, Box, Tooltip } from \"@mui/material\";\nimport { Ellipsis, X } from \"lucide-react\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\n\ninterface ExpandableTruncatedTextProps extends Omit {\n text: React.ReactNode;\n maxLines?: number;\n}\n\nconst ExpandableTruncatedText: React.FC = ({\n text,\n maxLines = 3,\n sx = {},\n ...typographyProps\n}) => {\n const [expanded, setExpanded] = useState(false);\n const [isTruncated, setIsTruncated] = useState(false);\n const textRef = useRef(null);\n\n // Check if text is actually truncated\n useEffect(() => {\n const checkTruncation = () => {\n if (textRef.current) {\n const element = textRef.current;\n const computedStyle = getComputedStyle(element);\n const lineHeight = parseFloat(computedStyle.lineHeight) || 20; // fallback to 20px\n const maxHeight = lineHeight * maxLines;\n const actualHeight = element.scrollHeight;\n\n const isTruncated = actualHeight > maxHeight;\n setIsTruncated(isTruncated);\n\n // Apply maxHeight to the element to actually truncate it\n if (isTruncated && !expanded) {\n element.style.maxHeight = `${maxHeight}px`;\n } else {\n element.style.maxHeight = \"none\";\n }\n }\n };\n\n // Use setTimeout to ensure the element is rendered\n const timeoutId = setTimeout(checkTruncation, 0);\n\n // Re-check on resize\n const resizeObserver = new ResizeObserver(checkTruncation);\n if (textRef.current) {\n resizeObserver.observe(textRef.current);\n }\n\n return () => {\n clearTimeout(timeoutId);\n resizeObserver.disconnect();\n };\n }, [text, maxLines, expanded]);\n\n const handleToggle = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setExpanded(!expanded);\n };\n\n // Shared button styles\n const buttonStyles = {\n position: \"absolute\" as const,\n right: 0,\n top: 53,\n transform: \"translateY(-50%)\",\n minWidth: \"auto\",\n width: \"20px\",\n height: \"20px\",\n backgroundColor: \"background.paper\",\n \"&:hover\": {\n backgroundColor: \"rgba(0, 0, 0, 0.04)\",\n },\n };\n\n // Text styles\n const textStyles = {\n display: \"block\",\n overflow: \"hidden\",\n flex: 1,\n marginRight: isTruncated ? \"24px\" : 0,\n ...sx,\n };\n\n return (\n \n \n {text}\n \n\n {isTruncated && (\n \n \n \n )}\n \n );\n};\n\nexport default ExpandableTruncatedText;\n", "export const matchesSupportedBooleanTerms = (input: string): boolean => {\n const supportedBooleanTermsPattern = /\\b(AND|OR)\\b|[&%*!]|[+/]\\d+/;\n return supportedBooleanTermsPattern.test(input);\n};\n\nexport const matchesUnsupportedBooleanTerms = (input: string): boolean => {\n const unsupportedBooleanTermsPattern = /[\\/+][ps]|#/;\n return unsupportedBooleanTermsPattern.test(input);\n};\n", "import { styled } from \"@/utils/styled\";\nimport Box from \"@mui/material/Box\";\n\nconst ScrollableContent = styled(Box)<{ $beforeHeightPx?: number }>`\n /* Respect user's OS/browser scrollbar preference */\n overflow-y: auto;\n position: relative;\n\n /* Reserve space so layout doesn't shift and side paddings remain equal */\n scrollbar-gutter: stable;\n\n /* No generic padding here; consumers add any needed spacing */\n\n ::before {\n content: \"\";\n position: sticky;\n display: block;\n z-index: 10;\n height: ${({ $beforeHeightPx = 16 }) => $beforeHeightPx}px;\n left: 0;\n right: 0;\n pointer-events: none;\n }\n\n ::after {\n content: \"\";\n position: sticky;\n display: block;\n height: 20px;\n z-index: 10;\n left: 0;\n right: 0;\n pointer-events: none;\n }\n\n &::before {\n top: 0;\n background: linear-gradient(to bottom, ${({ theme }) => theme.palette.background.default}, transparent);\n }\n\n ::after {\n bottom: -2px; /* Slight offset to ensure overlay of bottom. */\n background: linear-gradient(to top, ${({ theme }) => theme.palette.background.default}, transparent);\n }\n`;\nexport default ScrollableContent;\n", "/**\n * Compares two URLSearchParams objects and returns true if they are equal, false otherwise.\n * This function ignores keys in the ignoreKeys array.\n *\n * @param paramsA - The first URLSearchParams object to compare.\n * @param paramsB - The second URLSearchParams object to compare.\n * @param ignoreKeys - An array of keys to ignore in the comparison.\n * @returns true if the two objects are equal, false otherwise.\n */\nexport default function areUrlParamsTheSame(\n paramsA: URLSearchParams,\n paramsB: URLSearchParams,\n ignoreKeys: string[] = [],\n) {\n const keysA = Array.from(paramsA.keys());\n const keysB = Array.from(paramsB.keys());\n\n const filteredKeysA = keysA.filter((key) => !ignoreKeys.includes(key));\n const filteredKeysB = keysB.filter((key) => !ignoreKeys.includes(key));\n\n if (filteredKeysA.length !== filteredKeysB.length) {\n return false;\n }\n\n return filteredKeysA.every((key) => {\n const valuesA = paramsA.getAll(key);\n const valuesB = paramsB.getAll(key);\n if (valuesA.length !== valuesB.length) {\n return false;\n }\n const valuesACount = valuesA.reduce(\n (acc, value) => {\n acc[value] = (acc[value] || 0) + 1;\n return acc;\n },\n {} as Record,\n );\n const valuesBCount = valuesB.reduce(\n (acc, value) => {\n acc[value] = (acc[value] || 0) + 1;\n return acc;\n },\n {} as Record,\n );\n return Object.keys(valuesACount).every((value) => valuesACount[value] === valuesBCount[value]);\n });\n}\n", "import React from \"react\";\nimport { Typography, Box } from \"@mui/material\";\n\nimport { Lock } from \"lucide-react\";\n\nexport const FEATURE_DISABLED_MESSAGE = \"This feature has been disabled by your account admin.\";\n\nconst FeatureDisabledByAdmin: React.FC = () => (\n \n \n \n \n \n {FEATURE_DISABLED_MESSAGE}\n \n \n);\n\nexport default FeatureDisabledByAdmin;\n", "import { featureEnabled } from \"./featureFlags\";\n\nexport function isGenerativeAIAvailable(): boolean {\n return !featureEnabled(\"disable_generative_ai\") && !featureEnabled(\"incognito_queries\");\n}\n", "type AutoCorrectionExecutionParams = {\n lastKey: string | null;\n pendingQuery: string | null;\n queryType: string;\n autoCorrectionsAllowed: boolean;\n};\n\ntype AutoCorrectionExecutionResult = {\n shouldRun: boolean;\n nextKey: string | null;\n};\n\nconst buildAutoCorrectionKey = ({\n pendingQuery,\n queryType,\n autoCorrectionsAllowed,\n}: Omit): string => {\n return JSON.stringify([pendingQuery, queryType, autoCorrectionsAllowed]);\n};\n\nexport function computeAutoCorrectionExecution({\n lastKey,\n pendingQuery,\n queryType,\n autoCorrectionsAllowed,\n}: AutoCorrectionExecutionParams): AutoCorrectionExecutionResult {\n if (!pendingQuery || pendingQuery.trim() === \"\") {\n return { shouldRun: false, nextKey: null };\n }\n\n const nextKey = buildAutoCorrectionKey({\n pendingQuery,\n queryType,\n autoCorrectionsAllowed,\n });\n\n if (lastKey === nextKey) {\n return { shouldRun: false, nextKey };\n }\n\n return { shouldRun: true, nextKey };\n}\n", "// from https://github.com/mui/material-ui/blob/312270bc71224067e1910bbee9f800b4a2469cc7/packages/mui-base/src/useAutocomplete/useAutocomplete.js\n// tag v5.13.6\n\n/* eslint-disable no-constant-condition */\nimport * as React from \"react\";\nimport {\n unstable_setRef as setRef,\n unstable_useEventCallback as useEventCallback,\n unstable_useControlled as useControlled,\n unstable_useId as useId,\n usePreviousProps,\n} from \"@mui/utils\";\n\n// https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript\n// Give up on IE11 support for this feature\nfunction stripDiacritics(string) {\n return typeof string.normalize !== \"undefined\" ? string.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\") : string;\n}\n\nexport function createFilterOptions(config = {}) {\n const { ignoreAccents = true, ignoreCase = true, limit, matchFrom = \"any\", stringify, trim = false } = config;\n\n return (options, { inputValue, getOptionLabel }) => {\n let input = trim ? inputValue.trim() : inputValue;\n if (ignoreCase) {\n input = input.toLowerCase();\n }\n if (ignoreAccents) {\n input = stripDiacritics(input);\n }\n\n const filteredOptions = !input\n ? options\n : options.filter((option) => {\n let candidate = (stringify || getOptionLabel)(option);\n if (ignoreCase) {\n candidate = candidate.toLowerCase();\n }\n if (ignoreAccents) {\n candidate = stripDiacritics(candidate);\n }\n\n return matchFrom === \"start\" ? candidate.indexOf(input) === 0 : candidate.indexOf(input) > -1;\n });\n\n return typeof limit === \"number\" ? filteredOptions.slice(0, limit) : filteredOptions;\n };\n}\n\n// To replace with .findIndex() once we stop IE11 support.\nfunction findIndex(array, comp) {\n for (let i = 0; i < array.length; i += 1) {\n if (comp(array[i])) {\n return i;\n }\n }\n\n return -1;\n}\n\nconst defaultFilterOptions = createFilterOptions();\n\n// Number of options to jump in list box when `Page Up` and `Page Down` keys are used.\nconst pageSize = 5;\n\nconst defaultIsActiveElementInListbox = (listboxRef) =>\n listboxRef.current !== null && listboxRef.current.parentElement?.contains(document.activeElement);\n\nexport default function useAutocomplete(props) {\n const {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n unstable_isActiveElementInListbox = defaultIsActiveElementInListbox,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n unstable_classNamePrefix = \"Mui\",\n autoComplete = false,\n autoHighlight = false,\n autoSelect = false,\n blurOnSelect = false,\n clearOnBlur = !props.freeSolo,\n clearOnEscape = false,\n componentName = \"useAutocomplete\",\n defaultValue = props.multiple ? [] : null,\n disableClearable = false,\n disableCloseOnSelect = false,\n disabled: disabledProp,\n disabledItemsFocusable = false,\n disableListWrap = false,\n filterOptions = defaultFilterOptions,\n filterSelectedOptions = false,\n freeSolo = false,\n getOptionDisabled,\n getOptionLabel: getOptionLabelProp = (option) => option.label ?? option,\n groupBy,\n handleHomeEndKeys = !props.freeSolo,\n id: idProp,\n includeInputInList = false,\n inputValue: inputValueProp,\n isOptionEqualToValue = (option, value) => option === value,\n multiple = false,\n onChange,\n onClose,\n onHighlightChange,\n onInputChange,\n onOpen,\n open: openProp,\n openOnFocus = false,\n options,\n readOnly = false,\n selectOnFocus = !props.freeSolo,\n value: valueProp,\n } = props;\n\n const id = useId(idProp);\n\n let getOptionLabel = getOptionLabelProp;\n\n getOptionLabel = (option) => {\n const optionLabel = getOptionLabelProp(option);\n if (typeof optionLabel !== \"string\") {\n if (process.env.NODE_ENV !== \"production\") {\n const erroneousReturn = optionLabel === undefined ? \"undefined\" : `${typeof optionLabel} (${optionLabel})`;\n console.error(\n `MUI: The \\`getOptionLabel\\` method of ${componentName} returned ${erroneousReturn} instead of a string for ${JSON.stringify(\n option,\n )}.`,\n );\n }\n return String(optionLabel);\n }\n return optionLabel;\n };\n\n const ignoreFocus = React.useRef(false);\n const firstFocus = React.useRef(true);\n const inputRef = React.useRef(null);\n const listboxRef = React.useRef(null);\n const [anchorEl, setAnchorEl] = React.useState(null);\n\n const [focusedTag, setFocusedTag] = React.useState(-1);\n const defaultHighlighted = autoHighlight ? 0 : -1;\n const highlightedIndexRef = React.useRef(defaultHighlighted);\n\n const [value, setValueState] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: componentName,\n });\n const [inputValue, setInputValueState] = useControlled({\n controlled: inputValueProp,\n default: \"\",\n name: componentName,\n state: \"inputValue\",\n });\n\n const [focused, setFocused] = React.useState(false);\n\n const resetInputValue = React.useCallback(\n (event, newValue) => {\n // retain current `inputValue` if new option isn't selected and `clearOnBlur` is false\n // When `multiple` is enabled, `newValue` is an array of all selected items including the newly selected item\n const isOptionSelected = multiple ? value.length < newValue.length : newValue !== null;\n if (!isOptionSelected && !clearOnBlur) {\n return;\n }\n let newInputValue;\n if (multiple) {\n newInputValue = \"\";\n } else if (newValue == null) {\n newInputValue = \"\";\n } else {\n const optionLabel = getOptionLabel(newValue);\n newInputValue = typeof optionLabel === \"string\" ? optionLabel : \"\";\n }\n\n if (inputValue === newInputValue) {\n return;\n }\n\n setInputValueState(newInputValue);\n\n if (onInputChange) {\n onInputChange(event, newInputValue, \"reset\");\n }\n },\n [getOptionLabel, inputValue, multiple, onInputChange, setInputValueState, clearOnBlur, value],\n );\n\n const [open, setOpenState] = useControlled({\n controlled: openProp,\n default: false,\n name: componentName,\n state: \"open\",\n });\n\n const [inputPristine, setInputPristine] = React.useState(true);\n\n const inputValueIsSelectedValue = !multiple && value != null && inputValue === getOptionLabel(value);\n\n const popupOpen = open && !readOnly;\n\n const filteredOptions = popupOpen\n ? filterOptions(\n options.filter((option) => {\n if (\n filterSelectedOptions &&\n (multiple ? value : [value]).some((value2) => value2 !== null && isOptionEqualToValue(option, value2))\n ) {\n return false;\n }\n return true;\n }),\n // we use the empty string to manipulate `filterOptions` to not filter any options\n // i.e. the filter predicate always returns true\n {\n inputValue: inputValueIsSelectedValue && inputPristine ? \"\" : inputValue,\n getOptionLabel,\n },\n )\n : [];\n\n const previousProps = usePreviousProps({\n filteredOptions,\n value,\n inputValue,\n });\n\n React.useEffect(() => {\n const valueChange = value !== previousProps.value;\n\n if (focused && !valueChange) {\n return;\n }\n\n // Only reset the input's value when freeSolo if the component's value changes.\n if (freeSolo && !valueChange) {\n return;\n }\n\n resetInputValue(null, value);\n }, [value, resetInputValue, focused, previousProps.value, freeSolo]);\n\n const listboxAvailable = open && filteredOptions.length > 0 && !readOnly;\n\n if (process.env.NODE_ENV !== \"production\") {\n if (value !== null && !freeSolo && options.length > 0) {\n const missingValue = (multiple ? value : [value]).filter(\n (value2) => !options.some((option) => isOptionEqualToValue(option, value2)),\n );\n\n if (missingValue.length > 0) {\n console.warn(\n [\n `MUI: The value provided to ${componentName} is invalid.`,\n `None of the options match with \\`${\n missingValue.length > 1 ? JSON.stringify(missingValue) : JSON.stringify(missingValue[0])\n }\\`.`,\n \"You can use the `isOptionEqualToValue` prop to customize the equality test.\",\n ].join(\"\\n\"),\n );\n }\n }\n }\n\n const focusTag = useEventCallback((tagToFocus) => {\n if (tagToFocus === -1) {\n inputRef.current.focus();\n } else {\n anchorEl.querySelector(`[data-tag-index=\"${tagToFocus}\"]`).focus();\n }\n });\n\n // Ensure the focusedTag is never inconsistent\n React.useEffect(() => {\n if (multiple && focusedTag > value.length - 1) {\n setFocusedTag(-1);\n focusTag(-1);\n }\n }, [value, multiple, focusedTag, focusTag]);\n\n function validOptionIndex(index, direction) {\n if (!listboxRef.current || index === -1) {\n return -1;\n }\n\n let nextFocus = index;\n\n while (true) {\n // Out of range\n if (\n (direction === \"next\" && nextFocus === filteredOptions.length) ||\n (direction === \"previous\" && nextFocus === -1)\n ) {\n return -1;\n }\n\n const option = listboxRef.current.querySelector(`[data-option-index=\"${nextFocus}\"]`);\n\n // Same logic as MenuList.js\n const nextFocusDisabled = disabledItemsFocusable\n ? false\n : !option || option.disabled || option.getAttribute(\"aria-disabled\") === \"true\";\n\n if ((option && !option.hasAttribute(\"tabindex\")) || nextFocusDisabled) {\n // Move to the next element.\n nextFocus += direction === \"next\" ? 1 : -1;\n } else {\n return nextFocus;\n }\n }\n }\n\n const setHighlightedIndex = useEventCallback(({ event, index, reason = \"auto\" }) => {\n highlightedIndexRef.current = index;\n\n // does the index exist?\n if (index === -1) {\n inputRef.current.removeAttribute(\"aria-activedescendant\");\n } else {\n inputRef.current.setAttribute(\"aria-activedescendant\", `${id}-option-${index}`);\n }\n\n if (onHighlightChange) {\n onHighlightChange(event, index === -1 ? null : filteredOptions[index], reason);\n }\n\n if (!listboxRef.current) {\n return;\n }\n\n const prev = listboxRef.current.querySelector(`[role=\"option\"].${unstable_classNamePrefix}-focused`);\n if (prev) {\n prev.classList.remove(`${unstable_classNamePrefix}-focused`);\n prev.classList.remove(`${unstable_classNamePrefix}-focusVisible`);\n }\n\n let listboxNode = listboxRef.current;\n if (listboxRef.current.getAttribute(\"role\") !== \"listbox\") {\n listboxNode = listboxRef.current.parentElement.querySelector('[role=\"listbox\"]');\n }\n\n // \"No results\"\n if (!listboxNode) {\n return;\n }\n\n if (index === -1) {\n listboxNode.scrollTop = 0;\n return;\n }\n\n const option = listboxRef.current.querySelector(`[data-option-index=\"${index}\"]`);\n\n if (!option) {\n return;\n }\n\n option.classList.add(`${unstable_classNamePrefix}-focused`);\n if (reason === \"keyboard\") {\n option.classList.add(`${unstable_classNamePrefix}-focusVisible`);\n }\n\n // Scroll active descendant into view.\n // Logic copied from https://www.w3.org/WAI/content-assets/wai-aria-practices/patterns/combobox/examples/js/select-only.js\n //\n // Consider this API instead once it has a better browser support:\n // .scrollIntoView({ scrollMode: 'if-needed', block: 'nearest' });\n if (listboxNode.scrollHeight > listboxNode.clientHeight && reason !== \"mouse\") {\n const element = option;\n\n const scrollBottom = listboxNode.clientHeight + listboxNode.scrollTop;\n const elementBottom = element.offsetTop + element.offsetHeight;\n if (elementBottom > scrollBottom) {\n listboxNode.scrollTop = elementBottom - listboxNode.clientHeight;\n } else if (element.offsetTop - element.offsetHeight * (groupBy ? 1.3 : 0) < listboxNode.scrollTop) {\n listboxNode.scrollTop = element.offsetTop - element.offsetHeight * (groupBy ? 1.3 : 0);\n }\n }\n });\n\n const changeHighlightedIndex = useEventCallback(({ event, diff, direction = \"next\", reason = \"auto\" }) => {\n if (!popupOpen) {\n return;\n }\n\n const getNextIndex = () => {\n const maxIndex = filteredOptions.length - 1;\n\n if (diff === \"reset\") {\n return defaultHighlighted;\n }\n\n if (diff === \"start\") {\n return 0;\n }\n\n if (diff === \"end\") {\n return maxIndex;\n }\n\n const newIndex = highlightedIndexRef.current + diff;\n\n if (newIndex < 0) {\n if (newIndex === -1 && includeInputInList) {\n return -1;\n }\n\n if ((disableListWrap && highlightedIndexRef.current !== -1) || Math.abs(diff) > 1) {\n return 0;\n }\n\n return maxIndex;\n }\n\n if (newIndex > maxIndex) {\n if (newIndex === maxIndex + 1 && includeInputInList) {\n return -1;\n }\n\n if (disableListWrap || Math.abs(diff) > 1) {\n return maxIndex;\n }\n\n return 0;\n }\n\n return newIndex;\n };\n\n const nextIndex = validOptionIndex(getNextIndex(), direction);\n setHighlightedIndex({ index: nextIndex, reason, event });\n\n // Sync the content of the input with the highlighted option.\n if (autoComplete && diff !== \"reset\") {\n if (nextIndex === -1) {\n inputRef.current.value = inputValue;\n } else {\n const option = getOptionLabel(filteredOptions[nextIndex]);\n inputRef.current.value = option;\n\n // The portion of the selected suggestion that has not been typed by the user,\n // a completion string, appears inline after the input cursor in the textbox.\n const index = option.toLowerCase().indexOf(inputValue.toLowerCase());\n if (index === 0 && inputValue.length > 0) {\n inputRef.current.setSelectionRange(inputValue.length, option.length);\n }\n }\n }\n });\n\n const checkHighlightedOptionExists = () => {\n const isSameValue = (value1, value2) => {\n const label1 = value1 ? getOptionLabel(value1) : \"\";\n const label2 = value2 ? getOptionLabel(value2) : \"\";\n return label1 === label2;\n };\n\n if (\n highlightedIndexRef.current !== -1 &&\n previousProps.filteredOptions &&\n previousProps.filteredOptions.length !== filteredOptions.length &&\n previousProps.inputValue === inputValue &&\n (multiple\n ? value.length === previousProps.value.length &&\n previousProps.value.every((val, i) => getOptionLabel(value[i]) === getOptionLabel(val))\n : isSameValue(previousProps.value, value))\n ) {\n const previousHighlightedOption = previousProps.filteredOptions[highlightedIndexRef.current];\n\n if (previousHighlightedOption) {\n const previousHighlightedOptionExists = filteredOptions.some((option) => {\n return getOptionLabel(option) === getOptionLabel(previousHighlightedOption);\n });\n\n if (previousHighlightedOptionExists) {\n return true;\n }\n }\n }\n return false;\n };\n\n const syncHighlightedIndex = React.useCallback(() => {\n if (!popupOpen) {\n return;\n }\n\n // Check if the previously highlighted option still exists in the updated filtered options list and if the value and inputValue haven't changed\n // If it exists and the value and the inputValue haven't changed, return, otherwise continue execution\n if (checkHighlightedOptionExists()) {\n return;\n }\n\n const valueItem = multiple ? value[0] : value;\n\n // The popup is empty, reset\n if (filteredOptions.length === 0 || valueItem == null) {\n changeHighlightedIndex({ diff: \"reset\" });\n return;\n }\n\n if (!listboxRef.current) {\n return;\n }\n\n // Synchronize the value with the highlighted index\n if (valueItem != null) {\n // Bench IQ change: reset highlighting back to start instead of to first selected option\n changeHighlightedIndex({ diff: \"reset\" });\n return;\n // Original code follows below\n\n // const currentOption = filteredOptions[highlightedIndexRef.current];\n\n // // Keep the current highlighted index if possible\n // if (multiple && currentOption && findIndex(value, (val) => isOptionEqualToValue(currentOption, val)) !== -1) {\n // return;\n // }\n\n // const itemIndex = findIndex(filteredOptions, (optionItem) => isOptionEqualToValue(optionItem, valueItem));\n // if (itemIndex === -1) {\n // changeHighlightedIndex({ diff: \"reset\" });\n // } else {\n // setHighlightedIndex({ index: itemIndex });\n // }\n // return;\n }\n\n // Prevent the highlighted index to leak outside the boundaries.\n if (highlightedIndexRef.current >= filteredOptions.length - 1) {\n setHighlightedIndex({ index: filteredOptions.length - 1 });\n return;\n }\n\n // Restore the focus to the previous index.\n setHighlightedIndex({ index: highlightedIndexRef.current });\n // Ignore filteredOptions (and options, isOptionEqualToValue, getOptionLabel) not to break the scroll position\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n // Only sync the highlighted index when the option switch between empty and not\n filteredOptions.length,\n // Don't sync the highlighted index with the value when multiple\n // eslint-disable-next-line react-hooks/exhaustive-deps\n multiple ? false : value,\n filterSelectedOptions,\n changeHighlightedIndex,\n setHighlightedIndex,\n popupOpen,\n inputValue,\n multiple,\n ]);\n\n const handleListboxRef = useEventCallback((node) => {\n setRef(listboxRef, node);\n\n if (!node) {\n return;\n }\n\n syncHighlightedIndex();\n });\n\n if (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useEffect(() => {\n if (!inputRef.current || inputRef.current.nodeName !== \"INPUT\") {\n if (inputRef.current && inputRef.current.nodeName === \"TEXTAREA\") {\n console.warn(\n [\n `A textarea element was provided to ${componentName} where input was expected.`,\n `This is not a supported scenario but it may work under certain conditions.`,\n `A textarea keyboard navigation may conflict with Autocomplete controls (e.g. enter and arrow keys).`,\n `Make sure to test keyboard navigation and add custom event handlers if necessary.`,\n ].join(\"\\n\"),\n );\n } else {\n console.error(\n [\n `MUI: Unable to find the input element. It was resolved to ${inputRef.current} while an HTMLInputElement was expected.`,\n `Instead, ${componentName} expects an input element.`,\n \"\",\n componentName === \"useAutocomplete\"\n ? \"Make sure you have bound getInputProps correctly and that the normal ref/effect resolutions order is guaranteed.\"\n : \"Make sure you have customized the input component correctly.\",\n ].join(\"\\n\"),\n );\n }\n }\n }, [componentName]);\n }\n\n React.useEffect(() => {\n syncHighlightedIndex();\n }, [syncHighlightedIndex]);\n\n const handleOpen = (event) => {\n if (open) {\n return;\n }\n\n setOpenState(true);\n setInputPristine(true);\n\n if (onOpen) {\n onOpen(event);\n }\n };\n\n const handleClose = (event, reason) => {\n if (!open) {\n return;\n }\n\n setOpenState(false);\n\n if (onClose) {\n onClose(event, reason);\n }\n };\n\n const handleValue = (event, newValue, reason, details) => {\n if (multiple) {\n if (value.length === newValue.length && value.every((val, i) => val === newValue[i])) {\n return;\n }\n } else if (value === newValue) {\n return;\n }\n\n if (onChange) {\n onChange(event, newValue, reason, details);\n }\n\n setValueState(newValue);\n };\n\n const isTouch = React.useRef(false);\n\n const selectNewValue = (event, option, reasonProp = \"selectOption\", origin = \"options\") => {\n let reason = reasonProp;\n let newValue = option;\n\n if (multiple) {\n newValue = Array.isArray(value) ? value.slice() : [];\n\n if (process.env.NODE_ENV !== \"production\") {\n const matches = newValue.filter((val) => isOptionEqualToValue(option, val));\n\n if (matches.length > 1) {\n console.error(\n [\n `MUI: The \\`isOptionEqualToValue\\` method of ${componentName} does not handle the arguments correctly.`,\n `The component expects a single value to match a given option but found ${matches.length} matches.`,\n ].join(\"\\n\"),\n );\n }\n }\n\n const itemIndex = findIndex(newValue, (valueItem) => isOptionEqualToValue(option, valueItem));\n\n if (itemIndex === -1) {\n newValue.push(option);\n } else if (origin !== \"freeSolo\") {\n newValue.splice(itemIndex, 1);\n reason = \"removeOption\";\n }\n }\n\n resetInputValue(event, newValue);\n\n handleValue(event, newValue, reason, { option });\n if (!disableCloseOnSelect && (!event || (!event.ctrlKey && !event.metaKey))) {\n handleClose(event, reason);\n }\n\n if (\n blurOnSelect === true ||\n (blurOnSelect === \"touch\" && isTouch.current) ||\n (blurOnSelect === \"mouse\" && !isTouch.current)\n ) {\n inputRef.current.blur();\n }\n };\n\n function validTagIndex(index, direction) {\n if (index === -1) {\n return -1;\n }\n\n let nextFocus = index;\n\n while (true) {\n // Out of range\n if ((direction === \"next\" && nextFocus === value.length) || (direction === \"previous\" && nextFocus === -1)) {\n return -1;\n }\n\n const option = anchorEl.querySelector(`[data-tag-index=\"${nextFocus}\"]`);\n\n // Same logic as MenuList.js\n if (\n !option ||\n !option.hasAttribute(\"tabindex\") ||\n option.disabled ||\n option.getAttribute(\"aria-disabled\") === \"true\"\n ) {\n nextFocus += direction === \"next\" ? 1 : -1;\n } else {\n return nextFocus;\n }\n }\n }\n\n const handleFocusTag = (event, direction) => {\n if (!multiple) {\n return;\n }\n\n if (inputValue === \"\") {\n handleClose(event, \"toggleInput\");\n }\n\n let nextTag = focusedTag;\n\n if (focusedTag === -1) {\n if (inputValue === \"\" && direction === \"previous\") {\n nextTag = value.length - 1;\n }\n } else {\n nextTag += direction === \"next\" ? 1 : -1;\n\n if (nextTag < 0) {\n nextTag = 0;\n }\n\n if (nextTag === value.length) {\n nextTag = -1;\n }\n }\n\n nextTag = validTagIndex(nextTag, direction);\n\n setFocusedTag(nextTag);\n focusTag(nextTag);\n };\n\n const handleClear = (event) => {\n ignoreFocus.current = true;\n setInputValueState(\"\");\n\n if (onInputChange) {\n onInputChange(event, \"\", \"clear\");\n }\n\n handleValue(event, multiple ? [] : null, \"clear\");\n };\n\n const handleKeyDown = (other) => (event) => {\n if (other.onKeyDown) {\n other.onKeyDown(event);\n }\n\n if (event.defaultMuiPrevented) {\n return;\n }\n\n if (focusedTag !== -1 && [\"ArrowLeft\", \"ArrowRight\"].indexOf(event.key) === -1) {\n setFocusedTag(-1);\n focusTag(-1);\n }\n\n // Wait until IME is settled.\n if (event.which !== 229) {\n switch (event.key) {\n case \"Home\":\n if (popupOpen && handleHomeEndKeys) {\n // Prevent scroll of the page\n event.preventDefault();\n changeHighlightedIndex({ diff: \"start\", direction: \"next\", reason: \"keyboard\", event });\n }\n break;\n case \"End\":\n if (popupOpen && handleHomeEndKeys) {\n // Prevent scroll of the page\n event.preventDefault();\n changeHighlightedIndex({\n diff: \"end\",\n direction: \"previous\",\n reason: \"keyboard\",\n event,\n });\n }\n break;\n case \"PageUp\":\n // Prevent scroll of the page\n event.preventDefault();\n changeHighlightedIndex({\n diff: -pageSize,\n direction: \"previous\",\n reason: \"keyboard\",\n event,\n });\n handleOpen(event);\n break;\n case \"PageDown\":\n // Prevent scroll of the page\n event.preventDefault();\n changeHighlightedIndex({ diff: pageSize, direction: \"next\", reason: \"keyboard\", event });\n handleOpen(event);\n break;\n case \"ArrowDown\":\n // Prevent cursor move\n event.preventDefault();\n changeHighlightedIndex({ diff: 1, direction: \"next\", reason: \"keyboard\", event });\n handleOpen(event);\n break;\n case \"ArrowUp\":\n // Prevent cursor move\n event.preventDefault();\n changeHighlightedIndex({ diff: -1, direction: \"previous\", reason: \"keyboard\", event });\n handleOpen(event);\n break;\n case \"ArrowLeft\":\n handleFocusTag(event, \"previous\");\n break;\n case \"ArrowRight\":\n handleFocusTag(event, \"next\");\n break;\n case \"Enter\":\n if (highlightedIndexRef.current !== -1 && popupOpen) {\n const option = filteredOptions[highlightedIndexRef.current];\n const disabled = getOptionDisabled ? getOptionDisabled(option) : false;\n\n // Avoid early form validation, let the end-users continue filling the form.\n event.preventDefault();\n\n if (disabled) {\n return;\n }\n\n selectNewValue(event, option, \"selectOption\");\n\n // Move the selection to the end.\n if (autoComplete) {\n inputRef.current.setSelectionRange(inputRef.current.value.length, inputRef.current.value.length);\n }\n } else if (freeSolo && inputValue !== \"\" && inputValueIsSelectedValue === false) {\n if (multiple) {\n // Allow people to add new values before they submit the form.\n event.preventDefault();\n }\n selectNewValue(event, inputValue, \"createOption\", \"freeSolo\");\n }\n break;\n case \"Escape\":\n if (popupOpen) {\n // Avoid Opera to exit fullscreen mode.\n event.preventDefault();\n // Avoid the Modal to handle the event.\n event.stopPropagation();\n handleClose(event, \"escape\");\n } else if (clearOnEscape && (inputValue !== \"\" || (multiple && value.length > 0))) {\n // Avoid Opera to exit fullscreen mode.\n event.preventDefault();\n // Avoid the Modal to handle the event.\n event.stopPropagation();\n handleClear(event);\n }\n break;\n case \"Backspace\":\n if (multiple && !readOnly && inputValue === \"\" && value.length > 0) {\n const index = focusedTag === -1 ? value.length - 1 : focusedTag;\n const newValue = value.slice();\n newValue.splice(index, 1);\n handleValue(event, newValue, \"removeOption\", {\n option: value[index],\n });\n }\n break;\n case \"Delete\":\n if (multiple && !readOnly && inputValue === \"\" && value.length > 0 && focusedTag !== -1) {\n const index = focusedTag;\n const newValue = value.slice();\n newValue.splice(index, 1);\n handleValue(event, newValue, \"removeOption\", {\n option: value[index],\n });\n }\n break;\n default:\n }\n }\n };\n\n const handleFocus = (event) => {\n setFocused(true);\n\n if (openOnFocus && !ignoreFocus.current) {\n handleOpen(event);\n }\n };\n\n const handleBlur = (event) => {\n // Ignore the event when using the scrollbar with IE11\n if (unstable_isActiveElementInListbox(listboxRef)) {\n inputRef.current.focus();\n return;\n }\n\n setFocused(false);\n firstFocus.current = true;\n ignoreFocus.current = false;\n\n if (autoSelect && highlightedIndexRef.current !== -1 && popupOpen) {\n selectNewValue(event, filteredOptions[highlightedIndexRef.current], \"blur\");\n } else if (autoSelect && freeSolo && inputValue !== \"\") {\n selectNewValue(event, inputValue, \"blur\", \"freeSolo\");\n } else if (clearOnBlur) {\n resetInputValue(event, value);\n }\n\n handleClose(event, \"blur\");\n };\n\n const handleInputChange = (event) => {\n const newValue = event.target.value;\n\n if (inputValue !== newValue) {\n setInputValueState(newValue);\n setInputPristine(false);\n\n if (onInputChange) {\n onInputChange(event, newValue, \"input\");\n }\n }\n\n if (newValue === \"\") {\n if (!disableClearable && !multiple) {\n handleValue(event, null, \"clear\");\n }\n } else {\n handleOpen(event);\n }\n };\n\n const handleOptionMouseMove = (event) => {\n const index = Number(event.currentTarget.getAttribute(\"data-option-index\"));\n if (highlightedIndexRef.current !== index) {\n setHighlightedIndex({\n event,\n index,\n reason: \"mouse\",\n });\n }\n };\n\n const handleOptionTouchStart = (event) => {\n setHighlightedIndex({\n event,\n index: Number(event.currentTarget.getAttribute(\"data-option-index\")),\n reason: \"touch\",\n });\n isTouch.current = true;\n };\n\n const handleOptionClick = (event) => {\n const index = Number(event.currentTarget.getAttribute(\"data-option-index\"));\n selectNewValue(event, filteredOptions[index], \"selectOption\");\n\n isTouch.current = false;\n };\n\n const handleTagDelete = (index) => (event) => {\n const newValue = value.slice();\n newValue.splice(index, 1);\n handleValue(event, newValue, \"removeOption\", {\n option: value[index],\n });\n };\n\n const handlePopupIndicator = (event) => {\n if (open) {\n handleClose(event, \"toggleInput\");\n } else {\n handleOpen(event);\n }\n };\n\n // Prevent input blur when interacting with the combobox\n const handleMouseDown = (event) => {\n // Prevent focusing the input if click is anywhere outside the Autocomplete\n if (!event.currentTarget.contains(event.target)) {\n return;\n }\n if (event.target.getAttribute(\"id\") !== id) {\n event.preventDefault();\n }\n };\n\n // Focus the input when interacting with the combobox\n const handleClick = (event) => {\n // Prevent focusing the input if click is anywhere outside the Autocomplete\n if (!event.currentTarget.contains(event.target)) {\n return;\n }\n inputRef.current.focus();\n\n if (selectOnFocus && firstFocus.current && inputRef.current.selectionEnd - inputRef.current.selectionStart === 0) {\n inputRef.current.select();\n }\n\n firstFocus.current = false;\n };\n\n const handleInputMouseDown = (event) => {\n if (inputValue === \"\" || !open) {\n handlePopupIndicator(event);\n }\n };\n\n let dirty = freeSolo && inputValue.length > 0;\n dirty = dirty || (multiple ? value.length > 0 : value !== null);\n\n let groupedOptions = filteredOptions;\n if (groupBy) {\n // used to keep track of key and indexes in the result array\n const indexBy = new Map();\n let warn = false;\n\n groupedOptions = filteredOptions.reduce((acc, option, index) => {\n const group = groupBy(option);\n\n if (acc.length > 0 && acc[acc.length - 1].group === group) {\n acc[acc.length - 1].options.push(option);\n } else {\n if (process.env.NODE_ENV !== \"production\") {\n if (indexBy.get(group) && !warn) {\n console.warn(\n `MUI: The options provided combined with the \\`groupBy\\` method of ${componentName} returns duplicated headers.`,\n \"You can solve the issue by sorting the options with the output of `groupBy`.\",\n );\n warn = true;\n }\n indexBy.set(group, true);\n }\n\n acc.push({\n key: index,\n index,\n group,\n options: [option],\n });\n }\n\n return acc;\n }, []);\n }\n\n if (disabledProp && focused) {\n handleBlur();\n }\n\n return {\n getRootProps: (other = {}) => ({\n \"aria-owns\": listboxAvailable ? `${id}-listbox` : null,\n ...other,\n onKeyDown: handleKeyDown(other),\n onMouseDown: handleMouseDown,\n onClick: handleClick,\n }),\n getInputLabelProps: () => ({\n id: `${id}-label`,\n htmlFor: id,\n }),\n getInputProps: () => ({\n id,\n value: inputValue,\n onBlur: handleBlur,\n onFocus: handleFocus,\n onChange: handleInputChange,\n onMouseDown: handleInputMouseDown,\n // if open then this is handled imperatively so don't let react override\n // only have an opinion about this when closed\n \"aria-activedescendant\": popupOpen ? \"\" : null,\n \"aria-autocomplete\": autoComplete ? \"both\" : \"list\",\n \"aria-controls\": listboxAvailable ? `${id}-listbox` : undefined,\n \"aria-expanded\": listboxAvailable,\n // Disable browser's suggestion that might overlap with the popup.\n // Handle autocomplete but not autofill.\n autoComplete: \"off\",\n ref: inputRef,\n autoCapitalize: \"none\",\n spellCheck: \"false\",\n role: \"combobox\",\n disabled: disabledProp,\n }),\n getClearProps: () => ({\n tabIndex: -1,\n onClick: handleClear,\n }),\n getPopupIndicatorProps: () => ({\n tabIndex: -1,\n onClick: handlePopupIndicator,\n }),\n getTagProps: ({ index }) => ({\n key: index,\n \"data-tag-index\": index,\n tabIndex: -1,\n ...(!readOnly && { onDelete: handleTagDelete(index) }),\n }),\n getListboxProps: () => ({\n role: \"listbox\",\n id: `${id}-listbox`,\n \"aria-labelledby\": `${id}-label`,\n ref: handleListboxRef,\n onMouseDown: (event) => {\n // Prevent blur\n event.preventDefault();\n },\n }),\n getOptionProps: ({ index, option }) => {\n const selected = (multiple ? value : [value]).some(\n (value2) => value2 != null && isOptionEqualToValue(option, value2),\n );\n const disabled = getOptionDisabled ? getOptionDisabled(option) : false;\n\n return {\n key: getOptionLabel(option),\n tabIndex: -1,\n role: \"option\",\n id: `${id}-option-${index}`,\n onMouseMove: handleOptionMouseMove,\n onClick: handleOptionClick,\n onTouchStart: handleOptionTouchStart,\n \"data-option-index\": index,\n \"aria-disabled\": disabled,\n \"aria-selected\": selected,\n };\n },\n id,\n inputValue,\n value,\n dirty,\n expanded: popupOpen && anchorEl,\n popupOpen,\n focused: focused || focusedTag !== -1,\n anchorEl,\n setAnchorEl,\n focusedTag,\n groupedOptions,\n };\n}\n", "// from https://github.com/mui/material-ui/blob/312270bc71224067e1910bbee9f800b4a2469cc7/packages/mui-material/src/Autocomplete/Autocomplete.js\n// tag v5.13.6\n\nimport * as React from \"react\";\nimport PropTypes from \"prop-types\";\nimport clsx from \"clsx\";\nimport { chainPropTypes, integerPropType } from \"@mui/utils\";\nimport { unstable_composeClasses as composeClasses, createFilterOptions } from \"@mui/base\";\nimport useAutocomplete from \"./useAutocomplete\";\nimport { alpha } from \"@mui/system\";\nimport Popper from \"@mui/material/Popper\";\nimport ListSubheader from \"@mui/material/ListSubheader\";\nimport Paper from \"@mui/material/Paper\";\nimport IconButton from \"@mui/material/IconButton\";\nimport Chip from \"@mui/material/Chip\";\nimport { inputClasses } from \"@mui/material/Input\";\nimport { inputBaseClasses } from \"@mui/material/InputBase\";\nimport { outlinedInputClasses } from \"@mui/material/OutlinedInput\";\nimport { filledInputClasses } from \"@mui/material/FilledInput\";\nimport { X as ClearIcon, ChevronDown as ArrowDropDownIcon } from \"lucide-react\";\nimport { useThemeProps } from \"@mui/material/styles\";\nimport { styled } from \"@mui/material/styles\";\nimport { autocompleteClasses, getAutocompleteUtilityClass } from \"@mui/material/Autocomplete\";\nimport { capitalize } from \"@mui/material/utils\";\nimport { useForkRef } from \"@mui/material/utils\";\n\nconst useUtilityClasses = (ownerState) => {\n const {\n classes,\n disablePortal,\n expanded,\n focused,\n fullWidth,\n hasClearIcon,\n hasPopupIcon,\n inputFocused,\n popupOpen,\n size,\n } = ownerState;\n\n const slots = {\n root: [\n \"root\",\n expanded && \"expanded\",\n focused && \"focused\",\n fullWidth && \"fullWidth\",\n hasClearIcon && \"hasClearIcon\",\n hasPopupIcon && \"hasPopupIcon\",\n ],\n inputRoot: [\"inputRoot\"],\n input: [\"input\", inputFocused && \"inputFocused\"],\n tag: [\"tag\", `tagSize${capitalize(size)}`],\n endAdornment: [\"endAdornment\"],\n clearIndicator: [\"clearIndicator\"],\n popupIndicator: [\"popupIndicator\", popupOpen && \"popupIndicatorOpen\"],\n popper: [\"popper\", disablePortal && \"popperDisablePortal\"],\n paper: [\"paper\"],\n listbox: [\"listbox\"],\n loading: [\"loading\"],\n noOptions: [\"noOptions\"],\n option: [\"option\"],\n groupLabel: [\"groupLabel\"],\n groupUl: [\"groupUl\"],\n };\n\n return composeClasses(slots, getAutocompleteUtilityClass, classes);\n};\n\nconst AutocompleteRoot = styled(\"div\", {\n name: \"MuiAutocomplete\",\n slot: \"Root\",\n overridesResolver: (props, styles) => {\n const { ownerState } = props;\n const { fullWidth, hasClearIcon, hasPopupIcon, inputFocused, size } = ownerState;\n\n return [\n { [`& .${autocompleteClasses.tag}`]: styles.tag },\n { [`& .${autocompleteClasses.tag}`]: styles[`tagSize${capitalize(size)}`] },\n { [`& .${autocompleteClasses.inputRoot}`]: styles.inputRoot },\n { [`& .${autocompleteClasses.input}`]: styles.input },\n { [`& .${autocompleteClasses.input}`]: inputFocused && styles.inputFocused },\n styles.root,\n fullWidth && styles.fullWidth,\n hasPopupIcon && styles.hasPopupIcon,\n hasClearIcon && styles.hasClearIcon,\n ];\n },\n})(({ ownerState }) => ({\n [`&.${autocompleteClasses.focused} .${autocompleteClasses.clearIndicator}`]: {\n visibility: \"visible\",\n },\n /* Avoid double tap issue on iOS */\n \"@media (pointer: fine)\": {\n [`&:hover .${autocompleteClasses.clearIndicator}`]: {\n visibility: \"visible\",\n },\n },\n ...(ownerState.fullWidth && {\n width: \"100%\",\n }),\n [`& .${autocompleteClasses.tag}`]: {\n margin: 3,\n maxWidth: \"calc(100% - 6px)\",\n ...(ownerState.size === \"small\" && {\n margin: 2,\n maxWidth: \"calc(100% - 4px)\",\n }),\n },\n [`& .${autocompleteClasses.inputRoot}`]: {\n flexWrap: \"wrap\",\n [`.${autocompleteClasses.hasPopupIcon}&, .${autocompleteClasses.hasClearIcon}&`]: {\n paddingRight: 26 + 4,\n },\n [`.${autocompleteClasses.hasPopupIcon}.${autocompleteClasses.hasClearIcon}&`]: {\n paddingRight: 52 + 4,\n },\n [`& .${autocompleteClasses.input}`]: {\n width: 0,\n minWidth: 30,\n },\n },\n [`& .${inputClasses.root}`]: {\n paddingBottom: 1,\n \"& .MuiInput-input\": {\n padding: \"4px 4px 4px 0px\",\n },\n },\n [`& .${inputClasses.root}.${inputBaseClasses.sizeSmall}`]: {\n [`& .${inputClasses.input}`]: {\n padding: \"2px 4px 3px 0\",\n },\n },\n [`& .${outlinedInputClasses.root}`]: {\n padding: 9,\n [`.${autocompleteClasses.hasPopupIcon}&, .${autocompleteClasses.hasClearIcon}&`]: {\n paddingRight: 26 + 4 + 9,\n },\n [`.${autocompleteClasses.hasPopupIcon}.${autocompleteClasses.hasClearIcon}&`]: {\n paddingRight: 52 + 4 + 9,\n },\n [`& .${autocompleteClasses.input}`]: {\n padding: \"7.5px 4px 7.5px 5px\",\n },\n [`& .${autocompleteClasses.endAdornment}`]: {\n right: 9,\n },\n },\n [`& .${outlinedInputClasses.root}.${inputBaseClasses.sizeSmall}`]: {\n // Don't specify paddingRight, as it overrides the default value set when there is only\n // one of the popup or clear icon as the specificity is equal so the latter one wins\n paddingTop: 6,\n paddingBottom: 6,\n paddingLeft: 6,\n [`& .${autocompleteClasses.input}`]: {\n padding: \"2.5px 4px 2.5px 8px\",\n },\n },\n [`& .${filledInputClasses.root}`]: {\n paddingTop: 19,\n paddingLeft: 8,\n [`.${autocompleteClasses.hasPopupIcon}&, .${autocompleteClasses.hasClearIcon}&`]: {\n paddingRight: 26 + 4 + 9,\n },\n [`.${autocompleteClasses.hasPopupIcon}.${autocompleteClasses.hasClearIcon}&`]: {\n paddingRight: 52 + 4 + 9,\n },\n [`& .${filledInputClasses.input}`]: {\n padding: \"7px 4px\",\n },\n [`& .${autocompleteClasses.endAdornment}`]: {\n right: 9,\n },\n },\n [`& .${filledInputClasses.root}.${inputBaseClasses.sizeSmall}`]: {\n paddingBottom: 1,\n [`& .${filledInputClasses.input}`]: {\n padding: \"2.5px 4px\",\n },\n },\n [`& .${inputBaseClasses.hiddenLabel}`]: {\n paddingTop: 8,\n },\n [`& .${filledInputClasses.root}.${inputBaseClasses.hiddenLabel}`]: {\n paddingTop: 0,\n paddingBottom: 0,\n [`& .${autocompleteClasses.input}`]: {\n paddingTop: 16,\n paddingBottom: 17,\n },\n },\n [`& .${filledInputClasses.root}.${inputBaseClasses.hiddenLabel}.${inputBaseClasses.sizeSmall}`]: {\n [`& .${autocompleteClasses.input}`]: {\n paddingTop: 8,\n paddingBottom: 9,\n },\n },\n [`& .${autocompleteClasses.input}`]: {\n flexGrow: 1,\n textOverflow: \"ellipsis\",\n opacity: 0,\n ...(ownerState.inputFocused && {\n opacity: 1,\n }),\n },\n}));\n\nconst AutocompleteEndAdornment = styled(\"div\", {\n name: \"MuiAutocomplete\",\n slot: \"EndAdornment\",\n overridesResolver: (props, styles) => styles.endAdornment,\n})({\n // We use a position absolute to support wrapping tags.\n position: \"absolute\",\n right: 0,\n top: \"calc(50% - 14px)\", // Center vertically\n});\n\nconst AutocompleteClearIndicator = styled(IconButton, {\n name: \"MuiAutocomplete\",\n slot: \"ClearIndicator\",\n overridesResolver: (props, styles) => styles.clearIndicator,\n})({\n marginRight: -2,\n padding: 4,\n visibility: \"hidden\",\n});\n\nconst AutocompletePopupIndicator = styled(IconButton, {\n name: \"MuiAutocomplete\",\n slot: \"PopupIndicator\",\n overridesResolver: ({ ownerState }, styles) => ({\n ...styles.popupIndicator,\n ...(ownerState.popupOpen && styles.popupIndicatorOpen),\n }),\n})(({ ownerState }) => ({\n padding: 2,\n marginRight: -2,\n ...(ownerState.popupOpen && {\n transform: \"rotate(180deg)\",\n }),\n}));\n\nconst AutocompletePopper = styled(Popper, {\n name: \"MuiAutocomplete\",\n slot: \"Popper\",\n overridesResolver: (props, styles) => {\n const { ownerState } = props;\n\n return [\n { [`& .${autocompleteClasses.option}`]: styles.option },\n styles.popper,\n ownerState.disablePortal && styles.popperDisablePortal,\n ];\n },\n})(({ theme, ownerState }) => ({\n zIndex: (theme.vars || theme).zIndex.modal,\n ...(ownerState.disablePortal && {\n position: \"absolute\",\n }),\n}));\n\nconst AutocompletePaper = styled(Paper, {\n name: \"MuiAutocomplete\",\n slot: \"Paper\",\n overridesResolver: (props, styles) => styles.paper,\n})(({ theme }) => ({\n ...theme.typography.body1,\n overflow: \"auto\",\n}));\n\nconst AutocompleteLoading = styled(\"div\", {\n name: \"MuiAutocomplete\",\n slot: \"Loading\",\n overridesResolver: (props, styles) => styles.loading,\n})(({ theme }) => ({\n color: (theme.vars || theme).palette.text.secondary,\n padding: \"14px 16px\",\n}));\n\nconst AutocompleteNoOptions = styled(\"div\", {\n name: \"MuiAutocomplete\",\n slot: \"NoOptions\",\n overridesResolver: (props, styles) => styles.noOptions,\n})(({ theme }) => ({\n color: (theme.vars || theme).palette.text.secondary,\n padding: \"14px 16px\",\n}));\n\nconst AutocompleteListbox = styled(\"div\", {\n name: \"MuiAutocomplete\",\n slot: \"Listbox\",\n overridesResolver: (props, styles) => styles.listbox,\n})(({ theme }) => ({\n listStyle: \"none\",\n margin: 0,\n padding: \"8px 0\",\n maxHeight: \"40vh\",\n overflow: \"auto\",\n position: \"relative\",\n [`& .${autocompleteClasses.option}`]: {\n minHeight: 48,\n display: \"flex\",\n overflow: \"hidden\",\n justifyContent: \"flex-start\",\n alignItems: \"center\",\n cursor: \"pointer\",\n paddingTop: 6,\n boxSizing: \"border-box\",\n outline: \"0\",\n WebkitTapHighlightColor: \"transparent\",\n paddingBottom: 6,\n paddingLeft: 16,\n paddingRight: 16,\n [theme.breakpoints.up(\"sm\")]: {\n minHeight: \"auto\",\n },\n [`&.${autocompleteClasses.focused}`]: {\n backgroundColor: (theme.vars || theme).palette.action.hover,\n // Reset on touch devices, it doesn't add specificity\n \"@media (hover: none)\": {\n backgroundColor: \"transparent\",\n },\n },\n '&[aria-disabled=\"true\"]': {\n opacity: (theme.vars || theme).palette.action.disabledOpacity,\n pointerEvents: \"none\",\n },\n [`&.${autocompleteClasses.focusVisible}`]: {\n backgroundColor: (theme.vars || theme).palette.action.focus,\n },\n '&[aria-selected=\"true\"]': {\n backgroundColor: theme.vars\n ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})`\n : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),\n [`&.${autocompleteClasses.focused}`]: {\n backgroundColor: theme.vars\n ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))`\n : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n \"@media (hover: none)\": {\n backgroundColor: (theme.vars || theme).palette.action.selected,\n },\n },\n [`&.${autocompleteClasses.focusVisible}`]: {\n backgroundColor: theme.vars\n ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))`\n : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity),\n },\n },\n },\n}));\n\nconst AutocompleteGroupLabel = styled(ListSubheader, {\n name: \"MuiAutocomplete\",\n slot: \"GroupLabel\",\n overridesResolver: (props, styles) => styles.groupLabel,\n})(({ theme }) => ({\n backgroundColor: (theme.vars || theme).palette.background.paper,\n top: -8,\n}));\n\nconst AutocompleteGroupUl = styled(\"ul\", {\n name: \"MuiAutocomplete\",\n slot: \"GroupUl\",\n overridesResolver: (props, styles) => styles.groupUl,\n})({\n padding: 0,\n [`& .${autocompleteClasses.option}`]: {\n paddingLeft: 24,\n },\n});\n\nexport { createFilterOptions };\n\nconst Autocomplete = React.forwardRef(function Autocomplete(inProps, ref) {\n const props = useThemeProps({ props: inProps, name: \"MuiAutocomplete\" });\n /* eslint-disable @typescript-eslint/no-unused-vars */\n const {\n autoComplete = false,\n autoHighlight = false,\n autoSelect = false,\n blurOnSelect = false,\n ChipProps,\n className,\n clearIcon = ,\n clearOnBlur = !props.freeSolo,\n clearOnEscape = false,\n clearText = \"Clear\",\n closeText = \"Close\",\n componentsProps = {},\n defaultValue = props.multiple ? [] : null,\n disableClearable = false,\n disableCloseOnSelect = false,\n disabled = false,\n disabledItemsFocusable = false,\n disableListWrap = false,\n disablePortal = false,\n filterOptions,\n filterSelectedOptions = false,\n forcePopupIcon = \"auto\",\n freeSolo = false,\n fullWidth = false,\n getLimitTagsText = (more) => `+${more}`,\n getOptionDisabled,\n getOptionLabel = (option) => option.label ?? option,\n isOptionEqualToValue,\n groupBy,\n handleHomeEndKeys = !props.freeSolo,\n id: idProp,\n includeInputInList = false,\n inputValue: inputValueProp,\n limitTags = -1,\n ListboxComponent = \"ul\",\n ListboxProps,\n loading = false,\n loadingText = \"Loading\u2026\",\n multiple = false,\n noOptionsText = \"No options\",\n onChange,\n onClose,\n onHighlightChange,\n onInputChange,\n onOpen,\n open,\n openOnFocus = false,\n openText = \"Open\",\n options,\n PaperComponent = Paper,\n PopperComponent = Popper,\n popupIcon = ,\n readOnly = false,\n renderGroup: renderGroupProp,\n renderInput,\n renderOption: renderOptionProp,\n renderTags,\n selectOnFocus = !props.freeSolo,\n size = \"medium\",\n slotProps = {},\n value: valueProp,\n ...other\n } = props;\n /* eslint-enable @typescript-eslint/no-unused-vars */\n\n const {\n getRootProps,\n getInputProps,\n getInputLabelProps,\n getPopupIndicatorProps,\n getClearProps,\n getTagProps,\n getListboxProps,\n getOptionProps,\n value,\n dirty,\n expanded,\n id,\n popupOpen,\n focused,\n focusedTag,\n anchorEl,\n setAnchorEl,\n inputValue,\n groupedOptions,\n } = useAutocomplete({ ...props, componentName: \"Autocomplete\" });\n\n const hasClearIcon = !disableClearable && !disabled && dirty && !readOnly;\n const hasPopupIcon = (!freeSolo || forcePopupIcon === true) && forcePopupIcon !== false;\n\n const { onMouseDown: handleInputMouseDown } = getInputProps();\n const { ref: externalListboxRef } = ListboxProps ?? {};\n const { ref: listboxRef, ...otherListboxProps } = getListboxProps();\n\n const combinedListboxRef = useForkRef(listboxRef, externalListboxRef);\n\n // If you modify this, make sure to keep the `AutocompleteOwnerState` type in sync.\n const ownerState = {\n ...props,\n disablePortal,\n expanded,\n focused,\n fullWidth,\n hasClearIcon,\n hasPopupIcon,\n inputFocused: focusedTag === -1,\n popupOpen,\n size,\n };\n\n const classes = useUtilityClasses(ownerState);\n\n let startAdornment;\n\n if (multiple && value.length > 0) {\n const getCustomizedTagProps = (params) => ({\n className: classes.tag,\n disabled,\n ...getTagProps(params),\n });\n\n if (renderTags) {\n startAdornment = renderTags(value, getCustomizedTagProps, ownerState);\n } else {\n startAdornment = value.map((option, index) => (\n \n ));\n }\n }\n\n if (limitTags > -1 && Array.isArray(startAdornment)) {\n const more = startAdornment.length - limitTags;\n if (!focused && more > 0) {\n startAdornment = startAdornment.splice(0, limitTags);\n startAdornment.push(\n \n {getLimitTagsText(more)}\n ,\n );\n }\n }\n\n const defaultRenderGroup = (params) => (\n
  • \n \n {params.group}\n \n \n {params.children}\n \n
  • \n );\n\n const renderGroup = renderGroupProp || defaultRenderGroup;\n const defaultRenderOption = (props2, option) =>
  • {getOptionLabel(option)}
  • ;\n const renderOption = renderOptionProp || defaultRenderOption;\n\n const renderListOption = (option, index) => {\n const optionProps = getOptionProps({ option, index });\n\n return renderOption({ ...optionProps, className: classes.option }, option, {\n selected: optionProps[\"aria-selected\"],\n index,\n inputValue,\n });\n };\n\n const clearIndicatorSlotProps = slotProps.clearIndicator ?? componentsProps.clearIndicator;\n const paperSlotProps = slotProps.paper ?? componentsProps.paper;\n const popperSlotProps = slotProps.popper ?? componentsProps.popper;\n const popupIndicatorSlotProps = slotProps.popupIndicator ?? componentsProps.popupIndicator;\n\n return (\n \n \n {renderInput({\n id,\n disabled,\n fullWidth: true,\n size: size === \"small\" ? \"small\" : undefined,\n InputLabelProps: getInputLabelProps(),\n InputProps: {\n ref: setAnchorEl,\n className: classes.inputRoot,\n startAdornment,\n onClick: (event) => {\n if (event.target === event.currentTarget) {\n handleInputMouseDown(event);\n }\n },\n ...((hasClearIcon || hasPopupIcon) && {\n endAdornment: (\n \n {hasClearIcon ? (\n \n {clearIcon}\n \n ) : null}\n\n {hasPopupIcon ? (\n \n {popupIcon}\n \n ) : null}\n \n ),\n }),\n },\n inputProps: {\n className: classes.input,\n disabled,\n readOnly,\n ...getInputProps(),\n },\n })}\n \n {anchorEl ? (\n \n \n {loading && groupedOptions.length === 0 ? (\n \n {loadingText}\n \n ) : null}\n {groupedOptions.length === 0 && !freeSolo && !loading ? (\n {\n // Prevent input blur when interacting with the \"no options\" content\n event.preventDefault();\n }}\n >\n {noOptionsText}\n \n ) : null}\n {groupedOptions.length > 0 ? (\n \n {groupedOptions.map((option, index) => {\n if (groupBy) {\n return renderGroup({\n key: option.key,\n group: option.group,\n children: option.options.map((option2, index2) =>\n renderListOption(option2, option.index + index2),\n ),\n });\n }\n return renderListOption(option, index);\n })}\n \n ) : null}\n \n \n ) : null}\n \n );\n});\n\nAutocomplete.propTypes /* remove-proptypes */ = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the d.ts file and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * If `true`, the portion of the selected suggestion that has not been typed by the user,\n * known as the completion string, appears inline after the input cursor in the textbox.\n * The inline completion string is visually highlighted and has a selected state.\n * @default false\n */\n autoComplete: PropTypes.bool,\n /**\n * If `true`, the first option is automatically highlighted.\n * @default false\n */\n autoHighlight: PropTypes.bool,\n /**\n * If `true`, the selected option becomes the value of the input\n * when the Autocomplete loses focus unless the user chooses\n * a different option or changes the character string in the input.\n *\n * When using `freeSolo` mode, the typed value will be the input value\n * if the Autocomplete loses focus without highlighting an option.\n * @default false\n */\n autoSelect: PropTypes.bool,\n /**\n * Control if the input should be blurred when an option is selected:\n *\n * - `false` the input is not blurred.\n * - `true` the input is always blurred.\n * - `touch` the input is blurred after a touch event.\n * - `mouse` the input is blurred after a mouse event.\n * @default false\n */\n blurOnSelect: PropTypes.oneOfType([PropTypes.oneOf([\"mouse\", \"touch\"]), PropTypes.bool]),\n /**\n * Props applied to the [`Chip`](/material-ui/api/chip/) element.\n */\n ChipProps: PropTypes.object,\n /**\n * Override or extend the styles applied to the component.\n */\n classes: PropTypes.object,\n /**\n * @ignore\n */\n className: PropTypes.string,\n /**\n * The icon to display in place of the default clear icon.\n * @default \n */\n clearIcon: PropTypes.node,\n /**\n * If `true`, the input's text is cleared on blur if no value is selected.\n *\n * Set to `true` if you want to help the user enter a new value.\n * Set to `false` if you want to help the user resume their search.\n * @default !props.freeSolo\n */\n clearOnBlur: PropTypes.bool,\n /**\n * If `true`, clear all values when the user presses escape and the popup is closed.\n * @default false\n */\n clearOnEscape: PropTypes.bool,\n /**\n * Override the default text for the *clear* icon button.\n *\n * For localization purposes, you can use the provided [translations](/material-ui/guides/localization/).\n * @default 'Clear'\n */\n clearText: PropTypes.string,\n /**\n * Override the default text for the *close popup* icon button.\n *\n * For localization purposes, you can use the provided [translations](/material-ui/guides/localization/).\n * @default 'Close'\n */\n closeText: PropTypes.string,\n /**\n * The props used for each slot inside.\n * @default {}\n */\n componentsProps: PropTypes.shape({\n clearIndicator: PropTypes.object,\n paper: PropTypes.object,\n popper: PropTypes.object,\n popupIndicator: PropTypes.object,\n }),\n /**\n * The default value. Use when the component is not controlled.\n * @default props.multiple ? [] : null\n */\n defaultValue: chainPropTypes(PropTypes.any, (props) => {\n if (props.multiple && props.defaultValue !== undefined && !Array.isArray(props.defaultValue)) {\n return new Error(\n [\n \"MUI: The Autocomplete expects the `defaultValue` prop to be an array when `multiple={true}` or undefined.\",\n `However, ${props.defaultValue} was provided.`,\n ].join(\"\\n\"),\n );\n }\n return null;\n }),\n /**\n * If `true`, the input can't be cleared.\n * @default false\n */\n disableClearable: PropTypes.bool,\n /**\n * If `true`, the popup won't close when a value is selected.\n * @default false\n */\n disableCloseOnSelect: PropTypes.bool,\n /**\n * If `true`, the component is disabled.\n * @default false\n */\n disabled: PropTypes.bool,\n /**\n * If `true`, will allow focus on disabled items.\n * @default false\n */\n disabledItemsFocusable: PropTypes.bool,\n /**\n * If `true`, the list box in the popup will not wrap focus.\n * @default false\n */\n disableListWrap: PropTypes.bool,\n /**\n * If `true`, the `Popper` content will be under the DOM hierarchy of the parent component.\n * @default false\n */\n disablePortal: PropTypes.bool,\n /**\n * A function that determines the filtered options to be rendered on search.\n *\n * @default createFilterOptions()\n * @param {T[]} options The options to render.\n * @param {object} state The state of the component.\n * @returns {T[]}\n */\n filterOptions: PropTypes.func,\n /**\n * If `true`, hide the selected options from the list box.\n * @default false\n */\n filterSelectedOptions: PropTypes.bool,\n /**\n * Force the visibility display of the popup icon.\n * @default 'auto'\n */\n forcePopupIcon: PropTypes.oneOfType([PropTypes.oneOf([\"auto\"]), PropTypes.bool]),\n /**\n * If `true`, the Autocomplete is free solo, meaning that the user input is not bound to provided options.\n * @default false\n */\n freeSolo: PropTypes.bool,\n /**\n * If `true`, the input will take up the full width of its container.\n * @default false\n */\n fullWidth: PropTypes.bool,\n /**\n * The label to display when the tags are truncated (`limitTags`).\n *\n * @param {number} more The number of truncated tags.\n * @returns {ReactNode}\n * @default (more) => `+${more}`\n */\n getLimitTagsText: PropTypes.func,\n /**\n * Used to determine the disabled state for a given option.\n *\n * @param {T} option The option to test.\n * @returns {boolean}\n */\n getOptionDisabled: PropTypes.func,\n /**\n * Used to determine the string value for a given option.\n * It's used to fill the input (and the list box options if `renderOption` is not provided).\n *\n * If used in free solo mode, it must accept both the type of the options and a string.\n *\n * @param {T} option\n * @returns {string}\n * @default (option) => option.label ?? option\n */\n getOptionLabel: PropTypes.func,\n /**\n * If provided, the options will be grouped under the returned string.\n * The groupBy value is also used as the text for group headings when `renderGroup` is not provided.\n *\n * @param {T} options The options to group.\n * @returns {string}\n */\n groupBy: PropTypes.func,\n /**\n * If `true`, the component handles the \"Home\" and \"End\" keys when the popup is open.\n * It should move focus to the first option and last option, respectively.\n * @default !props.freeSolo\n */\n handleHomeEndKeys: PropTypes.bool,\n /**\n * This prop is used to help implement the accessibility logic.\n * If you don't provide an id it will fall back to a randomly generated one.\n */\n id: PropTypes.string,\n /**\n * If `true`, the highlight can move to the input.\n * @default false\n */\n includeInputInList: PropTypes.bool,\n /**\n * The input value.\n */\n inputValue: PropTypes.string,\n /**\n * Used to determine if the option represents the given value.\n * Uses strict equality by default.\n * \u26A0\uFE0F Both arguments need to be handled, an option can only match with one value.\n *\n * @param {T} option The option to test.\n * @param {T} value The value to test against.\n * @returns {boolean}\n */\n isOptionEqualToValue: PropTypes.func,\n /**\n * The maximum number of tags that will be visible when not focused.\n * Set `-1` to disable the limit.\n * @default -1\n */\n limitTags: integerPropType,\n /**\n * The component used to render the listbox.\n * @default 'ul'\n */\n ListboxComponent: PropTypes.elementType,\n /**\n * Props applied to the Listbox element.\n */\n ListboxProps: PropTypes.object,\n /**\n * If `true`, the component is in a loading state.\n * This shows the `loadingText` in place of suggestions (only if there are no suggestions to show, e.g. `options` are empty).\n * @default false\n */\n loading: PropTypes.bool,\n /**\n * Text to display when in a loading state.\n *\n * For localization purposes, you can use the provided [translations](/material-ui/guides/localization/).\n * @default 'Loading\u2026'\n */\n loadingText: PropTypes.node,\n /**\n * If `true`, `value` must be an array and the menu will support multiple selections.\n * @default false\n */\n multiple: PropTypes.bool,\n /**\n * Text to display when there are no options.\n *\n * For localization purposes, you can use the provided [translations](/material-ui/guides/localization/).\n * @default 'No options'\n */\n noOptionsText: PropTypes.node,\n /**\n * Callback fired when the value changes.\n *\n * @param {React.SyntheticEvent} event The event source of the callback.\n * @param {T|T[]} value The new value of the component.\n * @param {string} reason One of \"createOption\", \"selectOption\", \"removeOption\", \"blur\" or \"clear\".\n * @param {string} [details]\n */\n onChange: PropTypes.func,\n /**\n * Callback fired when the popup requests to be closed.\n * Use in controlled mode (see open).\n *\n * @param {React.SyntheticEvent} event The event source of the callback.\n * @param {string} reason Can be: `\"toggleInput\"`, `\"escape\"`, `\"selectOption\"`, `\"removeOption\"`, `\"blur\"`.\n */\n onClose: PropTypes.func,\n /**\n * Callback fired when the highlight option changes.\n *\n * @param {React.SyntheticEvent} event The event source of the callback.\n * @param {T} option The highlighted option.\n * @param {string} reason Can be: `\"keyboard\"`, `\"auto\"`, `\"mouse\"`, `\"touch\"`.\n */\n onHighlightChange: PropTypes.func,\n /**\n * Callback fired when the input value changes.\n *\n * @param {React.SyntheticEvent} event The event source of the callback.\n * @param {string} value The new value of the text input.\n * @param {string} reason Can be: `\"input\"` (user input), `\"reset\"` (programmatic change), `\"clear\"`.\n */\n onInputChange: PropTypes.func,\n /**\n * Callback fired when the popup requests to be opened.\n * Use in controlled mode (see open).\n *\n * @param {React.SyntheticEvent} event The event source of the callback.\n */\n onOpen: PropTypes.func,\n /**\n * If `true`, the component is shown.\n */\n open: PropTypes.bool,\n /**\n * If `true`, the popup will open on input focus.\n * @default false\n */\n openOnFocus: PropTypes.bool,\n /**\n * Override the default text for the *open popup* icon button.\n *\n * For localization purposes, you can use the provided [translations](/material-ui/guides/localization/).\n * @default 'Open'\n */\n openText: PropTypes.string,\n /**\n * Array of options.\n */\n options: PropTypes.array.isRequired,\n /**\n * The component used to render the body of the popup.\n * @default Paper\n */\n PaperComponent: PropTypes.elementType,\n /**\n * The component used to position the popup.\n * @default Popper\n */\n PopperComponent: PropTypes.elementType,\n /**\n * The icon to display in place of the default popup icon.\n * @default \n */\n popupIcon: PropTypes.node,\n /**\n * If `true`, the component becomes readonly. It is also supported for multiple tags where the tag cannot be deleted.\n * @default false\n */\n readOnly: PropTypes.bool,\n /**\n * Render the group.\n *\n * @param {AutocompleteRenderGroupParams} params The group to render.\n * @returns {ReactNode}\n */\n renderGroup: PropTypes.func,\n /**\n * Render the input.\n *\n * @param {object} params\n * @returns {ReactNode}\n */\n renderInput: PropTypes.func.isRequired,\n /**\n * Render the option, use `getOptionLabel` by default.\n *\n * @param {object} props The props to apply on the li element.\n * @param {T} option The option to render.\n * @param {object} state The state of the component.\n * @returns {ReactNode}\n */\n renderOption: PropTypes.func,\n /**\n * Render the selected value.\n *\n * @param {T[]} value The `value` provided to the component.\n * @param {function} getTagProps A tag props getter.\n * @param {object} ownerState The state of the Autocomplete component.\n * @returns {ReactNode}\n */\n renderTags: PropTypes.func,\n /**\n * If `true`, the input's text is selected on focus.\n * It helps the user clear the selected value.\n * @default !props.freeSolo\n */\n selectOnFocus: PropTypes.bool,\n /**\n * The size of the component.\n * @default 'medium'\n */\n size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([\n PropTypes.oneOf([\"small\", \"medium\"]),\n PropTypes.string,\n ]),\n /**\n * The props used for each slot inside.\n * @default {}\n */\n slotProps: PropTypes.shape({\n clearIndicator: PropTypes.object,\n paper: PropTypes.object,\n popper: PropTypes.object,\n popupIndicator: PropTypes.object,\n }),\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])),\n PropTypes.func,\n PropTypes.object,\n ]),\n /**\n * The value of the autocomplete.\n *\n * The value must have reference equality with the option in order to be selected.\n * You can customize the equality behavior with the `isOptionEqualToValue` prop.\n */\n value: chainPropTypes(PropTypes.any, (props) => {\n if (props.multiple && props.value !== undefined && !Array.isArray(props.value)) {\n return new Error(\n [\n \"MUI: The Autocomplete expects the `value` prop to be an array when `multiple={true}` or undefined.\",\n `However, ${props.value} was provided.`,\n ].join(\"\\n\"),\n );\n }\n return null;\n }),\n};\n\nexport default Autocomplete;\n", "const parser = module.exports = {};\n\nfunction diff(a1, a2) {\n\treturn a1.concat(a2).filter((val, index, arr) => {\n\t\treturn arr.indexOf(val) === arr.lastIndexOf(val);\n\t});\n}\n\nconst lc = value => value.toLowerCase();\n\nparser.parseName = function (name, opts = {}) {\n\tlet extraCompound = [];\n\tlet extraSalutations = [];\n\tlet extraSuffixes = [];\n\tlet ignoreCompound = [];\n\tlet ignoreSalutation = [];\n\tlet ignoreSuffix = [];\n\n\tif (Array.isArray(opts)) {\n\t\tignoreSuffix = opts.map(v => v.toLowerCase());\n\t} else {\n\t\t({\n\t\t\textraCompound = [],\n\t\t\textraSalutations = [], \n\t\t\textraSuffixes = [], \n\t\t\tignoreCompound = [],\n\t\t\tignoreSalutation = [],\n\t\t\tignoreSuffix = []\n\t\t} = opts);\n\n\t\textraCompound = extraCompound.map(lc);\n\t\textraSalutations = extraSalutations.map(lc);\n\t\textraSuffixes = extraSuffixes.map(lc);\n\t\tignoreCompound = ignoreCompound.map(lc);\n\t\tignoreSalutation = ignoreSalutation.map(lc);\n\t\tignoreSuffix = ignoreSuffix.map(lc);\n\t}\n\tconst salutations = ['mr', 'master', 'mister', 'mrs', 'miss', 'ms', 'dr', 'prof', 'rev', 'fr', 'judge', 'honorable', 'hon', 'tuan', 'sr', 'srta', 'br', 'pr', 'mx', 'sra', ...extraSalutations].filter(salutation => !ignoreSalutation.includes(salutation));\n\tconst suffixes = ['i', 'ii', 'iii', 'iv', 'v', 'senior', 'junior', 'jr', 'sr', 'phd', 'apr', 'rph', 'pe', 'md', 'ma', 'dmd', 'cme', 'qc', 'kc', ...extraSuffixes].filter(suffix => !ignoreSuffix.includes(suffix));\n\tconst compound = ['vere', 'von', 'van', 'de', 'del', 'della', 'der', 'den', 'di', 'da', 'pietro', 'vanden', 'du', 'st.', 'st', 'la', 'lo', 'ter', 'bin', 'ibn', 'te', 'ten', 'op', 'ben', 'al', ...extraCompound].filter(compound => !ignoreCompound.includes(compound));\n\n\tlet parts = name\n\t\t.trim()\n\t\t.replace(/\\b\\s+(,\\s+)\\b/, '$1') // fix name , suffix -> name, suffix\n\t\t.replace(/\\b,\\b/, ', ') // fix name,suffix -> name, suffix\n\t// look for quoted compound names\n\tparts = (parts.match(/[^\\s\"]+|\"[^\"]+\"/g) || parts.split(/\\s+/)).map(n => n.match(/^\".*\"$/) ? n.slice(1, -1) : n)\n\tconst attrs = {};\n\n\tif (!parts.length) {\n\t\treturn attrs;\n\t}\n\n\tif (parts.length === 1) {\n\t\tattrs.firstName = parts[0];\n\t}\n\n\t//handle suffix first always, remove trailing comma if there is one\n\tif (parts.length > 1 && suffixes.indexOf(parts[parts.length - 1].toLowerCase().replace(/\\./g, '')) > -1) {\n\t\tattrs.suffix = parts.pop();\n\t\tparts[parts.length - 1] = parts[parts.length - 1].replace(',', '');\n\t}\n\n\t//look for a comma to know we have last name first format\n\tconst firstNameFirstFormat = parts.every(part => {\n\t\treturn part.indexOf(',') === -1;\n\t});\n\n\tif (!firstNameFirstFormat) {\n\t\t//last name first format\n\t\t//assuming salutations are never used in this format\n\n\t\t//tracker variable for where first name begins in parts array\n\t\tlet firstNameIndex;\n\n\t\t//location of first comma will separate last name from rest\n\t\t//join all parts leading to first comma as last name\n\t\tconst lastName = parts.reduce((lastName, current, index) => {\n\t\t\tif (!Array.isArray(lastName)) {\n\t\t\t\treturn lastName;\n\t\t\t}\n\t\t\tif (current.indexOf(',') === -1) {\n\t\t\t\tlastName.push(current);\n\t\t\t\treturn lastName;\n\t\t\t} else {\n\t\t\t\tcurrent = current.replace(',', '');\n\n\t\t\t\t// handle case where suffix is included in part of last name (ie: 'Hearst Jr., Willian Randolph')\n\t\t\t\tif (suffixes.indexOf(current.toLowerCase().replace(/\\./g, '')) > -1) {\n\t\t\t\t\tattrs.suffix = current;\n\t\t\t\t} else {\n\t\t\t\t\tlastName.push(current);\n\t\t\t\t}\n\n\t\t\t\tfirstNameIndex = index + 1;\n\t\t\t\treturn lastName.join(' ');\n\t\t\t}\n\t\t}, []);\n\n\t\tattrs.lastName = lastName;\n\n\t\tvar remainingParts = parts.slice(firstNameIndex);\n\t\tif (remainingParts.length > 1) {\n\t\t\tattrs.firstName = remainingParts.shift();\n\t\t\tattrs.middleName = remainingParts.join(' ');\n\t\t} else if (remainingParts.length) {\n\t\t\tattrs.firstName = remainingParts[0];\n\t\t}\n\n\t\t//create full name from attrs object\n\t\tconst nameWords = [];\n\t\tif (attrs.firstName) {\n\t\t\tnameWords.push(attrs.firstName);\n\t\t}\n\t\tif (attrs.middleName) {\n\t\t\tnameWords.push(attrs.middleName)\n\t\t}\n\t\tnameWords.push(attrs.lastName)\n\t\tif (attrs.suffix) {\n\t\t\tnameWords.push(attrs.suffix);\n\t\t}\n\t\tattrs.fullName = nameWords.join(' ');\n\n\n\t} else {\n\t\t//first name first format\n\n\n\t\tif (parts.length > 1 && salutations.indexOf(parts[0].toLowerCase().replace(/\\./g, '')) > -1) {\n\t\t\tattrs.salutation = parts.shift();\n\n\t\t\t// if we have a salutation assume 2nd part is last name\n\t\t\tif (parts.length === 1) {\n\t\t\t\tattrs.lastName = parts.shift();\n\t\t\t} else {\n\t\t\t\tattrs.firstName = parts.shift();\n\t\t\t}\n\t\t} else {\n\t\t\tattrs.firstName = parts.shift();\n\t\t}\n\n\t\tif (!attrs.lastName) {\n\t\t\tattrs.lastName = parts.length ? parts.pop() : '';\n\t\t}\n\n\t\t// test for compound last name, we reverse because middle name is last bit to be defined.\n\t\t// We already know lastname, so check next word if its part of a compound last name.\n\t\tconst revParts = parts.slice(0).reverse();\n\t\tconst compoundParts = [];\n\n\t\trevParts.every(part => {\n\t\t\tconst test = part.toLowerCase().replace(/\\./g, '');\n\n\t\t\tif (compound.indexOf(test) > -1) {\n\t\t\t\tcompoundParts.push(part);\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t//break on first non compound word\n\t\t\treturn false;\n\t\t});\n\n\t\t//join compound parts with known last name\n\t\tif (compoundParts.length) {\n\t\t\tattrs.lastName = compoundParts.reverse().join(' ') + ' ' + attrs.lastName;\n\n\t\t\tparts = diff(parts, compoundParts);\n\t\t}\n\n\t\tif (parts.length) {\n\t\t\tattrs.middleName = parts.join(' ');\n\t\t}\n\n\t\t//remove comma like \", Jr.\"\n\t\tif (attrs.lastName) {\n\t\t\tattrs.lastName = attrs.lastName.replace(',', '');\n\t\t}\n\n\t\t//save a copy of original\n\t\tattrs.fullName = name;\n\n\t}\n\t//console.log('attrs:', JSON.stringify(attrs));\n\n\tfor (const [k, v] of Object.entries(attrs)) {\n\t\tattrs[k] = v.trim()\n\t}\n\treturn attrs;\n};\n\nparser.getFullestName = (str) => {\n\tlet name = str;\n\tlet names = [];\n\n\t//find fullname from strings like 'Jon and Sue Doyle'\n\tif (name.indexOf('&') > -1 || name.toLowerCase().indexOf(' and ') > -1) {\n\t\tnames = name.split(/\\s+(?:and|&)\\s+/gi);\n\n\t\t//pluck the name with the most parts (first, middle, last) from the array.\n\t\t//will grab 'Sue Doyle' in 'Jon & Sue Anne Doyle'\n\t\tif (names.length) {\n\t\t\tname = names.sort(function (a, b) {\n\t\t\t\treturn b.split(/\\s+/).length - a.split(/\\s+/).length;\n\t\t\t})[0];\n\t\t}\n\t}\n\n\treturn name;\n};\n\nparser.parseAddress = (str) => {\n\tstr = str.replace(/\\n/gi, ', ');\n\t//416 W. Manchester Blvd., Inglewood, CA 90301\n\tconst parts = str.split(/,\\s+/).reverse();\n\tlet stateZip;\n\tlet city;\n\tconst address = {};\n\n\tstateZip = parts[0].split(/\\s+/);\n\tparts.shift();\n\n\tcity = parts.shift();\n\n\taddress.address = parts.reverse().join(', ');\n\taddress.city = city;\n\taddress.state = stateZip[0];\n\taddress.zip = stateZip[1];\n\taddress.fullAddress = str;\n\n\treturn address;\n};\n", "/*\n * This file contains utilities for parsing and working with names.\n * Its essentially a wrapper around whatever parsing library we want, with a fixed interface\n * so we can swap them in/out without changing other code if it ever breaks or we find a better one.\n */\n\nimport { parseName as humanParseName } from \"humanparser\";\nimport { z } from \"zod\";\n\n/**\n * Simply insert whatever name parsing library code we want to use here\n */\nfunction parseNameImpl(fullName: string): any {\n return humanParseName(fullName); // humanparser: https://github.com/ralyodio/humanparser\n}\n\n/**\n * Zod schema for parsed name components\n */\nexport const ParsedNameSchema = z.object({\n /**\n * The salutation/title (e.g., \"Mr.\", \"Dr.\")\n */\n salutation: z.string().optional(),\n\n /**\n * The first name\n */\n firstName: z.string().optional(),\n\n /**\n * The middle name\n */\n middleName: z.string().optional(),\n\n /**\n * The last name\n */\n lastName: z.string().optional(),\n\n /**\n * The suffix (e.g., \"Jr.\", \"III\")\n */\n suffix: z.string().optional(),\n\n /**\n * The original full name\n */\n fullName: z.string().optional(),\n});\n\n/**\n * Interface for parsed name components, inferred from the Zod schema\n */\nexport type ParsedName = z.infer;\n\n/**\n * Parses a full name into its components\n *\n * @param fullName - The full name to parse\n * @returns An object containing the parsed name components\n *\n * @example\n * ```\n * const name = parseName(\"Mr. William R. Hearst, III\");\n * // Returns:\n * // {\n * // salutation: \"Mr.\",\n * // firstName: \"William\",\n * // middleName: \"R.\",\n * // lastName: \"Hearst\",\n * // suffix: \"III\",\n * // fullName: \"Mr. William R. Hearst, III\"\n * // }\n * ```\n */\nexport function parseName(fullName: string): ParsedName | undefined {\n if (!fullName) {\n return undefined;\n }\n\n try {\n // Currently using humanparser library\n const result: any = parseNameImpl(fullName);\n\n // Validate the result using our Zod schema\n const validationResult = ParsedNameSchema.safeParse(result);\n\n if (validationResult.success) {\n return validationResult.data;\n } else {\n // If validation fails, log the error and return a partial object\n console.error(`Invalid parsed name format for \"${fullName}\":`, validationResult.error);\n return undefined;\n }\n } catch (error) {\n // Return a partial object with just the full name if parsing fails\n console.error(`Error parsing name \"${fullName}\":`, error);\n return undefined;\n }\n}\n\n/**\n * Extracts just the last name from a full name\n *\n * @param fullName - The full name to parse\n * @returns The last name, or undefined if parsing fails\n */\nexport function getLastName(fullName: string): string | undefined {\n const parsed = parseName(fullName);\n return parsed?.lastName || undefined;\n}\n", "import React from \"react\";\nimport { Box, SxProps, Theme } from \"@mui/material\";\nimport { X } from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport { BIQButton } from \"./BIQButton\";\n\ninterface FilterButtonProps {\n /**\n * Whether the filter is applied or not. When applied, the button paints\n * with the BIQButton \"pressed\" background (taupe 30%) and adds a clickable\n * X on the right for clearing.\n */\n applied: boolean;\n /**\n * The element placed before the main content. Accepts a lucide icon\n * component (auto-sized by BIQButton) or an already-rendered ReactNode.\n */\n startIcon?: LucideIcon | React.ReactNode;\n /**\n * The content of the button.\n */\n children?: React.ReactNode;\n /**\n * Whether the filter can be edited or not.\n */\n disabled?: boolean;\n /**\n * Callback fired when the main button content is clicked.\n */\n onClick?: (event: React.MouseEvent) => void;\n /**\n * Callback fired when the clear button is clicked.\n */\n onClear?: () => void;\n /**\n * Additional styles to apply to the button.\n */\n sx?: SxProps;\n}\n\n/**\n * A button that describes a search filter. Wraps `BIQButton` (Secondary Large)\n * and adds the applied/cleared affordances on top.\n */\nexport function FilterButton(props: FilterButtonProps) {\n // Keyboard a11y: when the filter is applied, Backspace and Delete clear it.\n // The visible X is a non-focusable affordance (an interactive control nested\n // inside another button would be invalid HTML), so the parent button owns the\n // keyboard contract \u2014 same pattern MUI's Chip uses with onDelete.\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (props.applied && (event.key === \"Backspace\" || event.key === \"Delete\")) {\n event.preventDefault();\n props.onClear?.();\n }\n };\n\n return (\n {\n e.preventDefault();\n e.stopPropagation();\n props.onClear?.();\n }}\n sx={{ display: \"inline-flex\", alignItems: \"center\", cursor: \"pointer\" }}\n >\n \n \n ) : undefined\n }\n onClick={(e) => props.onClick?.(e)}\n onKeyDown={handleKeyDown}\n aria-keyshortcuts={props.applied ? \"Backspace Delete\" : undefined}\n disabled={props.disabled}\n sx={[\n // Applied state uses the semantic action.applied* tokens (which map to\n // the taupe scale per Figma FilterButton spec, node 474-19945).\n // Progression: enabled \u2192 applied, hover \u2192 appliedHover,\n // focused/pressed \u2192 appliedActive. Disabled applied falls back to\n // MUI's standard disabled styling (no taupe override).\n props.applied && !props.disabled\n ? (theme) => ({\n backgroundColor: theme.palette.action.applied,\n \"&:hover\": { backgroundColor: theme.palette.action.appliedHover },\n \"&:active\": { backgroundColor: theme.palette.action.appliedActive },\n \"&.Mui-focusVisible\": { backgroundColor: theme.palette.action.appliedActive },\n })\n : {},\n ...(Array.isArray(props.sx) ? props.sx : [props.sx]),\n ]}\n >\n {props.children}\n
    \n );\n}\n", "import React, { useMemo, useState, useRef, ChangeEvent, useEffect } from \"react\";\nimport {\n Checkbox,\n Box,\n Typography,\n MenuItem,\n AutocompleteRenderOptionState,\n Paper,\n MenuList,\n ListItemIcon,\n ListItemText,\n AutocompleteChangeReason,\n AutocompleteChangeDetails,\n Tooltip,\n} from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQChip } from \"@/components/atoms/BIQChip\";\nimport Autocomplete from \"../../vendor/@mui/material/Autocomplete\";\nimport { Check, ChevronDown as ExpandMoreIcon, ChevronUp as ExpandLessIcon, Gavel, Plus } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport { JudgesAPIJudge } from \"../../api/queries/judges.types\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { noSelectedRowFillSx } from \"@/components/theme/mixins/noSelectedRowFillSx\";\nimport GhostTextField from \"./GhostTextField\";\nimport { useQueryJudgesList } from \"../../api/judges\";\nimport { getLastName } from \"../../utils/nameParser\";\nimport { RequestJudgeModal } from \"../molecules/RequestJudgeModal\";\nimport { FilterButton } from \"./FilterButton\";\nimport { useSearchFilterDispatch } from \"../contexts/SearchFilterControlContext\";\nimport { canRequestJudge } from \"../../utils/canRequestJudge\";\n\nconst VIEWPORT_MARGIN_PX = 80;\n\n// This component uses a three-way option system to support hierarchical display:\n// - JudgeOption: standalone judges, used in single-select mode and for search matches in multi-select\n// - CourtOption: court headers that can expand/collapse to show nested judges\n// - NestedJudgeOption: judges displayed under their court (same data as JudgeOption but different rendering)\ninterface JudgeOption {\n type: \"judge\";\n data: JudgesAPIJudge;\n}\n\ninterface CourtOption {\n type: \"court\";\n data: {\n id: number;\n name: string;\n judges: JudgesAPIJudge[];\n };\n}\n\ninterface NestedJudgeOption {\n type: \"nested\";\n data: JudgesAPIJudge;\n}\n\ntype AutocompleteOption = JudgeOption | CourtOption | NestedJudgeOption;\n\nconst getOptionLabel = (option: AutocompleteOption) => option.data.name;\n\nconst getJudgeAriaLabel = (judge: JudgesAPIJudge, includeCourt: boolean) =>\n [judge.name, judge.display_label, includeCourt ? judge.court.name : null].filter(Boolean).join(\", \");\n\nconst JudgeDisplayLabelChip = ({ judge }: { judge: JudgesAPIJudge }) => {\n if (!judge.display_label) return null;\n\n const chip = (\n ({ display: \"inline-flex\", ml: `${theme.tokens.spacing[2]}px` })}\n aria-hidden=\"true\"\n >\n \n \n );\n\n if (!judge.display_label_helper_text) return chip;\n\n return (\n \n {chip}\n \n );\n};\n\ninterface JudgeAutocompleteProps {\n value: JudgesAPIJudge[];\n onChange?: (judges: JudgesAPIJudge[]) => void;\n onClear?: () => void;\n onOpenChange?: (isOpen: boolean) => void;\n multiselect?: boolean;\n placeholder?: string;\n isDisabled?: boolean;\n /**\n * The text to display on the button when no judges are selected.\n *\n * @default \"Judge\"\n */\n label?: string;\n}\n\n/**\n * Advanced autocomplete for judge selection with hierarchical display:\n * - Courts can expand/collapse to show nested judges\n * - Ghost text auto-completion like browser address bars\n * - Dual input system for persistent search + clear-on-select\n * - Custom keyboard navigation for group expansion\n * - Call stack hacking to override MUI's default highlighting behavior\n */\nconst JudgeAutocomplete: React.FC = ({\n value,\n onChange,\n onClear,\n onOpenChange,\n multiselect = true,\n placeholder = \"Select judge\",\n isDisabled = false,\n label = \"Judge\",\n}) => {\n const theme = useTheme();\n const judges = useQueryJudgesList();\n\n // Use SearchFilterControl to register when open\n const { registerOpenElement, unregisterOpenElement } = useSearchFilterDispatch();\n\n const data = useMemo(() => {\n const unsortedData = judges.data ?? []; // TODO: handle loading\n return [...unsortedData].sort((a, b) => {\n if (a == b) {\n return 0;\n } else if ((getLastName(a.name) ?? \"\") < (getLastName(b.name) ?? \"\")) {\n return -1;\n } else {\n return 1;\n }\n });\n }, [judges.data]);\n\n // TODO: Consider refactoring the endpoint to return data in the hierarchical format\n // we expect here (grouped by court) to avoid building this map on every component mount.\n // This would reduce client-side processing.\n const [courtOptions, judgeOptions, nestedJudgeOptions] = useMemo(() => {\n const courtOptions = new Map();\n const judgeOptions = new Map();\n const nestedJudgeOptions = new Map();\n\n data.forEach((judge) => {\n if (!courtOptions.has(judge.court.id)) {\n const court: CourtOption = {\n type: \"court\",\n data: {\n id: judge.court.id,\n name: judge.court.name,\n judges: [],\n },\n };\n courtOptions.set(judge.court.id, court);\n }\n courtOptions.get(judge.court.id)!.data.judges.push(judge);\n judgeOptions.set(judge.id, { type: \"judge\", data: judge });\n nestedJudgeOptions.set(judge.id, { type: \"nested\", data: judge });\n });\n\n return [courtOptions, judgeOptions, nestedJudgeOptions];\n }, [data]);\n\n const sortedCourts = useMemo(\n () =>\n Array.from(courtOptions.values()).sort((a, b) => {\n if (a.data.name === b.data.name) {\n return 0;\n } else if (a.data.name < b.data.name) {\n return -1;\n } else {\n return 1;\n }\n }),\n [courtOptions],\n );\n\n const courtIds = useMemo(() => new Set(courtOptions.keys()), [courtOptions]);\n const [expandedGroups, setExpandedGroups] = useState>(courtIds);\n\n const [inputValue, setInputValue] = useState(\"\");\n const [overrideEmptyInput, setOverrideEmptyInput] = useState(false);\n\n // Pass a different value to the actual TextField component than to the Autocomplete component\n // so that we can get the desired behavior on de/selecting an option: autocomplete filter list\n // doesn't reset, but text field input does.\n const textFieldValue = overrideEmptyInput ? \"\" : inputValue;\n\n // search term should use the non-cleared version\n const searchTerm = inputValue.toLowerCase().trim();\n\n const highlightRef = useRef(null);\n const [groupResetCounter, setGroupResetCounter] = useState(0);\n const textFieldRef = useRef(null);\n const buttonRef = useRef(null);\n const [position, setPosition] = useState({ top: 0, left: 0, maxHeight: undefined as number | undefined });\n const [isPositioned, setIsPositioned] = useState(false);\n // Ghost text provides browser-like auto-completion - shows grayed-out suggested completion\n // of the currently highlighted option that matches what the user has typed so far\n const [ghostText, setGhostText] = useState(\"\");\n const [isEditing, setIsEditing] = useState(false);\n\n // Notify parent when picker opens/closes and register/unregister with SearchFilterControl\n useEffect(() => {\n onOpenChange?.(isEditing);\n\n // Register/unregister with SearchFilterControl to prevent top bar from closing\n const elementId = `judge-autocomplete-${label}`;\n\n if (isEditing) {\n registerOpenElement({\n id: elementId,\n type: \"judge-autocomplete\",\n metadata: { label, multiselect },\n });\n } else {\n unregisterOpenElement(elementId);\n }\n }, [isEditing, onOpenChange, registerOpenElement, unregisterOpenElement, label, multiselect]);\n\n // Calculate position based on button location and viewport constraints\n const calculatePosition = () => {\n if (!buttonRef.current) return { top: 0, left: 0, maxHeight: undefined };\n\n const rect = buttonRef.current.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n\n const topMarginPx = VIEWPORT_MARGIN_PX;\n const bottomMarginPx = VIEWPORT_MARGIN_PX;\n\n // Calculate available space below and above\n const spaceBelow = viewportHeight - rect.bottom - bottomMarginPx;\n const spaceAbove = rect.top - topMarginPx;\n const dropdownHeight = 300; // Approximate height of the dropdown\n const dropdownWidth = 484; // Fixed width of the dropdown\n\n let top = rect.top;\n let left = rect.left;\n let maxHeight: number | undefined = undefined;\n\n // Determine positioning and height constraints\n if (spaceBelow >= dropdownHeight) {\n // Enough space below - position normally\n top = rect.top;\n } else if (spaceAbove >= dropdownHeight) {\n // Not enough space below, but enough above - position above\n top = rect.top - dropdownHeight;\n } else {\n // Not enough space in either direction - constrain height\n const availableHeight = viewportHeight - topMarginPx - bottomMarginPx;\n maxHeight = Math.max(200, availableHeight); // Minimum 200px height\n\n // Position to use available space optimally\n if (spaceBelow >= spaceAbove) {\n // More space below - position at button top but constrain height to fit\n top = rect.top;\n // Ensure the dropdown doesn't exceed viewport with bottom margin\n const maxAllowedHeight = viewportHeight - rect.top - bottomMarginPx;\n if (maxAllowedHeight > 0) {\n maxHeight = Math.min(maxHeight, maxAllowedHeight);\n }\n } else {\n // More space above - position above and constrain height\n const maxAllowedHeight = rect.top - topMarginPx;\n if (maxAllowedHeight > 0) {\n maxHeight = Math.min(maxHeight, maxAllowedHeight);\n top = rect.top - maxHeight;\n } else {\n // Fallback: position at top margin\n top = topMarginPx;\n maxHeight = Math.min(maxHeight, rect.top - topMarginPx);\n }\n }\n\n // Ensure minimum height\n maxHeight = Math.max(150, maxHeight);\n }\n\n // Ensure dropdown doesn't go off the right edge\n if (left + dropdownWidth > viewportWidth) {\n left = viewportWidth - dropdownWidth - 10; // 10px margin\n }\n\n // Ensure dropdown doesn't go off the left edge\n if (left < 10) {\n left = 10;\n }\n\n return { top, left, maxHeight };\n };\n\n // Handle positioning and repositioning for proper viewport awareness\n useEffect(() => {\n const updatePosition = () => {\n if (isEditing) {\n const newPosition = calculatePosition();\n setPosition(newPosition);\n setIsPositioned(true);\n }\n };\n\n if (isEditing) {\n updatePosition();\n window.addEventListener(\"resize\", updatePosition);\n window.addEventListener(\"scroll\", updatePosition, true);\n\n return () => {\n window.removeEventListener(\"resize\", updatePosition);\n window.removeEventListener(\"scroll\", updatePosition, true);\n };\n }\n }, [isEditing]);\n\n const [requestJudgeModalOpen, setRequestJudgeModalOpen] = useState(false);\n const requestJudgeAvailable = canRequestJudge();\n\n const searchResults = useMemo(() => {\n const searchTerms = searchTerm.split(\" \");\n\n // single-select case first\n if (!multiselect) {\n if (!searchTerm) {\n return sortedCourts.flatMap((court) => court.data.judges).map((judge) => judgeOptions.get(judge.id)!);\n }\n\n const prefixMatchedJudges: JudgeOption[] = [];\n const otherMatchedJudges: JudgeOption[] = [];\n Array.from(judgeOptions.values()).forEach((judge) => {\n if (judge.data.name.toLowerCase().startsWith(searchTerm)) {\n prefixMatchedJudges.push(judge);\n } else if (\n // match if all words match either the judge or the court\n searchTerms.every(\n (term) =>\n judge.data.name.toLowerCase().includes(term) || judge.data.court.name.toLowerCase().includes(term),\n )\n ) {\n otherMatchedJudges.push(judge);\n }\n });\n\n return [...prefixMatchedJudges, ...otherMatchedJudges];\n }\n\n if (!searchTerm) {\n return sortedCourts;\n }\n const prefixMatchedCourts: CourtOption[] = [];\n const otherMatchedCourts: CourtOption[] = [];\n const prefixMatchedJudges: JudgeOption[] = [];\n const otherMatchedJudges: JudgeOption[] = [];\n // Categorize courts\n sortedCourts.forEach((court) => {\n if (court.data.name.toLowerCase().startsWith(searchTerm)) {\n prefixMatchedCourts.push(court);\n } else if (searchTerms.every((term) => court.data.name.toLowerCase().includes(term))) {\n otherMatchedCourts.push(court);\n }\n });\n\n // Categorize judges\n Array.from(judgeOptions.values()).forEach((judge) => {\n if (judge.data.name.toLowerCase().startsWith(searchTerm)) {\n prefixMatchedJudges.push(judge);\n } else if (\n searchTerms.some((term) => judge.data.name.toLowerCase().includes(term)) &&\n searchTerms.every(\n (term) => judge.data.name.toLowerCase().includes(term) || judge.data.court.name.toLowerCase().includes(term),\n )\n ) {\n otherMatchedJudges.push(judge);\n }\n });\n\n const matchedJudges = [...prefixMatchedJudges, ...otherMatchedJudges];\n const matchedCourts = [...prefixMatchedCourts, ...otherMatchedCourts];\n\n // judges are grouped together (prefix-matched then others) and ditto courts.\n // overall relevance order is:\n // - prefix-matched judge, if any exist\n // - prefix-matched court, if any exist,\n // - any judge, if any exist\n // - any court, if any exist\n // Therefore we show courts followed by judges only in the event where there are no\n // prefix-matched judges and there are some prefix-matched courts.\n\n if (prefixMatchedJudges.length === 0 && prefixMatchedCourts.length > 0) {\n return [...matchedCourts, ...matchedJudges];\n }\n\n return [...matchedJudges, ...matchedCourts];\n }, [multiselect, sortedCourts, judgeOptions, searchTerm]);\n\n const firstCourtId = searchResults[0]?.type === \"court\" ? searchResults[0].data.id : null;\n\n useEffect(() => {\n if (searchTerm && firstCourtId !== null) {\n setExpandedGroups(new Set([firstCourtId]));\n } else if (searchTerm) {\n setExpandedGroups(new Set());\n } else {\n setExpandedGroups(courtIds);\n }\n }, [groupResetCounter, courtIds]);\n\n const pushMaybeCollapsedCourt = (court: CourtOption, target: AutocompleteOption[]): void => {\n target.push(court);\n if (expandedGroups.has(court.data.id)) {\n court.data.judges.forEach((judge) => {\n target.push(nestedJudgeOptions.get(judge.id)!);\n });\n }\n };\n\n // Compute filtered options inline during render\n const filteredOptions = useMemo(() => {\n const results: AutocompleteOption[] = [];\n searchResults.forEach((option) => {\n if (option.type === \"judge\") {\n results.push(option);\n } else {\n pushMaybeCollapsedCourt(option, results);\n }\n });\n\n return results;\n }, [searchResults, expandedGroups, pushMaybeCollapsedCourt]);\n\n const customFilterOptions = useMemo(() => () => filteredOptions, [filteredOptions]);\n\n const getGroupSelectionState = (courtId: number): \"none\" | \"partial\" | \"all\" => {\n const court = courtOptions.get(courtId);\n if (!court) return \"none\";\n\n const selectedInGroup = value.filter((judge) => judge.court.id === courtId);\n\n if (selectedInGroup.length === 0) return \"none\";\n if (selectedInGroup.length === court.data.judges.length) return \"all\";\n return \"partial\";\n };\n\n const handleGroupSelect = (courtId: number, existingJudges: JudgesAPIJudge[]) => {\n const court = courtOptions.get(courtId);\n if (!court) return;\n\n const currentState = getGroupSelectionState(courtId);\n\n if (currentState === \"none\") {\n // Select all judges from this court\n const newValue = [...existingJudges, ...court.data.judges];\n onChange?.(newValue);\n } else {\n // Deselect all judges from this court\n const newValue = existingJudges.filter((judge) => judge.court.id !== courtId);\n onChange?.(newValue);\n }\n };\n\n const toggleGroup = (courtId: number) => {\n setExpandedGroups((prev) => {\n const newSet = new Set(prev);\n if (newSet.has(courtId)) {\n newSet.delete(courtId);\n } else {\n newSet.add(courtId);\n }\n return newSet;\n });\n };\n\n const renderOptionSingle = (\n props: React.HTMLAttributes,\n option: AutocompleteOption,\n { selected }: AutocompleteRenderOptionState,\n ) => {\n const judge = (option as JudgeOption).data;\n return (\n // !important needed for long lists of options for some reason. if the options are narrowed\n // down it doesn't seem to be needed. Not sure why.\n \n \n {judge.name}\n \n \n \n {selected && (\n \n \n \n )}\n \n );\n };\n\n // Renders different option types with appropriate UI elements and behaviors\n // - Court groups: checkbox + court icon + expand/collapse button + court name\n // - Judges (nested or not): checkbox + judge name + optional display label\n // - Nested judges get extra left padding to show visual hierarchy\n const renderOptionMultiselect = (\n props: React.HTMLAttributes,\n option: AutocompleteOption,\n { selected }: AutocompleteRenderOptionState,\n ) => {\n if (option.type === \"court\") {\n const court = option.data;\n const groupState = getGroupSelectionState(court.id);\n const isExpanded = expandedGroups.has(court.id);\n\n return (\n \n toggleGroup(court.id)}>\n \n \n \n {court.name}\n \n {\n e.stopPropagation();\n toggleGroup(court.id);\n }}\n >\n {isExpanded ? : }\n \n \n );\n }\n\n const judge = option.data;\n\n // Check if it's a nested judge\n const isNested = option.type === \"nested\";\n const keyPrefix = isNested ? \"nested-judge\" : \"judge\";\n\n return (\n \n {isNested && }\n \n \n \n \n {judge.name}\n \n {!isNested && }\n \n \n );\n };\n\n const handleChange = (\n _event: React.SyntheticEvent,\n newValue: AutocompleteOption | AutocompleteOption[] | null,\n _reason: AutocompleteChangeReason,\n _details?: AutocompleteChangeDetails,\n ) => {\n if (multiselect) {\n setOverrideEmptyInput(true);\n updateGhostText(highlightRef.current, \"\");\n }\n\n if (newValue === null) {\n onChange?.([]);\n return;\n }\n\n if (!multiselect) {\n const newJudge = newValue as JudgeOption;\n onChange?.([newJudge.data]);\n setInputValue(newJudge.data.name);\n return;\n }\n\n const multiValue = newValue as AutocompleteOption[];\n\n const courtOption = multiValue.find((option) => option.type === \"court\");\n const existingJudges = multiValue\n .filter((option): option is JudgeOption | NestedJudgeOption => option.type !== \"court\")\n .map((option) => option.data);\n if (courtOption) {\n handleGroupSelect(courtOption.data.id, existingJudges);\n return;\n }\n\n onChange?.(existingJudges);\n };\n\n const allOptions = [\n ...Array.from(judgeOptions.values()),\n ...Array.from(courtOptions.values()),\n ...Array.from(nestedJudgeOptions.values()),\n ];\n\n const autoCompleteValue: JudgeOption[] = useMemo(() => {\n return value.map((judge) => judgeOptions.get(judge.id)!);\n }, [value, judgeOptions]);\n\n // Needs to be memoized or else the highlighting goes crazy\n // https://github.com/mui/material-ui/issues/29508#issuecomment-1959130611\n const handleClearRef = useRef(() => {\n onClear ? onClear() : onChange?.([]);\n });\n handleClearRef.current = () => {\n onClear ? onClear() : onChange?.([]);\n };\n\n const valueLengthRef = useRef(value.length);\n valueLengthRef.current = value.length;\n\n const onCloseRef = useRef<() => void>(() => {});\n\n const memoizedPaperComponent: React.JSXElementConstructor> = useMemo(() => {\n return ({ children, ...other }) => (\n \n {children}\n {valueLengthRef.current > 0 && (\n \n e.preventDefault()}\n onClick={() => handleClearRef.current()}\n >\n Clear\n \n e.preventDefault()}\n onClick={() => onCloseRef.current()}\n >\n Apply\n \n \n )}\n {requestJudgeAvailable && (\n \n e.preventDefault()}\n onClick={() => setRequestJudgeModalOpen(true)}\n >\n Don't see your judge? Add them to Bench IQ.\n \n \n )}\n \n );\n }, [position.maxHeight, requestJudgeAvailable, theme]);\n\n const onClose = () => {\n setExpandedGroups(courtIds);\n setGhostText(\"\");\n setInputValue(\"\");\n setIsEditing(false);\n setIsPositioned(false); // Reset positioning state for next open\n };\n onCloseRef.current = onClose;\n\n const handleClose = (event: React.SyntheticEvent, reason?: string) => {\n // If the close is due to clicking outside, check if it's a search field\n if (reason === \"blur\" || reason === \"toggleInput\") {\n const target = event.target as HTMLElement;\n const activeElement = document.activeElement as HTMLElement;\n\n // Check both the event target and the currently focused element\n const elementToCheck = activeElement || target;\n\n if (elementToCheck) {\n const isSearchField =\n elementToCheck.closest(\"[data-top-bar-keep-open]\") ||\n elementToCheck.matches('input[placeholder*=\"keywords\"]') ||\n elementToCheck.matches('input[placeholder*=\"Boolean\"]') ||\n elementToCheck.matches('textarea[placeholder*=\"Ask\"]') ||\n elementToCheck.closest(\".MuiTextField-root\");\n\n if (isSearchField) {\n return; // Don't close if interaction is with a search field\n }\n }\n }\n\n onClose();\n };\n\n const handleBlur = (event: React.FocusEvent) => {\n // Check if the blur is happening because of a click in a search text field\n // If so, don't close the judge dropdown\n const relatedTarget = event.relatedTarget as HTMLElement;\n if (relatedTarget) {\n // Check if the new focus target is a search text field or within a search card\n const isSearchField =\n relatedTarget.closest(\"[data-top-bar-keep-open]\") ||\n relatedTarget.matches('input[placeholder*=\"keywords\"]') ||\n relatedTarget.matches('input[placeholder*=\"Boolean\"]') ||\n relatedTarget.matches('textarea[placeholder*=\"Ask\"]') ||\n relatedTarget.closest(\".MuiTextField-root\");\n\n if (isSearchField) {\n return; // Don't close if focus moved to a search field\n }\n }\n\n onClose();\n };\n\n const onOpen = () => {\n if (multiselect) {\n return;\n }\n\n if (value.length > 0) {\n setInputValue(value[0].name);\n }\n\n // The ref isn't set yet at this point, so enqueue this for after\n setTimeout(() => {\n if (textFieldRef.current) {\n textFieldRef.current.select();\n }\n }, 0);\n };\n\n const updateGhostText = (option: AutocompleteOption | null, value: string) => {\n if (value && option?.data.name.toLowerCase().startsWith(value.toLowerCase())) {\n const newGhostText = value + option.data.name.slice(value.length);\n setGhostText(newGhostText);\n } else {\n setGhostText(\"\");\n }\n };\n\n const buttonText =\n value.length > 1 ? `${value[0].name} + ${value.length - 1}` : value.length === 1 ? value[0].name : label;\n\n const handleButtonClick = () => {\n // Calculate position immediately before showing dropdown to prevent flicker\n const newPosition = calculatePosition();\n setPosition(newPosition);\n setIsPositioned(true);\n setIsEditing(true);\n };\n\n return (\n \n \n }\n applied={value.length > 0}\n disabled={isDisabled}\n onClick={handleButtonClick}\n onClear={onClear || (() => onChange?.([]))}\n sx={{\n opacity: isEditing ? 0 : 1,\n transition: \"opacity 0.2s ease-in-out\",\n }}\n >\n {buttonText}\n \n \n {isEditing && isPositioned && (\n \n {requestJudgeAvailable\n ? \"This judge isn't in Bench IQ yet. Request them and we'll add their data within 24\u201348 hours.\"\n : \"This judge isn't in Bench IQ yet.\"}\n \n }\n multiple={multiselect}\n options={multiselect ? allOptions : []}\n value={multiselect ? autoCompleteValue : autoCompleteValue[0] || null}\n clearOnBlur={false}\n disableCloseOnSelect={multiselect}\n selectOnFocus={!multiselect}\n onChange={handleChange}\n open={isEditing}\n inputValue={inputValue}\n ListboxComponent={MenuList}\n onInputChange={(_event, newInputValue, reason) => {\n // don't clear text when hitting 'enter', we'll handle that in handleChange because that\n // will take care of *clearing* an option too (just hitting enter to remove an option won't\n // trigger this event)\n if (reason === \"reset\") {\n return;\n }\n\n setOverrideEmptyInput(false);\n setInputValue(newInputValue);\n }}\n onHighlightChange={(_event: React.SyntheticEvent, option: AutocompleteOption | null) => {\n highlightRef.current = option;\n updateGhostText(option, textFieldValue);\n }}\n onKeyDown={(event) => {\n // Custom keyboard navigation:\n // - Backspace when input appears empty but has hidden value deletes last chip. This matches\n // mui's existing behavior for empty inputValue but we need to duplicate it here because\n // of the double textFieldValue / inputValue divide.\n // - Left/Right arrows expand/collapse court groups when cursor is at input boundaries\n if (textFieldValue === \"\" && inputValue !== \"\" && event.key == \"Backspace\") {\n // Delete last chip, since the internal keydown handler won't catch it (it thinks inputValue is not \"\")\n const newValue = [...value];\n onChange?.(newValue.slice(0, -1));\n } else if ([\"ArrowLeft\", \"ArrowRight\"].indexOf(event.key) !== -1) {\n const input = event.target as HTMLInputElement;\n const cursorPosition = input.selectionStart || 0;\n const textLength = textFieldValue.length;\n\n if (highlightRef.current?.type === \"court\") {\n // Only handle arrow keys when they wouldn't move the cursor\n const shouldHandle =\n (event.key === \"ArrowLeft\" && cursorPosition === 0) ||\n (event.key === \"ArrowRight\" && cursorPosition === textLength);\n\n if (shouldHandle) {\n // mui checks this field internally, the point is to stop the left/right keys from closing the popup\n (event as any).defaultMuiPrevented = true;\n\n event.preventDefault();\n const courtId = highlightRef.current.data.id;\n if (event.key === \"ArrowLeft\") {\n expandedGroups.has(courtId) && toggleGroup(courtId);\n } else {\n !expandedGroups.has(courtId) && toggleGroup(courtId);\n }\n }\n } else if (textLength === 0) {\n // Default behavior would be to close the popup. that's weird, don't do it.\n (event as any).defaultMuiPrevented = true;\n }\n }\n }}\n filterOptions={customFilterOptions}\n getOptionLabel={getOptionLabel}\n isOptionEqualToValue={(option, value) => {\n const optionIsJudge = option.type !== \"court\";\n const valueIsJudge = value.type !== \"court\";\n return optionIsJudge === valueIsJudge && option.data.id === value.data.id;\n }}\n onClose={handleClose}\n onBlur={handleBlur}\n onOpen={onOpen}\n onFocus={onOpen}\n renderOption={multiselect ? renderOptionMultiselect : renderOptionSingle}\n renderInput={({ inputProps, ...params }) => (\n ) => {\n setOverrideEmptyInput(false);\n updateGhostText(highlightRef.current, event.target.value);\n setGroupResetCounter((prev) => prev + 1);\n inputProps.onChange?.(event);\n },\n }}\n ghostText={ghostText}\n variant=\"standard\"\n fullWidth\n autoFocus\n />\n )}\n forcePopupIcon={false}\n renderTags={(value: AutocompleteOption[], getTagProps) =>\n value.map((option, index) => (\n \n ))\n }\n ListboxProps={\n multiselect\n ? {\n style: {\n maxHeight: 5 * 54, // 5 list items * 54 px high\n },\n }\n : {\n style: {\n maxHeight: 5 * (36 + 8) - 8, // 5 list items * 36 px high + 8px gap, except the last gap\n gap: \"8px\",\n display: \"flex\",\n flexDirection: \"column\",\n },\n }\n }\n sx={{\n width: \"484px\",\n borderRadius: \"8px 8px 0 0\",\n border: 1,\n borderColor: theme.border.light,\n backgroundColor: theme.palette.background.paper,\n \"& .MuiAutocomplete-tag\": {\n margin: \"8px 4px 0 4px\",\n height: \"23px\",\n },\n \"& .MuiAutocomplete-inputRoot\": {\n padding: \"8px 16px 16px 8px\",\n },\n \"& .MuiAutocomplete-endAdornment\": {\n display: \"none\",\n },\n position: \"fixed\",\n top: position.top,\n left: position.left,\n zIndex: 1301,\n ...(position.maxHeight && {\n maxHeight: position.maxHeight,\n }),\n }}\n PaperComponent={memoizedPaperComponent}\n slotProps={{ paper: { sx: { \"& .MuiAutocomplete-noOptions\": { padding: 0 } } } }}\n />\n )}\n {requestJudgeAvailable && (\n setRequestJudgeModalOpen(false)}\n query={inputValue}\n />\n )}\n \n );\n};\n\nexport default JudgeAutocomplete;\n", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nexport const getPickersLocalization = pickersTranslations => {\n return {\n components: {\n MuiLocalizationProvider: {\n defaultProps: {\n localeText: _extends({}, pickersTranslations)\n }\n }\n }\n };\n};", "import { getPickersLocalization } from './utils/getPickersLocalization';\n\n// This object is not Partial because it is the default values\n\nconst enUSPickers = {\n // Calendar navigation\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n // View navigation\n openPreviousView: 'open previous view',\n openNextView: 'open next view',\n calendarViewSwitchingButtonAriaLabel: view => view === 'year' ? 'year view is open, switch to calendar view' : 'calendar view is open, switch to year view',\n // DateRange placeholders\n start: 'Start',\n end: 'End',\n // Action bar\n cancelButtonLabel: 'Cancel',\n clearButtonLabel: 'Clear',\n okButtonLabel: 'OK',\n todayButtonLabel: 'Today',\n // Toolbar titles\n datePickerToolbarTitle: 'Select date',\n dateTimePickerToolbarTitle: 'Select date & time',\n timePickerToolbarTitle: 'Select time',\n dateRangePickerToolbarTitle: 'Select date range',\n // Clock labels\n clockLabelText: (view, time, adapter) => `Select ${view}. ${time === null ? 'No time selected' : `Selected time is ${adapter.format(time, 'fullTime')}`}`,\n hoursClockNumberText: hours => `${hours} hours`,\n minutesClockNumberText: minutes => `${minutes} minutes`,\n secondsClockNumberText: seconds => `${seconds} seconds`,\n // Digital clock labels\n selectViewText: view => `Select ${view}`,\n // Calendar labels\n calendarWeekNumberHeaderLabel: 'Week number',\n calendarWeekNumberHeaderText: '#',\n calendarWeekNumberAriaLabelText: weekNumber => `Week ${weekNumber}`,\n calendarWeekNumberText: weekNumber => `${weekNumber}`,\n // Open picker labels\n openDatePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `Choose date, selected date is ${utils.format(value, 'fullDate')}` : 'Choose date',\n openTimePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `Choose time, selected time is ${utils.format(value, 'fullTime')}` : 'Choose time',\n fieldClearLabel: 'Clear value',\n // Table labels\n timeTableLabel: 'pick time',\n dateTableLabel: 'pick date',\n // Field section placeholders\n fieldYearPlaceholder: params => 'Y'.repeat(params.digitAmount),\n fieldMonthPlaceholder: params => params.contentType === 'letter' ? 'MMMM' : 'MM',\n fieldDayPlaceholder: () => 'DD',\n fieldWeekDayPlaceholder: params => params.contentType === 'letter' ? 'EEEE' : 'EE',\n fieldHoursPlaceholder: () => 'hh',\n fieldMinutesPlaceholder: () => 'mm',\n fieldSecondsPlaceholder: () => 'ss',\n fieldMeridiemPlaceholder: () => 'aa'\n};\nexport const DEFAULT_LOCALE = enUSPickers;\nexport const enUS = getPickersLocalization(enUSPickers);", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport * as React from 'react';\nimport { MuiPickersAdapterContext } from '../../LocalizationProvider/LocalizationProvider';\nimport { DEFAULT_LOCALE } from '../../locales/enUS';\nexport const useLocalizationContext = () => {\n const localization = React.useContext(MuiPickersAdapterContext);\n if (localization === null) {\n throw new Error(['MUI: Can not find the date and time pickers localization context.', 'It looks like you forgot to wrap your component in LocalizationProvider.', 'This can also happen if you are bundling multiple versions of the `@mui/x-date-pickers` package'].join('\\n'));\n }\n if (localization.utils === null) {\n throw new Error(['MUI: Can not find the date and time pickers adapter from its localization context.', 'It looks like you forgot to pass a `dateAdapter` to your LocalizationProvider.'].join('\\n'));\n }\n const localeText = React.useMemo(() => _extends({}, DEFAULT_LOCALE, localization.localeText), [localization.localeText]);\n return React.useMemo(() => _extends({}, localization, {\n localeText\n }), [localization, localeText]);\n};\nexport const useUtils = () => useLocalizationContext().utils;\nexport const useDefaultDates = () => useLocalizationContext().defaultDates;\nexport const useLocaleText = () => useLocalizationContext().localeText;\nexport const useNow = timezone => {\n const utils = useUtils();\n const now = React.useRef();\n if (now.current === undefined) {\n now.current = utils.dateWithTimezone(undefined, timezone);\n }\n return now.current;\n};", "export const areViewsEqual = (views, expectedViews) => {\n if (views.length !== expectedViews.length) {\n return false;\n }\n return expectedViews.every(expectedView => views.includes(expectedView));\n};\nexport const applyDefaultViewProps = ({\n openTo,\n defaultOpenTo,\n views,\n defaultViews\n}) => {\n const viewsWithDefault = views != null ? views : defaultViews;\n let openToWithDefault;\n if (openTo != null) {\n openToWithDefault = openTo;\n } else if (viewsWithDefault.includes(defaultOpenTo)) {\n openToWithDefault = defaultOpenTo;\n } else if (viewsWithDefault.length > 0) {\n openToWithDefault = viewsWithDefault[0];\n } else {\n throw new Error('MUI: The `views` prop must contain at least one view');\n }\n return {\n views: viewsWithDefault,\n openTo: openToWithDefault\n };\n};", "import { areViewsEqual } from './views';\nexport const findClosestEnabledDate = ({\n date,\n disableFuture,\n disablePast,\n maxDate,\n minDate,\n isDateDisabled,\n utils,\n timezone\n}) => {\n const today = utils.startOfDay(utils.dateWithTimezone(undefined, timezone));\n if (disablePast && utils.isBefore(minDate, today)) {\n minDate = today;\n }\n if (disableFuture && utils.isAfter(maxDate, today)) {\n maxDate = today;\n }\n let forward = date;\n let backward = date;\n if (utils.isBefore(date, minDate)) {\n forward = minDate;\n backward = null;\n }\n if (utils.isAfter(date, maxDate)) {\n if (backward) {\n backward = maxDate;\n }\n forward = null;\n }\n while (forward || backward) {\n if (forward && utils.isAfter(forward, maxDate)) {\n forward = null;\n }\n if (backward && utils.isBefore(backward, minDate)) {\n backward = null;\n }\n if (forward) {\n if (!isDateDisabled(forward)) {\n return forward;\n }\n forward = utils.addDays(forward, 1);\n }\n if (backward) {\n if (!isDateDisabled(backward)) {\n return backward;\n }\n backward = utils.addDays(backward, -1);\n }\n }\n return null;\n};\nexport const replaceInvalidDateByNull = (utils, value) => value == null || !utils.isValid(value) ? null : value;\nexport const applyDefaultDate = (utils, value, defaultValue) => {\n if (value == null || !utils.isValid(value)) {\n return defaultValue;\n }\n return value;\n};\nexport const areDatesEqual = (utils, a, b) => {\n if (!utils.isValid(a) && a != null && !utils.isValid(b) && b != null) {\n return true;\n }\n return utils.isEqual(a, b);\n};\nexport const getMonthsInYear = (utils, year) => {\n const firstMonth = utils.startOfYear(year);\n const months = [firstMonth];\n while (months.length < 12) {\n const prevMonth = months[months.length - 1];\n months.push(utils.addMonths(prevMonth, 1));\n }\n return months;\n};\nexport const mergeDateAndTime = (utils, dateParam, timeParam) => {\n let mergedDate = dateParam;\n mergedDate = utils.setHours(mergedDate, utils.getHours(timeParam));\n mergedDate = utils.setMinutes(mergedDate, utils.getMinutes(timeParam));\n mergedDate = utils.setSeconds(mergedDate, utils.getSeconds(timeParam));\n return mergedDate;\n};\nexport const getTodayDate = (utils, timezone, valueType) => valueType === 'date' ? utils.startOfDay(utils.dateWithTimezone(undefined, timezone)) : utils.dateWithTimezone(undefined, timezone);\nexport const formatMeridiem = (utils, meridiem) => {\n const date = utils.setHours(utils.date(), meridiem === 'am' ? 2 : 14);\n return utils.format(date, 'meridiem');\n};\nconst dateViews = ['year', 'month', 'day'];\nexport const isDatePickerView = view => dateViews.includes(view);\nexport const resolveDateFormat = (utils, {\n format,\n views\n}, isInToolbar) => {\n if (format != null) {\n return format;\n }\n const formats = utils.formats;\n if (areViewsEqual(views, ['year'])) {\n return formats.year;\n }\n if (areViewsEqual(views, ['month'])) {\n return formats.month;\n }\n if (areViewsEqual(views, ['day'])) {\n return formats.dayOfMonth;\n }\n if (areViewsEqual(views, ['month', 'year'])) {\n return `${formats.month} ${formats.year}`;\n }\n if (areViewsEqual(views, ['day', 'month'])) {\n return `${formats.month} ${formats.dayOfMonth}`;\n }\n if (isInToolbar) {\n // Little localization hack (Google is doing the same for android native pickers):\n // For english localization it is convenient to include weekday into the date \"Mon, Jun 1\".\n // For other locales using strings like \"June 1\", without weekday.\n return /en/.test(utils.getCurrentLocaleCode()) ? formats.normalDateWithWeekday : formats.normalDate;\n }\n return formats.keyboardDate;\n};\nexport const getWeekdays = (utils, date) => {\n const start = utils.startOfWeek(date);\n return [0, 1, 2, 3, 4, 5, 6].map(diff => utils.addDays(start, diff));\n};", "function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e))for(t=0;t {\n const {\n classes,\n isLandscape\n } = ownerState;\n const slots = {\n root: ['root'],\n content: ['content'],\n penIconButton: ['penIconButton', isLandscape && 'penIconButtonLandscape']\n };\n return composeClasses(slots, getPickersToolbarUtilityClass, classes);\n};\nconst PickersToolbarRoot = styled('div', {\n name: 'MuiPickersToolbar',\n slot: 'Root',\n overridesResolver: (props, styles) => styles.root\n})(({\n theme,\n ownerState\n}) => _extends({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n padding: theme.spacing(2, 3)\n}, ownerState.isLandscape && {\n height: 'auto',\n maxWidth: 160,\n padding: 16,\n justifyContent: 'flex-start',\n flexWrap: 'wrap'\n}));\nconst PickersToolbarContent = styled('div', {\n name: 'MuiPickersToolbar',\n slot: 'Content',\n overridesResolver: (props, styles) => styles.content\n})(({\n ownerState\n}) => {\n var _ownerState$landscape;\n return {\n display: 'flex',\n flexWrap: 'wrap',\n width: '100%',\n justifyContent: ownerState.isLandscape ? 'flex-start' : 'space-between',\n flexDirection: ownerState.isLandscape ? (_ownerState$landscape = ownerState.landscapeDirection) != null ? _ownerState$landscape : 'column' : 'row',\n flex: 1,\n alignItems: ownerState.isLandscape ? 'flex-start' : 'center'\n };\n});\nexport const PickersToolbar = /*#__PURE__*/React.forwardRef(function PickersToolbar(inProps, ref) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersToolbar'\n });\n const {\n children,\n className,\n toolbarTitle,\n hidden,\n titleId\n } = props;\n const ownerState = props;\n const classes = useUtilityClasses(ownerState);\n if (hidden) {\n return null;\n }\n return /*#__PURE__*/_jsxs(PickersToolbarRoot, {\n ref: ref,\n className: clsx(classes.root, className),\n ownerState: ownerState,\n children: [/*#__PURE__*/_jsx(Typography, {\n color: \"text.secondary\",\n variant: \"overline\",\n id: titleId,\n children: toolbarTitle\n }), /*#__PURE__*/_jsx(PickersToolbarContent, {\n className: classes.content,\n ownerState: ownerState,\n children: children\n })]\n });\n});", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport function getDatePickerToolbarUtilityClass(slot) {\n return generateUtilityClass('MuiDatePickerToolbar', slot);\n}\nexport const datePickerToolbarClasses = generateUtilityClasses('MuiDatePickerToolbar', ['root', 'title']);", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"value\", \"isLandscape\", \"onChange\", \"toolbarFormat\", \"toolbarPlaceholder\", \"views\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport Typography from '@mui/material/Typography';\nimport { styled, useThemeProps } from '@mui/material/styles';\nimport { unstable_composeClasses as composeClasses } from '@mui/utils';\nimport { PickersToolbar } from '../internals/components/PickersToolbar';\nimport { useLocaleText, useUtils } from '../internals/hooks/useUtils';\nimport { getDatePickerToolbarUtilityClass } from './datePickerToolbarClasses';\nimport { resolveDateFormat } from '../internals/utils/date-utils';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n classes\n } = ownerState;\n const slots = {\n root: ['root'],\n title: ['title']\n };\n return composeClasses(slots, getDatePickerToolbarUtilityClass, classes);\n};\nconst DatePickerToolbarRoot = styled(PickersToolbar, {\n name: 'MuiDatePickerToolbar',\n slot: 'Root',\n overridesResolver: (_, styles) => styles.root\n})({});\n\n/**\n * @ignore - do not document.\n */\nconst DatePickerToolbarTitle = styled(Typography, {\n name: 'MuiDatePickerToolbar',\n slot: 'Title',\n overridesResolver: (_, styles) => styles.title\n})(({\n ownerState\n}) => _extends({}, ownerState.isLandscape && {\n margin: 'auto 16px auto auto'\n}));\n/**\n * Demos:\n *\n * - [DatePicker](https://mui.com/x/react-date-pickers/date-picker/)\n * - [Custom components](https://mui.com/x/react-date-pickers/custom-components/)\n *\n * API:\n *\n * - [DatePickerToolbar API](https://mui.com/x/api/date-pickers/date-picker-toolbar/)\n */\nconst DatePickerToolbar = /*#__PURE__*/React.forwardRef(function DatePickerToolbar(inProps, ref) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiDatePickerToolbar'\n });\n const {\n value,\n isLandscape,\n toolbarFormat,\n toolbarPlaceholder = '\u2013\u2013',\n views\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const utils = useUtils();\n const localeText = useLocaleText();\n const classes = useUtilityClasses(props);\n const dateText = React.useMemo(() => {\n if (!value) {\n return toolbarPlaceholder;\n }\n const formatFromViews = resolveDateFormat(utils, {\n format: toolbarFormat,\n views\n }, true);\n return utils.formatByString(value, formatFromViews);\n }, [value, toolbarFormat, toolbarPlaceholder, utils, views]);\n const ownerState = props;\n return /*#__PURE__*/_jsx(DatePickerToolbarRoot, _extends({\n ref: ref,\n toolbarTitle: localeText.datePickerToolbarTitle,\n isLandscape: isLandscape,\n className: classes.root\n }, other, {\n children: /*#__PURE__*/_jsx(DatePickerToolbarTitle, {\n variant: \"h4\",\n align: isLandscape ? 'left' : 'center',\n ownerState: ownerState,\n className: classes.title,\n children: dateText\n })\n }));\n});\nprocess.env.NODE_ENV !== \"production\" ? DatePickerToolbar.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n classes: PropTypes.object,\n /**\n * className applied to the root component.\n */\n className: PropTypes.string,\n disabled: PropTypes.bool,\n /**\n * If `true`, show the toolbar even in desktop mode.\n * @default `true` for Desktop, `false` for Mobile.\n */\n hidden: PropTypes.bool,\n isLandscape: PropTypes.bool.isRequired,\n onChange: PropTypes.func.isRequired,\n /**\n * Callback called when a toolbar is clicked\n * @template TView\n * @param {TView} view The view to open\n */\n onViewChange: PropTypes.func.isRequired,\n readOnly: PropTypes.bool,\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n titleId: PropTypes.string,\n /**\n * Toolbar date format.\n */\n toolbarFormat: PropTypes.string,\n /**\n * Toolbar value placeholder\u2014it is displayed when the value is empty.\n * @default \"\u2013\u2013\"\n */\n toolbarPlaceholder: PropTypes.node,\n value: PropTypes.any,\n /**\n * Currently visible picker view.\n */\n view: PropTypes.oneOf(['day', 'month', 'year']).isRequired,\n views: PropTypes.arrayOf(PropTypes.oneOf(['day', 'month', 'year']).isRequired).isRequired\n} : void 0;\nexport { DatePickerToolbar };", "import _extends from \"@babel/runtime/helpers/esm/extends\";\n// TODO v7: This file exist only to simplify typing between\n// components/componentsProps and slots/slotProps\n// Should be deleted when components/componentsProps are removed\n\nexport const uncapitalizeObjectKeys = capitalizedObject => {\n if (capitalizedObject === undefined) {\n return undefined;\n }\n return Object.keys(capitalizedObject).reduce((acc, key) => _extends({}, acc, {\n [`${key.slice(0, 1).toLowerCase()}${key.slice(1)}`]: capitalizedObject[key]\n }), {});\n};", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport * as React from 'react';\nimport { useThemeProps } from '@mui/material/styles';\nimport { useDefaultDates, useUtils } from '../internals/hooks/useUtils';\nimport { applyDefaultViewProps } from '../internals/utils/views';\nimport { applyDefaultDate } from '../internals/utils/date-utils';\nimport { DatePickerToolbar } from './DatePickerToolbar';\nimport { uncapitalizeObjectKeys } from '../internals/utils/slots-migration';\nexport function useDatePickerDefaultizedProps(props, name) {\n var _themeProps$slots, _themeProps$disableFu, _themeProps$disablePa, _themeProps$slotProps;\n const utils = useUtils();\n const defaultDates = useDefaultDates();\n const themeProps = useThemeProps({\n props,\n name\n });\n const localeText = React.useMemo(() => {\n var _themeProps$localeTex;\n if (((_themeProps$localeTex = themeProps.localeText) == null ? void 0 : _themeProps$localeTex.toolbarTitle) == null) {\n return themeProps.localeText;\n }\n return _extends({}, themeProps.localeText, {\n datePickerToolbarTitle: themeProps.localeText.toolbarTitle\n });\n }, [themeProps.localeText]);\n const slots = (_themeProps$slots = themeProps.slots) != null ? _themeProps$slots : uncapitalizeObjectKeys(themeProps.components);\n return _extends({}, themeProps, {\n localeText\n }, applyDefaultViewProps({\n views: themeProps.views,\n openTo: themeProps.openTo,\n defaultViews: ['year', 'day'],\n defaultOpenTo: 'day'\n }), {\n disableFuture: (_themeProps$disableFu = themeProps.disableFuture) != null ? _themeProps$disableFu : false,\n disablePast: (_themeProps$disablePa = themeProps.disablePast) != null ? _themeProps$disablePa : false,\n minDate: applyDefaultDate(utils, themeProps.minDate, defaultDates.minDate),\n maxDate: applyDefaultDate(utils, themeProps.maxDate, defaultDates.maxDate),\n slots: _extends({\n toolbar: DatePickerToolbar\n }, slots),\n slotProps: (_themeProps$slotProps = themeProps.slotProps) != null ? _themeProps$slotProps : themeProps.componentsProps\n });\n}", "/**\n * Determines if a given element is a DOM element name (i.e. not a React component).\n */\nexport function isHostComponent(element) {\n return typeof element === 'string';\n}", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport { isHostComponent } from './isHostComponent';\n\n/**\n * Type of the ownerState based on the type of an element it applies to.\n * This resolves to the provided OwnerState for React components and `undefined` for host components.\n * Falls back to `OwnerState | undefined` when the exact type can't be determined in development time.\n */\n\n/**\n * Appends the ownerState object to the props, merging with the existing one if necessary.\n *\n * @param elementType Type of the element that owns the `existingProps`. If the element is a DOM node or undefined, `ownerState` is not applied.\n * @param otherProps Props of the element.\n * @param ownerState\n */\nexport function appendOwnerState(elementType, otherProps, ownerState) {\n if (elementType === undefined || isHostComponent(elementType)) {\n return otherProps;\n }\n return _extends({}, otherProps, {\n ownerState: _extends({}, otherProps.ownerState, ownerState)\n });\n}", "/**\n * Extracts event handlers from a given object.\n * A prop is considered an event handler if it is a function and its name starts with `on`.\n *\n * @param object An object to extract event handlers from.\n * @param excludeKeys An array of keys to exclude from the returned object.\n */\nexport function extractEventHandlers(object, excludeKeys = []) {\n if (object === undefined) {\n return {};\n }\n const result = {};\n Object.keys(object).filter(prop => prop.match(/^on[A-Z]/) && typeof object[prop] === 'function' && !excludeKeys.includes(prop)).forEach(prop => {\n result[prop] = object[prop];\n });\n return result;\n}", "/**\n * If `componentProps` is a function, calls it with the provided `ownerState`.\n * Otherwise, just returns `componentProps`.\n */\nexport function resolveComponentProps(componentProps, ownerState, slotState) {\n if (typeof componentProps === 'function') {\n return componentProps(ownerState, slotState);\n }\n return componentProps;\n}", "/**\n * Removes event handlers from the given object.\n * A field is considered an event handler if it is a function with a name beginning with `on`.\n *\n * @param object Object to remove event handlers from.\n * @returns Object with event handlers removed.\n */\nexport function omitEventHandlers(object) {\n if (object === undefined) {\n return {};\n }\n const result = {};\n Object.keys(object).filter(prop => !(prop.match(/^on[A-Z]/) && typeof object[prop] === 'function')).forEach(prop => {\n result[prop] = object[prop];\n });\n return result;\n}", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport clsx from 'clsx';\nimport { extractEventHandlers } from './extractEventHandlers';\nimport { omitEventHandlers } from './omitEventHandlers';\n/**\n * Merges the slot component internal props (usually coming from a hook)\n * with the externally provided ones.\n *\n * The merge order is (the latter overrides the former):\n * 1. The internal props (specified as a getter function to work with get*Props hook result)\n * 2. Additional props (specified internally on a Base UI component)\n * 3. External props specified on the owner component. These should only be used on a root slot.\n * 4. External props specified in the `slotProps.*` prop.\n * 5. The `className` prop - combined from all the above.\n * @param parameters\n * @returns\n */\nexport function mergeSlotProps(parameters) {\n const {\n getSlotProps,\n additionalProps,\n externalSlotProps,\n externalForwardedProps,\n className\n } = parameters;\n if (!getSlotProps) {\n // The simpler case - getSlotProps is not defined, so no internal event handlers are defined,\n // so we can simply merge all the props without having to worry about extracting event handlers.\n const joinedClasses = clsx(externalForwardedProps == null ? void 0 : externalForwardedProps.className, externalSlotProps == null ? void 0 : externalSlotProps.className, className, additionalProps == null ? void 0 : additionalProps.className);\n const mergedStyle = _extends({}, additionalProps == null ? void 0 : additionalProps.style, externalForwardedProps == null ? void 0 : externalForwardedProps.style, externalSlotProps == null ? void 0 : externalSlotProps.style);\n const props = _extends({}, additionalProps, externalForwardedProps, externalSlotProps);\n if (joinedClasses.length > 0) {\n props.className = joinedClasses;\n }\n if (Object.keys(mergedStyle).length > 0) {\n props.style = mergedStyle;\n }\n return {\n props,\n internalRef: undefined\n };\n }\n\n // In this case, getSlotProps is responsible for calling the external event handlers.\n // We don't need to include them in the merged props because of this.\n\n const eventHandlers = extractEventHandlers(_extends({}, externalForwardedProps, externalSlotProps));\n const componentsPropsWithoutEventHandlers = omitEventHandlers(externalSlotProps);\n const otherPropsWithoutEventHandlers = omitEventHandlers(externalForwardedProps);\n const internalSlotProps = getSlotProps(eventHandlers);\n\n // The order of classes is important here.\n // Emotion (that we use in libraries consuming Base UI) depends on this order\n // to properly override style. It requires the most important classes to be last\n // (see https://github.com/mui/material-ui/pull/33205) for the related discussion.\n const joinedClasses = clsx(internalSlotProps == null ? void 0 : internalSlotProps.className, additionalProps == null ? void 0 : additionalProps.className, className, externalForwardedProps == null ? void 0 : externalForwardedProps.className, externalSlotProps == null ? void 0 : externalSlotProps.className);\n const mergedStyle = _extends({}, internalSlotProps == null ? void 0 : internalSlotProps.style, additionalProps == null ? void 0 : additionalProps.style, externalForwardedProps == null ? void 0 : externalForwardedProps.style, externalSlotProps == null ? void 0 : externalSlotProps.style);\n const props = _extends({}, internalSlotProps, additionalProps, otherPropsWithoutEventHandlers, componentsPropsWithoutEventHandlers);\n if (joinedClasses.length > 0) {\n props.className = joinedClasses;\n }\n if (Object.keys(mergedStyle).length > 0) {\n props.style = mergedStyle;\n }\n return {\n props,\n internalRef: internalSlotProps.ref\n };\n}", "'use client';\n\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"elementType\", \"externalSlotProps\", \"ownerState\", \"skipResolvingSlotProps\"];\nimport { unstable_useForkRef as useForkRef } from '@mui/utils';\nimport { appendOwnerState } from './appendOwnerState';\nimport { mergeSlotProps } from './mergeSlotProps';\nimport { resolveComponentProps } from './resolveComponentProps';\n/**\n * @ignore - do not document.\n * Builds the props to be passed into the slot of an unstyled component.\n * It merges the internal props of the component with the ones supplied by the user, allowing to customize the behavior.\n * If the slot component is not a host component, it also merges in the `ownerState`.\n *\n * @param parameters.getSlotProps - A function that returns the props to be passed to the slot component.\n */\nexport function useSlotProps(parameters) {\n var _parameters$additiona;\n const {\n elementType,\n externalSlotProps,\n ownerState,\n skipResolvingSlotProps = false\n } = parameters,\n rest = _objectWithoutPropertiesLoose(parameters, _excluded);\n const resolvedComponentsProps = skipResolvingSlotProps ? {} : resolveComponentProps(externalSlotProps, ownerState);\n const {\n props: mergedProps,\n internalRef\n } = mergeSlotProps(_extends({}, rest, {\n externalSlotProps: resolvedComponentsProps\n }));\n const ref = useForkRef(internalRef, resolvedComponentsProps == null ? void 0 : resolvedComponentsProps.ref, (_parameters$additiona = parameters.additionalProps) == null ? void 0 : _parameters$additiona.ref);\n const props = appendOwnerState(elementType, _extends({}, mergedProps, {\n ref\n }), ownerState);\n return props;\n}", "export {};", "export {};", "'use client';\n\nexport { appendOwnerState } from './appendOwnerState';\nexport { areArraysEqual } from './areArraysEqual';\nexport { ClassNameConfigurator } from './ClassNameConfigurator';\nexport { extractEventHandlers } from './extractEventHandlers';\nexport { isHostComponent } from './isHostComponent';\nexport { resolveComponentProps } from './resolveComponentProps';\nexport { useSlotProps } from './useSlotProps';\nexport { mergeSlotProps } from './mergeSlotProps';\nexport { prepareForSlot } from './prepareForSlot';\nexport * from './PolymorphicComponent';\nexport * from './types';", "import { applyDefaultDate } from '../date-utils';\nexport const validateDate = ({\n props,\n value,\n adapter\n}) => {\n if (value === null) {\n return null;\n }\n const {\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n disablePast,\n disableFuture,\n timezone\n } = props;\n const now = adapter.utils.dateWithTimezone(undefined, timezone);\n const minDate = applyDefaultDate(adapter.utils, props.minDate, adapter.defaultDates.minDate);\n const maxDate = applyDefaultDate(adapter.utils, props.maxDate, adapter.defaultDates.maxDate);\n switch (true) {\n case !adapter.utils.isValid(value):\n return 'invalidDate';\n case Boolean(shouldDisableDate && shouldDisableDate(value)):\n return 'shouldDisableDate';\n case Boolean(shouldDisableMonth && shouldDisableMonth(value)):\n return 'shouldDisableMonth';\n case Boolean(shouldDisableYear && shouldDisableYear(value)):\n return 'shouldDisableYear';\n case Boolean(disableFuture && adapter.utils.isAfterDay(value, now)):\n return 'disableFuture';\n case Boolean(disablePast && adapter.utils.isBeforeDay(value, now)):\n return 'disablePast';\n case Boolean(minDate && adapter.utils.isBeforeDay(value, minDate)):\n return 'minDate';\n case Boolean(maxDate && adapter.utils.isAfterDay(value, maxDate)):\n return 'maxDate';\n default:\n return null;\n }\n};", "import * as React from 'react';\nimport { validateDate } from '../internals/utils/validation/validateDate';\nimport { useLocalizationContext } from '../internals/hooks/useUtils';\nexport const useIsDateDisabled = ({\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n minDate,\n maxDate,\n disableFuture,\n disablePast,\n timezone\n}) => {\n const adapter = useLocalizationContext();\n return React.useCallback(day => validateDate({\n adapter,\n value: day,\n props: {\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n minDate,\n maxDate,\n disableFuture,\n disablePast,\n timezone\n }\n }) !== null, [adapter, shouldDisableDate, shouldDisableMonth, shouldDisableYear, minDate, maxDate, disableFuture, disablePast, timezone]);\n};", "import { areViewsEqual } from './views';\nconst timeViews = ['hours', 'minutes', 'seconds'];\nexport const isTimeView = view => timeViews.includes(view);\nexport const isInternalTimeView = view => timeViews.includes(view) || view === 'meridiem';\nexport const getMeridiem = (date, utils) => {\n if (!date) {\n return null;\n }\n return utils.getHours(date) >= 12 ? 'pm' : 'am';\n};\nexport const convertValueToMeridiem = (value, meridiem, ampm) => {\n if (ampm) {\n const currentMeridiem = value >= 12 ? 'pm' : 'am';\n if (currentMeridiem !== meridiem) {\n return meridiem === 'am' ? value - 12 : value + 12;\n }\n }\n return value;\n};\nexport const convertToMeridiem = (time, meridiem, ampm, utils) => {\n const newHoursAmount = convertValueToMeridiem(utils.getHours(time), meridiem, ampm);\n return utils.setHours(time, newHoursAmount);\n};\nexport const getSecondsInDay = (date, utils) => {\n return utils.getHours(date) * 3600 + utils.getMinutes(date) * 60 + utils.getSeconds(date);\n};\nexport const createIsAfterIgnoreDatePart = (disableIgnoringDatePartForTimeValidation, utils) => (dateLeft, dateRight) => {\n if (disableIgnoringDatePartForTimeValidation) {\n return utils.isAfter(dateLeft, dateRight);\n }\n return getSecondsInDay(dateLeft, utils) > getSecondsInDay(dateRight, utils);\n};\nexport const resolveTimeFormat = (utils, {\n format,\n views,\n ampm\n}) => {\n if (format != null) {\n return format;\n }\n const formats = utils.formats;\n if (areViewsEqual(views, ['hours'])) {\n return ampm ? `${formats.hours12h} ${formats.meridiem}` : formats.hours24h;\n }\n if (areViewsEqual(views, ['minutes'])) {\n return formats.minutes;\n }\n if (areViewsEqual(views, ['seconds'])) {\n return formats.seconds;\n }\n if (areViewsEqual(views, ['minutes', 'seconds'])) {\n return `${formats.minutes}:${formats.seconds}`;\n }\n if (areViewsEqual(views, ['hours', 'minutes', 'seconds'])) {\n return ampm ? `${formats.hours12h}:${formats.minutes}:${formats.seconds} ${formats.meridiem}` : `${formats.hours24h}:${formats.minutes}:${formats.seconds}`;\n }\n return ampm ? `${formats.hours12h}:${formats.minutes} ${formats.meridiem}` : `${formats.hours24h}:${formats.minutes}`;\n};", "import { createIsAfterIgnoreDatePart } from './time-utils';\nimport { mergeDateAndTime, getTodayDate } from './date-utils';\nexport const SECTION_TYPE_GRANULARITY = {\n year: 1,\n month: 2,\n day: 3,\n hours: 4,\n minutes: 5,\n seconds: 6,\n milliseconds: 7\n};\nexport const getSectionTypeGranularity = sections => Math.max(...sections.map(section => {\n var _SECTION_TYPE_GRANULA;\n return (_SECTION_TYPE_GRANULA = SECTION_TYPE_GRANULARITY[section.type]) != null ? _SECTION_TYPE_GRANULA : 1;\n}));\nexport const getViewsGranularity = views => Math.max(...views.map(view => {\n var _SECTION_TYPE_GRANULA2;\n return (_SECTION_TYPE_GRANULA2 = SECTION_TYPE_GRANULARITY[view]) != null ? _SECTION_TYPE_GRANULA2 : 1;\n}));\nconst roundDate = (utils, granularity, date) => {\n if (granularity === SECTION_TYPE_GRANULARITY.year) {\n return utils.startOfYear(date);\n }\n if (granularity === SECTION_TYPE_GRANULARITY.month) {\n return utils.startOfMonth(date);\n }\n if (granularity === SECTION_TYPE_GRANULARITY.day) {\n return utils.startOfDay(date);\n }\n\n // We don't have startOfHour / startOfMinute / startOfSecond\n let roundedDate = date;\n if (granularity < SECTION_TYPE_GRANULARITY.minutes) {\n roundedDate = utils.setMinutes(roundedDate, 0);\n }\n if (granularity < SECTION_TYPE_GRANULARITY.seconds) {\n roundedDate = utils.setSeconds(roundedDate, 0);\n }\n if (granularity < SECTION_TYPE_GRANULARITY.milliseconds) {\n roundedDate = utils.setMilliseconds(roundedDate, 0);\n }\n return roundedDate;\n};\nexport const getDefaultReferenceDate = ({\n props,\n utils,\n granularity,\n timezone,\n getTodayDate: inGetTodayDate\n}) => {\n var _props$disableIgnorin;\n let referenceDate = inGetTodayDate ? inGetTodayDate() : roundDate(utils, granularity, getTodayDate(utils, timezone));\n if (props.minDate != null && utils.isAfterDay(props.minDate, referenceDate)) {\n referenceDate = roundDate(utils, granularity, props.minDate);\n }\n if (props.maxDate != null && utils.isBeforeDay(props.maxDate, referenceDate)) {\n referenceDate = roundDate(utils, granularity, props.maxDate);\n }\n const isAfter = createIsAfterIgnoreDatePart((_props$disableIgnorin = props.disableIgnoringDatePartForTimeValidation) != null ? _props$disableIgnorin : false, utils);\n if (props.minTime != null && isAfter(props.minTime, referenceDate)) {\n referenceDate = roundDate(utils, granularity, props.disableIgnoringDatePartForTimeValidation ? props.minTime : mergeDateAndTime(utils, referenceDate, props.minTime));\n }\n if (props.maxTime != null && isAfter(referenceDate, props.maxTime)) {\n referenceDate = roundDate(utils, granularity, props.disableIgnoringDatePartForTimeValidation ? props.maxTime : mergeDateAndTime(utils, referenceDate, props.maxTime));\n }\n return referenceDate;\n};", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"value\", \"referenceDate\"];\nimport { areDatesEqual, getTodayDate, replaceInvalidDateByNull } from './date-utils';\nimport { getDefaultReferenceDate } from './getDefaultReferenceDate';\nimport { addPositionPropertiesToSections, createDateStrForInputFromSections } from '../hooks/useField/useField.utils';\nexport const singleItemValueManager = {\n emptyValue: null,\n getTodayValue: getTodayDate,\n getInitialReferenceValue: _ref => {\n let {\n value,\n referenceDate\n } = _ref,\n params = _objectWithoutPropertiesLoose(_ref, _excluded);\n if (value != null && params.utils.isValid(value)) {\n return value;\n }\n if (referenceDate != null) {\n return referenceDate;\n }\n return getDefaultReferenceDate(params);\n },\n cleanValue: replaceInvalidDateByNull,\n areValuesEqual: areDatesEqual,\n isSameError: (a, b) => a === b,\n hasError: error => error != null,\n defaultErrorState: null,\n getTimezone: (utils, value) => value == null || !utils.isValid(value) ? null : utils.getTimezone(value),\n setTimezone: (utils, timezone, value) => value == null ? null : utils.setTimezone(value, timezone)\n};\nexport const singleItemFieldValueManager = {\n updateReferenceValue: (utils, value, prevReferenceValue) => value == null || !utils.isValid(value) ? prevReferenceValue : value,\n getSectionsFromValue: (utils, date, prevSections, isRTL, getSectionsFromDate) => {\n const shouldReUsePrevDateSections = !utils.isValid(date) && !!prevSections;\n if (shouldReUsePrevDateSections) {\n return prevSections;\n }\n return addPositionPropertiesToSections(getSectionsFromDate(date), isRTL);\n },\n getValueStrFromSections: createDateStrForInputFromSections,\n getActiveDateManager: (utils, state) => ({\n date: state.value,\n referenceDate: state.referenceValue,\n getSections: sections => sections,\n getNewValuesFromNewActiveDate: newActiveDate => ({\n value: newActiveDate,\n referenceValue: newActiveDate == null || !utils.isValid(newActiveDate) ? state.referenceValue : newActiveDate\n })\n }),\n parseValueStr: (valueStr, referenceValue, parseDate) => parseDate(valueStr.trim(), referenceValue)\n};", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport * as React from 'react';\nimport useEventCallback from '@mui/utils/useEventCallback';\nimport { useIsDateDisabled } from './useIsDateDisabled';\nimport { useUtils, useNow } from '../internals/hooks/useUtils';\nimport { singleItemValueManager } from '../internals/utils/valueManagers';\nimport { SECTION_TYPE_GRANULARITY } from '../internals/utils/getDefaultReferenceDate';\nexport const createCalendarStateReducer = (reduceAnimations, disableSwitchToMonthOnDayFocus, utils) => (state, action) => {\n switch (action.type) {\n case 'changeMonth':\n return _extends({}, state, {\n slideDirection: action.direction,\n currentMonth: action.newMonth,\n isMonthSwitchingAnimating: !reduceAnimations\n });\n case 'finishMonthSwitchingAnimation':\n return _extends({}, state, {\n isMonthSwitchingAnimating: false\n });\n case 'changeFocusedDay':\n {\n if (state.focusedDay != null && action.focusedDay != null && utils.isSameDay(action.focusedDay, state.focusedDay)) {\n return state;\n }\n const needMonthSwitch = action.focusedDay != null && !disableSwitchToMonthOnDayFocus && !utils.isSameMonth(state.currentMonth, action.focusedDay);\n return _extends({}, state, {\n focusedDay: action.focusedDay,\n isMonthSwitchingAnimating: needMonthSwitch && !reduceAnimations && !action.withoutMonthSwitchingAnimation,\n currentMonth: needMonthSwitch ? utils.startOfMonth(action.focusedDay) : state.currentMonth,\n slideDirection: action.focusedDay != null && utils.isAfterDay(action.focusedDay, state.currentMonth) ? 'left' : 'right'\n });\n }\n default:\n throw new Error('missing support');\n }\n};\nexport const useCalendarState = params => {\n const {\n value,\n referenceDate: referenceDateProp,\n defaultCalendarMonth,\n disableFuture,\n disablePast,\n disableSwitchToMonthOnDayFocus = false,\n maxDate,\n minDate,\n onMonthChange,\n reduceAnimations,\n shouldDisableDate,\n timezone\n } = params;\n const now = useNow(timezone);\n const utils = useUtils();\n const reducerFn = React.useRef(createCalendarStateReducer(Boolean(reduceAnimations), disableSwitchToMonthOnDayFocus, utils)).current;\n const referenceDate = React.useMemo(() => {\n let externalReferenceDate = null;\n if (referenceDateProp) {\n externalReferenceDate = referenceDateProp;\n } else if (defaultCalendarMonth) {\n // For `defaultCalendarMonth`, we just want to keep the month and the year to avoid a behavior change.\n externalReferenceDate = utils.startOfMonth(defaultCalendarMonth);\n }\n return singleItemValueManager.getInitialReferenceValue({\n value,\n utils,\n timezone,\n props: params,\n referenceDate: externalReferenceDate,\n granularity: SECTION_TYPE_GRANULARITY.day\n });\n }, [] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n const [calendarState, dispatch] = React.useReducer(reducerFn, {\n isMonthSwitchingAnimating: false,\n focusedDay: value || now,\n currentMonth: utils.startOfMonth(referenceDate),\n slideDirection: 'left'\n });\n const handleChangeMonth = React.useCallback(payload => {\n dispatch(_extends({\n type: 'changeMonth'\n }, payload));\n if (onMonthChange) {\n onMonthChange(payload.newMonth);\n }\n }, [onMonthChange]);\n const changeMonth = React.useCallback(newDate => {\n const newDateRequested = newDate;\n if (utils.isSameMonth(newDateRequested, calendarState.currentMonth)) {\n return;\n }\n handleChangeMonth({\n newMonth: utils.startOfMonth(newDateRequested),\n direction: utils.isAfterDay(newDateRequested, calendarState.currentMonth) ? 'left' : 'right'\n });\n }, [calendarState.currentMonth, handleChangeMonth, utils]);\n const isDateDisabled = useIsDateDisabled({\n shouldDisableDate,\n minDate,\n maxDate,\n disableFuture,\n disablePast,\n timezone\n });\n const onMonthSwitchingAnimationEnd = React.useCallback(() => {\n dispatch({\n type: 'finishMonthSwitchingAnimation'\n });\n }, []);\n const changeFocusedDay = useEventCallback((newFocusedDate, withoutMonthSwitchingAnimation) => {\n if (!isDateDisabled(newFocusedDate)) {\n dispatch({\n type: 'changeFocusedDay',\n focusedDay: newFocusedDate,\n withoutMonthSwitchingAnimation\n });\n }\n });\n return {\n referenceDate,\n calendarState,\n changeMonth,\n changeFocusedDay,\n isDateDisabled,\n onMonthSwitchingAnimationEnd,\n handleChangeMonth\n };\n};", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport const getPickersFadeTransitionGroupUtilityClass = slot => generateUtilityClass('MuiPickersFadeTransitionGroup', slot);\nexport const pickersFadeTransitionGroupClasses = generateUtilityClasses('MuiPickersFadeTransitionGroup', ['root']);", "import * as React from 'react';\nimport clsx from 'clsx';\nimport { TransitionGroup } from 'react-transition-group';\nimport Fade from '@mui/material/Fade';\nimport { styled, useTheme, useThemeProps } from '@mui/material/styles';\nimport composeClasses from '@mui/utils/composeClasses';\nimport { getPickersFadeTransitionGroupUtilityClass } from './pickersFadeTransitionGroupClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n classes\n } = ownerState;\n const slots = {\n root: ['root']\n };\n return composeClasses(slots, getPickersFadeTransitionGroupUtilityClass, classes);\n};\nconst PickersFadeTransitionGroupRoot = styled(TransitionGroup, {\n name: 'MuiPickersFadeTransitionGroup',\n slot: 'Root',\n overridesResolver: (_, styles) => styles.root\n})({\n display: 'block',\n position: 'relative'\n});\n\n/**\n * @ignore - do not document.\n */\nexport function PickersFadeTransitionGroup(inProps) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersFadeTransitionGroup'\n });\n const {\n children,\n className,\n reduceAnimations,\n transKey\n } = props;\n const classes = useUtilityClasses(props);\n const theme = useTheme();\n if (reduceAnimations) {\n return children;\n }\n return /*#__PURE__*/_jsx(PickersFadeTransitionGroupRoot, {\n className: clsx(classes.root, className),\n children: /*#__PURE__*/_jsx(Fade, {\n appear: false,\n mountOnEnter: true,\n unmountOnExit: true,\n timeout: {\n appear: theme.transitions.duration.enteringScreen,\n enter: theme.transitions.duration.enteringScreen,\n exit: 0\n },\n children: children\n }, transKey)\n });\n}", "export const DAY_SIZE = 36;\nexport const DAY_MARGIN = 2;\nexport const DIALOG_WIDTH = 320;\nexport const MAX_CALENDAR_HEIGHT = 280;\nexport const VIEW_HEIGHT = 334;\nexport const DIGITAL_CLOCK_VIEW_HEIGHT = 232;\nexport const MULTI_SECTION_CLOCK_SECTION_WIDTH = 48;", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport function getPickersDayUtilityClass(slot) {\n return generateUtilityClass('MuiPickersDay', slot);\n}\nexport const pickersDayClasses = generateUtilityClasses('MuiPickersDay', ['root', 'dayWithMargin', 'dayOutsideMonth', 'hiddenDaySpacingFiller', 'today', 'selected', 'disabled']);", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"autoFocus\", \"className\", \"day\", \"disabled\", \"disableHighlightToday\", \"disableMargin\", \"hidden\", \"isAnimating\", \"onClick\", \"onDaySelect\", \"onFocus\", \"onBlur\", \"onKeyDown\", \"onMouseDown\", \"onMouseEnter\", \"outsideCurrentMonth\", \"selected\", \"showDaysOutsideCurrentMonth\", \"children\", \"today\", \"isFirstVisibleCell\", \"isLastVisibleCell\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport { unstable_useEnhancedEffect as useEnhancedEffect, unstable_composeClasses as composeClasses, unstable_useForkRef as useForkRef } from '@mui/utils';\nimport { alpha, styled, useThemeProps } from '@mui/material/styles';\nimport { useUtils } from '../internals/hooks/useUtils';\nimport { DAY_SIZE, DAY_MARGIN } from '../internals/constants/dimensions';\nimport { getPickersDayUtilityClass, pickersDayClasses } from './pickersDayClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n selected,\n disableMargin,\n disableHighlightToday,\n today,\n disabled,\n outsideCurrentMonth,\n showDaysOutsideCurrentMonth,\n classes\n } = ownerState;\n const isHiddenDaySpacingFiller = outsideCurrentMonth && !showDaysOutsideCurrentMonth;\n const slots = {\n root: ['root', selected && !isHiddenDaySpacingFiller && 'selected', disabled && 'disabled', !disableMargin && 'dayWithMargin', !disableHighlightToday && today && 'today', outsideCurrentMonth && showDaysOutsideCurrentMonth && 'dayOutsideMonth', isHiddenDaySpacingFiller && 'hiddenDaySpacingFiller'],\n hiddenDaySpacingFiller: ['hiddenDaySpacingFiller']\n };\n return composeClasses(slots, getPickersDayUtilityClass, classes);\n};\nconst styleArg = ({\n theme,\n ownerState\n}) => _extends({}, theme.typography.caption, {\n width: DAY_SIZE,\n height: DAY_SIZE,\n borderRadius: '50%',\n padding: 0,\n // explicitly setting to `transparent` to avoid potentially getting impacted by change from the overridden component\n backgroundColor: 'transparent',\n transition: theme.transitions.create('background-color', {\n duration: theme.transitions.duration.short\n }),\n color: (theme.vars || theme).palette.text.primary,\n '@media (pointer: fine)': {\n '&:hover': {\n backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.hoverOpacity)\n }\n },\n '&:focus': {\n backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.focusOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.focusOpacity),\n [`&.${pickersDayClasses.selected}`]: {\n willChange: 'background-color',\n backgroundColor: (theme.vars || theme).palette.primary.dark\n }\n },\n [`&.${pickersDayClasses.selected}`]: {\n color: (theme.vars || theme).palette.primary.contrastText,\n backgroundColor: (theme.vars || theme).palette.primary.main,\n fontWeight: theme.typography.fontWeightMedium,\n '&:hover': {\n willChange: 'background-color',\n backgroundColor: (theme.vars || theme).palette.primary.dark\n }\n },\n [`&.${pickersDayClasses.disabled}:not(.${pickersDayClasses.selected})`]: {\n color: (theme.vars || theme).palette.text.disabled\n },\n [`&.${pickersDayClasses.disabled}&.${pickersDayClasses.selected}`]: {\n opacity: 0.6\n }\n}, !ownerState.disableMargin && {\n margin: `0 ${DAY_MARGIN}px`\n}, ownerState.outsideCurrentMonth && ownerState.showDaysOutsideCurrentMonth && {\n color: (theme.vars || theme).palette.text.secondary\n}, !ownerState.disableHighlightToday && ownerState.today && {\n [`&:not(.${pickersDayClasses.selected})`]: {\n border: `1px solid ${(theme.vars || theme).palette.text.secondary}`\n }\n});\nconst overridesResolver = (props, styles) => {\n const {\n ownerState\n } = props;\n return [styles.root, !ownerState.disableMargin && styles.dayWithMargin, !ownerState.disableHighlightToday && ownerState.today && styles.today, !ownerState.outsideCurrentMonth && ownerState.showDaysOutsideCurrentMonth && styles.dayOutsideMonth, ownerState.outsideCurrentMonth && !ownerState.showDaysOutsideCurrentMonth && styles.hiddenDaySpacingFiller];\n};\nconst PickersDayRoot = styled(ButtonBase, {\n name: 'MuiPickersDay',\n slot: 'Root',\n overridesResolver\n})(styleArg);\nconst PickersDayFiller = styled('div', {\n name: 'MuiPickersDay',\n slot: 'Root',\n overridesResolver\n})(({\n theme,\n ownerState\n}) => _extends({}, styleArg({\n theme,\n ownerState\n}), {\n // visibility: 'hidden' does not work here as it hides the element from screen readers as well\n opacity: 0,\n pointerEvents: 'none'\n}));\nconst noop = () => {};\nconst PickersDayRaw = /*#__PURE__*/React.forwardRef(function PickersDay(inProps, forwardedRef) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersDay'\n });\n const {\n autoFocus = false,\n className,\n day,\n disabled = false,\n disableHighlightToday = false,\n disableMargin = false,\n isAnimating,\n onClick,\n onDaySelect,\n onFocus = noop,\n onBlur = noop,\n onKeyDown = noop,\n onMouseDown = noop,\n onMouseEnter = noop,\n outsideCurrentMonth,\n selected = false,\n showDaysOutsideCurrentMonth = false,\n children,\n today: isToday = false\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const ownerState = _extends({}, props, {\n autoFocus,\n disabled,\n disableHighlightToday,\n disableMargin,\n selected,\n showDaysOutsideCurrentMonth,\n today: isToday\n });\n const classes = useUtilityClasses(ownerState);\n const utils = useUtils();\n const ref = React.useRef(null);\n const handleRef = useForkRef(ref, forwardedRef);\n\n // Since this is rendered when a Popper is opened we can't use passive effects.\n // Focusing in passive effects in Popper causes scroll jump.\n useEnhancedEffect(() => {\n if (autoFocus && !disabled && !isAnimating && !outsideCurrentMonth) {\n // ref.current being null would be a bug in MUI\n ref.current.focus();\n }\n }, [autoFocus, disabled, isAnimating, outsideCurrentMonth]);\n\n // For day outside of current month, move focus from mouseDown to mouseUp\n // Goal: have the onClick ends before sliding to the new month\n const handleMouseDown = event => {\n onMouseDown(event);\n if (outsideCurrentMonth) {\n event.preventDefault();\n }\n };\n const handleClick = event => {\n if (!disabled) {\n onDaySelect(day);\n }\n if (outsideCurrentMonth) {\n event.currentTarget.focus();\n }\n if (onClick) {\n onClick(event);\n }\n };\n if (outsideCurrentMonth && !showDaysOutsideCurrentMonth) {\n return /*#__PURE__*/_jsx(PickersDayFiller, {\n className: clsx(classes.root, classes.hiddenDaySpacingFiller, className),\n ownerState: ownerState,\n role: other.role\n });\n }\n return /*#__PURE__*/_jsx(PickersDayRoot, _extends({\n className: clsx(classes.root, className),\n ref: handleRef,\n centerRipple: true,\n disabled: disabled,\n tabIndex: selected ? 0 : -1,\n onKeyDown: event => onKeyDown(event, day),\n onFocus: event => onFocus(event, day),\n onBlur: event => onBlur(event, day),\n onMouseEnter: event => onMouseEnter(event, day),\n onClick: handleClick,\n onMouseDown: handleMouseDown\n }, other, {\n ownerState: ownerState,\n children: !children ? utils.format(day, 'dayOfMonth') : children\n }));\n});\nprocess.env.NODE_ENV !== \"production\" ? PickersDayRaw.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * A ref for imperative actions.\n * It currently only supports `focusVisible()` action.\n */\n action: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({\n current: PropTypes.shape({\n focusVisible: PropTypes.func.isRequired\n })\n })]),\n /**\n * If `true`, the ripples are centered.\n * They won't start at the cursor interaction position.\n * @default false\n */\n centerRipple: PropTypes.bool,\n /**\n * Override or extend the styles applied to the component.\n */\n classes: PropTypes.object,\n className: PropTypes.string,\n component: PropTypes.elementType,\n /**\n * The date to show.\n */\n day: PropTypes.any.isRequired,\n /**\n * If `true`, renders as disabled.\n * @default false\n */\n disabled: PropTypes.bool,\n /**\n * If `true`, today's date is rendering without highlighting with circle.\n * @default false\n */\n disableHighlightToday: PropTypes.bool,\n /**\n * If `true`, days are rendering without margin. Useful for displaying linked range of days.\n * @default false\n */\n disableMargin: PropTypes.bool,\n /**\n * If `true`, the ripple effect is disabled.\n *\n * \u26A0\uFE0F Without a ripple there is no styling for :focus-visible by default. Be sure\n * to highlight the element by applying separate styles with the `.Mui-focusVisible` class.\n * @default false\n */\n disableRipple: PropTypes.bool,\n /**\n * If `true`, the touch ripple effect is disabled.\n * @default false\n */\n disableTouchRipple: PropTypes.bool,\n /**\n * If `true`, the base button will have a keyboard focus ripple.\n * @default false\n */\n focusRipple: PropTypes.bool,\n /**\n * This prop can help identify which element has keyboard focus.\n * The class name will be applied when the element gains the focus through keyboard interaction.\n * It's a polyfill for the [CSS :focus-visible selector](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo).\n * The rationale for using this feature [is explained here](https://github.com/WICG/focus-visible/blob/HEAD/explainer.md).\n * A [polyfill can be used](https://github.com/WICG/focus-visible) to apply a `focus-visible` class to other components\n * if needed.\n */\n focusVisibleClassName: PropTypes.string,\n isAnimating: PropTypes.bool,\n /**\n * If `true`, day is the first visible cell of the month.\n * Either the first day of the month or the first day of the week depending on `showDaysOutsideCurrentMonth`.\n */\n isFirstVisibleCell: PropTypes.bool.isRequired,\n /**\n * If `true`, day is the last visible cell of the month.\n * Either the last day of the month or the last day of the week depending on `showDaysOutsideCurrentMonth`.\n */\n isLastVisibleCell: PropTypes.bool.isRequired,\n onBlur: PropTypes.func,\n onDaySelect: PropTypes.func.isRequired,\n onFocus: PropTypes.func,\n /**\n * Callback fired when the component is focused with a keyboard.\n * We trigger a `onFocus` callback too.\n */\n onFocusVisible: PropTypes.func,\n onKeyDown: PropTypes.func,\n onMouseEnter: PropTypes.func,\n /**\n * If `true`, day is outside of month and will be hidden.\n */\n outsideCurrentMonth: PropTypes.bool.isRequired,\n /**\n * If `true`, renders as selected.\n * @default false\n */\n selected: PropTypes.bool,\n /**\n * If `true`, days outside the current month are rendered:\n *\n * - if `fixedWeekNumber` is defined, renders days to have the weeks requested.\n *\n * - if `fixedWeekNumber` is not defined, renders day to fill the first and last week of the current month.\n *\n * - ignored if `calendars` equals more than `1` on range pickers.\n * @default false\n */\n showDaysOutsideCurrentMonth: PropTypes.bool,\n style: PropTypes.object,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n /**\n * @default 0\n */\n tabIndex: PropTypes.number,\n /**\n * If `true`, renders as today date.\n * @default false\n */\n today: PropTypes.bool,\n /**\n * Props applied to the `TouchRipple` element.\n */\n TouchRippleProps: PropTypes.object,\n /**\n * A ref that points to the `TouchRipple` element.\n */\n touchRippleRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({\n current: PropTypes.shape({\n pulsate: PropTypes.func.isRequired,\n start: PropTypes.func.isRequired,\n stop: PropTypes.func.isRequired\n })\n })])\n} : void 0;\n\n/**\n * Demos:\n *\n * - [DateCalendar](https://mui.com/x/react-date-pickers/date-calendar/)\n * API:\n *\n * - [PickersDay API](https://mui.com/x/api/date-pickers/pickers-day/)\n */\nexport const PickersDay = /*#__PURE__*/React.memo(PickersDayRaw);", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport const getPickersSlideTransitionUtilityClass = slot => generateUtilityClass('MuiPickersSlideTransition', slot);\nexport const pickersSlideTransitionClasses = generateUtilityClasses('MuiPickersSlideTransition', ['root', 'slideEnter-left', 'slideEnter-right', 'slideEnterActive', 'slideExit', 'slideExitActiveLeft-left', 'slideExitActiveLeft-right']);", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"children\", \"className\", \"reduceAnimations\", \"slideDirection\", \"transKey\", \"classes\"];\nimport * as React from 'react';\nimport clsx from 'clsx';\nimport { styled, useTheme, useThemeProps } from '@mui/material/styles';\nimport composeClasses from '@mui/utils/composeClasses';\nimport { CSSTransition, TransitionGroup } from 'react-transition-group';\nimport { getPickersSlideTransitionUtilityClass, pickersSlideTransitionClasses } from './pickersSlideTransitionClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n classes,\n slideDirection\n } = ownerState;\n const slots = {\n root: ['root'],\n exit: ['slideExit'],\n enterActive: ['slideEnterActive'],\n enter: [`slideEnter-${slideDirection}`],\n exitActive: [`slideExitActiveLeft-${slideDirection}`]\n };\n return composeClasses(slots, getPickersSlideTransitionUtilityClass, classes);\n};\nconst PickersSlideTransitionRoot = styled(TransitionGroup, {\n name: 'MuiPickersSlideTransition',\n slot: 'Root',\n overridesResolver: (_, styles) => [styles.root, {\n [`.${pickersSlideTransitionClasses['slideEnter-left']}`]: styles['slideEnter-left']\n }, {\n [`.${pickersSlideTransitionClasses['slideEnter-right']}`]: styles['slideEnter-right']\n }, {\n [`.${pickersSlideTransitionClasses.slideEnterActive}`]: styles.slideEnterActive\n }, {\n [`.${pickersSlideTransitionClasses.slideExit}`]: styles.slideExit\n }, {\n [`.${pickersSlideTransitionClasses['slideExitActiveLeft-left']}`]: styles['slideExitActiveLeft-left']\n }, {\n [`.${pickersSlideTransitionClasses['slideExitActiveLeft-right']}`]: styles['slideExitActiveLeft-right']\n }]\n})(({\n theme\n}) => {\n const slideTransition = theme.transitions.create('transform', {\n duration: theme.transitions.duration.complex,\n easing: 'cubic-bezier(0.35, 0.8, 0.4, 1)'\n });\n return {\n display: 'block',\n position: 'relative',\n overflowX: 'hidden',\n '& > *': {\n position: 'absolute',\n top: 0,\n right: 0,\n left: 0\n },\n [`& .${pickersSlideTransitionClasses['slideEnter-left']}`]: {\n willChange: 'transform',\n transform: 'translate(100%)',\n zIndex: 1\n },\n [`& .${pickersSlideTransitionClasses['slideEnter-right']}`]: {\n willChange: 'transform',\n transform: 'translate(-100%)',\n zIndex: 1\n },\n [`& .${pickersSlideTransitionClasses.slideEnterActive}`]: {\n transform: 'translate(0%)',\n transition: slideTransition\n },\n [`& .${pickersSlideTransitionClasses.slideExit}`]: {\n transform: 'translate(0%)'\n },\n [`& .${pickersSlideTransitionClasses['slideExitActiveLeft-left']}`]: {\n willChange: 'transform',\n transform: 'translate(-100%)',\n transition: slideTransition,\n zIndex: 0\n },\n [`& .${pickersSlideTransitionClasses['slideExitActiveLeft-right']}`]: {\n willChange: 'transform',\n transform: 'translate(100%)',\n transition: slideTransition,\n zIndex: 0\n }\n };\n});\n\n/**\n * @ignore - do not document.\n */\nexport function PickersSlideTransition(inProps) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersSlideTransition'\n });\n const {\n children,\n className,\n reduceAnimations,\n transKey\n // extracting `classes` from `other`\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const classes = useUtilityClasses(props);\n const theme = useTheme();\n if (reduceAnimations) {\n return /*#__PURE__*/_jsx(\"div\", {\n className: clsx(classes.root, className),\n children: children\n });\n }\n const transitionClasses = {\n exit: classes.exit,\n enterActive: classes.enterActive,\n enter: classes.enter,\n exitActive: classes.exitActive\n };\n return /*#__PURE__*/_jsx(PickersSlideTransitionRoot, {\n className: clsx(classes.root, className),\n childFactory: element => /*#__PURE__*/React.cloneElement(element, {\n classNames: transitionClasses\n }),\n role: \"presentation\",\n children: /*#__PURE__*/_jsx(CSSTransition, _extends({\n mountOnEnter: true,\n unmountOnExit: true,\n timeout: theme.transitions.duration.complex,\n classNames: transitionClasses\n }, other, {\n children: children\n }), transKey)\n });\n}", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport const getDayCalendarUtilityClass = slot => generateUtilityClass('MuiDayCalendar', slot);\nexport const dayPickerClasses = generateUtilityClasses('MuiDayCalendar', ['root', 'header', 'weekDayLabel', 'loadingContainer', 'slideTransition', 'monthContainer', 'weekContainer', 'weekNumberLabel', 'weekNumber']);", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"parentProps\", \"day\", \"focusableDay\", \"selectedDays\", \"isDateDisabled\", \"currentMonthNumber\", \"isViewFocused\"],\n _excluded2 = [\"ownerState\"];\nimport * as React from 'react';\nimport useEventCallback from '@mui/utils/useEventCallback';\nimport Typography from '@mui/material/Typography';\nimport { useSlotProps } from '@mui/base/utils';\nimport { styled, useTheme, useThemeProps } from '@mui/material/styles';\nimport { unstable_composeClasses as composeClasses, unstable_useControlled as useControlled } from '@mui/utils';\nimport clsx from 'clsx';\nimport { PickersDay } from '../PickersDay/PickersDay';\nimport { useUtils, useNow, useLocaleText } from '../internals/hooks/useUtils';\nimport { DAY_SIZE, DAY_MARGIN } from '../internals/constants/dimensions';\nimport { PickersSlideTransition } from './PickersSlideTransition';\nimport { useIsDateDisabled } from './useIsDateDisabled';\nimport { findClosestEnabledDate, getWeekdays } from '../internals/utils/date-utils';\nimport { getDayCalendarUtilityClass } from './dayCalendarClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nimport { jsxs as _jsxs } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n classes\n } = ownerState;\n const slots = {\n root: ['root'],\n header: ['header'],\n weekDayLabel: ['weekDayLabel'],\n loadingContainer: ['loadingContainer'],\n slideTransition: ['slideTransition'],\n monthContainer: ['monthContainer'],\n weekContainer: ['weekContainer'],\n weekNumberLabel: ['weekNumberLabel'],\n weekNumber: ['weekNumber']\n };\n return composeClasses(slots, getDayCalendarUtilityClass, classes);\n};\nconst weeksContainerHeight = (DAY_SIZE + DAY_MARGIN * 2) * 6;\nconst PickersCalendarDayRoot = styled('div', {\n name: 'MuiDayCalendar',\n slot: 'Root',\n overridesResolver: (_, styles) => styles.root\n})({});\nconst PickersCalendarDayHeader = styled('div', {\n name: 'MuiDayCalendar',\n slot: 'Header',\n overridesResolver: (_, styles) => styles.header\n})({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n});\nconst PickersCalendarWeekDayLabel = styled(Typography, {\n name: 'MuiDayCalendar',\n slot: 'WeekDayLabel',\n overridesResolver: (_, styles) => styles.weekDayLabel\n})(({\n theme\n}) => ({\n width: 36,\n height: 40,\n margin: '0 2px',\n textAlign: 'center',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n color: (theme.vars || theme).palette.text.secondary\n}));\nconst PickersCalendarWeekNumberLabel = styled(Typography, {\n name: 'MuiDayCalendar',\n slot: 'WeekNumberLabel',\n overridesResolver: (_, styles) => styles.weekNumberLabel\n})(({\n theme\n}) => ({\n width: 36,\n height: 40,\n margin: '0 2px',\n textAlign: 'center',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n color: theme.palette.text.disabled\n}));\nconst PickersCalendarWeekNumber = styled(Typography, {\n name: 'MuiDayCalendar',\n slot: 'WeekNumber',\n overridesResolver: (_, styles) => styles.weekNumber\n})(({\n theme\n}) => _extends({}, theme.typography.caption, {\n width: DAY_SIZE,\n height: DAY_SIZE,\n padding: 0,\n margin: `0 ${DAY_MARGIN}px`,\n color: theme.palette.text.disabled,\n fontSize: '0.75rem',\n alignItems: 'center',\n justifyContent: 'center',\n display: 'inline-flex'\n}));\nconst PickersCalendarLoadingContainer = styled('div', {\n name: 'MuiDayCalendar',\n slot: 'LoadingContainer',\n overridesResolver: (_, styles) => styles.loadingContainer\n})({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: weeksContainerHeight\n});\nconst PickersCalendarSlideTransition = styled(PickersSlideTransition, {\n name: 'MuiDayCalendar',\n slot: 'SlideTransition',\n overridesResolver: (_, styles) => styles.slideTransition\n})({\n minHeight: weeksContainerHeight\n});\nconst PickersCalendarWeekContainer = styled('div', {\n name: 'MuiDayCalendar',\n slot: 'MonthContainer',\n overridesResolver: (_, styles) => styles.monthContainer\n})({\n overflow: 'hidden'\n});\nconst PickersCalendarWeek = styled('div', {\n name: 'MuiDayCalendar',\n slot: 'WeekContainer',\n overridesResolver: (_, styles) => styles.weekContainer\n})({\n margin: `${DAY_MARGIN}px 0`,\n display: 'flex',\n justifyContent: 'center'\n});\nfunction WrappedDay(_ref) {\n var _ref2, _slots$day, _slotProps$day;\n let {\n parentProps,\n day,\n focusableDay,\n selectedDays,\n isDateDisabled,\n currentMonthNumber,\n isViewFocused\n } = _ref,\n other = _objectWithoutPropertiesLoose(_ref, _excluded);\n const {\n disabled,\n disableHighlightToday,\n isMonthSwitchingAnimating,\n showDaysOutsideCurrentMonth,\n components,\n componentsProps,\n slots,\n slotProps,\n timezone\n } = parentProps;\n const utils = useUtils();\n const now = useNow(timezone);\n const isFocusableDay = focusableDay !== null && utils.isSameDay(day, focusableDay);\n const isSelected = selectedDays.some(selectedDay => utils.isSameDay(selectedDay, day));\n const isToday = utils.isSameDay(day, now);\n const Day = (_ref2 = (_slots$day = slots == null ? void 0 : slots.day) != null ? _slots$day : components == null ? void 0 : components.Day) != null ? _ref2 : PickersDay;\n // We don't want to pass to ownerState down, to avoid re-rendering all the day whenever a prop changes.\n const _useSlotProps = useSlotProps({\n elementType: Day,\n externalSlotProps: (_slotProps$day = slotProps == null ? void 0 : slotProps.day) != null ? _slotProps$day : componentsProps == null ? void 0 : componentsProps.day,\n additionalProps: _extends({\n disableHighlightToday,\n showDaysOutsideCurrentMonth,\n role: 'gridcell',\n isAnimating: isMonthSwitchingAnimating,\n // it is used in date range dragging logic by accessing `dataset.timestamp`\n 'data-timestamp': utils.toJsDate(day).valueOf()\n }, other),\n ownerState: _extends({}, parentProps, {\n day,\n selected: isSelected\n })\n }),\n dayProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded2);\n const isDisabled = React.useMemo(() => disabled || isDateDisabled(day), [disabled, isDateDisabled, day]);\n const outsideCurrentMonth = React.useMemo(() => utils.getMonth(day) !== currentMonthNumber, [utils, day, currentMonthNumber]);\n const isFirstVisibleCell = React.useMemo(() => {\n const startOfMonth = utils.startOfMonth(utils.setMonth(day, currentMonthNumber));\n if (!showDaysOutsideCurrentMonth) {\n return utils.isSameDay(day, startOfMonth);\n }\n return utils.isSameDay(day, utils.startOfWeek(startOfMonth));\n }, [currentMonthNumber, day, showDaysOutsideCurrentMonth, utils]);\n const isLastVisibleCell = React.useMemo(() => {\n const endOfMonth = utils.endOfMonth(utils.setMonth(day, currentMonthNumber));\n if (!showDaysOutsideCurrentMonth) {\n return utils.isSameDay(day, endOfMonth);\n }\n return utils.isSameDay(day, utils.endOfWeek(endOfMonth));\n }, [currentMonthNumber, day, showDaysOutsideCurrentMonth, utils]);\n return /*#__PURE__*/_jsx(Day, _extends({}, dayProps, {\n day: day,\n disabled: isDisabled,\n autoFocus: isViewFocused && isFocusableDay,\n today: isToday,\n outsideCurrentMonth: outsideCurrentMonth,\n isFirstVisibleCell: isFirstVisibleCell,\n isLastVisibleCell: isLastVisibleCell,\n selected: isSelected,\n tabIndex: isFocusableDay ? 0 : -1,\n \"aria-selected\": isSelected,\n \"aria-current\": isToday ? 'date' : undefined\n }));\n}\n\n/**\n * @ignore - do not document.\n */\nexport function DayCalendar(inProps) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiDayCalendar'\n });\n const {\n onFocusedDayChange,\n className,\n currentMonth,\n selectedDays,\n focusedDay,\n loading,\n onSelectedDaysChange,\n onMonthSwitchingAnimationEnd,\n readOnly,\n reduceAnimations,\n renderLoading = () => /*#__PURE__*/_jsx(\"span\", {\n children: \"...\"\n }),\n slideDirection,\n TransitionProps,\n disablePast,\n disableFuture,\n minDate,\n maxDate,\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n dayOfWeekFormatter: dayOfWeekFormatterFromProps,\n hasFocus,\n onFocusedViewChange,\n gridLabelId,\n displayWeekNumber,\n fixedWeekNumber,\n autoFocus,\n timezone\n } = props;\n const now = useNow(timezone);\n const utils = useUtils();\n const classes = useUtilityClasses(props);\n const theme = useTheme();\n const isRTL = theme.direction === 'rtl';\n\n // before we could define this outside of the component scope, but now we need utils, which is only defined here\n const dayOfWeekFormatter = dayOfWeekFormatterFromProps || ((_day, date) => utils.format(date, 'weekdayShort').charAt(0).toUpperCase());\n const isDateDisabled = useIsDateDisabled({\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n timezone\n });\n const localeText = useLocaleText();\n const [internalHasFocus, setInternalHasFocus] = useControlled({\n name: 'DayCalendar',\n state: 'hasFocus',\n controlled: hasFocus,\n default: autoFocus != null ? autoFocus : false\n });\n const [internalFocusedDay, setInternalFocusedDay] = React.useState(() => focusedDay || now);\n const handleDaySelect = useEventCallback(day => {\n if (readOnly) {\n return;\n }\n onSelectedDaysChange(day);\n });\n const focusDay = day => {\n if (!isDateDisabled(day)) {\n onFocusedDayChange(day);\n setInternalFocusedDay(day);\n onFocusedViewChange == null || onFocusedViewChange(true);\n setInternalHasFocus(true);\n }\n };\n const handleKeyDown = useEventCallback((event, day) => {\n switch (event.key) {\n case 'ArrowUp':\n focusDay(utils.addDays(day, -7));\n event.preventDefault();\n break;\n case 'ArrowDown':\n focusDay(utils.addDays(day, 7));\n event.preventDefault();\n break;\n case 'ArrowLeft':\n {\n const newFocusedDayDefault = utils.addDays(day, isRTL ? 1 : -1);\n const nextAvailableMonth = utils.addMonths(day, isRTL ? 1 : -1);\n const closestDayToFocus = findClosestEnabledDate({\n utils,\n date: newFocusedDayDefault,\n minDate: isRTL ? newFocusedDayDefault : utils.startOfMonth(nextAvailableMonth),\n maxDate: isRTL ? utils.endOfMonth(nextAvailableMonth) : newFocusedDayDefault,\n isDateDisabled,\n timezone\n });\n focusDay(closestDayToFocus || newFocusedDayDefault);\n event.preventDefault();\n break;\n }\n case 'ArrowRight':\n {\n const newFocusedDayDefault = utils.addDays(day, isRTL ? -1 : 1);\n const nextAvailableMonth = utils.addMonths(day, isRTL ? -1 : 1);\n const closestDayToFocus = findClosestEnabledDate({\n utils,\n date: newFocusedDayDefault,\n minDate: isRTL ? utils.startOfMonth(nextAvailableMonth) : newFocusedDayDefault,\n maxDate: isRTL ? newFocusedDayDefault : utils.endOfMonth(nextAvailableMonth),\n isDateDisabled,\n timezone\n });\n focusDay(closestDayToFocus || newFocusedDayDefault);\n event.preventDefault();\n break;\n }\n case 'Home':\n focusDay(utils.startOfWeek(day));\n event.preventDefault();\n break;\n case 'End':\n focusDay(utils.endOfWeek(day));\n event.preventDefault();\n break;\n case 'PageUp':\n focusDay(utils.addMonths(day, 1));\n event.preventDefault();\n break;\n case 'PageDown':\n focusDay(utils.addMonths(day, -1));\n event.preventDefault();\n break;\n default:\n break;\n }\n });\n const handleFocus = useEventCallback((event, day) => focusDay(day));\n const handleBlur = useEventCallback((event, day) => {\n if (internalHasFocus && utils.isSameDay(internalFocusedDay, day)) {\n onFocusedViewChange == null || onFocusedViewChange(false);\n }\n });\n const currentMonthNumber = utils.getMonth(currentMonth);\n const validSelectedDays = React.useMemo(() => selectedDays.filter(day => !!day).map(day => utils.startOfDay(day)), [utils, selectedDays]);\n\n // need a new ref whenever the `key` of the transition changes: http://reactcommunity.org/react-transition-group/transition/#Transition-prop-nodeRef.\n const transitionKey = currentMonthNumber;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const slideNodeRef = React.useMemo(() => /*#__PURE__*/React.createRef(), [transitionKey]);\n const startOfCurrentWeek = utils.startOfWeek(now);\n const focusableDay = React.useMemo(() => {\n const startOfMonth = utils.startOfMonth(currentMonth);\n const endOfMonth = utils.endOfMonth(currentMonth);\n if (isDateDisabled(internalFocusedDay) || utils.isAfterDay(internalFocusedDay, endOfMonth) || utils.isBeforeDay(internalFocusedDay, startOfMonth)) {\n return findClosestEnabledDate({\n utils,\n date: internalFocusedDay,\n minDate: startOfMonth,\n maxDate: endOfMonth,\n disablePast,\n disableFuture,\n isDateDisabled,\n timezone\n });\n }\n return internalFocusedDay;\n }, [currentMonth, disableFuture, disablePast, internalFocusedDay, isDateDisabled, utils, timezone]);\n const weeksToDisplay = React.useMemo(() => {\n const currentMonthWithTimezone = utils.setTimezone(currentMonth, timezone);\n const toDisplay = utils.getWeekArray(currentMonthWithTimezone);\n let nextMonth = utils.addMonths(currentMonthWithTimezone, 1);\n while (fixedWeekNumber && toDisplay.length < fixedWeekNumber) {\n const additionalWeeks = utils.getWeekArray(nextMonth);\n const hasCommonWeek = utils.isSameDay(toDisplay[toDisplay.length - 1][0], additionalWeeks[0][0]);\n additionalWeeks.slice(hasCommonWeek ? 1 : 0).forEach(week => {\n if (toDisplay.length < fixedWeekNumber) {\n toDisplay.push(week);\n }\n });\n nextMonth = utils.addMonths(nextMonth, 1);\n }\n return toDisplay;\n }, [currentMonth, fixedWeekNumber, utils, timezone]);\n return /*#__PURE__*/_jsxs(PickersCalendarDayRoot, {\n role: \"grid\",\n \"aria-labelledby\": gridLabelId,\n className: classes.root,\n children: [/*#__PURE__*/_jsxs(PickersCalendarDayHeader, {\n role: \"row\",\n className: classes.header,\n children: [displayWeekNumber && /*#__PURE__*/_jsx(PickersCalendarWeekNumberLabel, {\n variant: \"caption\",\n role: \"columnheader\",\n \"aria-label\": localeText.calendarWeekNumberHeaderLabel,\n className: classes.weekNumberLabel,\n children: localeText.calendarWeekNumberHeaderText\n }), getWeekdays(utils, now).map((weekday, i) => {\n var _dayOfWeekFormatter;\n // regression-prevention:\n // since 'weekdayShort' now always returns an abbreviated form we slice the first 2 letters from it.\n const day = utils.format(weekday, 'weekdayShort').slice(0, 2);\n return /*#__PURE__*/_jsx(PickersCalendarWeekDayLabel, {\n variant: \"caption\",\n role: \"columnheader\",\n \"aria-label\": utils.format(utils.addDays(startOfCurrentWeek, i), 'weekday'),\n className: classes.weekDayLabel,\n children: (_dayOfWeekFormatter = dayOfWeekFormatter == null ? void 0 : dayOfWeekFormatter(day, weekday)) != null ? _dayOfWeekFormatter : day\n }, day + i.toString());\n })]\n }), loading ? /*#__PURE__*/_jsx(PickersCalendarLoadingContainer, {\n className: classes.loadingContainer,\n children: renderLoading()\n }) : /*#__PURE__*/_jsx(PickersCalendarSlideTransition, _extends({\n transKey: transitionKey,\n onExited: onMonthSwitchingAnimationEnd,\n reduceAnimations: reduceAnimations,\n slideDirection: slideDirection,\n className: clsx(className, classes.slideTransition)\n }, TransitionProps, {\n nodeRef: slideNodeRef,\n children: /*#__PURE__*/_jsx(PickersCalendarWeekContainer, {\n ref: slideNodeRef,\n role: \"rowgroup\",\n className: classes.monthContainer,\n children: weeksToDisplay.map((week, index) => /*#__PURE__*/_jsxs(PickersCalendarWeek, {\n role: \"row\",\n className: classes.weekContainer\n // fix issue of announcing row 1 as row 2\n // caused by week day labels row\n ,\n \"aria-rowindex\": index + 1,\n children: [displayWeekNumber && /*#__PURE__*/_jsx(PickersCalendarWeekNumber, {\n className: classes.weekNumber,\n role: \"rowheader\",\n \"aria-label\": localeText.calendarWeekNumberAriaLabelText(utils.getWeekNumber(week[0])),\n children: localeText.calendarWeekNumberText(utils.getWeekNumber(week[0]))\n }), week.map((day, dayIndex) => /*#__PURE__*/_jsx(WrappedDay, {\n parentProps: props,\n day: day,\n selectedDays: validSelectedDays,\n focusableDay: focusableDay,\n onKeyDown: handleKeyDown,\n onFocus: handleFocus,\n onBlur: handleBlur,\n onDaySelect: handleDaySelect,\n isDateDisabled: isDateDisabled,\n currentMonthNumber: currentMonthNumber,\n isViewFocused: internalHasFocus\n // fix issue of announcing column 1 as column 2 when `displayWeekNumber` is enabled\n ,\n \"aria-colindex\": dayIndex + 1\n }, day.toString()))]\n }, `week-${week[0]}`))\n })\n }))]\n });\n}", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport function getPickersMonthUtilityClass(slot) {\n return generateUtilityClass('MuiPickersMonth', slot);\n}\nexport const pickersMonthClasses = generateUtilityClasses('MuiPickersMonth', ['root', 'monthButton', 'disabled', 'selected']);", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"autoFocus\", \"children\", \"disabled\", \"selected\", \"value\", \"tabIndex\", \"onClick\", \"onKeyDown\", \"onFocus\", \"onBlur\", \"aria-current\", \"aria-label\", \"monthsPerRow\"];\nimport * as React from 'react';\nimport { styled, alpha, useThemeProps } from '@mui/material/styles';\nimport { unstable_composeClasses as composeClasses, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';\nimport { getPickersMonthUtilityClass, pickersMonthClasses } from './pickersMonthClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n disabled,\n selected,\n classes\n } = ownerState;\n const slots = {\n root: ['root'],\n monthButton: ['monthButton', disabled && 'disabled', selected && 'selected']\n };\n return composeClasses(slots, getPickersMonthUtilityClass, classes);\n};\nconst PickersMonthRoot = styled('div', {\n name: 'MuiPickersMonth',\n slot: 'Root',\n overridesResolver: (_, styles) => [styles.root]\n})(({\n ownerState\n}) => ({\n flexBasis: ownerState.monthsPerRow === 3 ? '33.3%' : '25%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center'\n}));\nconst PickersMonthButton = styled('button', {\n name: 'MuiPickersMonth',\n slot: 'MonthButton',\n overridesResolver: (_, styles) => [styles.monthButton, {\n [`&.${pickersMonthClasses.disabled}`]: styles.disabled\n }, {\n [`&.${pickersMonthClasses.selected}`]: styles.selected\n }]\n})(({\n theme\n}) => _extends({\n color: 'unset',\n backgroundColor: 'transparent',\n border: 0,\n outline: 0\n}, theme.typography.subtitle1, {\n margin: '8px 0',\n height: 36,\n width: 72,\n borderRadius: 18,\n cursor: 'pointer',\n '&:focus': {\n backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity)\n },\n '&:hover': {\n backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity)\n },\n '&:disabled': {\n cursor: 'auto',\n pointerEvents: 'none'\n },\n [`&.${pickersMonthClasses.disabled}`]: {\n color: (theme.vars || theme).palette.text.secondary\n },\n [`&.${pickersMonthClasses.selected}`]: {\n color: (theme.vars || theme).palette.primary.contrastText,\n backgroundColor: (theme.vars || theme).palette.primary.main,\n '&:focus, &:hover': {\n backgroundColor: (theme.vars || theme).palette.primary.dark\n }\n }\n}));\n\n/**\n * @ignore - do not document.\n */\nexport const PickersMonth = /*#__PURE__*/React.memo(function PickersMonth(inProps) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersMonth'\n });\n const {\n autoFocus,\n children,\n disabled,\n selected,\n value,\n tabIndex,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel\n // We don't want to forward this prop to the root element\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const ref = React.useRef(null);\n const classes = useUtilityClasses(props);\n useEnhancedEffect(() => {\n if (autoFocus) {\n var _ref$current;\n (_ref$current = ref.current) == null || _ref$current.focus();\n }\n }, [autoFocus]);\n return /*#__PURE__*/_jsx(PickersMonthRoot, _extends({\n className: classes.root,\n ownerState: props\n }, other, {\n children: /*#__PURE__*/_jsx(PickersMonthButton, {\n ref: ref,\n disabled: disabled,\n type: \"button\",\n role: \"radio\",\n tabIndex: disabled ? -1 : tabIndex,\n \"aria-current\": ariaCurrent,\n \"aria-checked\": selected,\n \"aria-label\": ariaLabel,\n onClick: event => onClick(event, value),\n onKeyDown: event => onKeyDown(event, value),\n onFocus: event => onFocus(event, value),\n onBlur: event => onBlur(event, value),\n className: classes.monthButton,\n ownerState: props,\n children: children\n })\n }));\n});", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport function getMonthCalendarUtilityClass(slot) {\n return generateUtilityClass('MuiMonthCalendar', slot);\n}\nexport const monthCalendarClasses = generateUtilityClasses('MuiMonthCalendar', ['root']);", "import * as React from 'react';\nimport useEventCallback from '@mui/utils/useEventCallback';\nimport useControlled from '@mui/utils/useControlled';\nimport { useUtils } from './useUtils';\n/**\n * Hooks making sure that:\n * - The value returned by `onChange` always have the timezone of `props.value` or `props.defaultValue` if defined\n * - The value rendered is always the one from `props.timezone` if defined\n */\nexport const useValueWithTimezone = ({\n timezone: timezoneProp,\n value: valueProp,\n defaultValue,\n onChange,\n valueManager\n}) => {\n var _ref, _ref2;\n const utils = useUtils();\n const firstDefaultValue = React.useRef(defaultValue);\n const inputValue = (_ref = valueProp != null ? valueProp : firstDefaultValue.current) != null ? _ref : valueManager.emptyValue;\n const inputTimezone = React.useMemo(() => valueManager.getTimezone(utils, inputValue), [utils, valueManager, inputValue]);\n const setInputTimezone = useEventCallback(newValue => {\n if (inputTimezone == null) {\n return newValue;\n }\n return valueManager.setTimezone(utils, inputTimezone, newValue);\n });\n const timezoneToRender = (_ref2 = timezoneProp != null ? timezoneProp : inputTimezone) != null ? _ref2 : 'default';\n const valueWithTimezoneToRender = React.useMemo(() => valueManager.setTimezone(utils, timezoneToRender, inputValue), [valueManager, utils, timezoneToRender, inputValue]);\n const handleValueChange = useEventCallback((newValue, ...otherParams) => {\n const newValueWithInputTimezone = setInputTimezone(newValue);\n onChange == null || onChange(newValueWithInputTimezone, ...otherParams);\n });\n return {\n value: valueWithTimezoneToRender,\n handleValueChange,\n timezone: timezoneToRender\n };\n};\n\n/**\n * Wrapper around `useControlled` and `useValueWithTimezone`\n */\nexport const useControlledValueWithTimezone = ({\n name,\n timezone: timezoneProp,\n value: valueProp,\n defaultValue,\n onChange: onChangeProp,\n valueManager\n}) => {\n const [valueWithInputTimezone, setValue] = useControlled({\n name,\n state: 'value',\n controlled: valueProp,\n default: defaultValue != null ? defaultValue : valueManager.emptyValue\n });\n const onChange = useEventCallback((newValue, ...otherParams) => {\n setValue(newValue);\n onChangeProp == null || onChangeProp(newValue, ...otherParams);\n });\n return useValueWithTimezone({\n timezone: timezoneProp,\n value: valueWithInputTimezone,\n defaultValue: undefined,\n onChange,\n valueManager\n });\n};", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"className\", \"value\", \"defaultValue\", \"referenceDate\", \"disabled\", \"disableFuture\", \"disablePast\", \"maxDate\", \"minDate\", \"onChange\", \"shouldDisableMonth\", \"readOnly\", \"disableHighlightToday\", \"autoFocus\", \"onMonthFocus\", \"hasFocus\", \"onFocusedViewChange\", \"monthsPerRow\", \"timezone\", \"gridLabelId\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport { useTheme } from '@mui/system';\nimport { styled, useThemeProps } from '@mui/material/styles';\nimport { unstable_useControlled as useControlled, unstable_composeClasses as composeClasses, unstable_useEventCallback as useEventCallback } from '@mui/utils';\nimport { PickersMonth } from './PickersMonth';\nimport { useUtils, useNow, useDefaultDates } from '../internals/hooks/useUtils';\nimport { getMonthCalendarUtilityClass } from './monthCalendarClasses';\nimport { applyDefaultDate, getMonthsInYear } from '../internals/utils/date-utils';\nimport { singleItemValueManager } from '../internals/utils/valueManagers';\nimport { SECTION_TYPE_GRANULARITY } from '../internals/utils/getDefaultReferenceDate';\nimport { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone';\nimport { DIALOG_WIDTH } from '../internals/constants/dimensions';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n classes\n } = ownerState;\n const slots = {\n root: ['root']\n };\n return composeClasses(slots, getMonthCalendarUtilityClass, classes);\n};\nexport function useMonthCalendarDefaultizedProps(props, name) {\n const utils = useUtils();\n const defaultDates = useDefaultDates();\n const themeProps = useThemeProps({\n props,\n name\n });\n return _extends({\n disableFuture: false,\n disablePast: false\n }, themeProps, {\n minDate: applyDefaultDate(utils, themeProps.minDate, defaultDates.minDate),\n maxDate: applyDefaultDate(utils, themeProps.maxDate, defaultDates.maxDate)\n });\n}\nconst MonthCalendarRoot = styled('div', {\n name: 'MuiMonthCalendar',\n slot: 'Root',\n overridesResolver: (props, styles) => styles.root\n})({\n display: 'flex',\n flexWrap: 'wrap',\n alignContent: 'stretch',\n padding: '0 4px',\n width: DIALOG_WIDTH,\n // avoid padding increasing width over defined\n boxSizing: 'border-box'\n});\nexport const MonthCalendar = /*#__PURE__*/React.forwardRef(function MonthCalendar(inProps, ref) {\n const props = useMonthCalendarDefaultizedProps(inProps, 'MuiMonthCalendar');\n const {\n className,\n value: valueProp,\n defaultValue,\n referenceDate: referenceDateProp,\n disabled,\n disableFuture,\n disablePast,\n maxDate,\n minDate,\n onChange,\n shouldDisableMonth,\n readOnly,\n disableHighlightToday,\n autoFocus = false,\n onMonthFocus,\n hasFocus,\n onFocusedViewChange,\n monthsPerRow = 3,\n timezone: timezoneProp,\n gridLabelId\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const {\n value,\n handleValueChange,\n timezone\n } = useControlledValueWithTimezone({\n name: 'MonthCalendar',\n timezone: timezoneProp,\n value: valueProp,\n defaultValue,\n onChange: onChange,\n valueManager: singleItemValueManager\n });\n const now = useNow(timezone);\n const theme = useTheme();\n const utils = useUtils();\n const referenceDate = React.useMemo(() => singleItemValueManager.getInitialReferenceValue({\n value,\n utils,\n props,\n timezone,\n referenceDate: referenceDateProp,\n granularity: SECTION_TYPE_GRANULARITY.month\n }), [] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n const ownerState = props;\n const classes = useUtilityClasses(ownerState);\n const todayMonth = React.useMemo(() => utils.getMonth(now), [utils, now]);\n const selectedMonth = React.useMemo(() => {\n if (value != null) {\n return utils.getMonth(value);\n }\n if (disableHighlightToday) {\n return null;\n }\n return utils.getMonth(referenceDate);\n }, [value, utils, disableHighlightToday, referenceDate]);\n const [focusedMonth, setFocusedMonth] = React.useState(() => selectedMonth || todayMonth);\n const [internalHasFocus, setInternalHasFocus] = useControlled({\n name: 'MonthCalendar',\n state: 'hasFocus',\n controlled: hasFocus,\n default: autoFocus != null ? autoFocus : false\n });\n const changeHasFocus = useEventCallback(newHasFocus => {\n setInternalHasFocus(newHasFocus);\n if (onFocusedViewChange) {\n onFocusedViewChange(newHasFocus);\n }\n });\n const isMonthDisabled = React.useCallback(dateToValidate => {\n const firstEnabledMonth = utils.startOfMonth(disablePast && utils.isAfter(now, minDate) ? now : minDate);\n const lastEnabledMonth = utils.startOfMonth(disableFuture && utils.isBefore(now, maxDate) ? now : maxDate);\n const monthToValidate = utils.startOfMonth(dateToValidate);\n if (utils.isBefore(monthToValidate, firstEnabledMonth)) {\n return true;\n }\n if (utils.isAfter(monthToValidate, lastEnabledMonth)) {\n return true;\n }\n if (!shouldDisableMonth) {\n return false;\n }\n return shouldDisableMonth(monthToValidate);\n }, [disableFuture, disablePast, maxDate, minDate, now, shouldDisableMonth, utils]);\n const handleMonthSelection = useEventCallback((event, month) => {\n if (readOnly) {\n return;\n }\n const newDate = utils.setMonth(value != null ? value : referenceDate, month);\n handleValueChange(newDate);\n });\n const focusMonth = useEventCallback(month => {\n if (!isMonthDisabled(utils.setMonth(value != null ? value : referenceDate, month))) {\n setFocusedMonth(month);\n changeHasFocus(true);\n if (onMonthFocus) {\n onMonthFocus(month);\n }\n }\n });\n React.useEffect(() => {\n setFocusedMonth(prevFocusedMonth => selectedMonth !== null && prevFocusedMonth !== selectedMonth ? selectedMonth : prevFocusedMonth);\n }, [selectedMonth]);\n const handleKeyDown = useEventCallback((event, month) => {\n const monthsInYear = 12;\n const monthsInRow = 3;\n switch (event.key) {\n case 'ArrowUp':\n focusMonth((monthsInYear + month - monthsInRow) % monthsInYear);\n event.preventDefault();\n break;\n case 'ArrowDown':\n focusMonth((monthsInYear + month + monthsInRow) % monthsInYear);\n event.preventDefault();\n break;\n case 'ArrowLeft':\n focusMonth((monthsInYear + month + (theme.direction === 'ltr' ? -1 : 1)) % monthsInYear);\n event.preventDefault();\n break;\n case 'ArrowRight':\n focusMonth((monthsInYear + month + (theme.direction === 'ltr' ? 1 : -1)) % monthsInYear);\n event.preventDefault();\n break;\n default:\n break;\n }\n });\n const handleMonthFocus = useEventCallback((event, month) => {\n focusMonth(month);\n });\n const handleMonthBlur = useEventCallback((event, month) => {\n if (focusedMonth === month) {\n changeHasFocus(false);\n }\n });\n return /*#__PURE__*/_jsx(MonthCalendarRoot, _extends({\n ref: ref,\n className: clsx(classes.root, className),\n ownerState: ownerState,\n role: \"radiogroup\",\n \"aria-labelledby\": gridLabelId\n }, other, {\n children: getMonthsInYear(utils, value != null ? value : referenceDate).map(month => {\n const monthNumber = utils.getMonth(month);\n const monthText = utils.format(month, 'monthShort');\n const monthLabel = utils.format(month, 'month');\n const isSelected = monthNumber === selectedMonth;\n const isDisabled = disabled || isMonthDisabled(month);\n return /*#__PURE__*/_jsx(PickersMonth, {\n selected: isSelected,\n value: monthNumber,\n onClick: handleMonthSelection,\n onKeyDown: handleKeyDown,\n autoFocus: internalHasFocus && monthNumber === focusedMonth,\n disabled: isDisabled,\n tabIndex: monthNumber === focusedMonth ? 0 : -1,\n onFocus: handleMonthFocus,\n onBlur: handleMonthBlur,\n \"aria-current\": todayMonth === monthNumber ? 'date' : undefined,\n \"aria-label\": monthLabel,\n monthsPerRow: monthsPerRow,\n children: monthText\n }, monthText);\n })\n }));\n});\nprocess.env.NODE_ENV !== \"production\" ? MonthCalendar.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n autoFocus: PropTypes.bool,\n /**\n * Override or extend the styles applied to the component.\n */\n classes: PropTypes.object,\n /**\n * className applied to the root element.\n */\n className: PropTypes.string,\n /**\n * The default selected value.\n * Used when the component is not controlled.\n */\n defaultValue: PropTypes.any,\n /**\n * If `true` picker is disabled\n */\n disabled: PropTypes.bool,\n /**\n * If `true`, disable values after the current date for date components, time for time components and both for date time components.\n * @default false\n */\n disableFuture: PropTypes.bool,\n /**\n * If `true`, today's date is rendering without highlighting with circle.\n * @default false\n */\n disableHighlightToday: PropTypes.bool,\n /**\n * If `true`, disable values before the current date for date components, time for time components and both for date time components.\n * @default false\n */\n disablePast: PropTypes.bool,\n gridLabelId: PropTypes.string,\n hasFocus: PropTypes.bool,\n /**\n * Maximal selectable date.\n */\n maxDate: PropTypes.any,\n /**\n * Minimal selectable date.\n */\n minDate: PropTypes.any,\n /**\n * Months rendered per row.\n * @default 3\n */\n monthsPerRow: PropTypes.oneOf([3, 4]),\n /**\n * Callback fired when the value changes.\n * @template TDate\n * @param {TDate} value The new value.\n */\n onChange: PropTypes.func,\n onFocusedViewChange: PropTypes.func,\n onMonthFocus: PropTypes.func,\n /**\n * If `true` picker is readonly\n */\n readOnly: PropTypes.bool,\n /**\n * The date used to generate the new value when both `value` and `defaultValue` are empty.\n * @default The closest valid month using the validation props, except callbacks such as `shouldDisableMonth`.\n */\n referenceDate: PropTypes.any,\n /**\n * Disable specific month.\n * @template TDate\n * @param {TDate} month The month to test.\n * @returns {boolean} If `true`, the month will be disabled.\n */\n shouldDisableMonth: PropTypes.func,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n /**\n * Choose which timezone to use for the value.\n * Example: \"default\", \"system\", \"UTC\", \"America/New_York\".\n * If you pass values from other timezones to some props, they will be converted to this timezone before being used.\n * @see See the {@link https://mui.com/x/react-date-pickers/timezone/ timezones documention} for more details.\n * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.\n */\n timezone: PropTypes.string,\n /**\n * The selected value.\n * Used when the component is controlled.\n */\n value: PropTypes.any\n} : void 0;", "export { MonthCalendar } from './MonthCalendar';\nexport { monthCalendarClasses, getMonthCalendarUtilityClass } from './monthCalendarClasses';\nexport { pickersMonthClasses } from './pickersMonthClasses';", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport function getPickersYearUtilityClass(slot) {\n return generateUtilityClass('MuiPickersYear', slot);\n}\nexport const pickersYearClasses = generateUtilityClasses('MuiPickersYear', ['root', 'yearButton', 'selected', 'disabled']);", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"autoFocus\", \"className\", \"children\", \"disabled\", \"selected\", \"value\", \"tabIndex\", \"onClick\", \"onKeyDown\", \"onFocus\", \"onBlur\", \"aria-current\", \"yearsPerRow\"];\nimport * as React from 'react';\nimport clsx from 'clsx';\nimport { unstable_composeClasses as composeClasses } from '@mui/utils';\nimport { alpha, styled, useThemeProps } from '@mui/material/styles';\nimport { getPickersYearUtilityClass, pickersYearClasses } from './pickersYearClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n disabled,\n selected,\n classes\n } = ownerState;\n const slots = {\n root: ['root'],\n yearButton: ['yearButton', disabled && 'disabled', selected && 'selected']\n };\n return composeClasses(slots, getPickersYearUtilityClass, classes);\n};\nconst PickersYearRoot = styled('div', {\n name: 'MuiPickersYear',\n slot: 'Root',\n overridesResolver: (_, styles) => [styles.root]\n})(({\n ownerState\n}) => ({\n flexBasis: ownerState.yearsPerRow === 3 ? '33.3%' : '25%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center'\n}));\nconst PickersYearButton = styled('button', {\n name: 'MuiPickersYear',\n slot: 'YearButton',\n overridesResolver: (_, styles) => [styles.yearButton, {\n [`&.${pickersYearClasses.disabled}`]: styles.disabled\n }, {\n [`&.${pickersYearClasses.selected}`]: styles.selected\n }]\n})(({\n theme\n}) => _extends({\n color: 'unset',\n backgroundColor: 'transparent',\n border: 0,\n outline: 0\n}, theme.typography.subtitle1, {\n margin: '6px 0',\n height: 36,\n width: 72,\n borderRadius: 18,\n cursor: 'pointer',\n '&:focus': {\n backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.focusOpacity})` : alpha(theme.palette.action.active, theme.palette.action.focusOpacity)\n },\n '&:hover': {\n backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity)\n },\n '&:disabled': {\n cursor: 'auto',\n pointerEvents: 'none'\n },\n [`&.${pickersYearClasses.disabled}`]: {\n color: (theme.vars || theme).palette.text.secondary\n },\n [`&.${pickersYearClasses.selected}`]: {\n color: (theme.vars || theme).palette.primary.contrastText,\n backgroundColor: (theme.vars || theme).palette.primary.main,\n '&:focus, &:hover': {\n backgroundColor: (theme.vars || theme).palette.primary.dark\n }\n }\n}));\n\n/**\n * @ignore - internal component.\n */\nexport const PickersYear = /*#__PURE__*/React.memo(function PickersYear(inProps) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersYear'\n });\n const {\n autoFocus,\n className,\n children,\n disabled,\n selected,\n value,\n tabIndex,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n 'aria-current': ariaCurrent\n // We don't want to forward this prop to the root element\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const ref = React.useRef(null);\n const classes = useUtilityClasses(props);\n\n // We can't forward the `autoFocus` to the button because it is a native button, not a MUI Button\n React.useEffect(() => {\n if (autoFocus) {\n // `ref.current` being `null` would be a bug in MUI.\n ref.current.focus();\n }\n }, [autoFocus]);\n return /*#__PURE__*/_jsx(PickersYearRoot, _extends({\n className: clsx(classes.root, className),\n ownerState: props\n }, other, {\n children: /*#__PURE__*/_jsx(PickersYearButton, {\n ref: ref,\n disabled: disabled,\n type: \"button\",\n role: \"radio\",\n tabIndex: disabled ? -1 : tabIndex,\n \"aria-current\": ariaCurrent,\n \"aria-checked\": selected,\n onClick: event => onClick(event, value),\n onKeyDown: event => onKeyDown(event, value),\n onFocus: event => onFocus(event, value),\n onBlur: event => onBlur(event, value),\n className: classes.yearButton,\n ownerState: props,\n children: children\n })\n }));\n});", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport function getYearCalendarUtilityClass(slot) {\n return generateUtilityClass('MuiYearCalendar', slot);\n}\nexport const yearCalendarClasses = generateUtilityClasses('MuiYearCalendar', ['root']);", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"autoFocus\", \"className\", \"value\", \"defaultValue\", \"referenceDate\", \"disabled\", \"disableFuture\", \"disablePast\", \"maxDate\", \"minDate\", \"onChange\", \"readOnly\", \"shouldDisableYear\", \"disableHighlightToday\", \"onYearFocus\", \"hasFocus\", \"onFocusedViewChange\", \"yearsPerRow\", \"timezone\", \"gridLabelId\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport { useTheme } from '@mui/system';\nimport { styled, useThemeProps } from '@mui/material/styles';\nimport { unstable_useForkRef as useForkRef, unstable_composeClasses as composeClasses, unstable_useControlled as useControlled, unstable_useEventCallback as useEventCallback } from '@mui/utils';\nimport { PickersYear } from './PickersYear';\nimport { useUtils, useNow, useDefaultDates } from '../internals/hooks/useUtils';\nimport { getYearCalendarUtilityClass } from './yearCalendarClasses';\nimport { applyDefaultDate } from '../internals/utils/date-utils';\nimport { singleItemValueManager } from '../internals/utils/valueManagers';\nimport { SECTION_TYPE_GRANULARITY } from '../internals/utils/getDefaultReferenceDate';\nimport { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone';\nimport { DIALOG_WIDTH, MAX_CALENDAR_HEIGHT } from '../internals/constants/dimensions';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n classes\n } = ownerState;\n const slots = {\n root: ['root']\n };\n return composeClasses(slots, getYearCalendarUtilityClass, classes);\n};\nfunction useYearCalendarDefaultizedProps(props, name) {\n var _themeProps$yearsPerR;\n const utils = useUtils();\n const defaultDates = useDefaultDates();\n const themeProps = useThemeProps({\n props,\n name\n });\n return _extends({\n disablePast: false,\n disableFuture: false\n }, themeProps, {\n yearsPerRow: (_themeProps$yearsPerR = themeProps.yearsPerRow) != null ? _themeProps$yearsPerR : 3,\n minDate: applyDefaultDate(utils, themeProps.minDate, defaultDates.minDate),\n maxDate: applyDefaultDate(utils, themeProps.maxDate, defaultDates.maxDate)\n });\n}\nconst YearCalendarRoot = styled('div', {\n name: 'MuiYearCalendar',\n slot: 'Root',\n overridesResolver: (props, styles) => styles.root\n})({\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n overflowY: 'auto',\n height: '100%',\n padding: '0 4px',\n width: DIALOG_WIDTH,\n maxHeight: MAX_CALENDAR_HEIGHT,\n // avoid padding increasing width over defined\n boxSizing: 'border-box',\n position: 'relative'\n});\nexport const YearCalendar = /*#__PURE__*/React.forwardRef(function YearCalendar(inProps, ref) {\n const props = useYearCalendarDefaultizedProps(inProps, 'MuiYearCalendar');\n const {\n autoFocus,\n className,\n value: valueProp,\n defaultValue,\n referenceDate: referenceDateProp,\n disabled,\n disableFuture,\n disablePast,\n maxDate,\n minDate,\n onChange,\n readOnly,\n shouldDisableYear,\n disableHighlightToday,\n onYearFocus,\n hasFocus,\n onFocusedViewChange,\n yearsPerRow,\n timezone: timezoneProp,\n gridLabelId\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const {\n value,\n handleValueChange,\n timezone\n } = useControlledValueWithTimezone({\n name: 'YearCalendar',\n timezone: timezoneProp,\n value: valueProp,\n defaultValue,\n onChange: onChange,\n valueManager: singleItemValueManager\n });\n const now = useNow(timezone);\n const theme = useTheme();\n const utils = useUtils();\n const referenceDate = React.useMemo(() => singleItemValueManager.getInitialReferenceValue({\n value,\n utils,\n props,\n timezone,\n referenceDate: referenceDateProp,\n granularity: SECTION_TYPE_GRANULARITY.year\n }), [] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n const ownerState = props;\n const classes = useUtilityClasses(ownerState);\n const todayYear = React.useMemo(() => utils.getYear(now), [utils, now]);\n const selectedYear = React.useMemo(() => {\n if (value != null) {\n return utils.getYear(value);\n }\n if (disableHighlightToday) {\n return null;\n }\n return utils.getYear(referenceDate);\n }, [value, utils, disableHighlightToday, referenceDate]);\n const [focusedYear, setFocusedYear] = React.useState(() => selectedYear || todayYear);\n const [internalHasFocus, setInternalHasFocus] = useControlled({\n name: 'YearCalendar',\n state: 'hasFocus',\n controlled: hasFocus,\n default: autoFocus != null ? autoFocus : false\n });\n const changeHasFocus = useEventCallback(newHasFocus => {\n setInternalHasFocus(newHasFocus);\n if (onFocusedViewChange) {\n onFocusedViewChange(newHasFocus);\n }\n });\n const isYearDisabled = React.useCallback(dateToValidate => {\n if (disablePast && utils.isBeforeYear(dateToValidate, now)) {\n return true;\n }\n if (disableFuture && utils.isAfterYear(dateToValidate, now)) {\n return true;\n }\n if (minDate && utils.isBeforeYear(dateToValidate, minDate)) {\n return true;\n }\n if (maxDate && utils.isAfterYear(dateToValidate, maxDate)) {\n return true;\n }\n if (!shouldDisableYear) {\n return false;\n }\n const yearToValidate = utils.startOfYear(dateToValidate);\n return shouldDisableYear(yearToValidate);\n }, [disableFuture, disablePast, maxDate, minDate, now, shouldDisableYear, utils]);\n const handleYearSelection = useEventCallback((event, year) => {\n if (readOnly) {\n return;\n }\n const newDate = utils.setYear(value != null ? value : referenceDate, year);\n handleValueChange(newDate);\n });\n const focusYear = useEventCallback(year => {\n if (!isYearDisabled(utils.setYear(value != null ? value : referenceDate, year))) {\n setFocusedYear(year);\n changeHasFocus(true);\n onYearFocus == null || onYearFocus(year);\n }\n });\n React.useEffect(() => {\n setFocusedYear(prevFocusedYear => selectedYear !== null && prevFocusedYear !== selectedYear ? selectedYear : prevFocusedYear);\n }, [selectedYear]);\n const handleKeyDown = useEventCallback((event, year) => {\n switch (event.key) {\n case 'ArrowUp':\n focusYear(year - yearsPerRow);\n event.preventDefault();\n break;\n case 'ArrowDown':\n focusYear(year + yearsPerRow);\n event.preventDefault();\n break;\n case 'ArrowLeft':\n focusYear(year + (theme.direction === 'ltr' ? -1 : 1));\n event.preventDefault();\n break;\n case 'ArrowRight':\n focusYear(year + (theme.direction === 'ltr' ? 1 : -1));\n event.preventDefault();\n break;\n default:\n break;\n }\n });\n const handleYearFocus = useEventCallback((event, year) => {\n focusYear(year);\n });\n const handleYearBlur = useEventCallback((event, year) => {\n if (focusedYear === year) {\n changeHasFocus(false);\n }\n });\n const scrollerRef = React.useRef(null);\n const handleRef = useForkRef(ref, scrollerRef);\n React.useEffect(() => {\n if (autoFocus || scrollerRef.current === null) {\n return;\n }\n const tabbableButton = scrollerRef.current.querySelector('[tabindex=\"0\"]');\n if (!tabbableButton) {\n return;\n }\n\n // Taken from useScroll in x-data-grid, but vertically centered\n const offsetHeight = tabbableButton.offsetHeight;\n const offsetTop = tabbableButton.offsetTop;\n const clientHeight = scrollerRef.current.clientHeight;\n const scrollTop = scrollerRef.current.scrollTop;\n const elementBottom = offsetTop + offsetHeight;\n if (offsetHeight > clientHeight || offsetTop < scrollTop) {\n // Button already visible\n return;\n }\n scrollerRef.current.scrollTop = elementBottom - clientHeight / 2 - offsetHeight / 2;\n }, [autoFocus]);\n return /*#__PURE__*/_jsx(YearCalendarRoot, _extends({\n ref: handleRef,\n className: clsx(classes.root, className),\n ownerState: ownerState,\n role: \"radiogroup\",\n \"aria-labelledby\": gridLabelId\n }, other, {\n children: utils.getYearRange(minDate, maxDate).map(year => {\n const yearNumber = utils.getYear(year);\n const isSelected = yearNumber === selectedYear;\n const isDisabled = disabled || isYearDisabled(year);\n return /*#__PURE__*/_jsx(PickersYear, {\n selected: isSelected,\n value: yearNumber,\n onClick: handleYearSelection,\n onKeyDown: handleKeyDown,\n autoFocus: internalHasFocus && yearNumber === focusedYear,\n disabled: isDisabled,\n tabIndex: yearNumber === focusedYear ? 0 : -1,\n onFocus: handleYearFocus,\n onBlur: handleYearBlur,\n \"aria-current\": todayYear === yearNumber ? 'date' : undefined,\n yearsPerRow: yearsPerRow,\n children: utils.format(year, 'year')\n }, utils.format(year, 'year'));\n })\n }));\n});\nprocess.env.NODE_ENV !== \"production\" ? YearCalendar.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n autoFocus: PropTypes.bool,\n /**\n * Override or extend the styles applied to the component.\n */\n classes: PropTypes.object,\n /**\n * className applied to the root element.\n */\n className: PropTypes.string,\n /**\n * The default selected value.\n * Used when the component is not controlled.\n */\n defaultValue: PropTypes.any,\n /**\n * If `true` picker is disabled\n */\n disabled: PropTypes.bool,\n /**\n * If `true`, disable values after the current date for date components, time for time components and both for date time components.\n * @default false\n */\n disableFuture: PropTypes.bool,\n /**\n * If `true`, today's date is rendering without highlighting with circle.\n * @default false\n */\n disableHighlightToday: PropTypes.bool,\n /**\n * If `true`, disable values before the current date for date components, time for time components and both for date time components.\n * @default false\n */\n disablePast: PropTypes.bool,\n gridLabelId: PropTypes.string,\n hasFocus: PropTypes.bool,\n /**\n * Maximal selectable date.\n */\n maxDate: PropTypes.any,\n /**\n * Minimal selectable date.\n */\n minDate: PropTypes.any,\n /**\n * Callback fired when the value changes.\n * @template TDate\n * @param {TDate} value The new value.\n */\n onChange: PropTypes.func,\n onFocusedViewChange: PropTypes.func,\n onYearFocus: PropTypes.func,\n /**\n * If `true` picker is readonly\n */\n readOnly: PropTypes.bool,\n /**\n * The date used to generate the new value when both `value` and `defaultValue` are empty.\n * @default The closest valid year using the validation props, except callbacks such as `shouldDisableYear`.\n */\n referenceDate: PropTypes.any,\n /**\n * Disable specific year.\n * @template TDate\n * @param {TDate} year The year to test.\n * @returns {boolean} If `true`, the year will be disabled.\n */\n shouldDisableYear: PropTypes.func,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n /**\n * Choose which timezone to use for the value.\n * Example: \"default\", \"system\", \"UTC\", \"America/New_York\".\n * If you pass values from other timezones to some props, they will be converted to this timezone before being used.\n * @see See the {@link https://mui.com/x/react-date-pickers/timezone/ timezones documention} for more details.\n * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.\n */\n timezone: PropTypes.string,\n /**\n * The selected value.\n * Used when the component is controlled.\n */\n value: PropTypes.any,\n /**\n * Years rendered per row.\n * @default 3\n */\n yearsPerRow: PropTypes.oneOf([3, 4])\n} : void 0;", "export { YearCalendar } from './YearCalendar';\nexport { yearCalendarClasses, getYearCalendarUtilityClass } from './yearCalendarClasses';\nexport { pickersYearClasses } from './pickersYearClasses';", "import * as React from 'react';\nimport useEventCallback from '@mui/utils/useEventCallback';\nimport { unstable_useControlled as useControlled } from '@mui/utils';\nlet warnedOnceNotValidView = false;\nexport function useViews({\n onChange,\n onViewChange,\n openTo,\n view: inView,\n views,\n autoFocus,\n focusedView: inFocusedView,\n onFocusedViewChange\n}) {\n var _views, _views2;\n if (process.env.NODE_ENV !== 'production') {\n if (!warnedOnceNotValidView) {\n if (inView != null && !views.includes(inView)) {\n console.warn(`MUI: \\`view=\"${inView}\"\\` is not a valid prop.`, `It must be an element of \\`views=[\"${views.join('\", \"')}\"]\\`.`);\n warnedOnceNotValidView = true;\n }\n if (inView == null && openTo != null && !views.includes(openTo)) {\n console.warn(`MUI: \\`openTo=\"${openTo}\"\\` is not a valid prop.`, `It must be an element of \\`views=[\"${views.join('\", \"')}\"]\\`.`);\n warnedOnceNotValidView = true;\n }\n }\n }\n const previousOpenTo = React.useRef(openTo);\n const previousViews = React.useRef(views);\n const defaultView = React.useRef(views.includes(openTo) ? openTo : views[0]);\n const [view, setView] = useControlled({\n name: 'useViews',\n state: 'view',\n controlled: inView,\n default: defaultView.current\n });\n const defaultFocusedView = React.useRef(autoFocus ? view : null);\n const [focusedView, setFocusedView] = useControlled({\n name: 'useViews',\n state: 'focusedView',\n controlled: inFocusedView,\n default: defaultFocusedView.current\n });\n React.useEffect(() => {\n // Update the current view when `openTo` or `views` props change\n if (previousOpenTo.current && previousOpenTo.current !== openTo || previousViews.current && previousViews.current.some(previousView => !views.includes(previousView))) {\n setView(views.includes(openTo) ? openTo : views[0]);\n previousViews.current = views;\n previousOpenTo.current = openTo;\n }\n }, [openTo, setView, view, views]);\n const viewIndex = views.indexOf(view);\n const previousView = (_views = views[viewIndex - 1]) != null ? _views : null;\n const nextView = (_views2 = views[viewIndex + 1]) != null ? _views2 : null;\n const handleFocusedViewChange = useEventCallback((viewToFocus, hasFocus) => {\n if (hasFocus) {\n // Focus event\n setFocusedView(viewToFocus);\n } else {\n // Blur event\n setFocusedView(prevFocusedView => viewToFocus === prevFocusedView ? null : prevFocusedView // If false the blur is due to view switching\n );\n }\n\n onFocusedViewChange == null || onFocusedViewChange(viewToFocus, hasFocus);\n });\n const handleChangeView = useEventCallback(newView => {\n if (newView === view) {\n return;\n }\n setView(newView);\n handleFocusedViewChange(newView, true);\n if (onViewChange) {\n onViewChange(newView);\n }\n });\n const goToNextView = useEventCallback(() => {\n if (nextView) {\n handleChangeView(nextView);\n }\n handleFocusedViewChange(nextView, true);\n });\n const setValueAndGoToNextView = useEventCallback((value, currentViewSelectionState, selectedView) => {\n const isSelectionFinishedOnCurrentView = currentViewSelectionState === 'finish';\n const hasMoreViews = selectedView ?\n // handles case like `DateTimePicker`, where a view might return a `finish` selection state\n // but we it's not the final view given all `views` -> overall selection state should be `partial`.\n views.indexOf(selectedView) < views.length - 1 : Boolean(nextView);\n const globalSelectionState = isSelectionFinishedOnCurrentView && hasMoreViews ? 'partial' : currentViewSelectionState;\n onChange(value, globalSelectionState);\n if (isSelectionFinishedOnCurrentView) {\n goToNextView();\n }\n });\n const setValueAndGoToView = useEventCallback((value, newView, selectedView) => {\n onChange(value, newView ? 'partial' : 'finish', selectedView);\n if (newView) {\n handleChangeView(newView);\n handleFocusedViewChange(newView, true);\n }\n });\n return {\n view,\n setView: handleChangeView,\n focusedView,\n setFocusedView: handleFocusedViewChange,\n nextView,\n previousView,\n defaultView: defaultView.current,\n goToNextView,\n setValueAndGoToNextView,\n setValueAndGoToView\n };\n}", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport const getPickersCalendarHeaderUtilityClass = slot => generateUtilityClass('MuiPickersCalendarHeader', slot);\nexport const pickersCalendarHeaderClasses = generateUtilityClasses('MuiPickersCalendarHeader', ['root', 'labelContainer', 'label', 'switchViewButton', 'switchViewIcon']);", "import { createSvgIcon } from '@mui/material/utils';\nimport * as React from 'react';\n\n/**\n * @ignore - internal component.\n */\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nimport { jsxs as _jsxs } from \"react/jsx-runtime\";\nexport const ArrowDropDownIcon = createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M7 10l5 5 5-5z\"\n}), 'ArrowDropDown');\n\n/**\n * @ignore - internal component.\n */\nexport const ArrowLeftIcon = createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z\"\n}), 'ArrowLeft');\n\n/**\n * @ignore - internal component.\n */\nexport const ArrowRightIcon = createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\"\n}), 'ArrowRight');\n\n/**\n * @ignore - internal component.\n */\nexport const CalendarIcon = createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z\"\n}), 'Calendar');\n\n/**\n * @ignore - internal component.\n */\nexport const ClockIcon = createSvgIcon( /*#__PURE__*/_jsxs(React.Fragment, {\n children: [/*#__PURE__*/_jsx(\"path\", {\n d: \"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"\n }), /*#__PURE__*/_jsx(\"path\", {\n d: \"M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z\"\n })]\n}), 'Clock');\n\n/**\n * @ignore - internal component.\n */\nexport const DateRangeIcon = createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\"\n}), 'DateRange');\n\n/**\n * @ignore - internal component.\n */\nexport const TimeIcon = createSvgIcon( /*#__PURE__*/_jsxs(React.Fragment, {\n children: [/*#__PURE__*/_jsx(\"path\", {\n d: \"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"\n }), /*#__PURE__*/_jsx(\"path\", {\n d: \"M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z\"\n })]\n}), 'Time');\n\n/**\n * @ignore - internal component.\n */\nexport const ClearIcon = createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n}), 'Clear');", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport function getPickersArrowSwitcherUtilityClass(slot) {\n return generateUtilityClass('MuiPickersArrowSwitcher', slot);\n}\nexport const pickersArrowSwitcherClasses = generateUtilityClasses('MuiPickersArrowSwitcher', ['root', 'spacer', 'button']);", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"children\", \"className\", \"slots\", \"slotProps\", \"isNextDisabled\", \"isNextHidden\", \"onGoToNext\", \"nextLabel\", \"isPreviousDisabled\", \"isPreviousHidden\", \"onGoToPrevious\", \"previousLabel\"],\n _excluded2 = [\"ownerState\"],\n _excluded3 = [\"ownerState\"];\nimport * as React from 'react';\nimport clsx from 'clsx';\nimport Typography from '@mui/material/Typography';\nimport { useTheme, styled, useThemeProps } from '@mui/material/styles';\nimport { unstable_composeClasses as composeClasses } from '@mui/utils';\nimport { useSlotProps } from '@mui/base/utils';\nimport IconButton from '@mui/material/IconButton';\nimport { ArrowLeftIcon, ArrowRightIcon } from '../../../icons';\nimport { getPickersArrowSwitcherUtilityClass } from './pickersArrowSwitcherClasses';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nimport { jsxs as _jsxs } from \"react/jsx-runtime\";\nconst PickersArrowSwitcherRoot = styled('div', {\n name: 'MuiPickersArrowSwitcher',\n slot: 'Root',\n overridesResolver: (props, styles) => styles.root\n})({\n display: 'flex'\n});\nconst PickersArrowSwitcherSpacer = styled('div', {\n name: 'MuiPickersArrowSwitcher',\n slot: 'Spacer',\n overridesResolver: (props, styles) => styles.spacer\n})(({\n theme\n}) => ({\n width: theme.spacing(3)\n}));\nconst PickersArrowSwitcherButton = styled(IconButton, {\n name: 'MuiPickersArrowSwitcher',\n slot: 'Button',\n overridesResolver: (props, styles) => styles.button\n})(({\n ownerState\n}) => _extends({}, ownerState.hidden && {\n visibility: 'hidden'\n}));\nconst useUtilityClasses = ownerState => {\n const {\n classes\n } = ownerState;\n const slots = {\n root: ['root'],\n spacer: ['spacer'],\n button: ['button']\n };\n return composeClasses(slots, getPickersArrowSwitcherUtilityClass, classes);\n};\nexport const PickersArrowSwitcher = /*#__PURE__*/React.forwardRef(function PickersArrowSwitcher(inProps, ref) {\n var _slots$previousIconBu, _slots$nextIconButton, _slots$leftArrowIcon, _slots$rightArrowIcon;\n const theme = useTheme();\n const isRTL = theme.direction === 'rtl';\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersArrowSwitcher'\n });\n const {\n children,\n className,\n slots,\n slotProps,\n isNextDisabled,\n isNextHidden,\n onGoToNext,\n nextLabel,\n isPreviousDisabled,\n isPreviousHidden,\n onGoToPrevious,\n previousLabel\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const ownerState = props;\n const classes = useUtilityClasses(ownerState);\n const nextProps = {\n isDisabled: isNextDisabled,\n isHidden: isNextHidden,\n goTo: onGoToNext,\n label: nextLabel\n };\n const previousProps = {\n isDisabled: isPreviousDisabled,\n isHidden: isPreviousHidden,\n goTo: onGoToPrevious,\n label: previousLabel\n };\n const PreviousIconButton = (_slots$previousIconBu = slots == null ? void 0 : slots.previousIconButton) != null ? _slots$previousIconBu : PickersArrowSwitcherButton;\n const previousIconButtonProps = useSlotProps({\n elementType: PreviousIconButton,\n externalSlotProps: slotProps == null ? void 0 : slotProps.previousIconButton,\n additionalProps: {\n size: 'medium',\n title: previousProps.label,\n 'aria-label': previousProps.label,\n disabled: previousProps.isDisabled,\n edge: 'end',\n onClick: previousProps.goTo\n },\n ownerState: _extends({}, ownerState, {\n hidden: previousProps.isHidden\n }),\n className: classes.button\n });\n const NextIconButton = (_slots$nextIconButton = slots == null ? void 0 : slots.nextIconButton) != null ? _slots$nextIconButton : PickersArrowSwitcherButton;\n const nextIconButtonProps = useSlotProps({\n elementType: NextIconButton,\n externalSlotProps: slotProps == null ? void 0 : slotProps.nextIconButton,\n additionalProps: {\n size: 'medium',\n title: nextProps.label,\n 'aria-label': nextProps.label,\n disabled: nextProps.isDisabled,\n edge: 'start',\n onClick: nextProps.goTo\n },\n ownerState: _extends({}, ownerState, {\n hidden: nextProps.isHidden\n }),\n className: classes.button\n });\n const LeftArrowIcon = (_slots$leftArrowIcon = slots == null ? void 0 : slots.leftArrowIcon) != null ? _slots$leftArrowIcon : ArrowLeftIcon;\n // The spread is here to avoid this bug mui/material-ui#34056\n const _useSlotProps = useSlotProps({\n elementType: LeftArrowIcon,\n externalSlotProps: slotProps == null ? void 0 : slotProps.leftArrowIcon,\n additionalProps: {\n fontSize: 'inherit'\n },\n ownerState: undefined\n }),\n leftArrowIconProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded2);\n const RightArrowIcon = (_slots$rightArrowIcon = slots == null ? void 0 : slots.rightArrowIcon) != null ? _slots$rightArrowIcon : ArrowRightIcon;\n // The spread is here to avoid this bug mui/material-ui#34056\n const _useSlotProps2 = useSlotProps({\n elementType: RightArrowIcon,\n externalSlotProps: slotProps == null ? void 0 : slotProps.rightArrowIcon,\n additionalProps: {\n fontSize: 'inherit'\n },\n ownerState: undefined\n }),\n rightArrowIconProps = _objectWithoutPropertiesLoose(_useSlotProps2, _excluded3);\n return /*#__PURE__*/_jsxs(PickersArrowSwitcherRoot, _extends({\n ref: ref,\n className: clsx(classes.root, className),\n ownerState: ownerState\n }, other, {\n children: [/*#__PURE__*/_jsx(PreviousIconButton, _extends({}, previousIconButtonProps, {\n children: isRTL ? /*#__PURE__*/_jsx(RightArrowIcon, _extends({}, rightArrowIconProps)) : /*#__PURE__*/_jsx(LeftArrowIcon, _extends({}, leftArrowIconProps))\n })), children ? /*#__PURE__*/_jsx(Typography, {\n variant: \"subtitle1\",\n component: \"span\",\n children: children\n }) : /*#__PURE__*/_jsx(PickersArrowSwitcherSpacer, {\n className: classes.spacer,\n ownerState: ownerState\n }), /*#__PURE__*/_jsx(NextIconButton, _extends({}, nextIconButtonProps, {\n children: isRTL ? /*#__PURE__*/_jsx(LeftArrowIcon, _extends({}, leftArrowIconProps)) : /*#__PURE__*/_jsx(RightArrowIcon, _extends({}, rightArrowIconProps))\n }))]\n }));\n});", "export { PickersArrowSwitcher } from './PickersArrowSwitcher';", "import * as React from 'react';\nimport { useUtils } from './useUtils';\nimport { getMeridiem, convertToMeridiem } from '../utils/time-utils';\nexport function useNextMonthDisabled(month, {\n disableFuture,\n maxDate,\n timezone\n}) {\n const utils = useUtils();\n return React.useMemo(() => {\n const now = utils.dateWithTimezone(undefined, timezone);\n const lastEnabledMonth = utils.startOfMonth(disableFuture && utils.isBefore(now, maxDate) ? now : maxDate);\n return !utils.isAfter(lastEnabledMonth, month);\n }, [disableFuture, maxDate, month, utils, timezone]);\n}\nexport function usePreviousMonthDisabled(month, {\n disablePast,\n minDate,\n timezone\n}) {\n const utils = useUtils();\n return React.useMemo(() => {\n const now = utils.dateWithTimezone(undefined, timezone);\n const firstEnabledMonth = utils.startOfMonth(disablePast && utils.isAfter(now, minDate) ? now : minDate);\n return !utils.isBefore(firstEnabledMonth, month);\n }, [disablePast, minDate, month, utils, timezone]);\n}\nexport function useMeridiemMode(date, ampm, onChange, selectionState) {\n const utils = useUtils();\n const meridiemMode = getMeridiem(date, utils);\n const handleMeridiemChange = React.useCallback(mode => {\n const timeWithMeridiem = date == null ? null : convertToMeridiem(date, mode, Boolean(ampm), utils);\n onChange(timeWithMeridiem, selectionState != null ? selectionState : 'partial');\n }, [ampm, date, onChange, selectionState, utils]);\n return {\n meridiemMode,\n handleMeridiemChange\n };\n}", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"slots\", \"slotProps\", \"currentMonth\", \"disabled\", \"disableFuture\", \"disablePast\", \"maxDate\", \"minDate\", \"onMonthChange\", \"onViewChange\", \"view\", \"reduceAnimations\", \"views\", \"labelId\", \"className\", \"timezone\"],\n _excluded2 = [\"ownerState\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport Fade from '@mui/material/Fade';\nimport { styled, useThemeProps } from '@mui/material/styles';\nimport { useSlotProps } from '@mui/base/utils';\nimport { unstable_composeClasses as composeClasses } from '@mui/utils';\nimport IconButton from '@mui/material/IconButton';\nimport { useLocaleText, useUtils } from '../internals/hooks/useUtils';\nimport { PickersFadeTransitionGroup } from '../DateCalendar/PickersFadeTransitionGroup';\nimport { ArrowDropDownIcon } from '../icons';\nimport { PickersArrowSwitcher } from '../internals/components/PickersArrowSwitcher';\nimport { usePreviousMonthDisabled, useNextMonthDisabled } from '../internals/hooks/date-helpers-hooks';\nimport { getPickersCalendarHeaderUtilityClass, pickersCalendarHeaderClasses } from './pickersCalendarHeaderClasses';\n\n// We keep the interface to allow module augmentation\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nimport { jsxs as _jsxs } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n classes\n } = ownerState;\n const slots = {\n root: ['root'],\n labelContainer: ['labelContainer'],\n label: ['label'],\n switchViewButton: ['switchViewButton'],\n switchViewIcon: ['switchViewIcon']\n };\n return composeClasses(slots, getPickersCalendarHeaderUtilityClass, classes);\n};\nconst PickersCalendarHeaderRoot = styled('div', {\n name: 'MuiPickersCalendarHeader',\n slot: 'Root',\n overridesResolver: (_, styles) => styles.root\n})({\n display: 'flex',\n alignItems: 'center',\n marginTop: 16,\n marginBottom: 8,\n paddingLeft: 24,\n paddingRight: 12,\n // prevent jumping in safari\n maxHeight: 30,\n minHeight: 30\n});\nconst PickersCalendarHeaderLabelContainer = styled('div', {\n name: 'MuiPickersCalendarHeader',\n slot: 'LabelContainer',\n overridesResolver: (_, styles) => styles.labelContainer\n})(({\n theme\n}) => _extends({\n display: 'flex',\n overflow: 'hidden',\n alignItems: 'center',\n cursor: 'pointer',\n marginRight: 'auto'\n}, theme.typography.body1, {\n fontWeight: theme.typography.fontWeightMedium\n}));\nconst PickersCalendarHeaderLabel = styled('div', {\n name: 'MuiPickersCalendarHeader',\n slot: 'Label',\n overridesResolver: (_, styles) => styles.label\n})({\n marginRight: 6\n});\nconst PickersCalendarHeaderSwitchViewButton = styled(IconButton, {\n name: 'MuiPickersCalendarHeader',\n slot: 'SwitchViewButton',\n overridesResolver: (_, styles) => styles.switchViewButton\n})(({\n ownerState\n}) => _extends({\n marginRight: 'auto'\n}, ownerState.view === 'year' && {\n [`.${pickersCalendarHeaderClasses.switchViewIcon}`]: {\n transform: 'rotate(180deg)'\n }\n}));\nconst PickersCalendarHeaderSwitchViewIcon = styled(ArrowDropDownIcon, {\n name: 'MuiPickersCalendarHeader',\n slot: 'SwitchViewIcon',\n overridesResolver: (_, styles) => styles.switchViewIcon\n})(({\n theme\n}) => ({\n willChange: 'transform',\n transition: theme.transitions.create('transform'),\n transform: 'rotate(0deg)'\n}));\n/**\n * Demos:\n *\n * - [DateCalendar](https://mui.com/x/react-date-pickers/date-calendar/)\n * - [DateRangeCalendar](https://mui.com/x/react-date-pickers/date-range-calendar/)\n * - [Custom slots and subcomponents](https://mui.com/x/react-date-pickers/custom-components/)\n *\n * API:\n *\n * - [PickersCalendarHeader API](https://mui.com/x/api/date-pickers/pickers-calendar-header/)\n */\nconst PickersCalendarHeader = /*#__PURE__*/React.forwardRef(function PickersCalendarHeader(inProps, ref) {\n var _slots$switchViewButt, _slots$switchViewIcon;\n const localeText = useLocaleText();\n const utils = useUtils();\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersCalendarHeader'\n });\n const {\n slots,\n slotProps,\n currentMonth: month,\n disabled,\n disableFuture,\n disablePast,\n maxDate,\n minDate,\n onMonthChange,\n onViewChange,\n view,\n reduceAnimations,\n views,\n labelId,\n className,\n timezone\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const ownerState = props;\n const classes = useUtilityClasses(props);\n const SwitchViewButton = (_slots$switchViewButt = slots == null ? void 0 : slots.switchViewButton) != null ? _slots$switchViewButt : PickersCalendarHeaderSwitchViewButton;\n const switchViewButtonProps = useSlotProps({\n elementType: SwitchViewButton,\n externalSlotProps: slotProps == null ? void 0 : slotProps.switchViewButton,\n additionalProps: {\n size: 'small',\n 'aria-label': localeText.calendarViewSwitchingButtonAriaLabel(view)\n },\n ownerState,\n className: classes.switchViewButton\n });\n const SwitchViewIcon = (_slots$switchViewIcon = slots == null ? void 0 : slots.switchViewIcon) != null ? _slots$switchViewIcon : PickersCalendarHeaderSwitchViewIcon;\n // The spread is here to avoid this bug mui/material-ui#34056\n const _useSlotProps = useSlotProps({\n elementType: SwitchViewIcon,\n externalSlotProps: slotProps == null ? void 0 : slotProps.switchViewIcon,\n ownerState: undefined,\n className: classes.switchViewIcon\n }),\n switchViewIconProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded2);\n const selectNextMonth = () => onMonthChange(utils.addMonths(month, 1), 'left');\n const selectPreviousMonth = () => onMonthChange(utils.addMonths(month, -1), 'right');\n const isNextMonthDisabled = useNextMonthDisabled(month, {\n disableFuture,\n maxDate,\n timezone\n });\n const isPreviousMonthDisabled = usePreviousMonthDisabled(month, {\n disablePast,\n minDate,\n timezone\n });\n const handleToggleView = () => {\n if (views.length === 1 || !onViewChange || disabled) {\n return;\n }\n if (views.length === 2) {\n onViewChange(views.find(el => el !== view) || views[0]);\n } else {\n // switching only between first 2\n const nextIndexToOpen = views.indexOf(view) !== 0 ? 0 : 1;\n onViewChange(views[nextIndexToOpen]);\n }\n };\n\n // No need to display more information\n if (views.length === 1 && views[0] === 'year') {\n return null;\n }\n return /*#__PURE__*/_jsxs(PickersCalendarHeaderRoot, _extends({}, other, {\n ownerState: ownerState,\n className: clsx(className, classes.root),\n ref: ref,\n children: [/*#__PURE__*/_jsxs(PickersCalendarHeaderLabelContainer, {\n role: \"presentation\",\n onClick: handleToggleView,\n ownerState: ownerState\n // putting this on the label item element below breaks when using transition\n ,\n \"aria-live\": \"polite\",\n className: classes.labelContainer,\n children: [/*#__PURE__*/_jsx(PickersFadeTransitionGroup, {\n reduceAnimations: reduceAnimations,\n transKey: utils.format(month, 'monthAndYear'),\n children: /*#__PURE__*/_jsx(PickersCalendarHeaderLabel, {\n id: labelId,\n ownerState: ownerState,\n className: classes.label,\n children: utils.format(month, 'monthAndYear')\n })\n }), views.length > 1 && !disabled && /*#__PURE__*/_jsx(SwitchViewButton, _extends({}, switchViewButtonProps, {\n children: /*#__PURE__*/_jsx(SwitchViewIcon, _extends({}, switchViewIconProps))\n }))]\n }), /*#__PURE__*/_jsx(Fade, {\n in: view === 'day',\n children: /*#__PURE__*/_jsx(PickersArrowSwitcher, {\n slots: slots,\n slotProps: slotProps,\n onGoToPrevious: selectPreviousMonth,\n isPreviousDisabled: isPreviousMonthDisabled,\n previousLabel: localeText.previousMonth,\n onGoToNext: selectNextMonth,\n isNextDisabled: isNextMonthDisabled,\n nextLabel: localeText.nextMonth\n })\n })]\n }));\n});\nprocess.env.NODE_ENV !== \"production\" ? PickersCalendarHeader.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * Override or extend the styles applied to the component.\n */\n classes: PropTypes.object,\n /**\n * className applied to the root element.\n */\n className: PropTypes.string,\n currentMonth: PropTypes.any.isRequired,\n disabled: PropTypes.bool,\n disableFuture: PropTypes.bool,\n disablePast: PropTypes.bool,\n labelId: PropTypes.string,\n maxDate: PropTypes.any.isRequired,\n minDate: PropTypes.any.isRequired,\n onMonthChange: PropTypes.func.isRequired,\n onViewChange: PropTypes.func,\n reduceAnimations: PropTypes.bool.isRequired,\n /**\n * The props used for each component slot.\n * @default {}\n */\n slotProps: PropTypes.object,\n /**\n * Overridable component slots.\n * @default {}\n */\n slots: PropTypes.object,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n timezone: PropTypes.string.isRequired,\n view: PropTypes.oneOf(['day', 'month', 'year']).isRequired,\n views: PropTypes.arrayOf(PropTypes.oneOf(['day', 'month', 'year']).isRequired).isRequired\n} : void 0;\nexport { PickersCalendarHeader };", "export { pickersCalendarHeaderClasses } from './pickersCalendarHeaderClasses';\nexport { PickersCalendarHeader } from './PickersCalendarHeader';", "import { styled } from '@mui/material/styles';\nimport { DIALOG_WIDTH, VIEW_HEIGHT } from '../../constants/dimensions';\nexport const PickerViewRoot = styled('div')({\n overflow: 'hidden',\n width: DIALOG_WIDTH,\n maxHeight: VIEW_HEIGHT,\n display: 'flex',\n flexDirection: 'column',\n margin: '0 auto'\n});", "export { PickerViewRoot } from './PickerViewRoot';", "import useMediaQuery from '@mui/material/useMediaQuery';\nconst PREFERS_REDUCED_MOTION = '@media (prefers-reduced-motion: reduce)';\n\n// detect if user agent has Android version < 10 or iOS version < 13\nconst mobileVersionMatches = typeof navigator !== 'undefined' && navigator.userAgent.match(/android\\s(\\d+)|OS\\s(\\d+)/i);\nconst androidVersion = mobileVersionMatches && mobileVersionMatches[1] ? parseInt(mobileVersionMatches[1], 10) : null;\nconst iOSVersion = mobileVersionMatches && mobileVersionMatches[2] ? parseInt(mobileVersionMatches[2], 10) : null;\nexport const slowAnimationDevices = androidVersion && androidVersion < 10 || iOSVersion && iOSVersion < 13 || false;\nexport const useDefaultReduceAnimations = () => {\n const prefersReduced = useMediaQuery(PREFERS_REDUCED_MOTION, {\n defaultMatches: false\n });\n return prefersReduced || slowAnimationDevices;\n};", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport const getDateCalendarUtilityClass = slot => generateUtilityClass('MuiDateCalendar', slot);\nexport const dateCalendarClasses = generateUtilityClasses('MuiDateCalendar', ['root', 'viewTransitionContainer']);", "import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nimport _extends from \"@babel/runtime/helpers/esm/extends\";\nconst _excluded = [\"autoFocus\", \"onViewChange\", \"value\", \"defaultValue\", \"referenceDate\", \"disableFuture\", \"disablePast\", \"defaultCalendarMonth\", \"onChange\", \"onYearChange\", \"onMonthChange\", \"reduceAnimations\", \"shouldDisableDate\", \"shouldDisableMonth\", \"shouldDisableYear\", \"view\", \"views\", \"openTo\", \"className\", \"disabled\", \"readOnly\", \"minDate\", \"maxDate\", \"disableHighlightToday\", \"focusedView\", \"onFocusedViewChange\", \"showDaysOutsideCurrentMonth\", \"fixedWeekNumber\", \"dayOfWeekFormatter\", \"components\", \"componentsProps\", \"slots\", \"slotProps\", \"loading\", \"renderLoading\", \"displayWeekNumber\", \"yearsPerRow\", \"monthsPerRow\", \"timezone\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport { useSlotProps } from '@mui/base/utils';\nimport { styled, useThemeProps } from '@mui/material/styles';\nimport { unstable_composeClasses as composeClasses, unstable_useId as useId, unstable_useEventCallback as useEventCallback } from '@mui/utils';\nimport { useCalendarState } from './useCalendarState';\nimport { useDefaultDates, useUtils } from '../internals/hooks/useUtils';\nimport { PickersFadeTransitionGroup } from './PickersFadeTransitionGroup';\nimport { DayCalendar } from './DayCalendar';\nimport { MonthCalendar } from '../MonthCalendar';\nimport { YearCalendar } from '../YearCalendar';\nimport { useViews } from '../internals/hooks/useViews';\nimport { PickersCalendarHeader } from '../PickersCalendarHeader';\nimport { findClosestEnabledDate, applyDefaultDate, mergeDateAndTime } from '../internals/utils/date-utils';\nimport { PickerViewRoot } from '../internals/components/PickerViewRoot';\nimport { useDefaultReduceAnimations } from '../internals/hooks/useDefaultReduceAnimations';\nimport { getDateCalendarUtilityClass } from './dateCalendarClasses';\nimport { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone';\nimport { singleItemValueManager } from '../internals/utils/valueManagers';\nimport { VIEW_HEIGHT } from '../internals/constants/dimensions';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nimport { jsxs as _jsxs } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n classes\n } = ownerState;\n const slots = {\n root: ['root'],\n viewTransitionContainer: ['viewTransitionContainer']\n };\n return composeClasses(slots, getDateCalendarUtilityClass, classes);\n};\nfunction useDateCalendarDefaultizedProps(props, name) {\n var _themeProps$loading, _themeProps$disablePa, _themeProps$disableFu, _themeProps$openTo, _themeProps$views, _themeProps$reduceAni, _themeProps$renderLoa;\n const utils = useUtils();\n const defaultDates = useDefaultDates();\n const defaultReduceAnimations = useDefaultReduceAnimations();\n const themeProps = useThemeProps({\n props,\n name\n });\n return _extends({}, themeProps, {\n loading: (_themeProps$loading = themeProps.loading) != null ? _themeProps$loading : false,\n disablePast: (_themeProps$disablePa = themeProps.disablePast) != null ? _themeProps$disablePa : false,\n disableFuture: (_themeProps$disableFu = themeProps.disableFuture) != null ? _themeProps$disableFu : false,\n openTo: (_themeProps$openTo = themeProps.openTo) != null ? _themeProps$openTo : 'day',\n views: (_themeProps$views = themeProps.views) != null ? _themeProps$views : ['year', 'day'],\n reduceAnimations: (_themeProps$reduceAni = themeProps.reduceAnimations) != null ? _themeProps$reduceAni : defaultReduceAnimations,\n renderLoading: (_themeProps$renderLoa = themeProps.renderLoading) != null ? _themeProps$renderLoa : () => /*#__PURE__*/_jsx(\"span\", {\n children: \"...\"\n }),\n minDate: applyDefaultDate(utils, themeProps.minDate, defaultDates.minDate),\n maxDate: applyDefaultDate(utils, themeProps.maxDate, defaultDates.maxDate)\n });\n}\nconst DateCalendarRoot = styled(PickerViewRoot, {\n name: 'MuiDateCalendar',\n slot: 'Root',\n overridesResolver: (props, styles) => styles.root\n})({\n display: 'flex',\n flexDirection: 'column',\n height: VIEW_HEIGHT\n});\nconst DateCalendarViewTransitionContainer = styled(PickersFadeTransitionGroup, {\n name: 'MuiDateCalendar',\n slot: 'ViewTransitionContainer',\n overridesResolver: (props, styles) => styles.viewTransitionContainer\n})({});\n/**\n *\n * Demos:\n *\n * - [Date Picker](https://mui.com/x/react-date-pickers/date-picker/)\n *\n * API:\n *\n * - [DateCalendar API](https://mui.com/x/api/date-pickers/date-calendar/)\n */\nexport const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(inProps, ref) {\n var _ref, _slots$calendarHeader, _slotProps$calendarHe;\n const utils = useUtils();\n const id = useId();\n const props = useDateCalendarDefaultizedProps(inProps, 'MuiDateCalendar');\n const {\n autoFocus,\n onViewChange,\n value: valueProp,\n defaultValue,\n referenceDate: referenceDateProp,\n disableFuture,\n disablePast,\n defaultCalendarMonth,\n onChange,\n onYearChange,\n onMonthChange,\n reduceAnimations,\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n view: inView,\n views,\n openTo,\n className,\n disabled,\n readOnly,\n minDate,\n maxDate,\n disableHighlightToday,\n focusedView: inFocusedView,\n onFocusedViewChange,\n showDaysOutsideCurrentMonth,\n fixedWeekNumber,\n dayOfWeekFormatter,\n components,\n componentsProps,\n slots,\n slotProps,\n loading,\n renderLoading,\n displayWeekNumber,\n yearsPerRow,\n monthsPerRow,\n timezone: timezoneProp\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const {\n value,\n handleValueChange,\n timezone\n } = useControlledValueWithTimezone({\n name: 'DateCalendar',\n timezone: timezoneProp,\n value: valueProp,\n defaultValue,\n onChange,\n valueManager: singleItemValueManager\n });\n const {\n view,\n setView,\n focusedView,\n setFocusedView,\n goToNextView,\n setValueAndGoToNextView\n } = useViews({\n view: inView,\n views,\n openTo,\n onChange: handleValueChange,\n onViewChange,\n autoFocus,\n focusedView: inFocusedView,\n onFocusedViewChange\n });\n const {\n referenceDate,\n calendarState,\n changeFocusedDay,\n changeMonth,\n handleChangeMonth,\n isDateDisabled,\n onMonthSwitchingAnimationEnd\n } = useCalendarState({\n value,\n defaultCalendarMonth,\n referenceDate: referenceDateProp,\n reduceAnimations,\n onMonthChange,\n minDate,\n maxDate,\n shouldDisableDate,\n disablePast,\n disableFuture,\n timezone\n });\n\n // When disabled, limit the view to the selected date\n const minDateWithDisabled = disabled && value || minDate;\n const maxDateWithDisabled = disabled && value || maxDate;\n const gridLabelId = `${id}-grid-label`;\n const hasFocus = focusedView !== null;\n const CalendarHeader = (_ref = (_slots$calendarHeader = slots == null ? void 0 : slots.calendarHeader) != null ? _slots$calendarHeader : components == null ? void 0 : components.CalendarHeader) != null ? _ref : PickersCalendarHeader;\n const calendarHeaderProps = useSlotProps({\n elementType: CalendarHeader,\n externalSlotProps: (_slotProps$calendarHe = slotProps == null ? void 0 : slotProps.calendarHeader) != null ? _slotProps$calendarHe : componentsProps == null ? void 0 : componentsProps.calendarHeader,\n additionalProps: {\n views,\n view,\n currentMonth: calendarState.currentMonth,\n onViewChange: setView,\n onMonthChange: (newMonth, direction) => handleChangeMonth({\n newMonth,\n direction\n }),\n minDate: minDateWithDisabled,\n maxDate: maxDateWithDisabled,\n disabled,\n disablePast,\n disableFuture,\n reduceAnimations,\n timezone,\n labelId: gridLabelId,\n slots,\n slotProps\n },\n ownerState: props\n });\n const handleDateMonthChange = useEventCallback(newDate => {\n const startOfMonth = utils.startOfMonth(newDate);\n const endOfMonth = utils.endOfMonth(newDate);\n const closestEnabledDate = isDateDisabled(newDate) ? findClosestEnabledDate({\n utils,\n date: newDate,\n minDate: utils.isBefore(minDate, startOfMonth) ? startOfMonth : minDate,\n maxDate: utils.isAfter(maxDate, endOfMonth) ? endOfMonth : maxDate,\n disablePast,\n disableFuture,\n isDateDisabled,\n timezone\n }) : newDate;\n if (closestEnabledDate) {\n setValueAndGoToNextView(closestEnabledDate, 'finish');\n onMonthChange == null || onMonthChange(startOfMonth);\n } else {\n goToNextView();\n changeMonth(startOfMonth);\n }\n changeFocusedDay(closestEnabledDate, true);\n });\n const handleDateYearChange = useEventCallback(newDate => {\n const startOfYear = utils.startOfYear(newDate);\n const endOfYear = utils.endOfYear(newDate);\n const closestEnabledDate = isDateDisabled(newDate) ? findClosestEnabledDate({\n utils,\n date: newDate,\n minDate: utils.isBefore(minDate, startOfYear) ? startOfYear : minDate,\n maxDate: utils.isAfter(maxDate, endOfYear) ? endOfYear : maxDate,\n disablePast,\n disableFuture,\n isDateDisabled,\n timezone\n }) : newDate;\n if (closestEnabledDate) {\n setValueAndGoToNextView(closestEnabledDate, 'finish');\n onYearChange == null || onYearChange(closestEnabledDate);\n } else {\n goToNextView();\n changeMonth(startOfYear);\n }\n changeFocusedDay(closestEnabledDate, true);\n });\n const handleSelectedDayChange = useEventCallback(day => {\n if (day) {\n // If there is a date already selected, then we want to keep its time\n return handleValueChange(mergeDateAndTime(utils, day, value != null ? value : referenceDate), 'finish');\n }\n return handleValueChange(day, 'finish');\n });\n React.useEffect(() => {\n if (value != null && utils.isValid(value)) {\n changeMonth(value);\n }\n }, [value]); // eslint-disable-line\n\n const ownerState = props;\n const classes = useUtilityClasses(ownerState);\n const baseDateValidationProps = {\n disablePast,\n disableFuture,\n maxDate,\n minDate\n };\n const commonViewProps = {\n disableHighlightToday,\n readOnly,\n disabled,\n timezone,\n gridLabelId\n };\n const prevOpenViewRef = React.useRef(view);\n React.useEffect(() => {\n // If the view change and the focus was on the previous view\n // Then we update the focus.\n if (prevOpenViewRef.current === view) {\n return;\n }\n if (focusedView === prevOpenViewRef.current) {\n setFocusedView(view, true);\n }\n prevOpenViewRef.current = view;\n }, [focusedView, setFocusedView, view]);\n const selectedDays = React.useMemo(() => [value], [value]);\n return /*#__PURE__*/_jsxs(DateCalendarRoot, _extends({\n ref: ref,\n className: clsx(classes.root, className),\n ownerState: ownerState\n }, other, {\n children: [/*#__PURE__*/_jsx(CalendarHeader, _extends({}, calendarHeaderProps)), /*#__PURE__*/_jsx(DateCalendarViewTransitionContainer, {\n reduceAnimations: reduceAnimations,\n className: classes.viewTransitionContainer,\n transKey: view,\n ownerState: ownerState,\n children: /*#__PURE__*/_jsxs(\"div\", {\n children: [view === 'year' && /*#__PURE__*/_jsx(YearCalendar, _extends({}, baseDateValidationProps, commonViewProps, {\n value: value,\n onChange: handleDateYearChange,\n shouldDisableYear: shouldDisableYear,\n hasFocus: hasFocus,\n onFocusedViewChange: isViewFocused => setFocusedView('year', isViewFocused),\n yearsPerRow: yearsPerRow,\n referenceDate: referenceDate\n })), view === 'month' && /*#__PURE__*/_jsx(MonthCalendar, _extends({}, baseDateValidationProps, commonViewProps, {\n hasFocus: hasFocus,\n className: className,\n value: value,\n onChange: handleDateMonthChange,\n shouldDisableMonth: shouldDisableMonth,\n onFocusedViewChange: isViewFocused => setFocusedView('month', isViewFocused),\n monthsPerRow: monthsPerRow,\n referenceDate: referenceDate\n })), view === 'day' && /*#__PURE__*/_jsx(DayCalendar, _extends({}, calendarState, baseDateValidationProps, commonViewProps, {\n onMonthSwitchingAnimationEnd: onMonthSwitchingAnimationEnd,\n onFocusedDayChange: changeFocusedDay,\n reduceAnimations: reduceAnimations,\n selectedDays: selectedDays,\n onSelectedDaysChange: handleSelectedDayChange,\n shouldDisableDate: shouldDisableDate,\n shouldDisableMonth: shouldDisableMonth,\n shouldDisableYear: shouldDisableYear,\n hasFocus: hasFocus,\n onFocusedViewChange: isViewFocused => setFocusedView('day', isViewFocused),\n showDaysOutsideCurrentMonth: showDaysOutsideCurrentMonth,\n fixedWeekNumber: fixedWeekNumber,\n dayOfWeekFormatter: dayOfWeekFormatter,\n displayWeekNumber: displayWeekNumber,\n components: components,\n componentsProps: componentsProps,\n slots: slots,\n slotProps: slotProps,\n loading: loading,\n renderLoading: renderLoading\n }))]\n })\n })]\n }));\n});\nprocess.env.NODE_ENV !== \"production\" ? DateCalendar.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * If `true`, the main element is focused during the first mount.\n * This main element is:\n * - the element chosen by the visible view if any (i.e: the selected day on the `day` view).\n * - the `input` element if there is a field rendered.\n */\n autoFocus: PropTypes.bool,\n classes: PropTypes.object,\n className: PropTypes.string,\n /**\n * Overridable components.\n * @default {}\n * @deprecated Please use `slots`.\n */\n components: PropTypes.object,\n /**\n * The props used for each component slot.\n * @default {}\n * @deprecated Please use `slotProps`.\n */\n componentsProps: PropTypes.object,\n /**\n * Formats the day of week displayed in the calendar header.\n * @param {string} day The day of week provided by the adapter. Deprecated, will be removed in v7: Use `date` instead.\n * @param {TDate} date The date of the day of week provided by the adapter.\n * @returns {string} The name to display.\n * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()\n */\n dayOfWeekFormatter: PropTypes.func,\n /**\n * Default calendar month displayed when `value` and `defaultValue` are empty.\n */\n defaultCalendarMonth: PropTypes.any,\n /**\n * The default selected value.\n * Used when the component is not controlled.\n */\n defaultValue: PropTypes.any,\n /**\n * If `true`, the picker and text field are disabled.\n * @default false\n */\n disabled: PropTypes.bool,\n /**\n * If `true`, disable values after the current date for date components, time for time components and both for date time components.\n * @default false\n */\n disableFuture: PropTypes.bool,\n /**\n * If `true`, today's date is rendering without highlighting with circle.\n * @default false\n */\n disableHighlightToday: PropTypes.bool,\n /**\n * If `true`, disable values before the current date for date components, time for time components and both for date time components.\n * @default false\n */\n disablePast: PropTypes.bool,\n /**\n * If `true`, the week number will be display in the calendar.\n */\n displayWeekNumber: PropTypes.bool,\n /**\n * Calendar will show more weeks in order to match this value.\n * Put it to 6 for having fix number of week in Gregorian calendars\n * @default undefined\n */\n fixedWeekNumber: PropTypes.number,\n /**\n * Controlled focused view.\n */\n focusedView: PropTypes.oneOf(['day', 'month', 'year']),\n /**\n * If `true`, calls `renderLoading` instead of rendering the day calendar.\n * Can be used to preload information and show it in calendar.\n * @default false\n */\n loading: PropTypes.bool,\n /**\n * Maximal selectable date.\n */\n maxDate: PropTypes.any,\n /**\n * Minimal selectable date.\n */\n minDate: PropTypes.any,\n /**\n * Months rendered per row.\n * @default 3\n */\n monthsPerRow: PropTypes.oneOf([3, 4]),\n /**\n * Callback fired when the value changes.\n * @template TDate\n * @param {TDate | null} value The new value.\n * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.\n */\n onChange: PropTypes.func,\n /**\n * Callback fired on focused view change.\n * @template TView\n * @param {TView} view The new view to focus or not.\n * @param {boolean} hasFocus `true` if the view should be focused.\n */\n onFocusedViewChange: PropTypes.func,\n /**\n * Callback fired on month change.\n * @template TDate\n * @param {TDate} month The new month.\n */\n onMonthChange: PropTypes.func,\n /**\n * Callback fired on view change.\n * @template TView\n * @param {TView} view The new view.\n */\n onViewChange: PropTypes.func,\n /**\n * Callback fired on year change.\n * @template TDate\n * @param {TDate} year The new year.\n */\n onYearChange: PropTypes.func,\n /**\n * The default visible view.\n * Used when the component view is not controlled.\n * Must be a valid option from `views` list.\n */\n openTo: PropTypes.oneOf(['day', 'month', 'year']),\n /**\n * Make picker read only.\n * @default false\n */\n readOnly: PropTypes.bool,\n /**\n * If `true`, disable heavy animations.\n * @default `@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13\n */\n reduceAnimations: PropTypes.bool,\n /**\n * The date used to generate the new value when both `value` and `defaultValue` are empty.\n * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`.\n */\n referenceDate: PropTypes.any,\n /**\n * Component displaying when passed `loading` true.\n * @returns {React.ReactNode} The node to render when loading.\n * @default () => ...\n */\n renderLoading: PropTypes.func,\n /**\n * Disable specific date.\n *\n * Warning: This function can be called multiple times (e.g. when rendering date calendar, checking if focus can be moved to a certain date, etc.). Expensive computations can impact performance.\n *\n * @template TDate\n * @param {TDate} day The date to test.\n * @returns {boolean} If `true` the date will be disabled.\n */\n shouldDisableDate: PropTypes.func,\n /**\n * Disable specific month.\n * @template TDate\n * @param {TDate} month The month to test.\n * @returns {boolean} If `true`, the month will be disabled.\n */\n shouldDisableMonth: PropTypes.func,\n /**\n * Disable specific year.\n * @template TDate\n * @param {TDate} year The year to test.\n * @returns {boolean} If `true`, the year will be disabled.\n */\n shouldDisableYear: PropTypes.func,\n /**\n * If `true`, days outside the current month are rendered:\n *\n * - if `fixedWeekNumber` is defined, renders days to have the weeks requested.\n *\n * - if `fixedWeekNumber` is not defined, renders day to fill the first and last week of the current month.\n *\n * - ignored if `calendars` equals more than `1` on range pickers.\n * @default false\n */\n showDaysOutsideCurrentMonth: PropTypes.bool,\n /**\n * The props used for each component slot.\n * @default {}\n */\n slotProps: PropTypes.object,\n /**\n * Overridable component slots.\n * @default {}\n */\n slots: PropTypes.object,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n /**\n * Choose which timezone to use for the value.\n * Example: \"default\", \"system\", \"UTC\", \"America/New_York\".\n * If you pass values from other timezones to some props, they will be converted to this timezone before being used.\n * @see See the {@link https://mui.com/x/react-date-pickers/timezone/ timezones documention} for more details.\n * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.\n */\n timezone: PropTypes.string,\n /**\n * The selected value.\n * Used when the component is controlled.\n */\n value: PropTypes.any,\n /**\n * The visible view.\n * Used when the component view is controlled.\n * Must be a valid option from `views` list.\n */\n view: PropTypes.oneOf(['day', 'month', 'year']),\n /**\n * Available views.\n */\n views: PropTypes.arrayOf(PropTypes.oneOf(['day', 'month', 'year']).isRequired),\n /**\n * Years rendered per row.\n * @default 3\n */\n yearsPerRow: PropTypes.oneOf([3, 4])\n} : void 0;", "export { DateCalendar } from './DateCalendar';\nexport { getDateCalendarUtilityClass, dateCalendarClasses } from './dateCalendarClasses';\nexport { dayPickerClasses } from './dayCalendarClasses';\nexport { pickersFadeTransitionGroupClasses } from './pickersFadeTransitionGroupClasses';\nexport { pickersSlideTransitionClasses } from './pickersSlideTransitionClasses';\n// TODO v7: Remove and export the `PickersCalendarHeader` folder from the root instead.\nexport * from '../PickersCalendarHeader';", "import * as React from 'react';\nimport { DateCalendar } from '../DateCalendar';\nimport { isDatePickerView } from '../internals/utils/date-utils';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport const renderDateViewCalendar = ({\n view,\n onViewChange,\n views,\n focusedView,\n onFocusedViewChange,\n value,\n defaultValue,\n referenceDate,\n onChange,\n className,\n classes,\n disableFuture,\n disablePast,\n minDate,\n maxDate,\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n reduceAnimations,\n onMonthChange,\n monthsPerRow,\n onYearChange,\n yearsPerRow,\n defaultCalendarMonth,\n components,\n componentsProps,\n slots,\n slotProps,\n loading,\n renderLoading,\n disableHighlightToday,\n readOnly,\n disabled,\n showDaysOutsideCurrentMonth,\n dayOfWeekFormatter,\n sx,\n autoFocus,\n fixedWeekNumber,\n displayWeekNumber,\n timezone\n}) => /*#__PURE__*/_jsx(DateCalendar, {\n view: view,\n onViewChange: onViewChange,\n views: views.filter(isDatePickerView),\n focusedView: focusedView && isDatePickerView(focusedView) ? focusedView : null,\n onFocusedViewChange: onFocusedViewChange,\n value: value,\n defaultValue: defaultValue,\n referenceDate: referenceDate,\n onChange: onChange,\n className: className,\n classes: classes,\n disableFuture: disableFuture,\n disablePast: disablePast,\n minDate: minDate,\n maxDate: maxDate,\n shouldDisableDate: shouldDisableDate,\n shouldDisableMonth: shouldDisableMonth,\n shouldDisableYear: shouldDisableYear,\n reduceAnimations: reduceAnimations,\n onMonthChange: onMonthChange,\n monthsPerRow: monthsPerRow,\n onYearChange: onYearChange,\n yearsPerRow: yearsPerRow,\n defaultCalendarMonth: defaultCalendarMonth,\n components: components,\n componentsProps: componentsProps,\n slots: slots,\n slotProps: slotProps,\n loading: loading,\n renderLoading: renderLoading,\n disableHighlightToday: disableHighlightToday,\n readOnly: readOnly,\n disabled: disabled,\n showDaysOutsideCurrentMonth: showDaysOutsideCurrentMonth,\n dayOfWeekFormatter: dayOfWeekFormatter,\n sx: sx,\n autoFocus: autoFocus,\n fixedWeekNumber: fixedWeekNumber,\n displayWeekNumber: displayWeekNumber,\n timezone: timezone\n});", "export { renderDateViewCalendar } from './dateViewRenderers';", "import * as React from 'react';\nexport const useOpenState = ({\n open,\n onOpen,\n onClose\n}) => {\n const isControllingOpenProp = React.useRef(typeof open === 'boolean').current;\n const [openState, setIsOpenState] = React.useState(false);\n\n // It is required to update inner state in useEffect in order to avoid situation when\n // Our component is not mounted yet, but `open` state is set to `true` (e.g. initially opened)\n React.useEffect(() => {\n if (isControllingOpenProp) {\n if (typeof open !== 'boolean') {\n throw new Error('You must not mix controlling and uncontrolled mode for `open` prop');\n }\n setIsOpenState(open);\n }\n }, [isControllingOpenProp, open]);\n const setIsOpen = React.useCallback(newIsOpen => {\n if (!isControllingOpenProp) {\n setIsOpenState(newIsOpen);\n }\n if (newIsOpen && onOpen) {\n onOpen();\n }\n if (!newIsOpen && onClose) {\n onClose();\n }\n }, [isControllingOpenProp, onOpen, onClose]);\n return {\n isOpen: openState,\n setIsOpen\n };\n};", "import * as React from 'react';\nimport { useLocalizationContext } from './useUtils';\nexport function useValidation(props, validate, isSameError, defaultErrorState) {\n const {\n value,\n onError\n } = props;\n const adapter = useLocalizationContext();\n const previousValidationErrorRef = React.useRef(defaultErrorState);\n const validationError = validate({\n adapter,\n value,\n props\n });\n React.useEffect(() => {\n if (onError && !isSameError(validationError, previousValidationErrorRef.current)) {\n onError(validationError, value);\n }\n previousValidationErrorRef.current = validationError;\n }, [isSameError, onError, previousValidationErrorRef, validationError, value]);\n return validationError;\n}", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport * as React from 'react';\nimport { unstable_useControlled as useControlled } from '@mui/utils';\nimport useEventCallback from '@mui/utils/useEventCallback';\nimport { useOpenState } from '../useOpenState';\nimport { useLocalizationContext, useUtils } from '../useUtils';\nimport { useValidation } from '../useValidation';\nimport { useValueWithTimezone } from '../useValueWithTimezone';\n\n/**\n * Decide if the new value should be published\n * The published value will be passed to `onChange` if defined.\n */\nconst shouldPublishValue = params => {\n const {\n action,\n hasChanged,\n dateState,\n isControlled\n } = params;\n const isCurrentValueTheDefaultValue = !isControlled && !dateState.hasBeenModifiedSinceMount;\n\n // The field is responsible for only calling `onChange` when needed.\n if (action.name === 'setValueFromField') {\n return true;\n }\n if (action.name === 'setValueFromAction') {\n // If the component is not controlled, and the value has not been modified since the mount,\n // Then we want to publish the default value whenever the user pressed the \"Accept\", \"Today\" or \"Clear\" button.\n if (isCurrentValueTheDefaultValue && ['accept', 'today', 'clear'].includes(action.pickerAction)) {\n return true;\n }\n return hasChanged(dateState.lastPublishedValue);\n }\n if (action.name === 'setValueFromView' && action.selectionState !== 'shallow') {\n // On the first view,\n // If the value is not controlled, then clicking on any value (including the one equal to `defaultValue`) should call `onChange`\n if (isCurrentValueTheDefaultValue) {\n return true;\n }\n return hasChanged(dateState.lastPublishedValue);\n }\n if (action.name === 'setValueFromShortcut') {\n // On the first view,\n // If the value is not controlled, then clicking on any value (including the one equal to `defaultValue`) should call `onChange`\n if (isCurrentValueTheDefaultValue) {\n return true;\n }\n return hasChanged(dateState.lastPublishedValue);\n }\n return false;\n};\n\n/**\n * Decide if the new value should be committed.\n * The committed value will be passed to `onAccept` if defined.\n * It will also be used as a reset target when calling the `cancel` picker action (when clicking on the \"Cancel\" button).\n */\nconst shouldCommitValue = params => {\n const {\n action,\n hasChanged,\n dateState,\n isControlled,\n closeOnSelect\n } = params;\n const isCurrentValueTheDefaultValue = !isControlled && !dateState.hasBeenModifiedSinceMount;\n if (action.name === 'setValueFromAction') {\n // If the component is not controlled, and the value has not been modified since the mount,\n // Then we want to commit the default value whenever the user pressed the \"Accept\", \"Today\" or \"Clear\" button.\n if (isCurrentValueTheDefaultValue && ['accept', 'today', 'clear'].includes(action.pickerAction)) {\n return true;\n }\n return hasChanged(dateState.lastCommittedValue);\n }\n if (action.name === 'setValueFromView' && action.selectionState === 'finish' && closeOnSelect) {\n // On picker where the 1st view is also the last view,\n // If the value is not controlled, then clicking on any value (including the one equal to `defaultValue`) should call `onAccept`\n if (isCurrentValueTheDefaultValue) {\n return true;\n }\n return hasChanged(dateState.lastCommittedValue);\n }\n if (action.name === 'setValueFromShortcut') {\n return action.changeImportance === 'accept' && hasChanged(dateState.lastCommittedValue);\n }\n return false;\n};\n\n/**\n * Decide if the picker should be closed after the value is updated.\n */\nconst shouldClosePicker = params => {\n const {\n action,\n closeOnSelect\n } = params;\n if (action.name === 'setValueFromAction') {\n return true;\n }\n if (action.name === 'setValueFromView') {\n return action.selectionState === 'finish' && closeOnSelect;\n }\n if (action.name === 'setValueFromShortcut') {\n return action.changeImportance === 'accept';\n }\n return false;\n};\n\n/**\n * Manage the value lifecycle of all the pickers.\n */\nexport const usePickerValue = ({\n props,\n valueManager,\n valueType,\n wrapperVariant,\n validator\n}) => {\n const {\n onAccept,\n onChange,\n value: inValue,\n defaultValue: inDefaultValue,\n closeOnSelect = wrapperVariant === 'desktop',\n selectedSections: selectedSectionsProp,\n onSelectedSectionsChange,\n timezone: timezoneProp\n } = props;\n const {\n current: defaultValue\n } = React.useRef(inDefaultValue);\n const {\n current: isControlled\n } = React.useRef(inValue !== undefined);\n\n /* eslint-disable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */\n if (process.env.NODE_ENV !== 'production') {\n React.useEffect(() => {\n if (isControlled !== (inValue !== undefined)) {\n console.error([`MUI: A component is changing the ${isControlled ? '' : 'un'}controlled value of a picker to be ${isControlled ? 'un' : ''}controlled.`, 'Elements should not switch from uncontrolled to controlled (or vice versa).', `Decide between using a controlled or uncontrolled value` + 'for the lifetime of the component.', \"The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.\", 'More info: https://fb.me/react-controlled-components'].join('\\n'));\n }\n }, [inValue]);\n React.useEffect(() => {\n if (!isControlled && defaultValue !== inDefaultValue) {\n console.error([`MUI: A component is changing the defaultValue of an uncontrolled picker after being initialized. ` + `To suppress this warning opt to use a controlled value.`].join('\\n'));\n }\n }, [JSON.stringify(defaultValue)]);\n }\n /* eslint-enable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */\n\n const utils = useUtils();\n const adapter = useLocalizationContext();\n const [selectedSections, setSelectedSections] = useControlled({\n controlled: selectedSectionsProp,\n default: null,\n name: 'usePickerValue',\n state: 'selectedSections'\n });\n const {\n isOpen,\n setIsOpen\n } = useOpenState(props);\n const [dateState, setDateState] = React.useState(() => {\n let initialValue;\n if (inValue !== undefined) {\n initialValue = inValue;\n } else if (defaultValue !== undefined) {\n initialValue = defaultValue;\n } else {\n initialValue = valueManager.emptyValue;\n }\n return {\n draft: initialValue,\n lastPublishedValue: initialValue,\n lastCommittedValue: initialValue,\n lastControlledValue: inValue,\n hasBeenModifiedSinceMount: false\n };\n });\n const {\n timezone,\n handleValueChange\n } = useValueWithTimezone({\n timezone: timezoneProp,\n value: inValue,\n defaultValue,\n onChange,\n valueManager\n });\n useValidation(_extends({}, props, {\n value: dateState.draft,\n timezone\n }), validator, valueManager.isSameError, valueManager.defaultErrorState);\n const updateDate = useEventCallback(action => {\n const updaterParams = {\n action,\n dateState,\n hasChanged: comparison => !valueManager.areValuesEqual(utils, action.value, comparison),\n isControlled,\n closeOnSelect\n };\n const shouldPublish = shouldPublishValue(updaterParams);\n const shouldCommit = shouldCommitValue(updaterParams);\n const shouldClose = shouldClosePicker(updaterParams);\n setDateState(prev => _extends({}, prev, {\n draft: action.value,\n lastPublishedValue: shouldPublish ? action.value : prev.lastPublishedValue,\n lastCommittedValue: shouldCommit ? action.value : prev.lastCommittedValue,\n hasBeenModifiedSinceMount: true\n }));\n if (shouldPublish) {\n const validationError = action.name === 'setValueFromField' ? action.context.validationError : validator({\n adapter,\n value: action.value,\n props: _extends({}, props, {\n value: action.value,\n timezone\n })\n });\n const context = {\n validationError\n };\n\n // TODO v7: Remove 2nd condition\n if (action.name === 'setValueFromShortcut' && action.shortcut != null) {\n context.shortcut = action.shortcut;\n }\n handleValueChange(action.value, context);\n }\n if (shouldCommit && onAccept) {\n onAccept(action.value);\n }\n if (shouldClose) {\n setIsOpen(false);\n }\n });\n if (inValue !== undefined && (dateState.lastControlledValue === undefined || !valueManager.areValuesEqual(utils, dateState.lastControlledValue, inValue))) {\n const isUpdateComingFromPicker = valueManager.areValuesEqual(utils, dateState.draft, inValue);\n setDateState(prev => _extends({}, prev, {\n lastControlledValue: inValue\n }, isUpdateComingFromPicker ? {} : {\n lastCommittedValue: inValue,\n lastPublishedValue: inValue,\n draft: inValue,\n hasBeenModifiedSinceMount: true\n }));\n }\n const handleClear = useEventCallback(() => {\n updateDate({\n value: valueManager.emptyValue,\n name: 'setValueFromAction',\n pickerAction: 'clear'\n });\n });\n const handleAccept = useEventCallback(() => {\n updateDate({\n value: dateState.lastPublishedValue,\n name: 'setValueFromAction',\n pickerAction: 'accept'\n });\n });\n const handleDismiss = useEventCallback(() => {\n updateDate({\n value: dateState.lastPublishedValue,\n name: 'setValueFromAction',\n pickerAction: 'dismiss'\n });\n });\n const handleCancel = useEventCallback(() => {\n updateDate({\n value: dateState.lastCommittedValue,\n name: 'setValueFromAction',\n pickerAction: 'cancel'\n });\n });\n const handleSetToday = useEventCallback(() => {\n updateDate({\n value: valueManager.getTodayValue(utils, timezone, valueType),\n name: 'setValueFromAction',\n pickerAction: 'today'\n });\n });\n const handleOpen = useEventCallback(() => setIsOpen(true));\n const handleClose = useEventCallback(() => setIsOpen(false));\n const handleChange = useEventCallback((newValue, selectionState = 'partial') => updateDate({\n name: 'setValueFromView',\n value: newValue,\n selectionState\n }));\n\n // TODO v7: Make changeImportance and label mandatory.\n const handleSelectShortcut = useEventCallback((newValue, changeImportance, shortcut) => updateDate({\n name: 'setValueFromShortcut',\n value: newValue,\n changeImportance: changeImportance != null ? changeImportance : 'accept',\n shortcut\n }));\n const handleChangeFromField = useEventCallback((newValue, context) => updateDate({\n name: 'setValueFromField',\n value: newValue,\n context\n }));\n const handleFieldSelectedSectionsChange = useEventCallback(newSelectedSections => {\n setSelectedSections(newSelectedSections);\n onSelectedSectionsChange == null || onSelectedSectionsChange(newSelectedSections);\n });\n const actions = {\n onClear: handleClear,\n onAccept: handleAccept,\n onDismiss: handleDismiss,\n onCancel: handleCancel,\n onSetToday: handleSetToday,\n onOpen: handleOpen,\n onClose: handleClose\n };\n const fieldResponse = {\n value: dateState.draft,\n onChange: handleChangeFromField,\n selectedSections,\n onSelectedSectionsChange: handleFieldSelectedSectionsChange\n };\n const viewValue = React.useMemo(() => valueManager.cleanValue(utils, dateState.draft), [utils, valueManager, dateState.draft]);\n const viewResponse = {\n value: viewValue,\n onChange: handleChange,\n onClose: handleClose,\n open: isOpen,\n onSelectedSectionsChange: handleFieldSelectedSectionsChange\n };\n const isValid = testedValue => {\n const error = validator({\n adapter,\n value: testedValue,\n props: _extends({}, props, {\n value: testedValue,\n timezone\n })\n });\n return !valueManager.hasError(error);\n };\n const layoutResponse = _extends({}, actions, {\n value: viewValue,\n onChange: handleChange,\n onSelectShortcut: handleSelectShortcut,\n isValid\n });\n return {\n open: isOpen,\n fieldProps: fieldResponse,\n viewProps: viewResponse,\n layoutProps: layoutResponse,\n actions\n };\n};", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"className\", \"sx\"];\nimport * as React from 'react';\nimport useEnhancedEffect from '@mui/utils/useEnhancedEffect';\nimport useEventCallback from '@mui/utils/useEventCallback';\nimport { useViews } from '../useViews';\nimport { isTimeView } from '../../utils/time-utils';\n\n/**\n * Props used to handle the views that are common to all pickers.\n */\n\n/**\n * Props used to handle the views of the pickers.\n */\n\n/**\n * Props used to handle the value of the pickers.\n */\n\n/**\n * Manage the views of all the pickers:\n * - Handles the view switch\n * - Handles the switch between UI views and field views\n * - Handles the focus management when switching views\n */\nexport const usePickerViews = ({\n props,\n propsFromPickerValue,\n additionalViewProps,\n inputRef,\n autoFocusView\n}) => {\n const {\n onChange,\n open,\n onSelectedSectionsChange,\n onClose\n } = propsFromPickerValue;\n const {\n views,\n openTo,\n onViewChange,\n disableOpenPicker,\n viewRenderers,\n timezone\n } = props;\n const propsToForwardToView = _objectWithoutPropertiesLoose(props, _excluded);\n const {\n view,\n setView,\n defaultView,\n focusedView,\n setFocusedView,\n setValueAndGoToNextView\n } = useViews({\n view: undefined,\n views,\n openTo,\n onChange,\n onViewChange,\n autoFocus: autoFocusView\n });\n const {\n hasUIView,\n viewModeLookup\n } = React.useMemo(() => views.reduce((acc, viewForReduce) => {\n let viewMode;\n if (disableOpenPicker) {\n viewMode = 'field';\n } else if (viewRenderers[viewForReduce] != null) {\n viewMode = 'UI';\n } else {\n viewMode = 'field';\n }\n acc.viewModeLookup[viewForReduce] = viewMode;\n if (viewMode === 'UI') {\n acc.hasUIView = true;\n }\n return acc;\n }, {\n hasUIView: false,\n viewModeLookup: {}\n }), [disableOpenPicker, viewRenderers, views]);\n const timeViewsCount = React.useMemo(() => views.reduce((acc, viewForReduce) => {\n if (viewRenderers[viewForReduce] != null && isTimeView(viewForReduce)) {\n return acc + 1;\n }\n return acc;\n }, 0), [viewRenderers, views]);\n const currentViewMode = viewModeLookup[view];\n const shouldRestoreFocus = useEventCallback(() => currentViewMode === 'UI');\n const [popperView, setPopperView] = React.useState(currentViewMode === 'UI' ? view : null);\n if (popperView !== view && viewModeLookup[view] === 'UI') {\n setPopperView(view);\n }\n useEnhancedEffect(() => {\n // Handle case of `DateTimePicker` without time renderers\n if (currentViewMode === 'field' && open) {\n onClose();\n setTimeout(() => {\n // focusing the input before the range selection is done\n // calling `onSelectedSectionsChange` outside of timeout results in an inconsistent behavior between Safari And Chrome\n inputRef == null || inputRef.current.focus();\n onSelectedSectionsChange(view);\n });\n }\n }, [view]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEnhancedEffect(() => {\n if (!open) {\n return;\n }\n let newView = view;\n\n // If the current view is a field view, go to the last popper view\n if (currentViewMode === 'field' && popperView != null) {\n newView = popperView;\n }\n\n // If the current view is not the default view and both are UI views\n if (newView !== defaultView && viewModeLookup[newView] === 'UI' && viewModeLookup[defaultView] === 'UI') {\n newView = defaultView;\n }\n if (newView !== view) {\n setView(newView);\n }\n setFocusedView(newView, true);\n }, [open]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const layoutProps = {\n views,\n view: popperView,\n onViewChange: setView\n };\n return {\n hasUIView,\n shouldRestoreFocus,\n layoutProps,\n renderCurrentView: () => {\n if (popperView == null) {\n return null;\n }\n const renderer = viewRenderers[popperView];\n if (renderer == null) {\n return null;\n }\n return renderer(_extends({}, propsToForwardToView, additionalViewProps, propsFromPickerValue, {\n views,\n timezone,\n onChange: setValueAndGoToNextView,\n view: popperView,\n onViewChange: setView,\n focusedView,\n onFocusedViewChange: setFocusedView,\n showViewSwitcher: timeViewsCount > 1,\n timeViewsCount\n }));\n }\n };\n};", "/* Use it instead of .includes method for IE support */\nexport function arrayIncludes(array, itemOrItems) {\n if (Array.isArray(itemOrItems)) {\n return itemOrItems.every(item => array.indexOf(item) !== -1);\n }\n return array.indexOf(itemOrItems) !== -1;\n}\nexport const onSpaceOrEnter = (innerFn, externalEvent) => event => {\n if (event.key === 'Enter' || event.key === ' ') {\n innerFn(event);\n\n // prevent any side effects\n event.preventDefault();\n event.stopPropagation();\n }\n if (externalEvent) {\n externalEvent(event);\n }\n};\nexport const executeInTheNextEventLoopTick = fn => {\n setTimeout(fn, 0);\n};\n\n// https://www.abeautifulsite.net/posts/finding-the-active-element-in-a-shadow-root/\nexport const getActiveElement = (root = document) => {\n const activeEl = root.activeElement;\n if (!activeEl) {\n return null;\n }\n if (activeEl.shadowRoot) {\n return getActiveElement(activeEl.shadowRoot);\n }\n return activeEl;\n};\nexport const DEFAULT_DESKTOP_MODE_MEDIA_QUERY = '@media (pointer: fine)';", "import * as React from 'react';\nimport { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';\nimport { arrayIncludes } from '../utils/utils';\nfunction getOrientation() {\n if (typeof window === 'undefined') {\n return 'portrait';\n }\n if (window.screen && window.screen.orientation && window.screen.orientation.angle) {\n return Math.abs(window.screen.orientation.angle) === 90 ? 'landscape' : 'portrait';\n }\n\n // Support IOS safari\n if (window.orientation) {\n return Math.abs(Number(window.orientation)) === 90 ? 'landscape' : 'portrait';\n }\n return 'portrait';\n}\nexport const useIsLandscape = (views, customOrientation) => {\n const [orientation, setOrientation] = React.useState(getOrientation);\n useEnhancedEffect(() => {\n const eventHandler = () => {\n setOrientation(getOrientation());\n };\n window.addEventListener('orientationchange', eventHandler);\n return () => {\n window.removeEventListener('orientationchange', eventHandler);\n };\n }, []);\n if (arrayIncludes(views, ['hours', 'minutes', 'seconds'])) {\n // could not display 13:34:44 in landscape mode\n return false;\n }\n const orientationToUse = customOrientation || orientation;\n return orientationToUse === 'landscape';\n};", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport { useIsLandscape } from '../useIsLandscape';\n\n/**\n * Props used to create the layout of the views.\n * Those props are exposed on all the pickers.\n */\n\n/**\n * Prepare the props for the view layout (managed by `PickersLayout`)\n */\nexport const usePickerLayoutProps = ({\n props,\n propsFromPickerValue,\n propsFromPickerViews,\n wrapperVariant\n}) => {\n const {\n orientation\n } = props;\n const isLandscape = useIsLandscape(propsFromPickerViews.views, orientation);\n const layoutProps = _extends({}, propsFromPickerViews, propsFromPickerValue, {\n isLandscape,\n wrapperVariant,\n disabled: props.disabled,\n readOnly: props.readOnly\n });\n return {\n layoutProps\n };\n};", "import { usePickerValue } from './usePickerValue';\nimport { usePickerViews } from './usePickerViews';\nimport { usePickerLayoutProps } from './usePickerLayoutProps';\nimport { buildWarning } from '../../utils/warning';\nconst warnRenderInputIsDefined = buildWarning(['The `renderInput` prop has been removed in version 6.0 of the Date and Time Pickers.', 'You can replace it with the `textField` component slot in most cases.', 'For more information, please have a look at the migration guide (https://mui.com/x/migration/migration-pickers-v5/#input-renderer-required-in-v5).']);\nexport const usePicker = ({\n props,\n valueManager,\n valueType,\n wrapperVariant,\n inputRef,\n additionalViewProps,\n validator,\n autoFocusView\n}) => {\n if (process.env.NODE_ENV !== 'production') {\n if (props.renderInput != null) {\n warnRenderInputIsDefined();\n }\n }\n const pickerValueResponse = usePickerValue({\n props,\n valueManager,\n valueType,\n wrapperVariant,\n validator\n });\n const pickerViewsResponse = usePickerViews({\n props,\n inputRef,\n additionalViewProps,\n autoFocusView,\n propsFromPickerValue: pickerValueResponse.viewProps\n });\n const pickerLayoutResponse = usePickerLayoutProps({\n props,\n wrapperVariant,\n propsFromPickerValue: pickerValueResponse.layoutProps,\n propsFromPickerViews: pickerViewsResponse.layoutProps\n });\n return {\n // Picker value\n open: pickerValueResponse.open,\n actions: pickerValueResponse.actions,\n fieldProps: pickerValueResponse.fieldProps,\n // Picker views\n renderCurrentView: pickerViewsResponse.renderCurrentView,\n hasUIView: pickerViewsResponse.hasUIView,\n shouldRestoreFocus: pickerViewsResponse.shouldRestoreFocus,\n // Picker layout\n layoutProps: pickerLayoutResponse.layoutProps\n };\n};", "export { usePicker } from './usePicker';", "import { unstable_generateUtilityClass as generateUtilityClass, unstable_generateUtilityClasses as generateUtilityClasses } from '@mui/utils';\nexport function getPickersLayoutUtilityClass(slot) {\n return generateUtilityClass('MuiPickersLayout', slot);\n}\nexport const pickersLayoutClasses = generateUtilityClasses('MuiPickersLayout', ['root', 'landscape', 'contentWrapper', 'toolbar', 'actionBar', 'shortcuts']);", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"onAccept\", \"onClear\", \"onCancel\", \"onSetToday\", \"actions\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@mui/material/Button';\nimport DialogActions from '@mui/material/DialogActions';\nimport { useLocaleText } from '../internals/hooks/useUtils';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\n/**\n * Demos:\n *\n * - [Custom slots and subcomponents](https://mui.com/x/react-date-pickers/custom-components/)\n * - [Custom layout](https://mui.com/x/react-date-pickers/custom-layout/)\n *\n * API:\n *\n * - [PickersActionBar API](https://mui.com/x/api/date-pickers/pickers-action-bar/)\n */\nfunction PickersActionBar(props) {\n const {\n onAccept,\n onClear,\n onCancel,\n onSetToday,\n actions\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n const localeText = useLocaleText();\n if (actions == null || actions.length === 0) {\n return null;\n }\n const buttons = actions == null ? void 0 : actions.map(actionType => {\n switch (actionType) {\n case 'clear':\n return /*#__PURE__*/_jsx(Button, {\n onClick: onClear,\n children: localeText.clearButtonLabel\n }, actionType);\n case 'cancel':\n return /*#__PURE__*/_jsx(Button, {\n onClick: onCancel,\n children: localeText.cancelButtonLabel\n }, actionType);\n case 'accept':\n return /*#__PURE__*/_jsx(Button, {\n onClick: onAccept,\n children: localeText.okButtonLabel\n }, actionType);\n case 'today':\n return /*#__PURE__*/_jsx(Button, {\n onClick: onSetToday,\n children: localeText.todayButtonLabel\n }, actionType);\n default:\n return null;\n }\n });\n return /*#__PURE__*/_jsx(DialogActions, _extends({}, other, {\n children: buttons\n }));\n}\nprocess.env.NODE_ENV !== \"production\" ? PickersActionBar.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * Ordered array of actions to display.\n * If empty, does not display that action bar.\n * @default `['cancel', 'accept']` for mobile and `[]` for desktop\n */\n actions: PropTypes.arrayOf(PropTypes.oneOf(['accept', 'cancel', 'clear', 'today']).isRequired),\n /**\n * If `true`, the actions do not have additional margin.\n * @default false\n */\n disableSpacing: PropTypes.bool,\n onAccept: PropTypes.func.isRequired,\n onCancel: PropTypes.func.isRequired,\n onClear: PropTypes.func.isRequired,\n onSetToday: PropTypes.func.isRequired,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])\n} : void 0;\nexport { PickersActionBar };", "export { PickersActionBar } from './PickersActionBar';", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"items\", \"changeImportance\", \"isLandscape\", \"onChange\", \"isValid\"],\n _excluded2 = [\"getValue\"];\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport List from '@mui/material/List';\nimport ListItem from '@mui/material/ListItem';\nimport Chip from '@mui/material/Chip';\nimport { VIEW_HEIGHT } from '../internals/constants/dimensions';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\n/**\n * Demos:\n *\n * - [Shortcuts](https://mui.com/x/react-date-pickers/shortcuts/)\n *\n * API:\n *\n * - [PickersShortcuts API](https://mui.com/x/api/date-pickers/pickers-shortcuts/)\n */\nfunction PickersShortcuts(props) {\n const {\n items,\n changeImportance,\n onChange,\n isValid\n } = props,\n other = _objectWithoutPropertiesLoose(props, _excluded);\n if (items == null || items.length === 0) {\n return null;\n }\n const resolvedItems = items.map(_ref => {\n let {\n getValue\n } = _ref,\n item = _objectWithoutPropertiesLoose(_ref, _excluded2);\n const newValue = getValue({\n isValid\n });\n return {\n label: item.label,\n onClick: () => {\n onChange(newValue, changeImportance, item);\n },\n disabled: !isValid(newValue)\n };\n });\n return /*#__PURE__*/_jsx(List, _extends({\n dense: true,\n sx: [{\n maxHeight: VIEW_HEIGHT,\n maxWidth: 200,\n overflow: 'auto'\n }, ...(Array.isArray(other.sx) ? other.sx : [other.sx])]\n }, other, {\n children: resolvedItems.map(item => {\n return /*#__PURE__*/_jsx(ListItem, {\n children: /*#__PURE__*/_jsx(Chip, _extends({}, item))\n }, item.label);\n })\n }));\n}\nprocess.env.NODE_ENV !== \"production\" ? PickersShortcuts.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * Importance of the change when picking a shortcut:\n * - \"accept\": fires `onChange`, fires `onAccept` and closes the picker.\n * - \"set\": fires `onChange` but do not fire `onAccept` and does not close the picker.\n * @default \"accept\"\n */\n changeImportance: PropTypes.oneOf(['accept', 'set']),\n className: PropTypes.string,\n component: PropTypes.elementType,\n /**\n * If `true`, compact vertical padding designed for keyboard and mouse input is used for\n * the list and list items.\n * The prop is available to descendant components as the `dense` context.\n * @default false\n */\n dense: PropTypes.bool,\n /**\n * If `true`, vertical padding is removed from the list.\n * @default false\n */\n disablePadding: PropTypes.bool,\n isLandscape: PropTypes.bool.isRequired,\n isValid: PropTypes.func.isRequired,\n /**\n * Ordered array of shortcuts to display.\n * If empty, does not display the shortcuts.\n * @default `[]`\n */\n items: PropTypes.arrayOf(PropTypes.shape({\n getValue: PropTypes.func.isRequired,\n label: PropTypes.string.isRequired\n })),\n onChange: PropTypes.func.isRequired,\n style: PropTypes.object,\n /**\n * The content of the subheader, normally `ListSubheader`.\n */\n subheader: PropTypes.node,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])\n} : void 0;\nexport { PickersShortcuts };", "export { PickersShortcuts } from './PickersShortcuts';", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport * as React from 'react';\nimport { useSlotProps } from '@mui/base/utils';\nimport { unstable_composeClasses as composeClasses } from '@mui/utils';\nimport { PickersActionBar } from '../PickersActionBar';\nimport { getPickersLayoutUtilityClass } from './pickersLayoutClasses';\nimport { PickersShortcuts } from '../PickersShortcuts';\nimport { uncapitalizeObjectKeys } from '../internals/utils/slots-migration';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nfunction toolbarHasView(toolbarProps) {\n return toolbarProps.view !== null;\n}\nconst useUtilityClasses = ownerState => {\n const {\n classes,\n isLandscape\n } = ownerState;\n const slots = {\n root: ['root', isLandscape && 'landscape'],\n contentWrapper: ['contentWrapper'],\n toolbar: ['toolbar'],\n actionBar: ['actionBar'],\n tabs: ['tabs'],\n landscape: ['landscape'],\n shortcuts: ['shortcuts']\n };\n return composeClasses(slots, getPickersLayoutUtilityClass, classes);\n};\nconst usePickerLayout = props => {\n var _slots$actionBar, _slots$shortcuts;\n const {\n wrapperVariant,\n onAccept,\n onClear,\n onCancel,\n onSetToday,\n view,\n views,\n onViewChange,\n value,\n onChange,\n onSelectShortcut,\n isValid,\n isLandscape,\n disabled,\n readOnly,\n children,\n components,\n componentsProps,\n slots: innerSlots,\n slotProps: innerSlotProps\n // TODO: Remove this \"as\" hack. It get introduced to mark `value` prop in PickersLayoutProps as not required.\n // The true type should be\n // - For pickers value: TDate | null\n // - For range pickers value: [TDate | null, TDate | null]\n } = props;\n const slots = innerSlots != null ? innerSlots : uncapitalizeObjectKeys(components);\n const slotProps = innerSlotProps != null ? innerSlotProps : componentsProps;\n const classes = useUtilityClasses(props);\n\n // Action bar\n\n const ActionBar = (_slots$actionBar = slots == null ? void 0 : slots.actionBar) != null ? _slots$actionBar : PickersActionBar;\n const actionBarProps = useSlotProps({\n elementType: ActionBar,\n externalSlotProps: slotProps == null ? void 0 : slotProps.actionBar,\n additionalProps: {\n onAccept,\n onClear,\n onCancel,\n onSetToday,\n actions: wrapperVariant === 'desktop' ? [] : ['cancel', 'accept'],\n className: classes.actionBar\n },\n ownerState: _extends({}, props, {\n wrapperVariant\n })\n });\n const actionBar = /*#__PURE__*/_jsx(ActionBar, _extends({}, actionBarProps));\n\n // Toolbar\n\n const Toolbar = slots == null ? void 0 : slots.toolbar;\n const toolbarProps = useSlotProps({\n elementType: Toolbar,\n externalSlotProps: slotProps == null ? void 0 : slotProps.toolbar,\n additionalProps: {\n isLandscape,\n onChange,\n value,\n view,\n onViewChange,\n views,\n disabled,\n readOnly,\n className: classes.toolbar\n },\n ownerState: _extends({}, props, {\n wrapperVariant\n })\n });\n const toolbar = toolbarHasView(toolbarProps) && !!Toolbar ? /*#__PURE__*/_jsx(Toolbar, _extends({}, toolbarProps)) : null;\n\n // Content\n\n const content = children;\n\n // Tabs\n\n const Tabs = slots == null ? void 0 : slots.tabs;\n const tabs = view && Tabs ? /*#__PURE__*/_jsx(Tabs, _extends({\n view: view,\n onViewChange: onViewChange\n }, slotProps == null ? void 0 : slotProps.tabs)) : null;\n\n // Shortcuts\n\n const Shortcuts = (_slots$shortcuts = slots == null ? void 0 : slots.shortcuts) != null ? _slots$shortcuts : PickersShortcuts;\n const shortcutsProps = useSlotProps({\n elementType: Shortcuts,\n externalSlotProps: slotProps == null ? void 0 : slotProps.shortcuts,\n additionalProps: {\n isValid,\n isLandscape,\n onChange: onSelectShortcut,\n className: classes.shortcuts\n },\n ownerState: {\n isValid,\n isLandscape,\n onChange: onSelectShortcut,\n className: classes.shortcuts,\n wrapperVariant\n }\n });\n const shortcuts = view && !!Shortcuts ? /*#__PURE__*/_jsx(Shortcuts, _extends({}, shortcutsProps)) : null;\n return {\n toolbar,\n content,\n tabs,\n actionBar,\n shortcuts\n };\n};\nexport default usePickerLayout;", "import * as React from 'react';\nimport PropTypes from 'prop-types';\nimport clsx from 'clsx';\nimport { styled, useThemeProps } from '@mui/material/styles';\nimport { unstable_composeClasses as composeClasses } from '@mui/utils';\nimport { pickersLayoutClasses, getPickersLayoutUtilityClass } from './pickersLayoutClasses';\nimport usePickerLayout from './usePickerLayout';\nimport { jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst useUtilityClasses = ownerState => {\n const {\n isLandscape,\n classes\n } = ownerState;\n const slots = {\n root: ['root', isLandscape && 'landscape'],\n contentWrapper: ['contentWrapper']\n };\n return composeClasses(slots, getPickersLayoutUtilityClass, classes);\n};\nconst PickersLayoutRoot = styled('div', {\n name: 'MuiPickersLayout',\n slot: 'Root',\n overridesResolver: (props, styles) => styles.root\n})(({\n theme,\n ownerState\n}) => ({\n display: 'grid',\n gridAutoColumns: 'max-content auto max-content',\n gridAutoRows: 'max-content auto max-content',\n [`& .${pickersLayoutClasses.toolbar}`]: ownerState.isLandscape ? {\n gridColumn: theme.direction === 'rtl' ? 3 : 1,\n gridRow: '2 / 3'\n } : {\n gridColumn: '2 / 4',\n gridRow: 1\n },\n [`.${pickersLayoutClasses.shortcuts}`]: ownerState.isLandscape ? {\n gridColumn: '2 / 4',\n gridRow: 1\n } : {\n gridColumn: theme.direction === 'rtl' ? 3 : 1,\n gridRow: '2 / 3'\n },\n [`& .${pickersLayoutClasses.actionBar}`]: {\n gridColumn: '1 / 4',\n gridRow: 3\n }\n}));\nPickersLayoutRoot.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n as: PropTypes.elementType,\n ownerState: PropTypes.shape({\n isLandscape: PropTypes.bool.isRequired\n }).isRequired,\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])\n};\nexport { PickersLayoutRoot };\nexport const PickersLayoutContentWrapper = styled('div', {\n name: 'MuiPickersLayout',\n slot: 'ContentWrapper',\n overridesResolver: (props, styles) => styles.contentWrapper\n})({\n gridColumn: 2,\n gridRow: 2,\n display: 'flex',\n flexDirection: 'column'\n});\n\n/**\n * Demos:\n *\n * - [Custom layout](https://mui.com/x/react-date-pickers/custom-layout/)\n *\n * API:\n *\n * - [PickersLayout API](https://mui.com/x/api/date-pickers/pickers-layout/)\n */\nconst PickersLayout = function PickersLayout(inProps) {\n const props = useThemeProps({\n props: inProps,\n name: 'MuiPickersLayout'\n });\n const {\n toolbar,\n content,\n tabs,\n actionBar,\n shortcuts\n } = usePickerLayout(props);\n const {\n sx,\n className,\n isLandscape,\n ref,\n wrapperVariant\n } = props;\n const ownerState = props;\n const classes = useUtilityClasses(ownerState);\n return /*#__PURE__*/_jsxs(PickersLayoutRoot, {\n ref: ref,\n sx: sx,\n className: clsx(className, classes.root),\n ownerState: ownerState,\n children: [isLandscape ? shortcuts : toolbar, isLandscape ? toolbar : shortcuts, /*#__PURE__*/_jsx(PickersLayoutContentWrapper, {\n className: classes.contentWrapper,\n children: wrapperVariant === 'desktop' ? /*#__PURE__*/_jsxs(React.Fragment, {\n children: [content, tabs]\n }) : /*#__PURE__*/_jsxs(React.Fragment, {\n children: [tabs, content]\n })\n }), actionBar]\n });\n};\nprocess.env.NODE_ENV !== \"production\" ? PickersLayout.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n children: PropTypes.node,\n classes: PropTypes.object,\n className: PropTypes.string,\n /**\n * Overridable components.\n * @default {}\n * @deprecated Please use `slots`.\n */\n components: PropTypes.object,\n /**\n * The props used for each component slot.\n * @default {}\n * @deprecated Please use `slotProps`.\n */\n componentsProps: PropTypes.object,\n disabled: PropTypes.bool,\n isLandscape: PropTypes.bool.isRequired,\n isValid: PropTypes.func.isRequired,\n onAccept: PropTypes.func.isRequired,\n onCancel: PropTypes.func.isRequired,\n onChange: PropTypes.func.isRequired,\n onClear: PropTypes.func.isRequired,\n onClose: PropTypes.func.isRequired,\n onDismiss: PropTypes.func.isRequired,\n onOpen: PropTypes.func.isRequired,\n onSelectShortcut: PropTypes.func.isRequired,\n onSetToday: PropTypes.func.isRequired,\n onViewChange: PropTypes.func.isRequired,\n /**\n * Force rendering in particular orientation.\n */\n orientation: PropTypes.oneOf(['landscape', 'portrait']),\n readOnly: PropTypes.bool,\n /**\n * The props used for each component slot.\n * @default {}\n */\n slotProps: PropTypes.object,\n /**\n * Overridable component slots.\n * @default {}\n */\n slots: PropTypes.object,\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n value: PropTypes.any,\n view: PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']),\n views: PropTypes.arrayOf(PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']).isRequired).isRequired,\n wrapperVariant: PropTypes.oneOf(['desktop', 'mobile'])\n} : void 0;\nexport { PickersLayout };", "export { PickersLayout, PickersLayoutRoot, PickersLayoutContentWrapper } from './PickersLayout';\nexport { default as usePickerLayout } from './usePickerLayout';\nexport { pickersLayoutClasses } from './pickersLayoutClasses';", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nconst _excluded = [\"props\", \"ref\"];\nimport * as React from 'react';\nimport clsx from 'clsx';\nimport { styled } from '@mui/material/styles';\nimport { usePicker } from '../usePicker';\nimport { LocalizationProvider } from '../../../LocalizationProvider';\nimport { PickersLayout } from '../../../PickersLayout';\nimport { DIALOG_WIDTH } from '../../constants/dimensions';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst PickerStaticLayout = styled(PickersLayout)(({\n theme\n}) => ({\n overflow: 'hidden',\n minWidth: DIALOG_WIDTH,\n backgroundColor: (theme.vars || theme).palette.background.paper\n}));\n\n/**\n * Hook managing all the single-date static pickers:\n * - StaticDatePicker\n * - StaticDateTimePicker\n * - StaticTimePicker\n */\nexport const useStaticPicker = _ref => {\n var _slots$layout;\n let {\n props,\n ref\n } = _ref,\n pickerParams = _objectWithoutPropertiesLoose(_ref, _excluded);\n const {\n localeText,\n slots,\n slotProps,\n className,\n sx,\n displayStaticWrapperAs,\n autoFocus\n } = props;\n const {\n layoutProps,\n renderCurrentView\n } = usePicker(_extends({}, pickerParams, {\n props,\n autoFocusView: autoFocus != null ? autoFocus : false,\n additionalViewProps: {},\n wrapperVariant: displayStaticWrapperAs\n }));\n const Layout = (_slots$layout = slots == null ? void 0 : slots.layout) != null ? _slots$layout : PickerStaticLayout;\n const renderPicker = () => {\n var _slotProps$layout, _slotProps$layout2, _slotProps$layout3;\n return /*#__PURE__*/_jsx(LocalizationProvider, {\n localeText: localeText,\n children: /*#__PURE__*/_jsx(Layout, _extends({}, layoutProps, slotProps == null ? void 0 : slotProps.layout, {\n slots: slots,\n slotProps: slotProps,\n sx: [...(Array.isArray(sx) ? sx : [sx]), ...(Array.isArray(slotProps == null || (_slotProps$layout = slotProps.layout) == null ? void 0 : _slotProps$layout.sx) ? slotProps.layout.sx : [slotProps == null || (_slotProps$layout2 = slotProps.layout) == null ? void 0 : _slotProps$layout2.sx])],\n className: clsx(className, slotProps == null || (_slotProps$layout3 = slotProps.layout) == null ? void 0 : _slotProps$layout3.className),\n ref: ref,\n children: renderCurrentView()\n }))\n });\n };\n return {\n renderPicker\n };\n};", "export { useStaticPicker } from './useStaticPicker';", "export { PickersArrowSwitcher } from './components/PickersArrowSwitcher/PickersArrowSwitcher';\nexport { PickersModalDialog } from './components/PickersModalDialog';\nexport { PickersPopper } from './components/PickersPopper';\nexport { PickersToolbar } from './components/PickersToolbar';\nexport { pickersToolbarClasses } from './components/pickersToolbarClasses';\nexport { pickersToolbarButtonClasses } from './components/pickersToolbarButtonClasses';\nexport { pickersToolbarTextClasses } from './components/pickersToolbarTextClasses';\nexport { pickersArrowSwitcherClasses } from './components/PickersArrowSwitcher/pickersArrowSwitcherClasses';\nexport { pickersPopperClasses } from './components/pickersPopperClasses';\nexport { PickersToolbarButton } from './components/PickersToolbarButton';\nexport { DAY_MARGIN, DIALOG_WIDTH } from './constants/dimensions';\nexport { useControlledValueWithTimezone } from './hooks/useValueWithTimezone';\nexport { useField, createDateStrForInputFromSections, addPositionPropertiesToSections } from './hooks/useField';\nexport { usePicker } from './hooks/usePicker';\nexport { useStaticPicker } from './hooks/useStaticPicker';\nexport { useLocalizationContext, useDefaultDates, useUtils, useLocaleText, useNow } from './hooks/useUtils';\nexport { useValidation } from './hooks/useValidation';\nexport { usePreviousMonthDisabled, useNextMonthDisabled } from './hooks/date-helpers-hooks';\nexport { applyDefaultDate, replaceInvalidDateByNull, areDatesEqual, getTodayDate } from './utils/date-utils';\nexport { splitFieldInternalAndForwardedProps } from './utils/fields';\nexport { getDefaultReferenceDate } from './utils/getDefaultReferenceDate';\nexport { executeInTheNextEventLoopTick, getActiveElement, onSpaceOrEnter, DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from './utils/utils';\nexport { useDefaultReduceAnimations } from './hooks/useDefaultReduceAnimations';\nexport { extractValidationProps } from './utils/validation/extractValidationProps';\nexport { validateDate } from './utils/validation/validateDate';\nexport { validateDateTime } from './utils/validation/validateDateTime';\nexport { validateTime } from './utils/validation/validateTime';\nexport { buildDeprecatedPropsWarning, buildWarning } from './utils/warning';\nexport { uncapitalizeObjectKeys } from './utils/slots-migration';\nexport { DayCalendar } from '../DateCalendar/DayCalendar';\nexport { useCalendarState } from '../DateCalendar/useCalendarState';", "import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport * as React from 'react';\nimport PropTypes from 'prop-types';\nimport { useDatePickerDefaultizedProps } from '../DatePicker/shared';\nimport { renderDateViewCalendar } from '../dateViewRenderers';\nimport { useStaticPicker } from '../internals/hooks/useStaticPicker';\nimport { validateDate } from '../internals';\nimport { singleItemValueManager } from '../internals/utils/valueManagers';\n/**\n * Demos:\n *\n * - [DatePicker](https://mui.com/x/react-date-pickers/date-picker/)\n * - [Validation](https://mui.com/x/react-date-pickers/validation/)\n *\n * API:\n *\n * - [StaticDatePicker API](https://mui.com/x/api/date-pickers/static-date-picker/)\n */\nconst StaticDatePicker = /*#__PURE__*/React.forwardRef(function StaticDatePicker(inProps, ref) {\n var _defaultizedProps$dis, _defaultizedProps$yea, _defaultizedProps$slo;\n const defaultizedProps = useDatePickerDefaultizedProps(inProps, 'MuiStaticDatePicker');\n const displayStaticWrapperAs = (_defaultizedProps$dis = defaultizedProps.displayStaticWrapperAs) != null ? _defaultizedProps$dis : 'mobile';\n const viewRenderers = _extends({\n day: renderDateViewCalendar,\n month: renderDateViewCalendar,\n year: renderDateViewCalendar\n }, defaultizedProps.viewRenderers);\n\n // Props with the default values specific to the static variant\n const props = _extends({}, defaultizedProps, {\n viewRenderers,\n displayStaticWrapperAs,\n yearsPerRow: (_defaultizedProps$yea = defaultizedProps.yearsPerRow) != null ? _defaultizedProps$yea : displayStaticWrapperAs === 'mobile' ? 3 : 4,\n slotProps: _extends({}, defaultizedProps.slotProps, {\n toolbar: _extends({\n hidden: displayStaticWrapperAs === 'desktop'\n }, (_defaultizedProps$slo = defaultizedProps.slotProps) == null ? void 0 : _defaultizedProps$slo.toolbar)\n })\n });\n const {\n renderPicker\n } = useStaticPicker({\n props,\n valueManager: singleItemValueManager,\n valueType: 'date',\n validator: validateDate,\n ref\n });\n return renderPicker();\n});\nStaticDatePicker.propTypes = {\n // ----------------------------- Warning --------------------------------\n // | These PropTypes are generated from the TypeScript type definitions |\n // | To update them edit the TypeScript types and run \"yarn proptypes\" |\n // ----------------------------------------------------------------------\n /**\n * If `true`, the main element is focused during the first mount.\n * This main element is:\n * - the element chosen by the visible view if any (i.e: the selected day on the `day` view).\n * - the `input` element if there is a field rendered.\n */\n autoFocus: PropTypes.bool,\n /**\n * Class name applied to the root element.\n */\n className: PropTypes.string,\n /**\n * Overridable components.\n * @default {}\n * @deprecated Please use `slots`.\n */\n components: PropTypes.object,\n /**\n * The props used for each component slot.\n * @default {}\n * @deprecated Please use `slotProps`.\n */\n componentsProps: PropTypes.object,\n /**\n * Formats the day of week displayed in the calendar header.\n * @param {string} day The day of week provided by the adapter. Deprecated, will be removed in v7: Use `date` instead.\n * @param {TDate} date The date of the day of week provided by the adapter.\n * @returns {string} The name to display.\n * @default (_day: string, date: TDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()\n */\n dayOfWeekFormatter: PropTypes.func,\n /**\n * Default calendar month displayed when `value` and `defaultValue` are empty.\n */\n defaultCalendarMonth: PropTypes.any,\n /**\n * The default value.\n * Used when the component is not controlled.\n */\n defaultValue: PropTypes.any,\n /**\n * If `true`, the picker and text field are disabled.\n * @default false\n */\n disabled: PropTypes.bool,\n /**\n * If `true`, disable values after the current date for date components, time for time components and both for date time components.\n * @default false\n */\n disableFuture: PropTypes.bool,\n /**\n * If `true`, today's date is rendering without highlighting with circle.\n * @default false\n */\n disableHighlightToday: PropTypes.bool,\n /**\n * If `true`, disable values before the current date for date components, time for time components and both for date time components.\n * @default false\n */\n disablePast: PropTypes.bool,\n /**\n * Force static wrapper inner components to be rendered in mobile or desktop mode.\n * @default \"mobile\"\n */\n displayStaticWrapperAs: PropTypes.oneOf(['desktop', 'mobile']),\n /**\n * If `true`, the week number will be display in the calendar.\n */\n displayWeekNumber: PropTypes.bool,\n /**\n * Calendar will show more weeks in order to match this value.\n * Put it to 6 for having fix number of week in Gregorian calendars\n * @default undefined\n */\n fixedWeekNumber: PropTypes.number,\n /**\n * If `true`, calls `renderLoading` instead of rendering the day calendar.\n * Can be used to preload information and show it in calendar.\n * @default false\n */\n loading: PropTypes.bool,\n /**\n * Locale for components texts.\n * Allows overriding texts coming from `LocalizationProvider` and `theme`.\n */\n localeText: PropTypes.object,\n /**\n * Maximal selectable date.\n */\n maxDate: PropTypes.any,\n /**\n * Minimal selectable date.\n */\n minDate: PropTypes.any,\n /**\n * Months rendered per row.\n * @default 3\n */\n monthsPerRow: PropTypes.oneOf([3, 4]),\n /**\n * Callback fired when the value is accepted.\n * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.\n * @param {TValue} value The value that was just accepted.\n */\n onAccept: PropTypes.func,\n /**\n * Callback fired when the value changes.\n * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.\n * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.\n * @param {TValue} value The new value.\n * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value.\n */\n onChange: PropTypes.func,\n /**\n * Callback fired when component requests to be closed.\n * Can be fired when selecting (by default on `desktop` mode) or clearing a value.\n * @deprecated Please avoid using as it will be removed in next major version.\n */\n onClose: PropTypes.func,\n /**\n * Callback fired when the error associated to the current value changes.\n * If the error has a non-null value, then the `TextField` will be rendered in `error` state.\n *\n * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.\n * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.\n * @param {TError} error The new error describing why the current value is not valid.\n * @param {TValue} value The value associated to the error.\n */\n onError: PropTypes.func,\n /**\n * Callback fired on month change.\n * @template TDate\n * @param {TDate} month The new month.\n */\n onMonthChange: PropTypes.func,\n /**\n * Callback fired on view change.\n * @template TView\n * @param {TView} view The new view.\n */\n onViewChange: PropTypes.func,\n /**\n * Callback fired on year change.\n * @template TDate\n * @param {TDate} year The new year.\n */\n onYearChange: PropTypes.func,\n /**\n * The default visible view.\n * Used when the component view is not controlled.\n * Must be a valid option from `views` list.\n */\n openTo: PropTypes.oneOf(['day', 'month', 'year']),\n /**\n * Force rendering in particular orientation.\n */\n orientation: PropTypes.oneOf(['landscape', 'portrait']),\n readOnly: PropTypes.bool,\n /**\n * If `true`, disable heavy animations.\n * @default `@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13\n */\n reduceAnimations: PropTypes.bool,\n /**\n * The date used to generate the new value when both `value` and `defaultValue` are empty.\n * @default The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.\n */\n referenceDate: PropTypes.any,\n /**\n * Component displaying when passed `loading` true.\n * @returns {React.ReactNode} The node to render when loading.\n * @default () => ...\n */\n renderLoading: PropTypes.func,\n /**\n * Disable specific date.\n *\n * Warning: This function can be called multiple times (e.g. when rendering date calendar, checking if focus can be moved to a certain date, etc.). Expensive computations can impact performance.\n *\n * @template TDate\n * @param {TDate} day The date to test.\n * @returns {boolean} If `true` the date will be disabled.\n */\n shouldDisableDate: PropTypes.func,\n /**\n * Disable specific month.\n * @template TDate\n * @param {TDate} month The month to test.\n * @returns {boolean} If `true`, the month will be disabled.\n */\n shouldDisableMonth: PropTypes.func,\n /**\n * Disable specific year.\n * @template TDate\n * @param {TDate} year The year to test.\n * @returns {boolean} If `true`, the year will be disabled.\n */\n shouldDisableYear: PropTypes.func,\n /**\n * If `true`, days outside the current month are rendered:\n *\n * - if `fixedWeekNumber` is defined, renders days to have the weeks requested.\n *\n * - if `fixedWeekNumber` is not defined, renders day to fill the first and last week of the current month.\n *\n * - ignored if `calendars` equals more than `1` on range pickers.\n * @default false\n */\n showDaysOutsideCurrentMonth: PropTypes.bool,\n /**\n * The props used for each component slot.\n * @default {}\n */\n slotProps: PropTypes.object,\n /**\n * Overridable component slots.\n * @default {}\n */\n slots: PropTypes.object,\n /**\n * The system prop that allows defining system overrides as well as additional CSS styles.\n */\n sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),\n /**\n * Choose which timezone to use for the value.\n * Example: \"default\", \"system\", \"UTC\", \"America/New_York\".\n * If you pass values from other timezones to some props, they will be converted to this timezone before being used.\n * @see See the {@link https://mui.com/x/react-date-pickers/timezone/ timezones documention} for more details.\n * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.\n */\n timezone: PropTypes.string,\n /**\n * The selected value.\n * Used when the component is controlled.\n */\n value: PropTypes.any,\n /**\n * The visible view.\n * Used when the component view is controlled.\n * Must be a valid option from `views` list.\n */\n view: PropTypes.oneOf(['day', 'month', 'year']),\n /**\n * Define custom view renderers for each section.\n * If `null`, the section will only have field editing.\n * If `undefined`, internally defined view will be the used.\n */\n viewRenderers: PropTypes.shape({\n day: PropTypes.func,\n month: PropTypes.func,\n year: PropTypes.func\n }),\n /**\n * Available views.\n */\n views: PropTypes.arrayOf(PropTypes.oneOf(['day', 'month', 'year']).isRequired),\n /**\n * Years rendered per row.\n * @default 3\n */\n yearsPerRow: PropTypes.oneOf([3, 4])\n};\nexport { StaticDatePicker };", "export { StaticDatePicker } from './StaticDatePicker';", "import dayjs from \"dayjs\";\n\nexport interface DateValidationResult {\n isValid: boolean;\n errorMessage?: string;\n}\n\n/**\n * Validates that a start date is not after an end date\n */\nexport const validateStartEndDates = (\n startDate: string | undefined,\n endDate: string | undefined,\n): DateValidationResult => {\n if (!startDate || !endDate) {\n return { isValid: true };\n }\n\n const start = dayjs(startDate);\n const end = dayjs(endDate);\n\n if (!start.isValid() || !end.isValid()) {\n return { isValid: true }; // Let individual date validation handle invalid dates\n }\n\n if (start.isAfter(end)) {\n return {\n isValid: false,\n errorMessage: \"Start date cannot be after end date\",\n };\n }\n\n return { isValid: true };\n};\n\n/**\n * Validates that an end date is not before a start date\n */\nexport const validateEndStartDates = (\n endDate: string | undefined,\n startDate: string | undefined,\n): DateValidationResult => {\n if (!startDate || !endDate) {\n return { isValid: true };\n }\n\n const start = dayjs(startDate);\n const end = dayjs(endDate);\n\n if (!start.isValid() || !end.isValid()) {\n return { isValid: true }; // Let individual date validation handle invalid dates\n }\n\n if (end.isBefore(start)) {\n return {\n isValid: false,\n errorMessage: \"End date cannot be before start date\",\n };\n }\n\n return { isValid: true };\n};\n\n/**\n * Validates a single date value\n */\nexport const validateDate = (date: string | undefined): DateValidationResult => {\n if (!date || date.trim() === \"\") {\n return { isValid: true };\n }\n\n const parsedDate = dayjs(date);\n if (!parsedDate.isValid()) {\n return {\n isValid: false,\n errorMessage: \"Invalid date format\",\n };\n }\n\n return { isValid: true };\n};\n", "import React, { useState, useRef, useEffect } from \"react\";\nimport { StaticDatePicker } from \"@mui/x-date-pickers/StaticDatePicker\";\nimport { Box, Typography, Popover } from \"@mui/material\";\nimport type { Theme } from \"@mui/material/styles\";\nimport dayjs, { Dayjs } from \"dayjs\";\nimport { Calendar, ChevronLeft, ChevronRight, ChevronDown } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\n\nconst LeftArrowIcon = () => ;\nconst RightArrowIcon = () => ;\nconst SwitchViewIcon = () => ;\nimport { FilterButton } from \"./FilterButton\";\nimport { validateStartEndDates, validateEndStartDates } from \"../../utils/dateValidation\";\nimport { useSearchFilterDispatch } from \"../contexts/SearchFilterControlContext\";\n\ninterface DateFilterChipProps {\n label: string;\n value: string | undefined;\n onChange: (value: string | undefined) => void;\n disabled?: boolean;\n // Validation props\n otherDateValue?: string | undefined;\n onValidationChange?: (isValid: boolean) => void;\n // Execute search immediately when day is selected (for search bar contexts)\n executeSearchOnDaySelect?: boolean;\n}\n\nconst DateFilterChip: React.FC = ({\n label,\n value,\n onChange,\n disabled = false,\n otherDateValue,\n onValidationChange,\n executeSearchOnDaySelect = false,\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const [pendingValue, setPendingValue] = useState(value);\n const pendingValueRef = useRef(value); // Ref for synchronous access\n\n // Track the current view to ensure we only trigger on day selections\n const [currentView, setCurrentView] = useState<\"year\" | \"month\" | \"day\">(\"day\");\n\n // Use SearchFilterControl to register when open\n const { registerOpenElement, unregisterOpenElement } = useSearchFilterDispatch();\n\n // Create buttonRef first\n const buttonRef = useRef(null);\n\n // Sync pending value when value prop changes (e.g., from URL updates)\n useEffect(() => {\n setPendingValue(value);\n pendingValueRef.current = value;\n }, [value]);\n\n // Register/unregister with SearchFilterControl when opening/closing\n useEffect(() => {\n const elementId = `date-filter-${label}`;\n\n if (isOpen) {\n registerOpenElement({\n id: elementId,\n type: \"dropdown\",\n metadata: { label, component: \"DateFilterChip\" },\n onClose: handleClose, // Provide close handler for SearchFilterControl\n });\n } else {\n unregisterOpenElement(elementId);\n }\n }, [isOpen, registerOpenElement, unregisterOpenElement, label]);\n\n // Check if date range is valid\n const isDateRangeValid = (dateStr: string) => {\n if (!otherDateValue || !dateStr) return true;\n\n const isStartDate = label.toLowerCase().includes(\"start\");\n const validation = isStartDate\n ? validateStartEndDates(dateStr, otherDateValue)\n : validateEndStartDates(dateStr, otherDateValue);\n return validation.isValid;\n };\n\n const handleButtonClick = (event: React.MouseEvent) => {\n event.stopPropagation();\n setIsOpen(true);\n };\n\n const handleClose = () => {\n const currentPendingValue = pendingValueRef.current;\n\n // Always close the picker\n setIsOpen(false);\n\n // Only call onChange (which triggers search and closes top bar) if:\n // 1. The value actually changed AND\n // 2. The value is valid\n if (currentPendingValue !== value) {\n const isValidDate = !currentPendingValue || isDateRangeValid(currentPendingValue);\n if (isValidDate) {\n onChange(currentPendingValue); // This triggers search and closes top bar\n onValidationChange?.(true);\n }\n // If invalid, just close the picker without triggering search (top bar stays open)\n }\n // If no change occurred, just close the picker (top bar stays open)\n };\n\n const handleClear = () => {\n // Clear immediately (no deferred commit for clear action)\n onChange(undefined);\n onValidationChange?.(true);\n setPendingValue(undefined);\n pendingValueRef.current = undefined;\n setIsOpen(false);\n };\n\n // Convert string date to Dayjs object for the date picker (use pending value for picker state)\n const dateValue = pendingValue ? dayjs(pendingValue) : null;\n\n // Calculate min/max date constraints based on other date value\n const getDateConstraints = () => {\n if (!otherDateValue) return {};\n\n const otherDate = dayjs(otherDateValue);\n if (!otherDate.isValid()) return {};\n\n const isStartDate = label.toLowerCase().includes(\"start\");\n\n if (isStartDate) {\n // For start date, max date should be the end date\n return { maxDate: otherDate };\n } else {\n // For end date, min date should be the start date\n return { minDate: otherDate };\n }\n };\n\n const dateConstraints = getDateConstraints();\n\n // Use pendingValue if available (for immediate UI feedback), otherwise use value\n const currentValue = pendingValue !== undefined ? pendingValue : value;\n\n // Format button text based on whether there's a value\n const getButtonText = () => {\n if (!currentValue) return label;\n\n const dayjsValue = dayjs(currentValue);\n if (!dayjsValue.isValid()) {\n return label;\n }\n\n const formattedDate = dayjsValue.format(\"MM/DD/YYYY\");\n if (label.toLowerCase().includes(\"start\")) {\n return `FROM ${formattedDate}`;\n } else if (label.toLowerCase().includes(\"end\")) {\n return `TO ${formattedDate}`;\n }\n return `${label}: ${formattedDate}`;\n };\n\n const isApplied = Boolean(currentValue && dayjs(currentValue).isValid());\n\n return (\n \n \n }\n disabled={disabled}\n onClick={handleButtonClick}\n onClear={handleClear}\n sx={{\n opacity: isOpen ? 0 : 1,\n transition: \"opacity 0.2s ease-in-out\",\n }}\n >\n {getButtonText()}\n \n \n\n {\n // Close on escape key or backdrop click (for story environments)\n if (reason === \"escapeKeyDown\" || reason === \"backdropClick\") {\n handleClose();\n }\n }}\n disableEnforceFocus\n disableAutoFocus\n disableRestoreFocus\n anchorOrigin={{\n vertical: \"top\",\n horizontal: \"left\",\n }}\n transformOrigin={{\n vertical: \"top\",\n horizontal: \"left\",\n }}\n PaperProps={\n {\n className: \"MuiPickersLayout-root\",\n \"data-filter-button\": true,\n \"data-top-bar-keep-open\": true,\n sx: (theme: Theme) => ({\n border: `1px solid ${theme.border.light}`,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n boxShadow: theme.tokens.shadows.md,\n p: 1,\n minWidth: 280,\n }),\n } as any\n }\n >\n \n \n \n \n {label}\n \n \n \n {\n if (newValue && newValue.isValid()) {\n const formattedDate = newValue.format(\"YYYY-MM-DD\");\n\n // Always update pending value for UI feedback\n setPendingValue(formattedDate);\n pendingValueRef.current = formattedDate; // Update ref synchronously\n\n // Update validation state immediately for UI feedback\n const isValidDate = isDateRangeValid(formattedDate);\n onValidationChange?.(isValidDate);\n\n // Only commit and close if we're in day view (meaning user clicked a day chip)\n // and executeSearchOnDaySelect is enabled\n if (executeSearchOnDaySelect && isValidDate && currentView === \"day\") {\n onChange(formattedDate);\n setIsOpen(false); // Close the picker after day selection\n }\n } else if (newValue === null) {\n setPendingValue(undefined);\n pendingValueRef.current = undefined; // Update ref synchronously\n onValidationChange?.(true);\n\n // If executeSearchOnDaySelect is enabled, commit the clear immediately\n if (executeSearchOnDaySelect) {\n onChange(undefined);\n setIsOpen(false);\n }\n }\n // Don't close automatically when executeSearchOnDaySelect is false - let user continue selecting\n }}\n onViewChange={(view) => {\n setCurrentView(view);\n }}\n disabled={disabled}\n {...dateConstraints}\n slots={{\n leftArrowIcon: LeftArrowIcon,\n rightArrowIcon: RightArrowIcon,\n switchViewIcon: SwitchViewIcon,\n }}\n slotProps={{\n actionBar: {\n actions: [], // Hide the action bar (OK/Cancel buttons)\n },\n }}\n sx={{\n \"& .MuiPickersToolbar-root\": {\n display: \"none\", // Hide the toolbar with selected date display\n },\n \"& .MuiPickersCalendarHeader-label\": {\n fontSize: \"0.875rem\",\n fontWeight: 600,\n lineHeight: 1.5,\n },\n \"& .MuiPickersYear-yearButton\": {\n fontSize: \"0.875rem\",\n fontWeight: 400,\n lineHeight: 1.6,\n },\n }}\n />\n \n \n \n );\n};\n\nexport default DateFilterChip;\n", "import React, { useState, useRef, useEffect } from \"react\";\nimport { Box, Popover } from \"@mui/material\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { Hash } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport { FilterButton } from \"./FilterButton\";\nimport { BIQInputField } from \"./BIQInputField\";\nimport { useSearchFilterDispatch } from \"../contexts/SearchFilterControlContext\";\n\ninterface CaseNumberFilterChipProps {\n /**\n * The current case number value\n */\n value?: string;\n /**\n * Callback fired when the case number changes\n */\n onChange: (value: string | undefined) => void;\n /**\n * Whether the filter is disabled\n */\n disabled?: boolean;\n}\n\n/**\n * A filter chip for case number input with validation.\n * Validates case number format (XX-YYYYY) and shows error states.\n */\nexport const CaseNumberFilterChip: React.FC = ({ value, onChange, disabled = false }) => {\n const theme = useTheme();\n const [isEditing, setIsEditing] = useState(false);\n const [inputValue, setInputValue] = useState(\"\");\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState(false);\n const inputRef = useRef(null);\n\n // Use SearchFilterControl to register when open\n const { registerOpenElement, unregisterOpenElement } = useSearchFilterDispatch();\n\n // Create buttonRef first\n const buttonRef = useRef(null);\n\n // Sync input value with prop value when not editing\n useEffect(() => {\n if (!isEditing) {\n setInputValue(value || \"\");\n setHasAttemptedSubmit(false);\n }\n }, [value, isEditing]);\n\n // Register/unregister with SearchFilterControl when opening/closing\n useEffect(() => {\n const elementId = \"case-number-filter\";\n\n if (isEditing) {\n registerOpenElement({\n id: elementId,\n type: \"dropdown\",\n metadata: { component: \"CaseNumberFilterChip\" },\n onClose: handleForceClose, // Provide close handler for SearchFilterControl\n });\n } else {\n unregisterOpenElement(elementId);\n }\n }, [isEditing, registerOpenElement, unregisterOpenElement]);\n\n // Auto-focus when editing starts\n useEffect(() => {\n if (isEditing && inputRef.current) {\n inputRef.current.focus();\n // Only call select if the method exists (not available in test environment)\n if (typeof inputRef.current.select === \"function\") {\n inputRef.current.select();\n }\n }\n }, [isEditing]);\n\n /**\n * Validates the case number format (XX-YYYYY)\n */\n const isValidFormat = (caseNumber: string): boolean => {\n if (!caseNumber.trim()) return true; // Empty is valid (clears the filter)\n return /^\\d{2}-\\d{5}$/.test(caseNumber.trim());\n };\n\n /**\n * Handles submitting the current input value\n */\n const handleSubmit = () => {\n setHasAttemptedSubmit(true);\n const trimmedValue = inputValue.trim();\n\n if (isValidFormat(trimmedValue)) {\n onChange(trimmedValue || undefined);\n setIsEditing(false);\n }\n // If invalid, keep editing mode open to show error\n };\n\n /**\n * Handles canceling the edit\n */\n const handleCancel = () => {\n setInputValue(value || \"\");\n setHasAttemptedSubmit(false);\n setIsEditing(false);\n };\n\n /**\n * Handles clearing the filter\n */\n const handleClear = () => {\n onChange(undefined);\n };\n\n /**\n * Handles key press events\n */\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n // Always close menu on Enter, even with errors (consistent with other filters)\n handleForceClose();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n handleCancel();\n }\n };\n\n const handleButtonClick = () => {\n setIsEditing(true);\n };\n\n const handleClose = () => {\n handleSubmit();\n };\n\n const handleForceClose = () => {\n setHasAttemptedSubmit(true);\n const trimmedValue = inputValue.trim();\n const normalizedNewValue = trimmedValue || undefined;\n\n // Always close the editing mode (for click-outside and blur events)\n setIsEditing(false);\n\n // Only call onChange (which triggers search and closes top bar) if:\n // 1. The value is valid AND\n // 2. The value actually changed\n if (isValidFormat(trimmedValue) && normalizedNewValue !== value) {\n onChange(normalizedNewValue);\n }\n // If invalid OR unchanged, just close the picker (top bar stays open)\n };\n\n // Only show error if user has tried to submit, or if editing and the input is definitely invalid (not just incomplete)\n // Allow partial/in-progress input (e.g., \"01-\" or \"01-01\") without error while editing\n const isPotentiallyValid = inputValue.trim() === \"\" || /^\\d{0,2}-?\\d{0,5}$/.test(inputValue.trim());\n const shouldShowError = hasAttemptedSubmit ? !isValidFormat(inputValue) : isEditing && !isPotentiallyValid;\n const isApplied = Boolean(value && value.trim());\n\n return (\n \n {/* Filter Button */}\n \n }\n applied={isApplied}\n disabled={disabled}\n onClick={handleButtonClick}\n onClear={handleClear}\n sx={{\n opacity: isEditing ? 0 : 1,\n transition: \"opacity 0.2s ease-in-out\",\n }}\n >\n {value || \"Case Number\"}\n \n \n\n {/* Popover Editor */}\n {\n // Close on escape key or backdrop click (for story environments)\n if (reason === \"escapeKeyDown\" || reason === \"backdropClick\") {\n handleClose();\n }\n }}\n disableRestoreFocus\n disableAutoFocus\n anchorOrigin={{\n vertical: \"top\",\n horizontal: \"left\",\n }}\n transformOrigin={{\n vertical: \"top\",\n horizontal: \"left\",\n }}\n PaperProps={\n {\n \"data-filter-button\": true,\n \"data-top-bar-keep-open\": true,\n sx: {\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n border: 1,\n borderColor: theme.border.light,\n padding: 2,\n width: 250,\n boxShadow: theme.tokens.shadows.md,\n },\n } as any\n }\n >\n \n setInputValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onBlur={handleForceClose}\n error={shouldShowError}\n helper={shouldShowError ? \"Invalid format. Use XX-YYYYY (e.g., 01-01139)\" : \"e.g., 01-01139\"}\n />\n \n \n \n );\n};\n\nexport default CaseNumberFilterChip;\n", "import React, { useCallback, useMemo, useState, useEffect } from \"react\";\nimport { Box } from \"@mui/material\";\nimport { useBooleanSearchBarDispatch, useBooleanSearchBarState } from \"../contexts/BooleanSearchBarControlContext\";\nimport JudgeAutocomplete from \"../atoms/JudgeAutocomplete\";\nimport DateFilterChip from \"../atoms/DateFilterChip\";\nimport CaseNumberFilterChip from \"../atoms/CaseNumberFilterChip\";\nimport { validateStartEndDates, validateEndStartDates } from \"../../utils/dateValidation\";\n\ninterface AppliedFiltersProps {\n /**\n * Called when a filter value changes and validation passes.\n * This should trigger a new search.\n * @param updatedValues - The fresh values that were just updated (to avoid stale state)\n */\n onFilterChange?: (updatedValues?: {\n caseNumber?: string | undefined;\n hearingDateFrom?: string | undefined;\n hearingDateTo?: string | undefined;\n judges?: any[];\n }) => void;\n\n /**\n * Called when validation state changes.\n * When validation fails, automatic search execution should be disabled.\n */\n onValidationChange?: (isValid: boolean) => void;\n\n /**\n * Whether to show all filters or only applied ones.\n * When true, all filters are shown even if they have no values.\n * When false, only filters with applied values are shown.\n * Defaults to false.\n */\n showAllFilters?: boolean;\n\n /**\n * Whether to use deferred mode where filter changes don't trigger immediate searches.\n * When true, filter changes only update local state without calling onFilterChange.\n * When false (default), filter changes trigger immediate searches via onFilterChange.\n * This is useful for modal contexts where you want to preview changes before applying.\n */\n deferredMode?: boolean;\n\n /**\n * Override filter values to display. When provided, these values are used instead of\n * the context values. This allows displaying URL-based \"applied\" values separately\n * from context-based \"pending\" values.\n */\n filterValues?: {\n selectedJudges?: any[];\n hearingDateFromInput?: string | undefined;\n hearingDateToInput?: string | undefined;\n caseNumberInput?: string | undefined;\n };\n}\n\n/**\n * Component that displays applied filters for hard filters: judge name, case number, and dates.\n * Shows filters in an applied state if they have values.\n * Executes new search immediately when values change and validation passes.\n * Provides validation state to prevent automatic search execution when invalid.\n */\nexport const AppliedFilters: React.FC = ({\n onFilterChange,\n onValidationChange,\n showAllFilters = false,\n deferredMode = false,\n filterValues,\n}) => {\n const {\n selectedJudges: contextSelectedJudges,\n hearingDateFromInput: contextHearingDateFromInput,\n hearingDateToInput: contextHearingDateToInput,\n caseNumberInput: contextCaseNumberInput,\n } = useBooleanSearchBarState();\n const { setSelectedJudges, setHearingDateFromInput, setHearingDateToInput, setCaseNumberInput } =\n useBooleanSearchBarDispatch();\n\n // Use override values if provided, otherwise fall back to context values\n // Important: When filterValues is provided, use its values even if they are undefined\n // Memoize these derivations to prevent unnecessary re-renders\n const selectedJudges = useMemo(\n () => (filterValues ? (filterValues.selectedJudges ?? []) : contextSelectedJudges),\n [filterValues?.selectedJudges, contextSelectedJudges],\n );\n const hearingDateFromInput = useMemo(\n () => (filterValues ? filterValues.hearingDateFromInput : contextHearingDateFromInput),\n [filterValues?.hearingDateFromInput, contextHearingDateFromInput],\n );\n const hearingDateToInput = useMemo(\n () => (filterValues ? filterValues.hearingDateToInput : contextHearingDateToInput),\n [filterValues?.hearingDateToInput, contextHearingDateToInput],\n );\n const caseNumberInput = useMemo(\n () => (filterValues ? filterValues.caseNumberInput : contextCaseNumberInput),\n [filterValues?.caseNumberInput, contextCaseNumberInput],\n );\n\n // Pending states for deferred commit (judges only)\n const [pendingJudges, setPendingJudges] = useState(selectedJudges);\n const [isJudgePickerOpen, setIsJudgePickerOpen] = useState(false);\n\n // Sync pending judges when selectedJudges changes from external sources (e.g., URL updates)\n useEffect(() => {\n setPendingJudges(selectedJudges);\n }, [selectedJudges]);\n\n // Validation states\n const [dateValidationState, setDateValidationState] = React.useState<{\n startDateValid: boolean;\n endDateValid: boolean;\n }>({ startDateValid: true, endDateValid: true });\n\n const [caseNumberValid, setCaseNumberValid] = React.useState(true);\n\n // Overall validation state\n const isValid = useMemo(() => {\n return dateValidationState.startDateValid && dateValidationState.endDateValid && caseNumberValid;\n }, [dateValidationState.startDateValid, dateValidationState.endDateValid, caseNumberValid]);\n\n // Notify parent of validation state changes\n React.useEffect(() => {\n onValidationChange?.(isValid);\n }, [isValid, onValidationChange]);\n\n // Handle judge selection change (deferred commit)\n const handleJudgeChange = useCallback(\n (judges: any[]) => {\n // Update pending judges immediately for UI feedback\n setPendingJudges(judges);\n // Don't commit to context or trigger search yet\n },\n [setPendingJudges],\n );\n\n // Optimized judge comparison to avoid expensive JSON.stringify\n const judgesChanged = useMemo(() => {\n if (pendingJudges.length !== selectedJudges.length) return true;\n return pendingJudges.some((pendingJudge, index) => pendingJudge.id !== selectedJudges[index]?.id);\n }, [pendingJudges, selectedJudges]);\n\n // Handle judge picker open/close state\n const handleJudgePickerStateChange = useCallback(\n (isOpen: boolean) => {\n if (isJudgePickerOpen && !isOpen) {\n // Picker is closing, commit the pending judges\n if (judgesChanged) {\n // Only update context if we're not using override values\n if (!filterValues?.selectedJudges) {\n setSelectedJudges(pendingJudges);\n }\n if (!deferredMode) {\n onFilterChange?.({ judges: pendingJudges });\n }\n }\n }\n setIsJudgePickerOpen(isOpen);\n },\n [\n isJudgePickerOpen,\n judgesChanged,\n pendingJudges,\n setSelectedJudges,\n onFilterChange,\n deferredMode,\n filterValues?.selectedJudges,\n ],\n );\n\n // Handle immediate judge clear (X button)\n const handleJudgeClear = useCallback(() => {\n const emptyJudges: any[] = [];\n\n // Clear the state immediately (only if we're not using override values)\n if (!filterValues?.selectedJudges) {\n setSelectedJudges(emptyJudges);\n }\n setPendingJudges(emptyJudges);\n\n // Trigger the filter change (only if not in deferred mode)\n if (!deferredMode) {\n onFilterChange?.({ judges: emptyJudges });\n }\n }, [setSelectedJudges, setPendingJudges, onFilterChange, deferredMode, filterValues?.selectedJudges]);\n\n // Handle start date change\n const handleStartDateChange = useCallback(\n (value: string | undefined) => {\n // Always update context if not using override values\n if (!filterValues?.hearingDateFromInput) {\n setHearingDateFromInput(value);\n }\n\n // Validate the date range\n const validation = validateStartEndDates(value, hearingDateToInput);\n setDateValidationState((prev) => ({ ...prev, startDateValid: validation.isValid }));\n\n // Always call onFilterChange when valid (even with filterValues override)\n // This ensures both TopSearchBar pending state and AdvancedModal working values get updated\n if (validation.isValid && !deferredMode) {\n onFilterChange?.({ hearingDateFrom: value });\n }\n },\n [setHearingDateFromInput, hearingDateToInput, onFilterChange, deferredMode, filterValues?.hearingDateFromInput],\n );\n\n // Handle end date change\n const handleEndDateChange = useCallback(\n (value: string | undefined) => {\n // Always update context if not using override values\n if (!filterValues?.hearingDateToInput) {\n setHearingDateToInput(value);\n }\n\n // Validate the date range\n const validation = validateEndStartDates(value, hearingDateFromInput);\n setDateValidationState((prev) => ({ ...prev, endDateValid: validation.isValid }));\n\n // Always call onFilterChange when valid (even with filterValues override)\n // This ensures both TopSearchBar pending state and AdvancedModal working values get updated\n if (validation.isValid && !deferredMode) {\n onFilterChange?.({ hearingDateTo: value });\n }\n },\n [setHearingDateToInput, hearingDateFromInput, onFilterChange, deferredMode, filterValues?.hearingDateToInput],\n );\n\n // Handle case number change\n const handleCaseNumberChange = useCallback(\n (value: string | undefined) => {\n // Always update context if not using override values\n if (!filterValues?.caseNumberInput) {\n setCaseNumberInput(value);\n }\n\n // Validate case number format (XX-YYYYY)\n const isValidFormat = !value || /^\\d{2}-\\d{5}$/.test(value);\n setCaseNumberValid(isValidFormat);\n\n // Always call onFilterChange when valid (even with filterValues override)\n // This ensures both TopSearchBar pending state and AdvancedModal working values get updated\n if (isValidFormat && !deferredMode) {\n onFilterChange?.({ caseNumber: value });\n }\n },\n [setCaseNumberInput, onFilterChange, deferredMode, filterValues?.caseNumberInput],\n );\n\n // Handle date validation change from DateFilterChip\n const handleStartDateValidationChange = useCallback((isValidDate: boolean) => {\n setDateValidationState((prev) => ({ ...prev, startDateValid: isValidDate }));\n }, []);\n\n const handleEndDateValidationChange = useCallback((isValidDate: boolean) => {\n setDateValidationState((prev) => ({ ...prev, endDateValid: isValidDate }));\n }, []);\n\n // Only render filters that have applied values\n const hasAppliedStartDate = hearingDateFromInput && hearingDateFromInput.trim() !== \"\";\n const hasAppliedEndDate = hearingDateToInput && hearingDateToInput.trim() !== \"\";\n const hasAppliedCaseNumber = caseNumberInput && caseNumberInput.trim() !== \"\";\n\n return (\n \n {/* Always show the judge autocomplete */}\n \n\n {(showAllFilters || hasAppliedStartDate) && (\n \n )}\n\n {(showAllFilters || hasAppliedEndDate) && (\n \n )}\n\n {(showAllFilters || hasAppliedCaseNumber) && (\n \n )}\n \n );\n};\n\nexport default AppliedFilters;\n", "import type { TranscriptsAPIReadableContentPreview } from \"../api/queries/transcripts.types\";\nimport type { NullableTranscriptScrollTarget } from \"../api/queries/transcriptScrollTargets.types\";\n\nexport type OverviewCitationClickEntry = {\n citationIndex: number;\n text: string;\n target: NullableTranscriptScrollTarget;\n};\n\nexport const overviewCitationClickEntries = (\n transcriptSearchResultPreview: TranscriptsAPIReadableContentPreview,\n): OverviewCitationClickEntry[] =>\n (transcriptSearchResultPreview.transcript_overview?.citations ?? [])\n .sort((a, b) => a.index - b.index)\n .flatMap((citation) =>\n citation.transcript_citations.map((text, index) => ({\n citationIndex: citation.index,\n text,\n target: citation.transcript_locations?.[index] ?? null,\n })),\n )\n .filter((entry) => entry.text.length > 0);\n\nexport const preferredOverviewCitationEntryIndex = (\n entries: OverviewCitationClickEntry[],\n citationIdx: number,\n): number => {\n const matchingEntries = entries\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => entry.citationIndex === citationIdx);\n const resolvedEntry = matchingEntries.find(({ entry }) => entry.target?.start);\n\n return (resolvedEntry ?? matchingEntries[0])?.index ?? -1;\n};\n", "import React from \"react\";\nimport { alpha } from \"@mui/material/styles\";\nimport { Box, Dialog, Stack, Typography } from \"@mui/material\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport MatterCodeAutocomplete from \"@/components/molecules/MatterCodeAutocomplete\";\nimport { colors } from \"@/components/theme/tokens\";\nimport { useEffectiveRailWidth } from \"@/components/AppShell/EffectiveRailWidthContext\";\nimport { MODAL_WIDTH } from \"@/utils/constants\";\n\nconst TOP_OFFSET_FROM_TOPBAR = 20;\nconst MODAL_BUTTON_SX = { paddingTop: \"7px\", paddingBottom: \"7px\" } as const;\n\ninterface LockedSearchMatterModalProps {\n open: boolean;\n searchName: string;\n matterCode: string;\n onContinue: () => void;\n onStartNewSearch: () => void;\n}\n\nconst LockedSearchMatterModal = ({\n open,\n searchName,\n matterCode,\n onContinue,\n onStartNewSearch,\n}: LockedSearchMatterModalProps) => {\n const effectiveRailWidth = useEffectiveRailWidth();\n const submit = (\n eventName: \"credit_matter_modal_continue_button_clicked\" | \"credit_matter_modal_start_new_search_button_clicked\",\n callback: () => void,\n ) => {\n void recordUserEvent({\n event_name: eventName,\n event_properties: { modal_variant: \"locked_search\" },\n });\n callback();\n };\n\n const handleClose = (_event: object, reason: \"backdropClick\" | \"escapeKeyDown\") => {\n void recordUserEvent({\n event_name:\n reason === \"escapeKeyDown\" ? \"credit_matter_modal_escape_key_pressed\" : \"credit_matter_modal_backdrop_clicked\",\n event_properties: { modal_variant: \"locked_search\" },\n });\n onContinue();\n };\n\n return (\n ({\n width: { xs: \"calc(100% - 48px)\", sm: MODAL_WIDTH },\n maxWidth: \"calc(100% - 48px)\",\n maxHeight: `calc(100vh - ${theme.tokens.layout.appShellTopBarHeight + TOP_OFFSET_FROM_TOPBAR + 24}px)`,\n marginTop: `${theme.tokens.layout.appShellTopBarHeight + TOP_OFFSET_FROM_TOPBAR}px`,\n padding: 0,\n display: \"flex\",\n flexDirection: \"column\",\n backgroundColor: \"background.paper\",\n border: `1px solid ${theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n boxShadow: theme.tokens.shadows.lg,\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n }),\n }}\n >\n \n Continue with this matter\n \n \n \n \n Search credits for your search, {searchName}, is currently assigned to Matter {matterCode}.\n To use a different matter, start a new search.\n \n undefined}\n disabled\n placeholder=\"Enter a matter number...\"\n />\n \n submit(\"credit_matter_modal_start_new_search_button_clicked\", onStartNewSearch)}\n sx={MODAL_BUTTON_SX}\n >\n Start new search\n \n submit(\"credit_matter_modal_continue_button_clicked\", onContinue)}\n sx={MODAL_BUTTON_SX}\n >\n Continue\n \n \n \n \n \n );\n};\n\nexport default LockedSearchMatterModal;\n", "import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useNavigate, useSearchParams } from \"../../utils/urlHelpers\";\n\nimport { styled } from \"@/utils/styled\";\nimport NoTranscriptResults from \"./NoTranscriptResults\";\nimport { formatResultCountLabel } from \"./formatResultCountLabel\";\nimport Box from \"@mui/material/Box\";\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\nimport CircularProgress from \"@mui/material/CircularProgress\";\n\nimport WindowTitle from \"../atoms/WindowTitle\";\nimport StyledPagination from \"../atoms/StyledPagination\";\nimport Alert from \"@mui/material/Alert\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport QueryResultCard from \"../molecules/QueryResultCard\";\n\nimport { useQueryBenchOpinionsAPIIndex, useQueryTranscriptsAPIIndex } from \"../../api/documents\";\nimport {\n TranscriptsAPIIndexURLSearchParams,\n TranscriptsAPIIndexURLSearchParamsQueryType,\n TranscriptsAPIReadableContentPreview,\n TranscriptsAPIIndexURLSearchParamsSortFields,\n TranscriptsAPIIndexURLSearchParamsSortDirections,\n} from \"../../api/queries/transcripts.types\";\nimport { BenchOpinionsAPIIndexURLSearchParams } from \"../../api/queries/benchOpinions.types\";\nimport useQueryAutoCorrections from \"../../api/queryAutoCorrections\";\nimport { Select } from \"@mui/material\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { BenchAlert } from \"@/components/atoms/BenchAlert\";\nimport ExpandableTruncatedText from \"../atoms/ExpandableTruncatedText\";\nimport { recordUserEvent } from \"../../api/userEvents\";\nimport { matchesSupportedBooleanTerms, matchesUnsupportedBooleanTerms } from \"../../utils/identifyBooleanTerms\";\nimport { normalizeQueryForComparison } from \"../../utils/booleanSearchValidation\";\n\nimport ScrollableContent from \"../atoms/ScrollableContent\";\nimport { SidepanelTranscriptReader } from \"../Reader/SidepanelTranscriptReader\";\nimport { useReaderPanelState, type UseReaderPanelStateReturn } from \"../AppShell/useReaderPanelState\";\nimport { useTranscriptDisplayTitle } from \"../../hooks/useTranscriptDisplayTitle\";\nimport areUrlParamsTheSame from \"../../utils/areUrlParamsTheSame\";\nimport { TranscriptQueryResultType as QueryResultType } from \"../../api/queries\";\nimport { AlertTriangle, ArrowUpDown } from \"lucide-react\";\nimport FeatureDisabledByAdmin from \"../atoms/FeatureDisabledByAdmin\";\nimport { featureEnabled } from \"../../utils/featureFlags\";\nimport { isGenerativeAIAvailable } from \"../../utils/queryCorrectionUtils\";\nimport { computeAutoCorrectionExecution } from \"../../utils/autoCorrectionExecution\";\nimport AppliedFilters from \"../molecules/AppliedFilters\";\nimport { useBooleanSearchBarDispatch, useBooleanSearchBarState } from \"../contexts/BooleanSearchBarControlContext\";\nimport { useQueryJudgesList } from \"../../api/judges\";\nimport { RESULTS_PANEL_MIN_WIDTH, PAGE_CONTENT_MAX_WIDTH } from \"../../utils/constants\";\nimport type {\n NullableTranscriptScrollTarget,\n TranscriptScrollTarget,\n} from \"../../api/queries/transcriptScrollTargets.types\";\nimport { overviewCitationClickEntries, preferredOverviewCitationEntryIndex } from \"../../utils/overviewCitations\";\nimport { useOptionalClientMatter } from \"@/contexts/ClientMatterContext\";\nimport { isCreditBillingLive } from \"@/utils/creditBilling\";\nimport { AppShell } from \"../AppShell\";\nimport { TopBarRight } from \"../AppShell/TopBarRight\";\nimport ActiveMatterButton from \"../atoms/ActiveMatterButton\";\nimport LockedSearchMatterModal from \"../molecules/LockedSearchMatterModal\";\nimport { openCreditMatterLaunchTab } from \"@/utils/creditMatterLaunch\";\nimport { CLERK_ERROR_COPY } from \"@/utils/clerkErrorCopy\";\n\n// TODO Phase 2 review: margin-top 100px doesn't match scale (also overridden by 0 below \u2014 possibly dead)\nconst LoadingResultsContainer = styled(Box)`\n height: 100%;\n display: flex;\n margin-top: 100px;\n margin-left: auto;\n margin-right: auto;\n\n width: 100%;\n min-width: ${RESULTS_PANEL_MIN_WIDTH}px;\n max-width: ${PAGE_CONTENT_MAX_WIDTH}px;\n margin-top: 0;\n justify-content: center;\n align-items: center;\n flex: 1 1 auto;\n`;\n\n// TODO Phase 2 review: min-height 200px is a layout dimension, no token category\nconst InlineLoadingResultsContainer = styled(Box)`\n display: flex;\n justify-content: center;\n align-items: center;\n flex: 1 1 auto;\n min-height: 200px;\n padding: ${({ theme }) => theme.tokens.spacing[5]}px;\n`;\n\nconst QueryResultsContainer = styled(Box)(({ theme }) => ({\n marginTop: 0,\n marginLeft: \"auto\",\n marginRight: \"auto\",\n height: \"100%\",\n width: \"100%\",\n minWidth: `${RESULTS_PANEL_MIN_WIDTH}px`,\n maxWidth: `${PAGE_CONTENT_MAX_WIDTH}px`,\n WebkitBoxSizing: \"border-box\" /* Safari/Chrome, other WebKit */,\n MozBoxSizing: \"border-box\" /* Firefox, other Gecko */,\n boxSizing: \"border-box\" /* Opera/IE 8+ */,\n display: \"flex\",\n flexDirection: \"column\",\n overflowY: \"hidden\",\n paddingLeft: theme.tokens.spacing[6],\n paddingRight: theme.tokens.spacing[6],\n paddingTop: theme.tokens.spacing[6],\n paddingBottom: theme.tokens.spacing[4],\n}));\n\ntype ParamsToUpdate = {\n paramsToUpdate: TranscriptsAPIIndexURLSearchParams | BenchOpinionsAPIIndexURLSearchParams;\n resultType?: QueryResultType;\n};\n\nconst numberParam = (urlParams: URLSearchParams, key: string): number | undefined => {\n const value = urlParams.get(key);\n if (value === null || value.trim() === \"\") return undefined;\n\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n};\n\nexport const parseInitialReaderTranscriptTarget = (\n urlParams: URLSearchParams,\n excerpt: string | null,\n): TranscriptScrollTarget | null => {\n const requestedSource = urlParams.get(\"initialReaderTranscriptTargetSource\");\n const source: TranscriptScrollTarget[\"source\"] =\n requestedSource === \"clerk_citation\" ? \"clerk_citation\" : \"bench_opinion_reference\";\n const startAnchorId = urlParams.get(\"initialReaderTranscriptTargetAnchorId\") ?? undefined;\n const endAnchorId = urlParams.get(\"initialReaderTranscriptTargetEndAnchorId\") ?? undefined;\n const startPage = numberParam(urlParams, \"initialReaderTranscriptTargetPage\");\n const startLine = numberParam(urlParams, \"initialReaderTranscriptTargetLine\");\n const endPage = numberParam(urlParams, \"initialReaderTranscriptTargetEndPage\");\n const endLine = numberParam(urlParams, \"initialReaderTranscriptTargetEndLine\");\n const startAbsoluteLineIndex = numberParam(urlParams, \"initialReaderTranscriptTargetAbsoluteLineIndex\");\n const endAbsoluteLineIndex = numberParam(urlParams, \"initialReaderTranscriptTargetEndAbsoluteLineIndex\");\n const startCharOffset = numberParam(urlParams, \"initialReaderTranscriptTargetCharOffset\");\n const endCharOffset = numberParam(urlParams, \"initialReaderTranscriptTargetEndCharOffset\");\n const offsetSpace = urlParams.get(\"initialReaderTranscriptTargetOffsetSpace\");\n const documentOffsetTarget =\n offsetSpace === \"document\" &&\n startCharOffset !== undefined &&\n endCharOffset !== undefined &&\n endCharOffset >= startCharOffset;\n\n if (!documentOffsetTarget && !startAnchorId && (startPage === undefined || startLine === undefined)) {\n return null;\n }\n\n return {\n excerpt: excerpt ?? \"\",\n source,\n offset_space: documentOffsetTarget ? \"document\" : \"anchor\",\n content_fingerprint: urlParams.get(\"initialReaderTranscriptTargetContentFingerprint\") ?? undefined,\n anchor_schema_version: urlParams.get(\"initialReaderTranscriptTargetAnchorSchemaVersion\") ?? undefined,\n start: {\n anchor_id: startAnchorId,\n page: startPage ?? 0,\n line_number: startLine ?? 0,\n absolute_line_index: startAbsoluteLineIndex,\n char_offset: startCharOffset,\n },\n end:\n endAnchorId ||\n endPage !== undefined ||\n endLine !== undefined ||\n endAbsoluteLineIndex !== undefined ||\n endCharOffset !== undefined\n ? {\n anchor_id: endAnchorId,\n page: endPage ?? startPage ?? 0,\n line_number: endLine ?? startLine ?? 0,\n absolute_line_index: endAbsoluteLineIndex,\n char_offset: endCharOffset,\n }\n : undefined,\n };\n};\n\nexport const creditSearchExecutionIdForUpdate = (\n currentExecutionId: string | null,\n isOnlyPaginationChange: boolean,\n createId: () => string = () => crypto.randomUUID(),\n) => (isOnlyPaginationChange && currentExecutionId ? currentExecutionId : createId());\n\nconst QueryResults = () => {\n const queryAutoCorrections = useQueryAutoCorrections();\n const clientMatter = useOptionalClientMatter();\n const [lockedSearchMatterDialogOpen, setLockedSearchMatterDialogOpen] = useState(false);\n const isAIDisabled = featureEnabled(\"disable_generative_ai\");\n const judgesQuery = useQueryJudgesList();\n\n // Get context values for building URL parameters\n const {\n additionalQueryInput,\n hearingDateFromInput,\n hearingDateToInput,\n caseNumberInput,\n caseNameInput,\n motionTypeInput,\n getSelectedJudgeNamesString,\n } = useBooleanSearchBarState();\n\n const { expandAndFocusQueryText } = useBooleanSearchBarDispatch();\n\n // search params\n const [searchParams, setSearchParams] = useSearchParams();\n const navigate = useNavigate();\n const prevUrlParamsRef = useRef(new URLSearchParams(searchParams.toString()));\n const lastAutoCorrectionRequestKeyRef = useRef(null);\n const urlParams: URLSearchParams = searchParams;\n const initialReaderTranscriptIdString: string | null = urlParams.get(\"initialReaderTranscriptId\"); // opens the specified transcript in the reader on page load\n const initialReaderTranscriptId: number | null = initialReaderTranscriptIdString\n ? parseInt(initialReaderTranscriptIdString)\n : null;\n // The \"Copy Link\" / \"Share Transcript\" menu stamps `readerView=full` on the\n // shareable URL so opening it lands directly in full-screen. In-app deep\n // links that reuse `initialReaderTranscriptId` (e.g. a bench-opinion \"View\n // in transcript\" click) omit the marker and stay in the paneled mode.\n const openReaderInFullScreen: boolean = urlParams.get(\"readerView\") === \"full\";\n // Opens the in-transcript search drawer automatically once the reader has a transcript.\n // Used by deep-link entry points like the Folder Detail page's row Search action.\n const initialOpenSearch: boolean = urlParams.get(\"openSearch\") === \"1\";\n const initialReaderTranscriptTextToHighlight: string | null = urlParams.get(\"initialReaderTranscriptTextToHighlight\"); // uses scroll_within to capture initial highlight\n /*\n * Deep-link target \u2014 drives the reader's initial scroll/highlight on\n * pages opened via `?initialReaderTranscriptId=\u2026&initialReaderTranscriptTarget\u2026`.\n * Examples: bench-opinion citation \"View in transcript\" links, Clerk\n * citation links, activity history links. Forwarded to\n * `` \u2192 `` as\n * `initialScrollTarget`; if null, the reader opens at the top of the\n * transcript with no highlight.\n */\n const initialReaderTranscriptScrollTarget = useMemo(\n () => parseInitialReaderTranscriptTarget(urlParams, initialReaderTranscriptTextToHighlight),\n [urlParams, initialReaderTranscriptTextToHighlight],\n );\n const queryType: TranscriptsAPIIndexURLSearchParamsQueryType = (urlParams.get(\"queryType\") ??\n \"keyword-boolean\") as TranscriptsAPIIndexURLSearchParamsQueryType; // semantic or keyword-boolean\n // Bench Opinions were removed from the UI (the result-type tabs are gone), so\n // a lingering `queryResultType=bench-opinion` \u2014 from a stale Activity History\n // link or an old bookmarked URL \u2014 is coerced back to `transcript`. Without the\n // tabs there's no way to leave that state, so the bench-opinion render path is\n // no longer reachable from the UI.\n const rawQueryResultType = urlParams.get(\"queryResultType\") ?? \"transcript\";\n const queryResultType: QueryResultType = (\n rawQueryResultType === \"bench-opinion\" ? \"transcript\" : rawQueryResultType\n ) as QueryResultType;\n const pendingQuery: string | null = urlParams.get(\"pendingQuery\"); // Query that needs correction\n const queryText: string = urlParams.get(\"queryText\") ?? pendingQuery ?? \"\"; // Use queryText if available, otherwise pendingQuery\n const hasExplicitSearchQueryParam = urlParams.has(\"queryText\") || urlParams.has(\"pendingQuery\");\n const rawJudgeIds: string | null = urlParams.get(\"judgeIds\");\n const judgeIds: string[] = rawJudgeIds !== null ? rawJudgeIds.split(\",\") : [];\n const additionalQuery: string | null = urlParams.get(\"additionalQuery\"); // \"search within\" advanced filter\n const hearingDateFrom: string | null = urlParams.get(\"hearingDateFrom\");\n const hearingDateTo: string | null = urlParams.get(\"hearingDateTo\");\n const caseNumber: string | null = urlParams.get(\"caseNumber\");\n const caseName: string | null = urlParams.get(\"caseName\");\n const motionType: string | null = urlParams.get(\"motionType\");\n const sortField: TranscriptsAPIIndexURLSearchParamsSortFields | null = urlParams.get(\n \"sortField\",\n ) as TranscriptsAPIIndexURLSearchParamsSortFields;\n const sortDirection: TranscriptsAPIIndexURLSearchParamsSortDirections | null = urlParams.get(\n \"sortDirection\",\n ) as TranscriptsAPIIndexURLSearchParamsSortDirections;\n const queryResultsPage: string = urlParams.get(\"page\") ?? \"1\";\n const originalQueryParam: string | null = urlParams.get(\"originalQuery\");\n const creditSearchExecutionId: string | null = urlParams.get(\"creditSearchExecutionId\");\n const disableAutoCorrections: boolean = urlParams.get(\"disableAutoCorrections\") === \"true\";\n const hasExplicitSearchFilterParam = [\n \"judgeIds\",\n \"additionalQuery\",\n \"hearingDateFrom\",\n \"hearingDateTo\",\n \"caseNumber\",\n \"caseName\",\n \"motionType\",\n ].some((key) => urlParams.get(key)?.trim());\n const hasUserExecutedTranscriptSearch = hasExplicitSearchQueryParam || hasExplicitSearchFilterParam;\n const creditSearchAdmissionNeeded =\n isCreditBillingLive() &&\n queryResultType === \"transcript\" &&\n hasUserExecutedTranscriptSearch &&\n !creditSearchExecutionId;\n const creditSearchAdmissionKey = creditSearchAdmissionNeeded ? searchParams.toString() : null;\n const creditSearchAdmissionAttemptRef = useRef(null);\n const currentCreditSearchAdmissionKeyRef = useRef(creditSearchAdmissionKey);\n currentCreditSearchAdmissionKeyRef.current = creditSearchAdmissionKey;\n\n useEffect(() => {\n if (!creditSearchAdmissionKey || creditSearchAdmissionAttemptRef.current === creditSearchAdmissionKey) return;\n\n // Defer opening the prompt so React Strict Mode can cancel its first effect pass\n // without resolving a prompt that the second pass still displays.\n const timeoutId = window.setTimeout(() => {\n creditSearchAdmissionAttemptRef.current = creditSearchAdmissionKey;\n const admitSearch = async () => {\n const matterCode = await clientMatter?.ensureMatter();\n if (!matterCode || currentCreditSearchAdmissionKeyRef.current !== creditSearchAdmissionKey) return;\n\n const nextSearchParams = new URLSearchParams(searchParams);\n nextSearchParams.set(\"creditSearchExecutionId\", crypto.randomUUID());\n setSearchParams(nextSearchParams, { replace: true });\n };\n\n void admitSearch().catch(() => undefined);\n }, 0);\n\n return () => window.clearTimeout(timeoutId);\n }, [clientMatter, creditSearchAdmissionKey, searchParams, setSearchParams]);\n\n // Query correction state - must be declared before React Query hooks\n const [isCorrectingQuery, setIsCorrectingQuery] = useState(false);\n\n const quickCorrectionsEnabled = isGenerativeAIAvailable();\n\n // Track the previous query to distinguish new queries from filter changes\n const previousQueryTextRef = useRef(\"\");\n\n /*\n * returned results from the main search, contains metadata and excerpts\n * related to the search but no content. Don't fetch if:\n * - we have a pendingQuery that needs correction first, OR\n * - the user landed via a deep-link with NO active search query\n * (`initialReaderTranscriptId` or `\u2026TextToHighlight` set AND no\n * queryText/pendingQuery in the URL) \u2014 there's nothing to render\n * in the AppArea, so the API call would be wasted.\n *\n * DO fetch when the URL has BOTH `initialReaderTranscriptId` AND a\n * search query \u2014 that's the natural \"user clicked a result then\n * refreshed\" flow, and skipping the fetch makes the results disappear\n * after refresh.\n */\n const shouldFetchResults =\n !pendingQuery &&\n !creditSearchAdmissionNeeded &&\n (hasUserExecutedTranscriptSearch ||\n (!isCreditBillingLive() && !initialReaderTranscriptId && !initialReaderTranscriptTextToHighlight));\n const transcriptSearchResults = useQueryTranscriptsAPIIndex(aggregateSearchParams(), shouldFetchResults);\n const billedSearchMatterCode = transcriptSearchResults.data?.client_matter_code || null;\n const startNewSearch = () => {\n setLockedSearchMatterDialogOpen(false);\n openCreditMatterLaunchTab(\"search\");\n };\n const benchOpinionSearchResults = useQueryBenchOpinionsAPIIndex(\n aggregateSearchParamsForBenchOpinion(),\n shouldFetchResults,\n );\n\n const [contentHighlights, setContentHighlights] = useState(\n initialReaderTranscriptTextToHighlight || initialReaderTranscriptScrollTarget\n ? [initialReaderTranscriptTextToHighlight ?? \"\"]\n : [],\n );\n /*\n * Parallel scroll-target array for `contentHighlights`. Each entry\n * carries the structured anchor (`anchor_id`, page, line) for the\n * matching snippet so the wrapper's `selectedContentScrollTarget`\n * memo can resolve a real target on result-card click. Without this,\n * the structured `TranscriptBody` render path (used for enriched\n * transcripts like Pearl Resources / 564) had no scroll target \u2014\n * `decorateContentWithHighlights`'s HTML `biq-scrollable-highlight`\n * span ids only exist in the legacy HTML-blob render. Indices stay\n * aligned with `contentHighlights` so `selectedHighlightIndexForMainSearch`\n * indexes both consistently.\n */\n const [contentScrollTargets, setContentScrollTargets] = useState(\n initialReaderTranscriptScrollTarget ? [initialReaderTranscriptScrollTarget] : [],\n );\n\n // The reader keeps track of its open/closed state, its current tab, and whether the user\n // has manually scrolled, but sometimes we need to force-update it. We do that with a useEffect\n // in the reader and a counter that increases.\n const [readerOpenOverrideCounter, setReaderOpenOverrideCounter] = useState(0);\n const [tabOverrideCounter, setTabOverrideCounter] = useState(0);\n const [manualScrollOverrideCounter, setManualScrollOverrideCounter] = useState(0);\n\n const [readerTranscriptId, setReaderTranscriptId] = useState(initialReaderTranscriptId);\n const updateReaderTranscriptId = (newTranscriptId: number | null): void => {\n setReaderTranscriptId(newTranscriptId);\n setReaderOpenOverrideCounter((prev) => prev + 1);\n };\n\n // main Search Bar state\n const [queryTextInput, _setQueryTextInput] = useState(queryText);\n // Sort state\n const [sortFieldInput, setSortFieldInput] = useState(sortField); // relevance or date\n const [sortDirectionInput, setSortDirectionInput] = useState(\n sortDirection,\n ); // descending or ascending by time, used for sort by date\n\n const displayedSearchResults =\n queryResultType === \"bench-opinion\" ? benchOpinionSearchResults : transcriptSearchResults;\n\n // which highlight is currently selected\n const [selectedHighlightIndexForMainSearch, setSelectedHighlightIndexForMainSearch] = useState(0);\n\n // Applied filters validation state\n const [isFiltersValid, setIsFiltersValid] = useState(true);\n\n const scrollableContentRef = useRef(null); // used to reset scroll position on pagination change\n\n // results found - memoized objects\n const transcriptSearchResultsFound = useMemo((): { totalCount?: number; totalPages?: number } => {\n return {\n totalCount: transcriptSearchResults.data?.total_count,\n totalPages: transcriptSearchResults.data?.total_pages,\n };\n }, [transcriptSearchResults.data]);\n\n const benchOpinionsSearchResultsFound = useMemo((): { totalCount?: number; totalPages?: number } => {\n return {\n totalCount: benchOpinionSearchResults.data?.total_count,\n totalPages: benchOpinionSearchResults.data?.total_pages,\n };\n }, [benchOpinionSearchResults.data]);\n\n const searchResultsFound = useMemo((): { totalCount?: number; totalPages?: number } => {\n return queryResultType === \"bench-opinion\" ? benchOpinionsSearchResultsFound : transcriptSearchResultsFound;\n }, [queryResultType, transcriptSearchResultsFound, benchOpinionsSearchResultsFound]);\n\n // close the transcript reader upon a new search, this is needed in ui v2 because the top search bar uses query params to control state\n useEffect(() => {\n if (!areUrlParamsTheSame(prevUrlParamsRef.current, urlParams, [\"page\", \"queryResultType\"])) {\n updateReaderTranscriptId(initialReaderTranscriptId);\n }\n prevUrlParamsRef.current = new URLSearchParams(urlParams.toString());\n }, [urlParams, initialReaderTranscriptId]);\n\n // Handle query corrections when pendingQuery is present\n useEffect(() => {\n if (creditSearchAdmissionNeeded) return;\n\n const autoCorrectionsAllowed = quickCorrectionsEnabled && !disableAutoCorrections;\n\n const { shouldRun, nextKey } = computeAutoCorrectionExecution({\n lastKey: lastAutoCorrectionRequestKeyRef.current,\n pendingQuery,\n queryType,\n autoCorrectionsAllowed,\n });\n\n lastAutoCorrectionRequestKeyRef.current = nextKey;\n\n if (!shouldRun) {\n return;\n }\n\n if (pendingQuery == null) {\n return;\n }\n\n const pendingQueryValue = pendingQuery;\n\n const shouldCorrectQuery = quickCorrectionsEnabled && queryType === \"keyword-boolean\" && !disableAutoCorrections;\n\n // Log initial pending query event for tracking\n recordUserEvent({\n event_name: \"search_transcripts_pending\",\n event_properties: {\n query: pendingQueryValue,\n query_type: queryType,\n judge_ids_filter: rawJudgeIds || undefined,\n search_within_search_query: additionalQuery || undefined,\n hearing_date_from: hearingDateFrom || undefined,\n hearing_date_to: hearingDateTo || undefined,\n case_number: caseNumber || undefined,\n case_name: caseName || undefined,\n motion_type: motionType || undefined,\n supported_boolean_included_in_query: matchesSupportedBooleanTerms(pendingQueryValue),\n unsupported_boolean_included_in_query: matchesUnsupportedBooleanTerms(pendingQueryValue),\n },\n });\n\n if (shouldCorrectQuery && !isCorrectingQuery) {\n setIsCorrectingQuery(true);\n\n // Use the V2 API for corrections\n queryAutoCorrections\n .correctQuery(pendingQueryValue)\n .then((result: { corrected_query?: string } | null) => {\n setIsCorrectingQuery(false);\n if (result && result.corrected_query && result.corrected_query !== pendingQueryValue) {\n // Correction was applied - update URL with corrected query\n const newParams = new URLSearchParams(searchParams);\n newParams.delete(\"pendingQuery\");\n newParams.set(\"queryText\", result.corrected_query);\n newParams.set(\"originalQuery\", pendingQueryValue);\n setSearchParams(newParams, { replace: true });\n\n // Do not log event here; the general effect will log once after URL is updated\n } else {\n // No correction needed - convert to queryText\n const newParams = new URLSearchParams(searchParams);\n newParams.delete(\"pendingQuery\");\n newParams.set(\"queryText\", pendingQueryValue);\n setSearchParams(newParams, { replace: true });\n }\n })\n .catch((error: unknown) => {\n console.warn(\"Query correction failed:\", error);\n setIsCorrectingQuery(false);\n\n // On error, fall back to using the pending query as-is\n const newParams = new URLSearchParams(searchParams);\n newParams.delete(\"pendingQuery\");\n newParams.set(\"queryText\", pendingQueryValue);\n setSearchParams(newParams, { replace: true });\n });\n } else if (!shouldCorrectQuery) {\n // If we have a pendingQuery but shouldn't correct it, just convert it to queryText\n const newParams = new URLSearchParams(searchParams);\n newParams.delete(\"pendingQuery\");\n newParams.set(\"queryText\", pendingQueryValue);\n setSearchParams(newParams, { replace: true });\n\n // Do not log event here; the general effect will log once after URL is updated\n }\n }, [\n pendingQuery,\n queryType,\n disableAutoCorrections,\n quickCorrectionsEnabled,\n additionalQuery,\n creditSearchAdmissionNeeded,\n ]);\n\n // Loading states: isLoadingResults tracks any search loading, isLoadingNewQuery specifically tracks query text changes (not filters)\n const isLoadingResults =\n isCorrectingQuery ||\n (queryResultType === \"transcript\" && shouldFetchResults && !transcriptSearchResults.isFetched) ||\n (queryResultType === \"bench-opinion\" && !benchOpinionSearchResults.isFetched);\n\n const currentQuery = queryText || \"\";\n const hasQueryChanged = previousQueryTextRef.current !== currentQuery;\n const isLoadingNewQuery = (pendingQuery !== null || hasQueryChanged) && isLoadingResults;\n\n // Track when a query completes loading so we can detect the next query change\n useEffect(() => {\n if (!isLoadingResults) {\n previousQueryTextRef.current = currentQuery;\n }\n }, [isLoadingResults, currentQuery]);\n\n // Log search event when page loads with queryText (from TopSearchBar or direct URL)\n // This useEffect handles cases where corrections were already applied (e.g., from TopSearchBar)\n const hasLoggedSearchRef = useRef(null);\n useEffect(() => {\n if (creditSearchAdmissionNeeded) return;\n\n const hasNonEmptyPendingQuery = pendingQuery !== null && pendingQuery.trim() !== \"\";\n\n // Non-empty pendingQuery gets logged after corrections convert it to queryText.\n if (hasNonEmptyPendingQuery) {\n return;\n }\n\n // Avoid logging a plain /transcripts page load as an empty search.\n if (!hasExplicitSearchQueryParam && queryText.trim() === \"\") {\n return;\n }\n\n // Skip if we've already logged this exact search\n const searchKey = `${queryText}|${originalQueryParam || \"\"}|${rawJudgeIds || \"\"}|${additionalQuery || \"\"}|${hearingDateFrom || \"\"}|${hearingDateTo || \"\"}|${caseNumber || \"\"}|${caseName || \"\"}|${motionType || \"\"}`;\n if (hasLoggedSearchRef.current === searchKey) {\n return;\n }\n\n // Mark this search as logged\n hasLoggedSearchRef.current = searchKey;\n\n // Log the search event\n recordUserEvent({\n event_name: \"search_transcripts\",\n event_properties: {\n query: queryText,\n original_query: originalQueryParam || undefined,\n corrected_query: originalQueryParam ? queryText : undefined,\n query_type: queryType,\n judge_ids_filter: rawJudgeIds || undefined,\n search_within_search_query: additionalQuery || undefined,\n hearing_date_from: hearingDateFrom || undefined,\n hearing_date_to: hearingDateTo || undefined,\n case_number: caseNumber || undefined,\n case_name: caseName || undefined,\n motion_type: motionType || undefined,\n credit_search_execution_id: creditSearchExecutionId || undefined,\n supported_boolean_included_in_query: matchesSupportedBooleanTerms(queryText),\n unsupported_boolean_included_in_query: matchesUnsupportedBooleanTerms(queryText),\n },\n });\n }, [\n queryText,\n hasExplicitSearchQueryParam,\n originalQueryParam,\n queryType,\n rawJudgeIds,\n additionalQuery,\n hearingDateFrom,\n hearingDateTo,\n caseNumber,\n caseName,\n motionType,\n creditSearchExecutionId,\n pendingQuery,\n creditSearchAdmissionNeeded,\n ]);\n\n // detect invalid/unsupported operators in search query\n const unsupportedBooleanTerms: string[] = useMemo(() => {\n if (!queryTextInput || queryType !== \"keyword-boolean\") {\n return [];\n }\n const substrings = new Set();\n const regexPatterns: RegExp[] = [/\\/p/g, /\\+p/g, /\\/s/g, /\\+s/g, /#/g];\n regexPatterns.forEach((pattern) => {\n let match;\n while ((match = pattern.exec(queryTextInput)) !== null) {\n substrings.add(match[0]);\n }\n });\n return Array.from(substrings);\n }, [queryTextInput, queryType]);\n\n function aggregateSearchParams(): TranscriptsAPIIndexURLSearchParams {\n return {\n queryType: queryType as TranscriptsAPIIndexURLSearchParamsQueryType,\n queryText,\n judgeIds,\n additionalQuery,\n hearingDateFrom,\n hearingDateTo,\n caseNumber,\n caseName,\n motionType,\n sortField,\n sortDirection,\n page: queryResultType === \"transcript\" ? queryResultsPage : \"1\",\n creditSearchExecutionId,\n };\n }\n\n function aggregateSearchParamsForBenchOpinion(): BenchOpinionsAPIIndexURLSearchParams {\n return {\n queryText,\n judgeIds,\n additionalQuery,\n hearingDateFrom,\n hearingDateTo,\n caseNumber,\n caseName,\n motionType,\n sortField,\n sortDirection,\n page: queryResultType === \"bench-opinion\" ? queryResultsPage : \"1\",\n };\n }\n\n const handleSortByChange = (value: string) => {\n const sortByValue = value;\n let sortField: TranscriptsAPIIndexURLSearchParamsSortFields | undefined = undefined;\n let sortDirection: TranscriptsAPIIndexURLSearchParamsSortDirections | undefined = undefined;\n\n switch (sortByValue) {\n case \"newest-to-oldest\":\n sortField = \"date_of_hearing\";\n sortDirection = \"desc\";\n break;\n case \"oldest-to-newest\":\n sortField = \"date_of_hearing\";\n sortDirection = \"asc\";\n break;\n case \"relevance\":\n sortField = \"relevance\";\n break;\n default:\n sortField = \"relevance\";\n break;\n }\n\n updateURLSearchParams({\n paramsToUpdate: {\n sortDirection: sortDirection,\n sortField: sortField,\n page: \"1\",\n },\n });\n setSortFieldInput(sortField);\n setSortDirectionInput(sortDirection ?? null);\n };\n\n /*\n Gathers input field values for main search filters and updates URL params to match them, triggers both transcript and bench opinion main search via query key update\n */\n const updateURLSearchParams = async ({ paramsToUpdate, resultType }: ParamsToUpdate) => {\n // Check if this is only a pagination change\n const isOnlyPaginationChange = Object.keys(paramsToUpdate).length === 1 && \"page\" in paramsToUpdate;\n\n // the search bar is a separate component with its own input states\n // use the URL params as a source of truth\n const newSearchParams = new URLSearchParams(urlParams.toString());\n\n for (const [key, value] of Object.entries(paramsToUpdate)) {\n if (value !== undefined && value !== null) {\n newSearchParams.set(key, value.toString());\n } else {\n // Remove parameter when value is undefined or null\n newSearchParams.delete(key);\n }\n }\n\n newSearchParams.set(\"queryResultType\", resultType ?? queryResultType ?? \"transcript\");\n\n const newQueryResultsType = newSearchParams.get(\"queryResultType\");\n const newQueryType = (newSearchParams.get(\"queryType\") ??\n \"keyword-boolean\") as TranscriptsAPIIndexURLSearchParamsQueryType;\n const newQueryText = newSearchParams.get(\"queryText\") ?? \"\";\n const newHearingDateFrom = newSearchParams.get(\"hearingDateFrom\");\n const newHearingDateTo = newSearchParams.get(\"hearingDateTo\");\n const newCaseNumber = newSearchParams.get(\"caseNumber\");\n const newCaseName = newSearchParams.get(\"caseName\");\n const newMotionType = newSearchParams.get(\"motionType\");\n const newSortField = newSearchParams.get(\"sortField\");\n const newSortDirection = newSearchParams.get(\"sortDirection\");\n const newJudgeIds = newSearchParams.get(\"judgeIds\");\n const newPage = newSearchParams.get(\"page\") ?? \"1\";\n if (isCreditBillingLive() && newQueryResultsType === \"transcript\") {\n const matterCode = await clientMatter?.ensureMatter();\n if (!matterCode) return;\n // Pagination belongs to the current search execution. Keeping its ID\n // stable lets the server charge each page once, including page revisits.\n newSearchParams.set(\n \"creditSearchExecutionId\",\n creditSearchExecutionIdForUpdate(newSearchParams.get(\"creditSearchExecutionId\"), isOnlyPaginationChange),\n );\n }\n setSearchParams(newSearchParams, { replace: !isCreditBillingLive() });\n\n // Avoid duplicate logging: the general effect logs transcript searches once after URL updates\n if (newQueryResultsType !== \"transcript\") {\n const newOriginalQuery = newSearchParams.get(\"originalQuery\");\n recordUserEvent({\n event_name: \"search_bench_opinions\",\n event_properties: {\n query: newQueryText,\n original_query: newOriginalQuery || undefined,\n corrected_query: newOriginalQuery ? newQueryText : undefined,\n query_type: newQueryType,\n hearing_date_from: newHearingDateFrom || undefined,\n hearing_date_to: newHearingDateTo || undefined,\n case_number: newCaseNumber || undefined,\n case_name: newCaseName || undefined,\n motion_type: newMotionType || undefined,\n sort_field: (newSortField as TranscriptsAPIIndexURLSearchParamsSortFields) || undefined,\n sort_direction: (newSortDirection as TranscriptsAPIIndexURLSearchParamsSortDirections) || undefined,\n judge_ids_filter: newJudgeIds && newJudgeIds.length > 0 ? newJudgeIds.toString() : undefined,\n page: parseInt(newPage) || undefined,\n supported_boolean_included_in_query: matchesSupportedBooleanTerms(newQueryText),\n unsupported_boolean_included_in_query: matchesUnsupportedBooleanTerms(newQueryText),\n },\n });\n }\n\n // Only close the reader and drawers if this is not just a pagination change\n if (!isOnlyPaginationChange) {\n // the closing logic is handled by another useEffect hook\n updateReaderTranscriptId(null);\n }\n };\n\n // Applied filters handlers\n const handleFilterChange = (updatedValues?: {\n caseNumber?: string | undefined;\n hearingDateFrom?: string | undefined;\n hearingDateTo?: string | undefined;\n judges?: any[];\n }) => {\n // Only trigger search if filters are valid\n if (isFiltersValid) {\n // Use fresh values from updatedValues if available, otherwise fall back to context\n const judgeIdsString = updatedValues?.judges\n ? updatedValues.judges.map((judge) => judge.name).join(\",\")\n : getSelectedJudgeNamesString();\n\n const paramsToUpdate: any = {\n page: \"1\",\n // Use fresh values when available, otherwise use context values\n judgeIds: judgeIdsString.length > 0 ? judgeIdsString : undefined,\n additionalQuery: additionalQueryInput || undefined,\n hearingDateFrom:\n updatedValues && \"hearingDateFrom\" in updatedValues\n ? updatedValues.hearingDateFrom\n : hearingDateFromInput || undefined,\n hearingDateTo:\n updatedValues && \"hearingDateTo\" in updatedValues\n ? updatedValues.hearingDateTo\n : hearingDateToInput || undefined,\n caseNumber:\n updatedValues && \"caseNumber\" in updatedValues ? updatedValues.caseNumber : caseNumberInput || undefined,\n caseName: caseNameInput || undefined,\n motionType: motionTypeInput || undefined,\n };\n\n updateURLSearchParams({ paramsToUpdate });\n } else {\n }\n };\n\n const handleFilterValidationChange = (isValid: boolean) => {\n setIsFiltersValid(isValid);\n };\n\n // AutoCorrections handlers\n const handleSearchWithOriginal = () => {\n if (originalQueryParam) {\n // Track the revert event\n recordUserEvent({\n event_name: \"revert_autocorrected_query\",\n event_properties: {\n original_query: originalQueryParam,\n corrected_query: queryText,\n },\n });\n\n updateURLSearchParams({\n paramsToUpdate: {\n queryText: originalQueryParam,\n disableAutoCorrections: \"true\" as string | null,\n page: \"1\",\n },\n });\n }\n };\n\n /*\n Handles clicking on a transcript in the search results list.\n transcriptSearchResultPreview does not contain full transcript content, only a preview with metadata needed for rendering it in the list view (this data was fetched during queryTranscripts)\n If the highlighted excerpt number is changed, its also provided\n */\n const handleExcerptClick = async (\n transcriptSearchResultPreview: TranscriptsAPIReadableContentPreview,\n index: number,\n ) => {\n setManualScrollOverrideCounter((prev) => prev + 1);\n if (!transcriptSearchResultPreview) {\n throw new Error(\"Query result excerpt had no metadata attached\");\n }\n const selectedTranscriptId = transcriptSearchResultPreview.id;\n\n // Track result card click events\n if (queryResultType === \"transcript\") {\n recordUserEvent({\n event_name: \"click_transcript_result_card_from_boolean_results\",\n event_properties: { transcript_id: selectedTranscriptId },\n });\n } else if (queryResultType === \"bench-opinion\") {\n recordUserEvent({\n event_name: \"click_bench_opinion_result_card_from_boolean_results\",\n event_properties: { transcript_id: selectedTranscriptId },\n });\n }\n\n setContentHighlights(transcriptSearchResultPreview.content_highlights);\n /*\n * Parallel scroll targets from the same result preview. The structured\n * `` render path (enriched transcripts like Pearl\n * Resources / 564) needs an `anchor_id` to scroll to \u2014 without this\n * the wrapper's `selectedContentScrollTarget` resolves to `null` and\n * `TranscriptReader`'s scroll-to-anchor effect bails. Indices in\n * `highlight_targets` align with `content_highlights` per the\n * backend `TranscriptsAPIReadableContentPreview` schema.\n */\n setContentScrollTargets(transcriptSearchResultPreview.highlight_targets ?? []);\n updateReaderTranscriptId(transcriptSearchResultPreview.id);\n setTabOverrideCounter((prev) => prev + 1);\n setSelectedHighlightIndexForMainSearch(index);\n };\n\n const handleOverviewCitationClick = (\n transcriptSearchResultPreview: TranscriptsAPIReadableContentPreview,\n citationIdx: number,\n ) => {\n const citationEntries = overviewCitationClickEntries(transcriptSearchResultPreview);\n const selectedIndex = preferredOverviewCitationEntryIndex(citationEntries, citationIdx);\n if (selectedIndex === -1) {\n return;\n }\n\n setManualScrollOverrideCounter((prev) => prev + 1);\n updateReaderTranscriptId(transcriptSearchResultPreview.id);\n setTabOverrideCounter((prev) => prev + 1);\n setContentHighlights(citationEntries.map((entry) => entry.text));\n /*\n * Mirror the citation entries' scroll targets so structured-render\n * transcripts can scroll-to-anchor on overview-citation clicks too.\n * Entries without a resolved target (the `.target` is nullable per\n * `overviewCitationClickEntries`) are passed through as null; the\n * wrapper's `selectedContentScrollTarget` already tolerates null.\n */\n setContentScrollTargets(citationEntries.map((entry) => entry.target));\n setSelectedHighlightIndexForMainSearch(selectedIndex);\n };\n\n const renderUnsupportedBooleanTermsWarning = () => {\n if (unsupportedBooleanTerms.length !== 0) {\n return (\n \n You have currently unsupported Boolean connector(s) and/or expander(s) in your query:{\" \"}\n {unsupportedBooleanTerms.join(\", \")} \u2014 Only the following are supported:{\" \"}\n \", &, AND, |, OR, NOT, %, +n, /n, *, !\n \n );\n }\n };\n\n const renderQuerySyntaxErrorAlert = () => {\n if (!displayedSearchResults.isError) {\n return;\n }\n\n const { error } = displayedSearchResults;\n\n let message;\n\n if (error.apiCode === \"monthly_credit_limit_reached\") {\n message = CLERK_ERROR_COPY.monthlyCreditLimit;\n } else if (error.apiCode === \"credit_access_expired\") {\n message = CLERK_ERROR_COPY.creditAccessExpired;\n } else if (queryType === \"keyword-boolean\" && error.code === 400) {\n message = `There is an issue with the request: ${error.message}`;\n }\n\n const fallback =\n \"We couldn't load these search results. Please try again. If the problem persists, contact support@benchiq.com.\";\n\n return {message || fallback};\n };\n\n const renderTranscriptQueryResults = transcriptSearchResults.data?.results?.map(\n (queryResult: TranscriptsAPIReadableContentPreview) => {\n const isSelected = readerTranscriptId === queryResult.id;\n return (\n handleOverviewCitationClick(queryResult, citationIdx)}\n />\n );\n },\n );\n\n const renderBenchOpinionQueryResults = benchOpinionSearchResults.data?.results?.map(\n (queryResult: TranscriptsAPIReadableContentPreview) => {\n const isSelected = readerTranscriptId === queryResult.id;\n return (\n handleOverviewCitationClick(queryResult, citationIdx)}\n />\n );\n },\n );\n\n const renderQueryResults = () => {\n if (queryResultType === \"transcript\") {\n if (transcriptSearchResults.isFetched && transcriptSearchResults.status !== \"success\") {\n return null;\n }\n return renderTranscriptQueryResults;\n } else if (queryResultType === \"bench-opinion\") {\n if (benchOpinionSearchResults.isFetched && benchOpinionSearchResults.status !== \"success\") {\n return null;\n }\n return renderBenchOpinionQueryResults;\n }\n };\n\n const renderPagination = () => {\n if (\n (queryResultType === \"transcript\" && transcriptSearchResults.status !== \"success\") ||\n (queryResultType === \"bench-opinion\" && benchOpinionSearchResults.status !== \"success\")\n ) {\n return;\n }\n return (\n (searchResultsFound.totalCount ?? 0) > 0 && (\n {\n updateURLSearchParams({\n paramsToUpdate: { page: String(page) },\n });\n if (String(page) !== queryResultsPage) {\n scrollableContentRef.current?.scrollTo({ top: 0, left: 0, behavior: \"instant\" });\n }\n }}\n color=\"primary\"\n shape=\"rounded\"\n disabled={displayedSearchResults.isPlaceholderData}\n />\n )\n );\n };\n\n const hasResults = (searchResultsFound.totalCount ?? 0) > 0;\n\n // Create URL-based filter values to display applied filters (not pending ones from context)\n const urlBasedFilterValues = useMemo(() => {\n // Convert judge names from URL back to judge objects\n const urlSelectedJudges = judgesQuery.data?.filter((judge) => judgeIds.includes(judge.name)) ?? [];\n\n return {\n selectedJudges: urlSelectedJudges,\n hearingDateFromInput: hearingDateFrom || undefined,\n hearingDateToInput: hearingDateTo || undefined,\n caseNumberInput: caseNumber || undefined,\n };\n }, [judgesQuery.data, judgeIds, hearingDateFrom, hearingDateTo, caseNumber]);\n\n const renderHeader = () => {\n const hasAnySearch = Boolean(queryText || caseName || motionType);\n // Inline style \u2014 spans use the `style` prop, not sx; kept as raw CSS.\n const sx = { marginRight: \"8px\" };\n const isAutoCorrectionActive =\n quickCorrectionsEnabled &&\n !!originalQueryParam &&\n normalizeQueryForComparison(originalQueryParam) !== normalizeQueryForComparison(queryText) &&\n !!queryText;\n const resultsText = () => {\n // If V2 feature flag is enabled and we have an original query different from current query,\n // render the auto correction display instead of the standard results text\n // Compare normalized queries to be agnostic to quote types and whitespace\n if (isAutoCorrectionActive) {\n return (\n <>\n Showing results for:\n \n {queryText}\n \n {caseName && casename: {caseName}}\n {motionType && motion: {motionType}}\n \n );\n }\n\n // Standard results text\n return (\n <>\n Showing results for:\n {queryText && (\n \n {queryText}\n \n )}\n {caseName && casename: {caseName}}\n {motionType && motion: {motionType}}\n \n );\n };\n\n let selectedValue;\n\n if (sortFieldInput === \"date_of_hearing\" && sortDirectionInput === \"desc\") {\n selectedValue = \"newest-to-oldest\";\n } else if (sortFieldInput === \"date_of_hearing\" && sortDirectionInput === \"asc\") {\n selectedValue = \"oldest-to-newest\";\n } else if (sortFieldInput === \"relevance\") {\n selectedValue = \"relevance\";\n } else {\n selectedValue = \"relevance\";\n }\n\n // \"Transcripts (N)\" count label shown in the sort row (bench opinions are\n // not reachable on this page, so the label is always Transcripts \u2014 see the\n // queryResultType coercion near the top of the component).\n //\n // Hidden while results are loading: the query uses keepPreviousData, so during\n // a filter/sort/page refetch `totalCount` still holds the previous search's\n // count \u2014 showing it next to the loading spinner would briefly be stale.\n const resultCountLabel = isLoadingResults\n ? null\n : formatResultCountLabel(searchResultsFound.totalCount, \"Transcripts\");\n\n return (\n <>\n \n {hasAnySearch && (\n \n )}\n {isAutoCorrectionActive && (\n \n Search instead for{\" \"}\n \n {originalQueryParam}\n \n \n )}\n {/* Placeholder: new filter buttons. included button for visuals. */}\n \n \n {resultCountLabel && (\n \n {resultCountLabel}\n \n )}\n \n handleSortByChange(e.target.value)}\n displayEmpty\n disableUnderline\n autoWidth\n MenuProps={{\n anchorOrigin: { vertical: \"bottom\", horizontal: \"left\" },\n transformOrigin: { vertical: \"top\", horizontal: \"left\" },\n }}\n IconComponent={() => null}\n renderValue={() => }\n sx={{\n \"& .MuiSelect-select\": {\n // without the !important, there's still some padding-right coming from somewhere else.\n padding: \"0px !important\",\n // otherwise there's an unsightly rectangular dark background after clicking the icon button\n \":focus\": { backgroundColor: \"unset\" },\n },\n }}\n >\n Relevance\n Newest to Oldest\n Oldest to Newest\n \n \n {!creditSearchAdmissionNeeded && !isLoadingResults && !hasResults && }\n \n \n );\n };\n\n function renderQueryResultsContainer() {\n /*\n * Hide the AppArea results UI ONLY when the user landed via a pure\n * deep-link (initialReaderTranscriptId set AND no search query in\n * the URL) \u2014 there's nothing to render. When the URL ALSO has a\n * search query (i.e. user was on a results page, clicked into a\n * transcript, then refreshed), the results should still render\n * alongside the reader so a browser-refresh doesn't lose the page's\n * primary content.\n */\n if (initialReaderTranscriptId !== null && !hasExplicitSearchQueryParam) {\n return null;\n }\n\n // For new queries, show full-screen loading\n if (isLoadingNewQuery) {\n return (\n \n \n \n Loading search results...\n \n \n );\n }\n\n // For filter changes or when we already have results, show inline loading within the results container\n return (\n \n {renderHeader()}\n\n \n \n {creditSearchAdmissionNeeded ? null : isLoadingResults ? (\n \n \n \n Loading search results...\n \n \n ) : (\n \n {renderQueryResults()}\n {renderPagination()}\n \n )}\n \n \n \n );\n }\n\n if (isAIDisabled && queryResultType === \"bench-opinion\") {\n return ;\n }\n\n // Deep-link via ?initialReaderTranscriptId=...: a shareable \"Copy Link\" URL\n // carries `readerView=full`, which opens the reader directly in\n // fullscreen-overlay mode. A PURE deep link without a search query (legacy\n // bookmarked/shared links from before the readerView marker existed) also\n // opens fullscreen: renderQueryResultsContainer renders nothing for it, so\n // paneled mode would show a blank AppArea with the reader clipped off-canvas.\n // In-app deep links that DO carry a search query stay paneled, since the\n // full-screen takeover hid the in-page search affordances + felt jarring\n // there (see QA: \"expands the reader into full screen mode. It should not\n // do that.\"). Users can still toggle full screen via the expand button.\n const panel = useReaderPanelState({\n isReaderOpen: readerTranscriptId !== null,\n onClose: () => setReaderTranscriptId(null),\n openRequestKey: readerOpenOverrideCounter,\n defaultMode:\n openReaderInFullScreen || (initialReaderTranscriptId !== null && !hasExplicitSearchQueryParam)\n ? \"expanded\"\n : \"on\",\n });\n\n // A reader opened as a pure deep-link (URL / new tab, no search query behind\n // it) has no results page to return to \u2014 renderQueryResultsContainer renders\n // nothing in that case. So both closing AND collapsing the reader should send\n // the user home rather than leave a blank AppArea behind the dismissed reader.\n const isStandaloneReader = initialReaderTranscriptId !== null && !hasExplicitSearchQueryParam;\n const readerPanel = useMemo(() => {\n if (!isStandaloneReader) return panel;\n const goHome = () => navigate({ pathname: \"/\" });\n return { ...panel, handleClose: goHome, handleToggleExpand: goHome };\n }, [panel, isStandaloneReader, navigate]);\n\n // Title for the reader's TopBar. Reads from the same transcript query cache\n // the reader populates internally, so it resolves for BOTH search-result and\n // URL deep-link opens (search doesn't fetch when initialReaderTranscriptId is\n // set, so a search-preview-derived title would be empty there). Matches every\n // other reader entry point (NotesPage, StarredPage, FolderDetailPage, etc.).\n const readerTitle = useTranscriptDisplayTitle(readerTranscriptId);\n\n return (\n <>\n \n {isCreditBillingLive() && billedSearchMatterCode && (\n \n setLockedSearchMatterDialogOpen(true)}\n trackingContext=\"search\"\n />\n }\n />\n \n )}\n {billedSearchMatterCode && (\n setLockedSearchMatterDialogOpen(false)}\n onStartNewSearch={startNewSearch}\n />\n )}\n {renderUnsupportedBooleanTermsWarning()}\n {renderQuerySyntaxErrorAlert()}\n {renderQueryResultsContainer()}\n {readerTranscriptId !== null && (\n \n )}\n \n );\n};\n\nexport default QueryResults;\n", "import { BenchOpinionsAPIIndexURLSearchParams } from \"../api/queries/benchOpinions.types\";\nimport { TranscriptsAPIIndexURLSearchParams } from \"../api/queries/transcripts.types\";\nimport { UserEventAPIResponse } from \"../api/userEvents\";\nimport { SearchBenchOpinionsUserEvent, SearchTranscriptsUserEvent } from \"../generated_types/userEvents\";\n\ninterface TranscriptCitationPinpoint {\n startPage: number;\n startLine: number;\n endPage: number;\n endLine: number;\n}\n\n/**\n * Recover the structured transcript location from a generated Bluebook\n * citation so existing activity-history events can deep-link to the cited\n * lines without requiring a data migration.\n */\nexport const parseTranscriptCitationPinpoint = (citation: string): TranscriptCitationPinpoint | null => {\n const match = citation.match(/^[^,]*?\\b(\\d+):(\\d+)(?:\\s*[-\u2013\u2014]\\s*(?:(\\d+):)?(\\d+))?\\s*,/u);\n if (!match) return null;\n\n const startPage = Number(match[1]);\n const startLine = Number(match[2]);\n const endPage = match[4] ? Number(match[3] ?? match[1]) : startPage;\n const endLine = match[4] ? Number(match[4]) : startLine;\n if (\n ![startPage, startLine, endPage, endLine].every((value) => Number.isSafeInteger(value) && value > 0) ||\n endPage < startPage ||\n (endPage === startPage && endLine < startLine)\n ) {\n return null;\n }\n\n return { startPage, startLine, endPage, endLine };\n};\n\nconst convertToSearchParams = (\n event: SearchBenchOpinionsUserEvent | SearchTranscriptsUserEvent,\n): TranscriptsAPIIndexURLSearchParams | BenchOpinionsAPIIndexURLSearchParams => {\n const { event_properties } = event;\n\n const searchParams = {\n queryText: event_properties.query,\n queryType: event_properties.query_type,\n page: event_properties.page?.toString(),\n judgeIds:\n !event_properties.judge_ids_filter || event_properties.judge_ids_filter.length === 0\n ? null\n : event_properties.judge_ids_filter.split(\",\"),\n additionalQuery: event_properties.search_within_search_query,\n hearingDateTo: event_properties.hearing_date_to,\n hearingDateFrom: event_properties.hearing_date_from,\n caseNumber: event_properties.case_number,\n caseName: event_properties.case_name,\n motionType: event_properties.motion_type,\n sortField: event_properties.sort_field,\n sortDirection: event_properties.sort_direction,\n originalQuery: event_properties.original_query,\n creditSearchExecutionId:\n \"credit_search_execution_id\" in event_properties ? event_properties.credit_search_execution_id : undefined,\n };\n\n return searchParams;\n};\n\nexport const getContentUrl = (item: UserEventAPIResponse): string => {\n if (item.event_name === \"start_ask_ai_search\") {\n throw new Error(\"Deprecated Ask AI history entries do not have a destination URL\");\n }\n\n const url = new URL(\"/transcripts\", window.location.origin);\n\n if (item.event_name === \"view_transcript\" || item.event_name === \"generate_transcript_citation\") {\n url.searchParams.append(\"initialReaderTranscriptId\", item.event_properties.transcript_id.toString());\n if (item.event_name === \"generate_transcript_citation\") {\n // History is a standalone reader entry point. Preserve that layout and\n // add the pinpoint as a structured target so the reader highlights and\n // scrolls to the cited lines instead of opening at the transcript top.\n url.searchParams.set(\"readerView\", \"full\");\n const pinpoint = parseTranscriptCitationPinpoint(item.event_properties.citation);\n if (pinpoint) {\n url.searchParams.set(\"initialReaderTranscriptTargetPage\", pinpoint.startPage.toString());\n url.searchParams.set(\"initialReaderTranscriptTargetLine\", pinpoint.startLine.toString());\n url.searchParams.set(\"initialReaderTranscriptTargetEndPage\", pinpoint.endPage.toString());\n url.searchParams.set(\"initialReaderTranscriptTargetEndLine\", pinpoint.endLine.toString());\n }\n }\n } else if (item.event_name === \"view_bench_opinion\") {\n url.searchParams.append(\"initialReaderTranscriptId\", item.event_properties.transcript_id.toString());\n url.searchParams.append(\"queryResultType\", \"bench-opinion\");\n } else if (item.event_name === \"search_transcripts\") {\n const searchParams = convertToSearchParams(item);\n url.searchParams.append(\"queryResultType\", \"transcript\");\n Object.entries(searchParams).forEach(([key, value]) => {\n if (value != null) {\n if (key == \"judgeIds\") {\n value = (value as string[]).join(\",\");\n }\n url.searchParams.append(key, value as string);\n }\n });\n } else if (item.event_name === \"search_bench_opinions\") {\n const searchParams = convertToSearchParams(item);\n url.searchParams.append(\"queryResultType\", \"bench-opinion\");\n Object.entries(searchParams).forEach(([key, value]) => {\n if (value != null) {\n if (key == \"judgeIds\") {\n value = (value as string[]).join(\",\");\n }\n url.searchParams.append(key, value as string);\n }\n });\n } else {\n throw new Error(`Unexpected event type: ${(item as UserEventAPIResponse).event_name}`);\n }\n return url.toString();\n};\n", "export type FilterState = {\n displayName: string;\n value: string;\n};\n\nexport const transformQueryToFilters = (queryString: string): FilterState[] => {\n const urlParams = new URLSearchParams(queryString);\n\n const filters = [];\n\n // Extract judgeIds and transform into a display format\n const judgeIds = urlParams.get(\"judgeIds\");\n if (judgeIds) {\n judgeIds.split(\",\").forEach((judgeId) =>\n filters.push({\n displayName: \"Judge\",\n value: judgeId.trim(), // Split and trim judges\n }),\n );\n }\n\n // Extract hearing dates\n const hearingDateFrom = urlParams.get(\"hearingDateFrom\");\n const hearingDateTo = urlParams.get(\"hearingDateTo\");\n if (hearingDateFrom || hearingDateTo) {\n filters.push({\n displayName: \"Hearing date\",\n value: `${hearingDateFrom || \"Earliest\"} - ${hearingDateTo || \"Latest\"}`,\n });\n }\n\n // Extract case number\n const caseNumber = urlParams.get(\"caseNumber\");\n if (caseNumber) {\n filters.push({\n displayName: \"Case number\",\n value: caseNumber,\n });\n }\n\n // Extract case name\n const caseName = urlParams.get(\"caseName\");\n if (caseName) {\n filters.push({\n displayName: \"Case name\",\n value: caseName,\n });\n }\n\n // Extract motion type\n const motionType = urlParams.get(\"motionType\");\n if (motionType) {\n filters.push({\n displayName: \"Motion type\",\n value: motionType,\n });\n }\n\n return filters;\n};\n", "import React, { useMemo } from \"react\";\nimport Tooltip from \"@mui/material/Tooltip\";\nimport { FilterState } from \"./FiltersButtonWithTooltip\"; // Import FilterState type\n\ninterface FilterTooltipProps {\n filterStates: FilterState[]; // Accept filterStates as a prop\n readonly maxTooltipLinesBeforeTruncation?: number;\n readonly defaultTooltipTextRenderer?: (filterName: string, stringValue: string) => string;\n children: React.ReactElement;\n}\n\nconst FilterTooltip: React.FC = ({\n filterStates = [],\n maxTooltipLinesBeforeTruncation = 5,\n defaultTooltipTextRenderer = (filterName: string, stringValue: string) => `${filterName}: ${stringValue}`,\n children,\n}) => {\n // Generate tooltip content based on filterStates\n const trimmedTooltipText = useMemo(() => {\n let out = [];\n for (const filterState of filterStates) {\n if (!filterState.value) continue;\n let line = \"\";\n if (filterState.tooltipTextRenderer) {\n line = filterState.tooltipTextRenderer(filterState.displayName, String(filterState.value));\n } else {\n // default tooltip text renderer\n line = defaultTooltipTextRenderer(filterState.displayName, String(filterState.value));\n }\n if (line.length > 50) {\n line = line.slice(0, 47) + \"...\";\n }\n out.push(line);\n }\n // limit the number of lines in the tooltip to maxTooltipLinesBeforeTruncation\n if (out.length > maxTooltipLinesBeforeTruncation) {\n out = out.slice(0, maxTooltipLinesBeforeTruncation);\n out.push(\"...\");\n }\n return out.join(\"\\n\");\n }, [filterStates, maxTooltipLinesBeforeTruncation]);\n\n return (\n {trimmedTooltipText}
    : null}\n >\n {children}\n \n );\n};\n\nexport default FilterTooltip;\n", "import React, { forwardRef } from \"react\";\nimport { alpha } from \"@mui/material/styles\";\nimport { styled } from \"@/utils/styled\";\nimport Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\nimport FilterTooltip from \"../../atoms/FilterTooltip\";\nimport { UserEventAPIResponse } from \"../../../api/userEvents\";\nimport { FilterState } from \"../../atoms/FiltersButtonWithTooltip\";\n\nconst ActivityItem = styled(Box)`\n display: flex;\n flex-direction: row;\n align-items: center;\n padding: 16px 0;\n\n :last-child {\n border-bottom: none;\n }\n\n :hover {\n background: ${({ theme }) => alpha(theme.palette.primary.main, 0.08)};\n }\n`;\n\nconst ActivityItemInfo = styled(Typography)<{ disabled: boolean }>`\n font-size: 14px;\n font-weight: 300;\n color: ${({ theme, disabled }) => (disabled ? theme.palette.text.disabled : \"inherit\")};\n`;\n\nconst TimeInfo = styled(ActivityItemInfo)`\n flex: 3;\n`;\n\nconst TypeInfo = styled(ActivityItemInfo)`\n flex: 4;\n`;\n\nconst ContentInfo = styled(\"a\")<{ disabled: boolean }>`\n font-family: ${({ theme }) => theme.typography.fontFamily};\n font-size: 14px;\n font-weight: 300;\n text-decoration: none;\n color: ${({ theme, disabled }) => (disabled ? theme.palette.text.disabled : theme.palette.text.primary)};\n cursor: ${(props) => (props.disabled ? \"default\" : \"pointer\")};\n flex: 10;\n\n :hover {\n text-decoration: ${(props) => (props.disabled ? \"none\" : \"underline\")};\n }\n`;\n\ninterface ActivityHistoryItemProps {\n item: UserEventAPIResponse;\n disabled?: boolean;\n onContentClick?: (item: UserEventAPIResponse) => void;\n href: string;\n typeInfo: string;\n content: React.ReactElement;\n filterStates: FilterState[];\n timestamp: string;\n}\n\nconst ActivityHistoryItem = forwardRef(\n ({ item, onContentClick, disabled = false, href, typeInfo, content, filterStates, timestamp }, ref) => {\n return (\n \n {timestamp}\n {typeInfo}\n onContentClick(item)}\n >\n {content}\n \n \n );\n },\n);\n\nActivityHistoryItem.displayName = \"ActivityHistoryItem\";\n\nexport default ActivityHistoryItem;\n", "import React, { useEffect } from \"react\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\nimport { styled } from \"@/utils/styled\";\nimport { getContentUrl } from \"../../utils/activityHistory\";\nimport { Box, CircularProgress, Typography } from \"@mui/material\";\nimport { History } from \"lucide-react\";\nimport { EmptyState, EMPTY_STATE_PAGE_TOP_OFFSET } from \"../molecules/EmptyState\";\nimport { transformQueryToFilters, FilterState } from \"../../utils/transformQueryToFilters\";\nimport { useGlobalAlert } from \"../../contexts/GlobalAlertContext\";\nimport { fetchUserEvents, recordUserEvent, UserEventAPIResponse } from \"../../api/userEvents\";\nimport ScrollableContent from \"../atoms/ScrollableContent\";\nimport { useContinuousScroll } from \"../../utils/useContinuousScrollHook\";\nimport ActivityHistoryItem from \"../molecules/activity_history/ActivityHistoryItem\";\nimport { PAGE_CONTENT_MAX_WIDTH } from \"../../utils/constants\";\n\nconst PageContainer = styled(Box)`\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n`;\n\nconst ActivityList = styled(Box)``;\n\nconst ActivityGroupContainer = styled(Box)`\n margin-bottom: 32px;\n`;\n\nconst PageContents = styled(Box)`\n width: 100%;\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n padding: 0 max(24px, calc((100% - ${PAGE_CONTENT_MAX_WIDTH}px) / 2 + 24px));\n box-sizing: border-box;\n`;\n\nconst ResultsContainer = styled(ScrollableContent)`\n flex: 1;\n min-height: 0;\n &::after {\n position: fixed;\n }\n`;\n\nconst LoadingIndicator = styled(Box)`\n display: flex;\n justify-content: center;\n padding-top: 20px;\n padding-bottom: 100px;\n`;\n\nconst useInfiniteActivityHistory = (sortDirection: SortDirection) => {\n return useInfiniteQuery({\n queryKey: [\"infiniteActivityHistory\", sortDirection],\n queryFn: ({ pageParam = 1 }) => fetchUserEvents({ pageParam, sortDirection }),\n initialPageParam: 1,\n getNextPageParam: (lastPage) => lastPage.next_page,\n staleTime: 5 * 60 * 1000, // 5 minutes\n // Activity is append-only from the user's perspective. Always refresh\n // when the tab mounts so an event recorded elsewhere in the app (such as\n // generating a transcript citation) is visible immediately on return.\n refetchOnMount: \"always\",\n });\n};\n\ntype GroupingKeyType = Date;\nexport type SortDirection = \"asc\" | \"desc\";\nconst LEGACY_ASK_AI_UNAVAILABLE_COPY = \"Legacy Ask AI result no longer available\";\n\nconst getStatusDisplayName = (status: string): string => {\n const statusMap: Record = {\n deprecated: \"Deprecated\",\n done: \"Complete\",\n running: \"In-Progress\",\n done_with_failures: \"Complete\",\n failed: \"Error\",\n };\n\n return statusMap[status] || status;\n};\n\nconst getEventTypeDisplayName = (eventName: string): string => {\n const eventTypeMap: Record = {\n search_bench_opinions: \"Searched\",\n search_transcripts: \"Searched\",\n start_ask_ai_search: \"Ask AI (deprecated)\",\n view_bench_opinion: \"Read\",\n view_transcript: \"Read\",\n generate_transcript_citation: \"Generated citation\",\n };\n\n return eventTypeMap[eventName] ?? \"Unknown\";\n};\n\ninterface ActivityHistoryPageProps {\n sortDirection?: SortDirection;\n}\n\nconst ActivityHistoryPage: React.FC = ({ sortDirection = \"desc\" }) => {\n const { data, fetchNextPage, hasNextPage, isError, isLoading, isFetchingNextPage } =\n useInfiniteActivityHistory(sortDirection);\n const lastElementRef = useContinuousScroll(fetchNextPage, hasNextPage);\n const { setAlertWithOptions } = useGlobalAlert();\n\n useEffect(() => {\n if (isError) {\n setAlertWithOptions(\n \"An error occurred while fetching activity history. If this error persists, please contact support@benchiq.com.\",\n \"error\",\n );\n } else {\n setAlertWithOptions(null);\n }\n return () => setAlertWithOptions(null);\n }, [isError]);\n\n if (isError) return null;\n\n if (isLoading)\n return (\n \n \n \n );\n\n const emptyState = () => {\n if (data?.pages[0].data.length === 0) {\n return (\n }\n title=\"Your trail starts here\"\n description=\"Searches, views, and downloads collect here as you work, creating a trail you can retrace anytime.\"\n />\n );\n }\n };\n\n const handleContentInfoClick = (item: UserEventAPIResponse): void => {\n recordUserEvent({\n event_name: \"click_activity_history_link\",\n event_properties: {\n user_event_id: item.id,\n user_event_name: item.event_name,\n },\n });\n\n // Track result card click events for transcript/bench opinion views\n if (item.event_name === \"view_transcript\" || item.event_name === \"view_bench_opinion\") {\n recordUserEvent({\n event_name: \"click_read_transcript_list_item_from_activity_history\",\n event_properties: {\n transcript_id: item.event_properties.transcript_id,\n },\n });\n }\n };\n\n const groupingKeysAreEq = (a: GroupingKeyType, b: GroupingKeyType): boolean => {\n return a.toDateString() === b.toDateString();\n };\n\n const groupingFunction = (item: UserEventAPIResponse): GroupingKeyType => {\n return item.created_at;\n };\n\n const formatGroupingKey = (key: GroupingKeyType): string => {\n return key.toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n };\n\n const formatTypeInfo = (item: UserEventAPIResponse): string => {\n return getEventTypeDisplayName(item.event_name);\n };\n\n const formatContent = (item: UserEventAPIResponse): string => {\n if (item.event_name === \"search_bench_opinions\" || item.event_name === \"search_transcripts\") {\n const displayQuery = item.event_properties.original_query || item.event_properties.query;\n return displayQuery || \"FILTERS ONLY SEARCH\";\n } else if (item.event_name === \"view_bench_opinion\" || item.event_name === \"view_transcript\") {\n return item.additional_properties.citation;\n } else if (item.event_name === \"generate_transcript_citation\") {\n return item.event_properties.citation;\n } else if (item.event_name === \"start_ask_ai_search\") {\n return item.event_properties.question || \"Unknown question\";\n }\n throw new Error(`Unexpected event type: ${(item as UserEventAPIResponse).event_name}`);\n };\n\n const formatLegacyAskAiContent = (item: UserEventAPIResponse): React.ReactElement => (\n \n {formatContent(item)}\n \n {LEGACY_ASK_AI_UNAVAILABLE_COPY}\n \n \n );\n\n const formatFilterStates = (item: UserEventAPIResponse): FilterState[] => {\n if (item.event_name === \"start_ask_ai_search\") {\n const judgeIds = item.event_properties.query?.judge_ids ?? [];\n\n return [\n {\n displayName: `Judge${judgeIds.length === 1 ? \"\" : \"s\"}`,\n value: judgeIds.length > 0 ? judgeIds.join(\", \") : \"Unknown\",\n },\n {\n displayName: \"Status\",\n value: getStatusDisplayName(String(item.additional_properties?.status ?? \"deprecated\")),\n },\n ];\n }\n\n return transformQueryToFilters(getContentUrl(item));\n };\n\n const formatTimestamp = (date: Date): string => {\n return date.toLocaleTimeString(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n });\n };\n\n const activityHistoryGrouping = (\n group: UserEventAPIResponse[],\n groupIndex: number,\n groupArr: UserEventAPIResponse[][],\n groupingKey: GroupingKeyType,\n ) => {\n return (\n \n \n {formatGroupingKey(groupingKey)}\n \n {group.map((item, itemIndex, arr) => {\n if (item.event_name === \"start_ask_ai_search\") {\n return (\n \n );\n }\n\n const url = getContentUrl(item);\n return (\n \n {formatContent(item)}\n \n }\n filterStates={formatFilterStates(item)}\n timestamp={formatTimestamp(item.created_at)}\n ref={groupIndex === groupArr.length - 1 && itemIndex === arr.length - 1 ? lastElementRef : undefined}\n />\n );\n })}\n \n );\n };\n\n const activityHistoryData = () => {\n let prevGroupingKey: GroupingKeyType | null = null;\n return (\n \n {data?.pages\n .reduce((acc, page) => acc.concat(page.data), [])\n .reduce((acc, item) => {\n const groupingKey = groupingFunction(item);\n if (prevGroupingKey === null || !groupingKeysAreEq(prevGroupingKey, groupingKey)) {\n acc.push([]);\n }\n acc[acc.length - 1].push(item);\n prevGroupingKey = groupingKey;\n return acc;\n }, [])\n .map((group, groupIndex, groupArr) =>\n activityHistoryGrouping(group, groupIndex, groupArr, groupingFunction(group[0])),\n )}\n \n );\n };\n\n return (\n \n \n \n {emptyState()}\n {activityHistoryData()}\n {/* TODO: https://app.asana.com/0/1205268994786591/1209785935056813 */}\n {(isFetchingNextPage || hasNextPage) && (\n \n \n \n )}\n \n \n \n );\n};\n\nexport default ActivityHistoryPage;\n", "const getCsrfToken = () => {\n var metas = document.getElementsByTagName(\"meta\");\n\n for (let i = 0; i < metas.length; i++) {\n if (metas[i].getAttribute(\"name\") == \"csrf-token\") {\n return metas[i].getAttribute(\"content\");\n }\n }\n\n return null;\n};\n\n// TODO: figure out a way to universally send requests including the CSRF token\nconst handleSignOut = () => {\n const url = \"/api/sign_out\";\n const wasSignedIn = window.userSignedIn;\n const options = {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-CSRF-Token\": getCsrfToken() ?? \"\",\n },\n };\n\n window.userSignedIn = false;\n fetch(url, options)\n .then(() => {\n window.location.href = \"/users/sign_in\";\n })\n .catch((error) => {\n window.userSignedIn = wasSignedIn;\n console.log(error); // TODO: handle the error here\n });\n};\n\nexport default handleSignOut;\n", "import React, { useState, useEffect, KeyboardEvent } from \"react\";\nimport { Typography, Stack, Dialog } from \"@mui/material\";\nimport { AlertTriangle } from \"lucide-react\";\nimport { BenchAlert } from \"@/components/atoms/BenchAlert\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport MatterCodeAutocomplete, { getMatterCodeOptions } from \"@/components/molecules/MatterCodeAutocomplete\";\nimport { MODAL_WIDTH } from \"../../utils/constants\";\nimport { useTimeEntry } from \"../../contexts/TimeEntryContext\";\nimport handleSignOut from \"../../utils/handleSignOut\";\nimport { useSessionExpiredModal } from \"../../contexts/GlobalAlertContext\";\nimport { featureEnabled } from \"../../utils/featureFlags\";\nimport { recordUserEvent } from \"../../api/userEvents\";\n\nconst TimeTrackingModal: React.FC = () => {\n const { currentTimeEntry, isEndingTimeEntry, createTimeEntry } = useTimeEntry()!;\n const { sessionExpiredOpen } = useSessionExpiredModal();\n\n const [matterCode, setMatterCode] = useState(currentTimeEntry?.matter_code || \"\");\n const [showModal, setShowModal] = useState(\n !currentTimeEntry || Boolean(currentTimeEntry?.ended_at) || Boolean(isEndingTimeEntry),\n );\n const modalVariant = !currentTimeEntry\n ? \"hourly_start\"\n : currentTimeEntry.matter_code === \"TRAINING PERIOD\"\n ? \"hourly_training_ended\"\n : \"hourly_restart\";\n\n const matterCodeOptions = getMatterCodeOptions();\n\n useEffect(() => {\n setShowModal(!currentTimeEntry || Boolean(currentTimeEntry?.ended_at) || Boolean(isEndingTimeEntry));\n }, [currentTimeEntry, isEndingTimeEntry]);\n\n const trackNewMatterCodeInLocalStorage = () => {\n if (!matterCodeOptions.includes(matterCode!)) {\n const newMatterCodeOptions = [...matterCodeOptions, matterCode!];\n window.localStorage.setItem(\"matterCodes\", JSON.stringify(newMatterCodeOptions));\n }\n };\n\n const trackAction = (\n eventName:\n | \"on_demand_hourly_matter_modal_start_timer_button_clicked\"\n | \"on_demand_hourly_matter_modal_enter_key_pressed\"\n | \"on_demand_hourly_matter_modal_logout_button_clicked\",\n ) => {\n void recordUserEvent({\n event_name: eventName,\n event_properties: { modal_variant: modalVariant },\n });\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Enter\" && Boolean(matterCode) && matterCode !== \"TRAINING PERIOD\") {\n trackAction(\"on_demand_hourly_matter_modal_enter_key_pressed\");\n void createTimeEntry(matterCode);\n trackNewMatterCodeInLocalStorage();\n }\n };\n\n const logout = () => {\n void recordUserEvent({\n event_name: \"on_demand_hourly_matter_modal_logout_button_clicked\",\n event_properties: { modal_variant: modalVariant },\n });\n handleSignOut();\n };\n\n // Title + body copy are state-dependent (Figma 11223/11224).\n const getModalContent = (): { title: string; body: React.ReactNode } => {\n if (currentTimeEntry) {\n if (currentTimeEntry.matter_code === \"TRAINING PERIOD\") {\n return {\n title: \"Your onboarding has ended\",\n body: \"Your time in Bench IQ is now billed to a client matter. Enter a matter number to continue.\",\n };\n }\n return {\n title: \"Your timer stopped\",\n body: `Your timer for matter [${currentTimeEntry.matter_code}] stopped. Confirm the matter and start tracking again.`,\n };\n }\n return {\n title: \"Start a timer\",\n body: \"Bench IQ bills your active time in-app to a client matter. Enter a matter number to start tracking.\",\n };\n };\n\n if (sessionExpiredOpen) return null;\n\n const { title, body } = getModalContent();\n\n // Gating modal \u2014 there is no close affordance (backdrop click + Escape leave\n // it open). The only exit is the Logout button in the footer.\n return (\n {\n requestAnimationFrame(() => {\n const restored = document.activeElement;\n if (restored instanceof HTMLElement) restored.classList.remove(\"Mui-focusVisible\");\n });\n },\n }}\n PaperProps={{ sx: (theme) => ({ borderRadius: `${theme.tokens.radii.smallRadius}px`, width: MODAL_WIDTH }) }}\n >\n \n {title}\n \n {body}\n \n \n {featureEnabled(\"custom_time_entry_modal_non_billable_alert\") && (\n \n For non-billable work in Bench IQ, request approval from your practice group leader.\n \n )}\n \n \n Logout\n \n {\n trackAction(\"on_demand_hourly_matter_modal_start_timer_button_clicked\");\n try {\n await createTimeEntry(matterCode!);\n trackNewMatterCodeInLocalStorage();\n } catch {\n // Error is handled globally (session expired modal or alert)\n }\n }}\n >\n Start timer\n \n \n \n \n );\n};\n\nexport default TimeTrackingModal;\n", "import * as React from \"react\";\n\nimport { styled } from \"@/utils/styled\";\n\nimport Alert from \"@mui/material/Alert\";\nimport Stack from \"@mui/material/Stack\";\nimport Collapse from \"@mui/material/Collapse\";\nimport { X } from \"lucide-react\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { useGlobalAlert } from \"@/contexts/GlobalAlertContext\";\n\n// The messages under failure in bench-iq/config/locales/devise.en.yml will surface as errors unless marked in here\nconst NOT_SEVERE_WINDOW_ALERT_MESSAGES = Object.freeze({ \"You are already signed in.\": true });\n\nconst StyledAlert = styled(Alert)<{ position: string; $userSignedIn: boolean }>`\n z-index: 1001;\n position: ${({ position }) => position || \"relative\"};\n bottom: ${({ $userSignedIn }) =>\n $userSignedIn || window.location.pathname === \"/users/sso/sign_in\" ? \"0px\" : \"992px\"};\n`;\n\nexport interface AlertsProps {\n alertPosition?: string;\n userSignedIn?: boolean;\n}\n\nconst Alerts = ({ alertPosition = \"relative\", userSignedIn = window.userSignedIn }: AlertsProps) => {\n const { flashNotice, setFlashNotice, flashAlert, setFlashAlert } = useGlobalAlert();\n\n const expireAlerts = () => {\n setFlashAlert(null);\n setFlashNotice(null);\n };\n\n setTimeout(expireAlerts, 3000);\n\n let noticeComponent = null;\n let alertComponent = null;\n\n if (flashNotice) {\n noticeComponent = (\n \n {\n setFlashNotice(null);\n }}\n />\n }\n >\n {flashNotice}\n \n \n );\n }\n\n if (flashAlert) {\n const severity = flashAlert in NOT_SEVERE_WINDOW_ALERT_MESSAGES ? \"info\" : \"error\";\n\n alertComponent = (\n \n {\n setFlashAlert(null);\n }}\n />\n }\n >\n {flashAlert}\n \n \n );\n }\n\n return (\n \n {noticeComponent}\n {alertComponent}\n \n );\n};\n\nexport default Alerts;\n", "import React from \"react\";\nimport { Dialog, DialogTitle, DialogActions, Link, Typography } from \"@mui/material\";\nimport { X } from \"lucide-react\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\n\ninterface TermsOfServiceModalProps {\n open: boolean;\n onClose: () => void;\n}\n\nconst TERMS_CONTENT = (\n <>\n

    \n Welcome to Bench IQ!\n

    \n\n

    \n These Bench IQ Terms of Service (\"Terms\") govern your use of the proprietary software platform and related\n services which are accessible via the Bench IQ website{\" \"}\n \n app.benchiq.com\n {\" \"}\n (the \"Site\"). The Site, Bench IQ platform and related services are collectively referred to as the \"Services\". The\n Services are made available to you by Bench IQ, Inc. and its affiliates and subsidiaries (\"Bench IQ\") hereunder,\n and are designed to facilitate the review and analysis of court hearing transcripts.\n

    \n\n

    These key terms as well as others are further described below.

    \n\n

    \n Bench IQ will provide the Services to you only if you accept these Terms. If you click on the \"I accept\" button on\n the sign-up page or use the Services, you are indicating that you understand and accept these Terms. If you are\n entering into these Terms on behalf of a company or other legal entity, you represent that you have the authority\n to bind such entity to these Terms, in which case the terms \"You\" or \"Your\" will refer to such entity. If you do\n not accept these Terms, then you are not authorized to use the Services.\n

    \n\n

    \n Account: In order to use the Services, you must create an account (\"Account\") and establish a\n username and a password or utilize a Single Sign-On (SSO) account provided by an approved third-party identity\n provider. In addition to your username or SSO credentials, in connection with Account set up and use of the\n Services, we will collect your name, role, email and other relevant account information, along with automatically\n created information inherent to the delivery of online services (such as IP/MAC addresses, browser/device\n information, and other unique identifiers) in order to: (i) to manage your information and accounts, (ii) provide\n access to our Services, (iii) detect security events, (iv) prevent fraud, (v) improve/upgrade/enhance our\n Services, and (vi) share with necessary third party sub-processors (such as our cloud hosting services). We will\n retain this information only for as long as necessary, and you may request that it be deleted by emailing us at{\" \"}\n support@benchiq.com.\n

    \n\n

    \n You agree to provide accurate, current and complete information about your Account. Bench IQ reserves the right to\n suspend or terminate your Account if any information provided during the registration process or thereafter proves\n to be inaccurate, false or misleading. You are responsible for maintaining the confidentiality of your password\n and Account, and agree to notify Bench IQ if your password is lost, stolen, or disclosed to an unauthorized third\n party, or otherwise may have been compromised. You will not share your Account credentials with any other person\n or otherwise permit any other person or entity to access or use the Services. You agree to notify us immediately\n of any unauthorized use of your account, user name or password. We are not liable for any losses you incur as a\n result of someone else's use of your account or password, either with or without your knowledge. You may be held\n liable for any losses incurred by us, our affiliates, officers, directors, employees, consultants, agents and\n representatives due to someone else's use of your account or password.\n

    \n\n

    \n You acknowledge that we have the right to monitor your access to and use of the Services for the purposes of\n operating and improving the Services (including without limitation for fraud prevention, risk assessment,\n investigation and customer support purposes, analytics, and advertising), to ensure your compliance with these\n Terms, and to comply with applicable law or the order or requirement of a court.\n

    \n\n

    \n When you use the Site, which may be hosted in part or its entirety by a third party, the Site may collect\n information indirectly and automatically (through, for example, the use of \"cookies\" or your \"IP address\") about\n your activities. We use this activity information (the \"Activity Information\") for internal purposes such as to\n administer the Site, improve the Site, and help us understand how the Site is being used. \"Cookies\" are small\n pieces of information stored on your hard drive, not on the Site. You are always free to decline cookies if your\n browser permits, but in that case, some portions of the Site may not operate properly. An \"IP address\" is a number\n that is automatically assigned to your computer when you use the internet.\n

    \n\n

    \n Beta Features: You acknowledge that: (a) some features of the Services are designated \"BETA\". The\n features so designated are in beta; (b) these features may not operate properly, be in final form or fully\n functional and may contain errors or omissions, design flaws or other problems; (c) use of these features may\n result in unexpected results, corruption or loss of data, information, content or communications, or other\n unpredictable damage or loss; and (d) Bench IQ has no obligation to release a commercial version of these\n features. You assume all risks arising from use of these features, including, without limitation, the risk of\n damage to your computer system or the corruption or loss of data, information or content.\n

    \n\n

    \n The Services: Subject to these Terms, Bench IQ grants you the right to use the Services. When you\n use the Services, you may choose to submit text queries (\"User Input\") to the Services. By submitting User Input\n to the Services, you authorize Bench IQ to use such User Input and you grant to Bench IQ a non-exclusive,\n transferable, worldwide, royalty-free, license, with the right to sublicense, to use, copy, modify, create\n derivative works based upon, distribute, publicly display, and publicly perform your User Input in connection with\n operating, providing, marketing and promoting the Services. When you use the Services your User Input is used to\n generate content displayed by the Services (\"Service Output\") and for development of our statistical models, for\n example, to allow us to improve the quality and performance of our search result generators.\n

    \n\n

    \n Intellectual Property Rights: The Services are owned and operated by Bench IQ, and contain\n materials that are proprietary and are protected by copyright laws, international treaty provisions, trademarks,\n service marks, and other intellectual property laws and treaties. Except as otherwise expressly authorized by\n Bench IQ in writing, none of the Services or content appearing on the Services may be copied, reproduced,\n republished, downloaded, uploaded, posted, displayed, transmitted or distributed in any way, and no part of the\n Services shall be construed to confer any license under any of Bench IQ's intellectual property rights, whether by\n estoppel, implication or otherwise. Any rights not expressly granted in these Terms are reserved by Bench IQ.\n

    \n\n

    \n Any trademarks, logos, taglines, and service marks displayed on the Services constitute registered and\n unregistered trademarks or service marks of Bench IQ.\n

    \n\n

    \n You represent and warrant that you own all of your User Input or that you have all rights necessary to grant Bench\n IQ the rights in your User Input under these Terms and that your User Input does not infringe any third-party\n intellectual property rights, rights of publicity or privacy, or violate applicable law. As between you and Bench\n IQ, Bench IQ owns all right, title, and interest in and to the Services and all Service Output, including all\n intellectual property rights therein.\n

    \n\n

    \n No Guarantee of Results; No Legal Advice; No Attorney-Client Relationship: Bench IQ provides the\n Services, and the data associated with the Services, to allow you to utilize your professional judgment in serving\n your clients. Bench IQ does not guarantee that your use of the Services will lead to any specific outcome nor have\n any guaranteed result. Bench IQ through the Services is not providing legal advice. Neither the Services nor the\n Service Output constitute legal advice. Your use of the Services does not create an attorney-client relationship\n between you and Bench IQ.\n

    \n\n

    \n No Warranty of PACER Data. Bench IQ acquires transcript and transcript-related data directly from\n PACER. There may be instances in which data in PACER is incomplete or incorrect. Bench IQ is not responsible for\n incomplete or incorrect PACER data.\n

    \n\n

    \n Geographic Applicability of the Services. Bench IQ's registered office is based in the state of\n Indiana in the United States. We provide the Services for use only by persons located in the United States. We\n make no claims that the Services or any of its content is accessible or appropriate outside of the United States.\n Access to the Services may not be legal by certain persons or in certain countries. If you access the Services\n from outside the United States, you do so on your own initiative and at your own risk, and are responsible for\n compliance with local laws.\n

    \n\n

    \n Artificial Intelligence (\"AI\") and Generative AI Features. The Model Rules of Professional\n Conduct promulgated by the American Bar Association and adopted by state bar associations, and similar rules,\n contain ethical rules that may apply to the use of AI. The Federal Rules of Civil Procedure and applicable state\n procedural rules contain certain accuracy requirements that apply to an attorney submitting a court document.\n Further, some courts have implemented special rules governing the use of AI and generative AI. Some of the\n Services involve the use of AI, such as Bench Opinions\u2122 and \"transcript Q&A\". In connection with your use of the\n Services you are responsible for knowing the applicable ethical and procedural rules; Bench IQ is not responsible\n for your violation of court or ethical rules regarding the use of AI or generative AI. You are responsible for\n using your professional judgment when utilizing the Service Output.\n

    \n\n

    \n Feedback. You may choose to provide Bench IQ with feedback and comments and suggestions for\n improvements to the Services (collectively, \"Feedback\"). As part of providing Bench IQ with such Feedback, we may\n ask you to complete any surveys or other questionnaires that Bench IQ may send to you from time to time regarding\n your experience in using the Services. We may edit, copy, publish, distribute, translate, and otherwise use any\n Feedback that you forward to us. We are not obligated (1) to maintain any Feedback in confidence; (2) to pay\n compensation for any Feedback; or (3) to respond to any Feedback. You acknowledge and agree that all Feedback will\n be the sole and exclusive property of Bench IQ and that Bench IQ may use the Feedback at its sole discretion in\n connection with its provision of the Services. You hereby assign to Bench IQ and agree to assign to Bench IQ all\n of your right, title, and interest in and to all Feedback, including all intellectual property rights therein. At\n Bench IQ's request and expense, you will execute documents and take such further acts as Bench IQ may reasonably\n request to assist Bench IQ to acquire, perfect and maintain its intellectual property rights and other legal\n protections for the Feedback.\n

    \n\n

    \n Electronic Communications. You agree to receive all communications and notices that we provide in\n connection with the Services (\"Message Services\"), including, but not limited to, communications related to our\n delivery of the Services via electronic means, including by e-mail, text, in-product notifications, or by posting\n them on the Services. If you do not wish to continue participating in a Message Service we offer, you may opt out\n by contacting support@benchiq.com with UNSUBSCRIBE in the subject\n line.\n

    \n\n

    \n Privacy. You acknowledge that, except as described in these Terms, the information you provide to\n us or that we collect will be used and protected as described in our Privacy Policy. You also acknowledge that we\n may process User Input in accordance with our Privacy Policy.\n

    \n\n

    \n Confidentiality. \"Confidential Information\" means: (a) the Services, including any Feedback that\n you provide to Bench IQ; (b) any Bench IQ business or technical information that is disclosed to you in connection\n with your use of the Services, including, but not limited to, any information relating to Bench IQ's plans,\n designs, technical features, business opportunities or know-how that is designated by Bench IQ as \"confidential\"\n or \"proprietary\" and if orally disclosed, is reduced to writing by Bench IQ within thirty (30) days of such\n disclosure; and (c) any tests, assessments or trials related to the Services, including any data, results or\n information from such tests, assessments or trials. Confidential Information excludes any information that: (a) is\n or becomes generally known to the public other than as a result of your breach of these Terms; (b) is rightfully\n known to you at the time of disclosure without restrictions on use or disclosure; (c) is independently developed\n by you, without access to or use of any Confidential Information; or (d) is rightfully obtained by you from a\n third party, who has the right to disclose it and who discloses it without restrictions on use or disclosure. You\n will maintain all Confidential Information in strict confidence and you may disclose Confidential Information only\n to persons who have a bona fide need to know such Confidential Information for the testing and evaluation of the\n Services and providing Feedback, provided that any such person first executes or is otherwise already bound by a\n written agreement that contains use and nondisclosure restrictions at least as protective of the Confidential\n Information as those set forth in this Agreement. You will not use Confidential Information, except solely as\n necessary to test and evaluate the Services. You will protect Bench IQ's Confidential Information from\n unauthorized use and disclosure using efforts equivalent to the efforts that you ordinarily use with respect to\n your own confidential information and in no event less than a reasonable standard of care.\n

    \n\n

    \n General Prohibitions. You agree not to: (i) access, tamper with, \"hack\", or use non-public areas\n of the Services, Bench IQ's computer systems, or the technical delivery systems of Bench IQ's providers; (ii)\n attempt to probe, scan or test the vulnerability of any Bench IQ system or network or breach any security or\n authentication measures except as allowed by Bench IQ's Responsible Disclosure policy{\" \"}\n \n https://benchiq.com/responsible-disclosure\n \n ; (iii) attempt to decipher, decompile, disassemble or reverse engineer any of the software or code used to\n provide the Services; (iv) collect or store any personally identifiable information (\"PII\") from the Services from\n other users of the Services without their express permission; (v) impersonate or misrepresent your affiliation\n with any person or entity; (vi) violate any applicable law or regulation; (vii) download transcripts in bulk,\n and/or scrape transcript content from the Site (you may, however, download individual transcripts in the course of\n your research on the Site); (viii) distribute computer viruses or other code, files, or programs that interrupt,\n destroy, or limit the functionality of any Bench IQ computer software or hardware or electronic communications\n equipment; (ix) remove, circumvent, disable, damage, or otherwise interfere with the Services' security-related\n features, or features that enforce limitations on use of the Services; (x) access or use the Services for the\n purpose of developing or operating products or services intended to be offered to third parties in competition\n with the Services, allow access to your Account by a direct competitor of Bench IQ; or (xi) encourage or enable\n any other individual to do any of the foregoing.\n

    \n\n

    \n Changes to the Services. The Services are evolving over time and we may change or discontinue all\n or any part of the Services, at any time and without notice, at our sole discretion. We may remove or disable\n access to any content on the Services, at any time and without notice. We are not be liable to you or to any third\n party for any modification, suspension or discontinuance of the Services or removal or disabling of access to any\n content on the Services.\n

    \n\n

    \n Changes to These Terms. Bench IQ may modify the Terms at any time, in our sole discretion. If we\n do so, we'll let you know either by posting the modified Terms on the Site and/or through email. It is important\n that you review the Terms whenever we modify them because if you continue to use the Services after we have posted\n modified Terms, you are indicating to us that you agree to be bound by the modified Terms. If you do not agree to\n be bound by the modified Terms, then you are no longer authorized to use the Services.\n

    \n\n

    \n Term; Termination. These Terms will remain in effect until terminated. Bench IQ may terminate\n these Terms without advance notice, at any time and for any reason including your violation of these Terms. You\n may terminate these Terms at any time upon written notice to Bench IQ. Upon expiration or termination: (i) your\n right to access and use the Services and related content will immediately terminate; and (ii) you will promptly\n destroy or return any Bench IQ Confidential Information in your possession or control. Some provisions of these\n Terms will survive termination, such as any obligation you have to pay us or indemnify us, any limitations on our\n liability, and any provisions regarding ownership of intellectual property rights.\n

    \n\n

    \n Disclaimers. THE SERVICES ARE PROVIDED ON AN \"AS IS,\" \"WITH ALL FAULTS\", AND \"AS AVAILABLE\"\n BASIS. BENCH IQ DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT IN CONNECTION WITH THE SERVICES. YOU ACKNOWLEDGE THAT YOU\n ARE USING THE SERVICES AT YOUR SOLE RISK. Bench IQ makes no representations or warranties regarding the\n suitability of the Services for your intended requirements or purposes or regarding any data, information or\n content that you access through the use of the Services.\n

    \n\n

    \n WE DO NOT WARRANT THAT ACCESS TO OR USE OF THE SERVICES WILL FUNCTION WITHOUT INTERRUPTION, WILL MEET YOUR\n REQUIREMENTS, IS FREE OF MALICIOUS CODE OR THAT IT IS FREE OF ERRORS OR OMISSIONS, OR LOSS OR SECURITY BREACH OF\n TRANSMITTED INFORMATION, OR THAT NO VIRUSES WILL BE TRANSMITTED THROUGH ACCESS TO OR USE OF THE SERVICES.\n

    \n\n

    \n SOME STATE LAWS DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIES. IF THESE LAWS APPLY TO YOU, SOME OR ALL OF THE\n FOREGOING DISCLAIMERS, EXCLUSIONS AND LIMITATIONS MAY NOT APPLY TO YOU, AND YOU MIGHT HAVE ADDITIONAL RIGHTS.\n

    \n\n

    \n Limitation of Liability. IN NO EVENT WILL BENCH IQ BE LIABLE TO YOU FOR ANY DIRECT, SPECIAL,\n INCIDENTAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES (INCLUDING LOSS OF USE, DATA, BUSINESS OR PROFITS)\n ARISING OUT OF OR IN CONNECTION WITH THESE TERMS OR THE USE OR PERFORMANCE OF THE SERVICES, WHETHER SUCH LIABILITY\n ARISES FROM ANY CLAIM BASED UPON CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,\n AND WHETHER OR NOT BENCH IQ HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.\n

    \n\n

    \n UNDER NO CIRCUMSTANCES WILL THE TOTAL AGGREGATE AMOUNT THAT BENCH IQ IS LIABLE TO YOU EXCEED THE GREATER OF (I)\n $100.00 OR (II) THE AMOUNTS PAID BY YOU TO BENCH IQ IN CONNECTION WITH THE SERVICES IN THE TWELVE (12) MONTH\n PERIOD PRECEDING THE EVENT ON WHICH YOUR CLAIM IS BASED. THE FOREGOING CAP ON LIABILITY SHALL NOT APPLY TO BENCH\n IQ'S LIABILITY FOR (1) DEATH, TANGIBLE PROPERTY DAMAGE, OR PERSONAL INJURY CAUSED BY OUR GROSS NEGLIGENCE OR FOR\n (2) ANY INJURY CAUSED BY OUR FRAUD OR FRAUDULENT MISREPRESENTATION.\n

    \n\n

    \n SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF PUNITIVE, INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE\n PRIOR LIMITATION OR EXCLUSION MAY NOT APPLY TO YOU. THE FOREGOING LIMITATIONS AND EXCLUSIONS OF LIABILITY AND\n DISCLAIMERS FORM AN ESSENTIAL BASIS OF THE BARGAIN BETWEEN THE PARTIES, AND WE WOULD NOT ENTER INTO THIS AGREEMENT\n WITHOUT SUCH LIMITATIONS, EXCLUSIONS, AND DISCLAIMERS.\n

    \n\n

    \n Indemnification. You agree to defend, indemnify, and hold us, our affiliates, officers,\n directors, employees, suppliers, consultants, and agents harmless from any and all third-party claims, liability,\n damages, and costs (including, but not limited to, attorney's fees) arising from or related to, as applicable: (a)\n your access to and use of the Services; (b) violation of these Terms by you; or (c) infringement of any\n intellectual property or other right of any person or entity by you.\n

    \n\n

    \n We retain the exclusive right to settle, compromise, and pay, without your prior consent, any and all claims or\n causes of action that are brought against us. We reserve the right, at your expense, to assume the exclusive\n defense and control of any matter for which you are required to indemnify us and you agree to cooperate with our\n defense of these claims. You agree not to settle any matter in which we are named as a defendant and/or for which\n you have indemnity obligations without our prior written consent. We will use reasonable efforts to notify you of\n any such claim, action, or proceeding upon becoming aware of it.\n

    \n\n

    \n If you are a California resident, you waive California Civil Code Section 1542, which provides: A general release\n does not extend to claims that the creditor or releasing party does not know or suspect to exist in his or her\n favor at the time of executing the release, and that if known by him or her would have materially affected his or\n her settlement with the debtor or released party. If you are not a California resident, you waive your rights\n under any statute or common law principle similar to Section 1542 that governs your rights in the jurisdiction of\n your residence.\n

    \n\n

    \n General. These Terms will be governed by the laws of the State of New York. You may not assign\n these Terms without Bench IQ's prior written consent, and any attempt by you to do so will be void and of no\n effect. Bench IQ may freely assign these Terms. The failure by Bench IQ to enforce any provision of these Terms\n will not constitute a waiver of that or any other provision. If any provision of these Terms is held to be\n unenforceable or invalid, that provision will be enforced to the maximum extent possible and the other provisions\n will remain in full force and effect. These Terms are the complete and exclusive understanding and agreement\n between the parties regarding their subject matter, and supersede all other proposals, understandings or\n communications between the parties, oral or written in this regard. Nothing in these Terms will be construed to\n create a partnership, joint venture or agency relationship between Bench IQ and you. Any notices or other\n communications provided by Bench IQ under these Terms, including those regarding modifications to these Terms,\n will be given: (i) via email; and/or (ii) by posting to the Site. For notices made by e-mail, the date of receipt\n will be deemed the date on which such notice is transmitted. The headings used throughout these Terms are solely\n for the convenience of reference and are not to be used as an aid in the interpretation of these Terms.\n

    \n\n

    \n If you have any questions or concerns about the Services or these Terms, please contact us at{\" \"}\n support@benchiq.com.\n

    \n \n);\n\nconst TermsOfServiceModal: React.FC = ({ open, onClose }) => {\n return (\n ({\n height: \"calc(100vh - 112px)\", // 56px top + 56px bottom margin\n maxHeight: \"calc(100vh - 112px)\",\n margin: \"56px auto\", // 56px top/bottom, auto left/right for centering\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n maxWidth: \"760px\", // Set max width to 760px as requested\n width: \"calc(100vw - 112px)\", // Account for margins\n overflow: \"visible\",\n }),\n }}\n >\n ({\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n padding: 3,\n borderBottom: `1px solid ${theme.border.default}`,\n })}\n >\n \n Terms of Service\n \n \n \n\n by default, and we'd get a scary warning \"no nesting p in p\"\n color=\"textPrimary\"\n sx={{\n padding: 3,\n overflowY: \"auto\",\n }}\n >\n {TERMS_CONTENT}\n \n\n ({\n padding: 3,\n borderTop: `1px solid ${theme.border.default}`,\n justifyContent: \"space-between\",\n alignItems: \"center\",\n })}\n >\n \n Copyright \u00A9 {new Date().getFullYear()} Bench IQ, Inc. All rights reserved.\n \n \n Close\n \n \n \n );\n};\n\nexport default TermsOfServiceModal;\n", "import React, { type FormEvent, type ReactNode, useLayoutEffect, useState } from \"react\";\nimport {\n Alert,\n Box,\n Checkbox,\n CircularProgress,\n FormControlLabel,\n FormHelperText,\n IconButton,\n Link as MuiLink,\n MenuItem,\n Stack,\n Typography,\n} from \"@mui/material\";\nimport { ChevronDown, Eye, EyeOff } from \"lucide-react\";\nimport { Link as RouterLink } from \"react-router-dom\";\nimport { useTheme, type SxProps, type Theme } from \"@mui/material/styles\";\n\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQInputField, type BIQInputFieldProps } from \"@/components/atoms/BIQInputField\";\nimport LogoMark from \"@/components/atoms/icons/LogoMark\";\nimport WindowTitle from \"@/components/atoms/WindowTitle\";\nimport TermsOfServiceModal from \"@/components/molecules/TermsOfServiceModal\";\nimport { useOptionalGlobalAlert } from \"@/contexts/GlobalAlertContext\";\n\nexport const AUTH_CARD_TOP_OFFSET = 100;\n\nexport const authFieldLabelSx: SxProps = (theme) => ({\n ...theme.typography.body2,\n color: theme.palette.text.secondary,\n fontWeight: theme.typography.fontWeightMedium,\n});\n\nexport const AuthTextField = React.forwardRef(({ sx, ...props }, ref) => (\n ({\n \"& .MuiInputBase-input\": {\n ...theme.typography.body1,\n padding: \"16px 12px\",\n },\n }),\n ...(Array.isArray(sx) ? sx : [sx]),\n ]}\n {...props}\n />\n));\nAuthTextField.displayName = \"AuthTextField\";\n\n// Auth cards show the server's flash message themselves, so they take it out of\n// the page-wide banner instead of showing it twice.\nexport const useClaimedFlash = (kind: \"alert\" | \"notice\") => {\n const globalAlert = useOptionalGlobalAlert();\n const [message] = useState(() => (kind === \"alert\" ? window.alertMessage : window.notice) || null);\n\n useLayoutEffect(() => {\n if (!message) return;\n if (kind === \"alert\") globalAlert?.setFlashAlert(null);\n else globalAlert?.setFlashNotice(null);\n }, [globalAlert, kind, message]);\n\n return message;\n};\n\ninterface AuthPageProps {\n title: string;\n children: ReactNode;\n alert?: string | null;\n info?: string | null;\n notice?: string | null;\n}\n\nexport const AuthPage = ({ title, children, alert, info, notice }: AuthPageProps) => (\n \n \n ({\n border: `1px solid ${theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n bgcolor: \"background.paper\",\n boxSizing: \"border-box\",\n display: \"flex\",\n flexDirection: \"column\",\n flexShrink: 0,\n gap: 3,\n py: 3,\n width: \"100%\",\n maxWidth: 416,\n })}\n >\n \n \n \n \n {title}\n \n \n {alert && (\n \n {alert}\n \n )}\n {info && (\n \n {info}\n \n )}\n {notice && (\n \n {notice}\n \n )}\n {children}\n \n
    \n
    \n);\n\nexport const AuthSubmitButton = ({\n loading,\n disabled,\n children,\n}: {\n loading: boolean;\n disabled?: boolean;\n children: ReactNode;\n}) => (\n : undefined}\n >\n {children}\n \n);\n\nexport const AuthForm = ({\n children,\n id,\n onSubmit,\n}: {\n children: ReactNode;\n id?: string;\n onSubmit: (event: FormEvent) => void;\n}) => (\n \n {children}\n \n);\n\nexport const AuthLink = ({ to, children }: { to: string; children: ReactNode }) => (\n \n {children}\n \n);\n\nexport const AuthFooter = ({ children }: { children: ReactNode }) => (\n \n {children}\n \n);\n\nexport const AuthTermsAcceptance = ({\n checked,\n error,\n id,\n onBlur,\n onChange,\n}: {\n checked: boolean;\n error?: string;\n id: string;\n onBlur?: () => void;\n onChange: (checked: boolean) => void;\n}) => {\n const [showTerms, setShowTerms] = useState(false);\n const helperTextId = `${id}-helper-text`;\n\n return (\n <>\n \n onChange(event.target.checked)}\n />\n }\n label={\n \n I accept the{\" \"}\n {\n event.preventDefault();\n event.stopPropagation();\n setShowTerms(true);\n }}\n >\n Terms of Service\n \n \n }\n sx={{ m: 0 }}\n />\n {error && (\n \n {error}\n \n )}\n \n setShowTerms(false)} />\n \n );\n};\n\ninterface PasswordFieldProps extends Omit {\n showRequirements?: boolean;\n}\n\nexport const PasswordField = ({ showRequirements, value, onFocus, onBlur, ...props }: PasswordFieldProps) => {\n const [visible, setVisible] = useState(false);\n const password = String(value || \"\");\n\n return (\n \n setVisible((current) => !current)}\n >\n {visible ? : }\n \n }\n />\n {showRequirements && }\n \n );\n};\n\nexport const passwordRules = [\n { label: \"Must be at least 15 characters\", valid: (password: string) => password.length >= 15 },\n { label: \"Include 1 uppercase letter\", valid: (password: string) => /[A-Z]/.test(password) },\n { label: \"Include 1 lowercase letter\", valid: (password: string) => /[a-z]/.test(password) },\n { label: \"Include 1 numeric character\", valid: (password: string) => /\\d/.test(password) },\n { label: \"Include 1 symbol character\", valid: (password: string) => /[^a-zA-Z0-9]/.test(password) },\n] as const;\n\nexport const passwordIsValid = (password: string) => passwordRules.every((rule) => rule.valid(password));\n\nexport const PasswordRequirements = ({ password }: { password: string }) => (\n \n {passwordRules.map((rule) => (\n \n {rule.label}\n \n ))}\n \n);\n\nexport const ROLE_OPTIONS = [\n [\"associate\", \"Associate\"],\n [\"counsel\", \"Counsel\"],\n [\"partner\", \"Partner\"],\n [\"paralegal\", \"Paralegal\"],\n [\"staff\", \"Staff\"],\n [\"other\", \"Other\"],\n] as const;\n\ninterface RoleSelectProps {\n id: string;\n value: string;\n onBlur?: () => void;\n onChange: (value: string) => void;\n error?: string;\n}\n\nconst RoleSelectIcon = (props: React.ComponentProps) => {\n const theme = useTheme();\n\n return ;\n};\n\nexport const RoleSelect = ({ id, value, onBlur, onChange, error }: RoleSelectProps) => {\n const labelId = `${id}-label`;\n\n return (\n <>\n \n Role\n \n onChange(event.target.value)}\n sx={(theme) => ({\n \"& .MuiSelect-select.MuiInputBase-input\": {\n ...theme.typography.body1,\n padding: \"16px 40px 16px 12px !important\",\n },\n })}\n SelectProps={{\n displayEmpty: true,\n IconComponent: RoleSelectIcon,\n labelId,\n renderValue: (selected) => {\n const selectedLabel = ROLE_OPTIONS.find(([option]) => option === selected)?.[1];\n\n return (\n \n {selectedLabel || \"Select role\"}\n \n );\n },\n }}\n >\n {ROLE_OPTIONS.map(([option, label]) => (\n \n \n {label}\n \n \n ))}\n \n \n );\n};\n", "export interface AuthSuccess {\n status: string;\n redirect_to?: string;\n email?: string;\n result?: \"verified\" | \"invalid\";\n first_name?: string | null;\n last_name?: string | null;\n role?: string | null;\n custom_role?: string | null;\n saml_sign_in_url?: string;\n}\n\ninterface AuthErrorPayload {\n error?: {\n code?: string;\n message?: string;\n };\n field_errors?: Record;\n}\n\nexport class AuthApiError extends Error {\n code: string;\n fieldErrors: Record;\n status: number;\n\n constructor(payload: AuthErrorPayload, status: number) {\n super(payload.error?.message || \"Something went wrong. Try again.\");\n this.name = \"AuthApiError\";\n this.code = payload.error?.code || \"request_failed\";\n this.fieldErrors = payload.field_errors || {};\n this.status = status;\n }\n}\n\nconst csrfToken = () => document.querySelector('meta[name=\"csrf-token\"]')?.content || \"\";\n\nexport async function authRequest(\n url: string,\n options: { method?: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\"; body?: unknown; headers?: Record } = {},\n): Promise {\n const method = options.method || \"GET\";\n const response = await fetch(url, {\n method,\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"X-CSRF-Token\": csrfToken(),\n ...options.headers,\n },\n body: method === \"GET\" ? undefined : JSON.stringify(options.body || {}),\n });\n\n let payload: T | AuthErrorPayload;\n try {\n payload = (await response.json()) as T | AuthErrorPayload;\n } catch (_error) {\n throw new AuthApiError(\n { error: { code: \"invalid_response\", message: \"The server returned an invalid response. Try again.\" } },\n response.status,\n );\n }\n\n if (!response.ok) throw new AuthApiError(payload as AuthErrorPayload, response.status);\n return payload as T;\n}\n\nexport const validEmail = (email: string) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email.trim());\n\nexport const firstFieldError = (errors: Record, field: string) => errors[field]?.[0];\n\nexport const focusFirstAuthError = (errors: Record, fieldIds: Record) => {\n const field = Object.keys(fieldIds).find((name) => errors[name]?.length);\n if (!field) return;\n\n window.setTimeout(() => document.getElementById(fieldIds[field])?.focus(), 0);\n};\n\nexport const currentReturnTo = () => new URLSearchParams(window.location.search).get(\"return_to\") || undefined;\n\nexport const withReturnTo = (path: string) => {\n const returnTo = currentReturnTo();\n return returnTo ? `${path}?return_to=${encodeURIComponent(returnTo)}` : path;\n};\n", "import React, { useRef, useState } from \"react\";\nimport { Checkbox, FormControlLabel, Stack, Typography } from \"@mui/material\";\n\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport {\n AuthFooter,\n AuthForm,\n AuthLink,\n AuthPage,\n AuthSubmitButton,\n AuthTextField,\n PasswordField,\n useClaimedFlash,\n} from \"./AuthComponents\";\nimport { AuthApiError, authRequest, currentReturnTo, validEmail, withReturnTo } from \"./authApi\";\n\nexport const LoginPage = () => {\n const emailEdited = useRef(false);\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [rememberMe, setRememberMe] = useState(false);\n const [emailError, setEmailError] = useState();\n const flashAlert = useClaimedFlash(\"alert\");\n const flashNotice = useClaimedFlash(\"notice\");\n const [alert, setAlert] = useState(flashAlert);\n const [loading, setLoading] = useState(false);\n\n const submit = async (event: React.FormEvent) => {\n event.preventDefault();\n const nextEmailError = validEmail(email) ? undefined : \"Enter a valid email address.\";\n setEmailError(nextEmailError);\n if (nextEmailError || !password) {\n if (!password) setAlert(\"Enter your password.\");\n window.setTimeout(() => document.getElementById(nextEmailError ? \"login-email\" : \"login-password\")?.focus(), 0);\n return;\n }\n\n setAlert(null);\n setLoading(true);\n let navigationStarted = false;\n try {\n const response = await authRequest(\"/users/sign_in\", {\n method: \"POST\",\n body: {\n user: { email, password, remember_me: rememberMe ? \"1\" : \"0\" },\n return_to: currentReturnTo(),\n },\n });\n window.location.assign(response.redirect_to || \"/\");\n } catch (error) {\n setPassword(\"\");\n if (error instanceof AuthApiError && error.code === \"sso_required\") {\n navigationStarted = handOffToSso(email, setAlert);\n } else {\n setAlert(error instanceof AuthApiError ? error.message : \"Something went wrong. Try again.\");\n }\n } finally {\n if (!navigationStarted) setLoading(false);\n }\n };\n\n return (\n \n \n {\n if (emailEdited.current) {\n setEmailError(!validEmail(email) ? \"Enter a valid email address.\" : undefined);\n }\n }}\n onChange={(event) => {\n const nextEmail = event.target.value;\n emailEdited.current = true;\n setEmail(nextEmail);\n if (emailError && validEmail(nextEmail)) setEmailError(undefined);\n }}\n />\n \n setPassword(event.target.value)}\n />\n \n setRememberMe(event.target.checked)} />}\n label=\"Remember me\"\n sx={{ m: 0, \"& .MuiFormControlLabel-label\": { typography: \"body2\" } }}\n />\n Forgot password?\n \n \n Log in\n \n \n or sign in with your organization\n \n \n Log in with SSO\n \n \n Not registered yet? Create an account.\n \n \n );\n};\n\nconst SAML_SIGN_IN_PATH = \"/users/saml/sign_in\";\n\nexport const submitSamlSignInForm = (email: string, returnTo?: string) => {\n const authenticityToken = document.querySelector('meta[name=\"csrf-token\"]')?.content;\n if (!authenticityToken) throw new Error(\"Missing CSRF token\");\n\n const form = document.createElement(\"form\");\n form.method = \"post\";\n form.action = SAML_SIGN_IN_PATH;\n\n const appendHiddenInput = (name: string, value: string) => {\n const input = document.createElement(\"input\");\n input.type = \"hidden\";\n input.name = name;\n input.value = value;\n form.appendChild(input);\n };\n\n appendHiddenInput(\"authenticity_token\", authenticityToken);\n appendHiddenInput(\"email\", email);\n if (returnTo) appendHiddenInput(\"return_to\", returnTo);\n\n document.body.appendChild(form);\n form.submit();\n};\n\n// Firms with SSO cannot use a password, so the server answers `sso_required`\n// and the page continues to the firm's identity provider with the same email.\nexport const handOffToSso = (email: string, setAlert: (alert: string) => void) => {\n try {\n submitSamlSignInForm(email.trim().toLowerCase(), currentReturnTo());\n return true;\n } catch (_error) {\n setAlert(\"We couldn't start SSO. Refresh the page and try again.\");\n return false;\n }\n};\n\nexport const SsoLoginPage = () => {\n const emailEdited = useRef(false);\n const [email, setEmail] = useState(\"\");\n const [emailError, setEmailError] = useState();\n const flashAlert = useClaimedFlash(\"alert\");\n const [alert, setAlert] = useState(flashAlert);\n const [loading, setLoading] = useState(false);\n\n const submit = async (event: React.FormEvent) => {\n event.preventDefault();\n if (!validEmail(email)) {\n setEmailError(\"Enter a valid email address.\");\n window.setTimeout(() => document.getElementById(\"sso-email\")?.focus(), 0);\n return;\n }\n\n setEmailError(undefined);\n setAlert(null);\n setLoading(true);\n let navigationStarted = false;\n try {\n const response = await authRequest(\"/users/saml/discovery\", {\n method: \"POST\",\n body: { email },\n });\n if (response.saml_sign_in_url !== SAML_SIGN_IN_PATH) throw new Error(\"Invalid SSO handoff\");\n\n submitSamlSignInForm(email, currentReturnTo());\n navigationStarted = true;\n } catch (error) {\n setAlert(error instanceof AuthApiError ? error.message : \"We could not start SSO. Try again.\");\n } finally {\n if (!navigationStarted) setLoading(false);\n }\n };\n\n return (\n \n \n {\n if (emailEdited.current) {\n setEmailError(!validEmail(email) ? \"Enter a valid email address.\" : undefined);\n }\n }}\n onChange={(event) => {\n const nextEmail = event.target.value;\n emailEdited.current = true;\n setEmail(nextEmail);\n if (emailError && validEmail(nextEmail)) setEmailError(undefined);\n }}\n />\n Log in\n \n \n or\n \n \n Go back to login\n \n \n Not registered yet? Create an account.\n \n \n );\n};\n", "import React, { useRef, useState } from \"react\";\nimport { CircularProgress } from \"@mui/material\";\n\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\n\nimport {\n AuthFooter,\n AuthForm,\n AuthLink,\n AuthPage,\n AuthSubmitButton,\n AuthTermsAcceptance,\n AuthTextField,\n PasswordField,\n passwordIsValid,\n RoleSelect,\n} from \"./AuthComponents\";\nimport { AuthApiError, authRequest, firstFieldError, focusFirstAuthError, validEmail } from \"./authApi\";\nimport { submitSamlSignInForm } from \"./LoginPages\";\n\ntype SignupErrors = Record;\ntype SignupAvailability = \"unchecked\" | \"checking\" | \"available\" | \"sso\" | \"unavailable\" | \"invalid\";\n\nconst SIGNUP_FIELD_IDS = {\n email: \"signup-email\",\n first_name: \"signup-first-name\",\n last_name: \"signup-last-name\",\n role: \"signup-role\",\n custom_role: \"signup-custom-role\",\n password: \"signup-password\",\n accepted_tos: \"signup-accepted-tos\",\n};\n\nexport const SignupPage = () => {\n const emailEdited = useRef(false);\n const [email, setEmail] = useState(\"\");\n const [firstName, setFirstName] = useState(\"\");\n const [lastName, setLastName] = useState(\"\");\n const [role, setRole] = useState(\"\");\n const [customRole, setCustomRole] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [acceptedTos, setAcceptedTos] = useState(false);\n const [passwordFocused, setPasswordFocused] = useState(false);\n const [errors, setErrors] = useState({});\n const [alert, setAlert] = useState(null);\n const [availability, setAvailability] = useState(\"unchecked\");\n const [loading, setLoading] = useState(false);\n const [ssoStarting, setSsoStarting] = useState(false);\n const latestEmail = useRef(\"\");\n const availabilityRequest = useRef<{\n email: string;\n promise: Promise;\n }>();\n\n const setFieldError = (field: string, message: string) => {\n setErrors((current) => ({ ...current, [field]: [message] }));\n };\n\n const clearFieldError = (field: string) => {\n setErrors((current) => {\n if (!current[field]?.length) return current;\n\n const nextErrors = { ...current };\n delete nextErrors[field];\n return nextErrors;\n });\n };\n\n const checkAvailability = async (): Promise => {\n const normalizedEmail = email.trim().toLowerCase();\n if (!validEmail(normalizedEmail)) {\n setErrors((current) => ({ ...current, email: [\"Enter a valid email address.\"] }));\n setAvailability(\"invalid\");\n return \"invalid\";\n }\n\n if (availabilityRequest.current?.email === normalizedEmail) {\n return availabilityRequest.current.promise;\n }\n\n setErrors((current) => ({ ...current, email: [] }));\n setAlert(null);\n setAvailability(\"checking\");\n\n const promise = authRequest(\"/users/registration/availability\", {\n method: \"POST\",\n body: { user: { email: normalizedEmail } },\n })\n .then((response): SignupAvailability => {\n if (latestEmail.current.trim().toLowerCase() !== normalizedEmail) {\n if (availabilityRequest.current?.email === normalizedEmail) availabilityRequest.current = undefined;\n return \"unchecked\";\n }\n\n if (response.status === \"registration_available\") {\n if (availabilityRequest.current?.email === normalizedEmail) availabilityRequest.current = undefined;\n setAvailability(\"available\");\n return \"available\";\n }\n\n if (response.status === \"sso_required\" && response.saml_sign_in_url === \"/users/saml/sign_in\") {\n if (availabilityRequest.current?.email === normalizedEmail) availabilityRequest.current = undefined;\n setAvailability(\"sso\");\n return \"sso\";\n }\n\n if (availabilityRequest.current?.email === normalizedEmail) availabilityRequest.current = undefined;\n setAvailability(\"invalid\");\n setAlert(\"We couldn't check this email. Try again.\");\n return \"invalid\";\n })\n .catch((error): SignupAvailability => {\n if (latestEmail.current.trim().toLowerCase() !== normalizedEmail) {\n if (availabilityRequest.current?.email === normalizedEmail) availabilityRequest.current = undefined;\n return \"unchecked\";\n }\n\n if (error instanceof AuthApiError && error.code === \"registration_unavailable\") {\n if (availabilityRequest.current?.email === normalizedEmail) availabilityRequest.current = undefined;\n setAvailability(\"unavailable\");\n setAlert(error.message);\n return \"unavailable\";\n }\n\n if (error instanceof AuthApiError && error.code === \"validation_failed\") {\n setErrors(error.fieldErrors);\n setAvailability(\"invalid\");\n if (availabilityRequest.current?.email === normalizedEmail) availabilityRequest.current = undefined;\n return \"invalid\";\n }\n\n setAvailability(\"invalid\");\n setAlert(error instanceof AuthApiError ? error.message : \"We couldn't check this email. Try again.\");\n if (availabilityRequest.current?.email === normalizedEmail) availabilityRequest.current = undefined;\n return \"invalid\";\n });\n\n availabilityRequest.current = { email: normalizedEmail, promise };\n return promise;\n };\n\n const validate = () => {\n const nextErrors: SignupErrors = {};\n if (!validEmail(email)) nextErrors.email = [\"Enter a valid email address.\"];\n if (!firstName.trim()) nextErrors.first_name = [\"Enter your first name.\"];\n if (!lastName.trim()) nextErrors.last_name = [\"Enter your last name.\"];\n if (!role) nextErrors.role = [\"Select your role.\"];\n if (role === \"other\" && !customRole.trim()) nextErrors.custom_role = [\"Enter your role.\"];\n if (!passwordIsValid(password)) nextErrors.password = [\"Your password must meet every requirement.\"];\n if (!acceptedTos) nextErrors.accepted_tos = [\"You must accept the Terms of Service.\"];\n setErrors(nextErrors);\n focusFirstAuthError(nextErrors, SIGNUP_FIELD_IDS);\n return Object.keys(nextErrors).length === 0;\n };\n\n const submit = async (event: React.FormEvent) => {\n event.preventDefault();\n if (!validEmail(email)) {\n validate();\n return;\n }\n\n const availabilityDecision = availability === \"available\" ? \"available\" : await checkAvailability();\n if (availabilityDecision !== \"available\") return;\n if (!validate()) return;\n\n setAlert(null);\n setLoading(true);\n try {\n const response = await authRequest(\"/users\", {\n method: \"POST\",\n body: {\n user: {\n email,\n first_name: firstName,\n last_name: lastName,\n role,\n custom_role: role === \"other\" ? customRole : undefined,\n password,\n accepted_tos: acceptedTos,\n },\n },\n });\n if (response.status === \"sso_redirect\" && response.redirect_to) {\n window.location.assign(response.redirect_to);\n } else {\n window.location.assign(\"/users/confirmation/new\");\n }\n } catch (error) {\n if (error instanceof AuthApiError) {\n setErrors(error.fieldErrors);\n setAlert(error.message);\n if (error.code === \"registration_unavailable\") setAvailability(\"unavailable\");\n focusFirstAuthError(error.fieldErrors, SIGNUP_FIELD_IDS);\n } else {\n setAlert(\"Something went wrong. Try again.\");\n }\n } finally {\n setLoading(false);\n }\n };\n\n const continueWithSso = () => {\n setAlert(null);\n setSsoStarting(true);\n try {\n submitSamlSignInForm(email.trim().toLowerCase());\n } catch (_error) {\n setAlert(\"We couldn't start SSO. Refresh the page and try again.\");\n setSsoStarting(false);\n }\n };\n\n const showProfileFields = availability !== \"sso\";\n\n return (\n \n \n {\n if (emailEdited.current) {\n void checkAvailability();\n }\n }}\n onChange={(event) => {\n const nextEmail = event.target.value;\n emailEdited.current = true;\n latestEmail.current = nextEmail;\n setEmail(nextEmail);\n if (validEmail(nextEmail)) clearFieldError(\"email\");\n if (availabilityRequest.current?.email !== nextEmail.trim().toLowerCase()) {\n setAvailability(\"unchecked\");\n setAlert(null);\n }\n }}\n />\n {availability === \"sso\" && (\n : undefined}\n onClick={continueWithSso}\n >\n Continue with SSO\n \n )}\n {showProfileFields && (\n <>\n {\n if (!firstName.trim()) setFieldError(\"first_name\", \"Enter your first name.\");\n }}\n onChange={(event) => {\n const nextFirstName = event.target.value;\n setFirstName(nextFirstName);\n if (nextFirstName.trim()) clearFieldError(\"first_name\");\n }}\n />\n {\n if (!lastName.trim()) setFieldError(\"last_name\", \"Enter your last name.\");\n }}\n onChange={(event) => {\n const nextLastName = event.target.value;\n setLastName(nextLastName);\n if (nextLastName.trim()) clearFieldError(\"last_name\");\n }}\n />\n {\n if (!role) setFieldError(\"role\", \"Select your role.\");\n }}\n onChange={(nextRole) => {\n setRole(nextRole);\n clearFieldError(\"role\");\n if (nextRole !== \"other\") {\n setCustomRole(\"\");\n clearFieldError(\"custom_role\");\n }\n }}\n />\n {role === \"other\" && (\n {\n if (!customRole.trim()) setFieldError(\"custom_role\", \"Enter your role.\");\n }}\n onChange={(event) => {\n const nextCustomRole = event.target.value;\n setCustomRole(nextCustomRole);\n if (nextCustomRole.trim()) clearFieldError(\"custom_role\");\n }}\n />\n )}\n setPasswordFocused(true)}\n onBlur={() => {\n setPasswordFocused(false);\n if (!passwordIsValid(password)) {\n setFieldError(\"password\", \"Your password must meet every requirement.\");\n }\n }}\n onChange={(event) => {\n const nextPassword = event.target.value;\n setPassword(nextPassword);\n if (passwordIsValid(nextPassword)) clearFieldError(\"password\");\n }}\n />\n {\n if (!acceptedTos) setFieldError(\"accepted_tos\", \"You must accept the Terms of Service.\");\n }}\n onChange={(checked) => {\n setAcceptedTos(checked);\n if (checked) clearFieldError(\"accepted_tos\");\n }}\n />\n \n Sign up\n \n \n )}\n \n \n Already registered? Log in.\n \n \n );\n};\n", "export const hardNavigate = (path: string) => window.location.assign(path);\n", "import React, { useRef, useState } from \"react\";\nimport { Typography } from \"@mui/material\";\n\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport {\n AuthFooter,\n AuthForm,\n AuthLink,\n AuthPage,\n AuthSubmitButton,\n AuthTextField,\n PasswordField,\n passwordIsValid,\n} from \"./AuthComponents\";\nimport { AuthApiError, authRequest, firstFieldError, validEmail } from \"./authApi\";\nimport * as authNavigation from \"./authNavigation\";\nimport { handOffToSso } from \"./LoginPages\";\n\ninterface PasswordEmailRequestPageProps {\n title: string;\n description?: string;\n submitLabel: string;\n}\n\nconst PasswordEmailRequestPage = ({ title, description, submitLabel }: PasswordEmailRequestPageProps) => {\n const emailEdited = useRef(false);\n const [email, setEmail] = useState(\"\");\n const [emailError, setEmailError] = useState();\n const [alert, setAlert] = useState(null);\n const [loading, setLoading] = useState(false);\n\n const submit = async (event: React.FormEvent) => {\n event.preventDefault();\n const submittedEmail = String(new FormData(event.currentTarget as HTMLFormElement).get(\"email\") || email);\n setEmail(submittedEmail);\n if (!validEmail(submittedEmail)) {\n setEmailError(\"Enter a valid email address.\");\n window.setTimeout(() => document.getElementById(\"forgot-password-email\")?.focus(), 0);\n return;\n }\n\n setEmailError(undefined);\n setAlert(null);\n setLoading(true);\n let navigationStarted = false;\n try {\n const response = await authRequest(\"/users/password\", {\n method: \"POST\",\n body: { user: { email: submittedEmail } },\n });\n window.location.assign(response.redirect_to || \"/users/password/requested\");\n } catch (error) {\n if (error instanceof AuthApiError && error.code === \"sso_required\") {\n navigationStarted = handOffToSso(submittedEmail, setAlert);\n } else {\n setAlert(error instanceof AuthApiError ? error.message : \"Something went wrong. Try again.\");\n }\n } finally {\n if (!navigationStarted) setLoading(false);\n }\n };\n\n return (\n \n {description && (\n \n {description}\n \n )}\n \n {\n if (emailEdited.current) {\n setEmailError(!validEmail(email) ? \"Enter a valid email address.\" : undefined);\n }\n }}\n onChange={(event) => {\n const nextEmail = event.target.value;\n emailEdited.current = true;\n setEmail(nextEmail);\n if (emailError && validEmail(nextEmail)) setEmailError(undefined);\n }}\n />\n {submitLabel}\n \n \n Back to login\n \n \n );\n};\n\nexport const ForgotPasswordPage = () => ;\n\nexport const ExpiredResetLinkPage = () => (\n \n);\n\nexport const PasswordRequestedPage = () => (\n \n \n If your account is associated with this email address, you will receive an email to reset your password.\n \n \n Back to login\n \n \n);\n\nexport const ResetPasswordPage = () => {\n const token = new URLSearchParams(window.location.search).get(\"reset_password_token\") || \"\";\n const username = document.getElementById(\"password-reset-context\")?.dataset.username || \"\";\n const [password, setPassword] = useState(\"\");\n const [focused, setFocused] = useState(false);\n const [fieldErrors, setFieldErrors] = useState>({});\n const [alert, setAlert] = useState(null);\n const [expired, setExpired] = useState(!token);\n const [loading, setLoading] = useState(false);\n\n const showExpiredLinkPage = () => {\n setPassword(\"\");\n window.history.replaceState({}, \"\", \"/users/password/expired\");\n setExpired(true);\n };\n\n const submit = async (event: React.FormEvent) => {\n event.preventDefault();\n if (!token) return;\n if (!passwordIsValid(password)) {\n setFieldErrors({ password: [\"Your password must meet every requirement.\"] });\n window.setTimeout(() => document.getElementById(\"new-password\")?.focus(), 0);\n return;\n }\n\n setFieldErrors({});\n setAlert(null);\n setLoading(true);\n try {\n const response = await authRequest(\"/users/password\", {\n method: \"PATCH\",\n body: { user: { reset_password_token: token, password } },\n });\n window.location.assign(response.redirect_to || \"/\");\n } catch (error) {\n if (error instanceof AuthApiError) {\n if (error.code === \"invalid_authenticity_token\") {\n authNavigation.hardNavigate(\"/users/password/expired\");\n return;\n }\n\n if (error.code === \"reset_token_invalid\" || firstFieldError(error.fieldErrors, \"reset_password_token\")) {\n showExpiredLinkPage();\n return;\n }\n\n setFieldErrors(error.fieldErrors);\n setAlert(error.message);\n } else {\n setAlert(\"Something went wrong. Try again.\");\n }\n } finally {\n setLoading(false);\n }\n };\n\n if (expired) return ;\n\n return (\n \n \n \n setFocused(true)}\n onBlur={() => setFocused(false)}\n onChange={(event) => setPassword(event.target.value)}\n />\n \n Update password\n \n \n \n );\n};\n", "import React, { useEffect, useState } from \"react\";\nimport { CircularProgress, Stack, Typography } from \"@mui/material\";\n\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { AuthPage } from \"./AuthComponents\";\nimport { AuthApiError, authRequest } from \"./authApi\";\n\nexport const VerifyEmailPage = () => {\n const [email, setEmail] = useState();\n const [alert, setAlert] = useState(null);\n const [notice, setNotice] = useState(null);\n const [loading, setLoading] = useState(true);\n const [resending, setResending] = useState(false);\n\n useEffect(() => {\n authRequest(\"/users/confirmation/new\")\n .then((response) => setEmail(response.email))\n .catch((error) => setAlert(error instanceof AuthApiError ? error.message : \"Something went wrong.\"))\n .finally(() => setLoading(false));\n }, []);\n\n const resend = async () => {\n if (!email || resending) return;\n setAlert(null);\n setNotice(null);\n setResending(true);\n try {\n await authRequest(\"/users/confirmation\", { method: \"POST\", body: { user: { email } } });\n setNotice(\"Verification email sent.\");\n } catch (error) {\n setAlert(error instanceof AuthApiError ? error.message : \"Something went wrong. Try again.\");\n } finally {\n setResending(false);\n }\n };\n\n return (\n \n {loading ? (\n \n \n \n ) : (\n <>\n \n {email\n ? `We sent an email to ${email}. Click the link in the email to verify your account.`\n : \"Open the verification email we sent and click its link to verify your account.\"}\n \n \n {resending ? \"Sending\u2026\" : \"Resend email\"}\n \n \n )}\n \n );\n};\n\nexport const EmailVerificationResultPage = () => {\n const [result, setResult] = useState<\"verified\" | \"invalid\">();\n\n useEffect(() => {\n authRequest(\"/users/confirmation/result\")\n .then((response) => setResult(response.result || \"invalid\"))\n .catch(() => setResult(\"invalid\"));\n }, []);\n\n if (!result) {\n return (\n \n \n \n \n \n );\n }\n\n const verified = result === \"verified\";\n return (\n \n \n {verified ? \"You can now close this window.\" : \"This verification link is invalid or has already been used.\"}\n \n \n Return to Bench IQ\n \n \n );\n};\n", "import React, { useEffect, useState } from \"react\";\nimport { CircularProgress, Stack } from \"@mui/material\";\n\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\n\nimport {\n AuthFooter,\n AuthForm,\n AuthLink,\n AuthPage,\n AuthSubmitButton,\n AuthTermsAcceptance,\n AuthTextField,\n PasswordField,\n passwordIsValid,\n RoleSelect,\n} from \"./AuthComponents\";\nimport { AuthApiError, authRequest, firstFieldError, focusFirstAuthError } from \"./authApi\";\nimport { handOffToSso } from \"./LoginPages\";\n\nconst INVITATION_FIELD_IDS = {\n first_name: \"invitation-first-name\",\n last_name: \"invitation-last-name\",\n role: \"invitation-role\",\n custom_role: \"invitation-custom-role\",\n password: \"new-password\",\n accepted_tos: \"invitation-accepted-tos\",\n};\n\nexport const InvitationPage = () => {\n const token = new URLSearchParams(window.location.search).get(\"invitation_token\") || \"\";\n const [email, setEmail] = useState(\"\");\n const [firstName, setFirstName] = useState(\"\");\n const [lastName, setLastName] = useState(\"\");\n const [role, setRole] = useState(\"\");\n const [customRole, setCustomRole] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [acceptedTos, setAcceptedTos] = useState(false);\n const [passwordFocused, setPasswordFocused] = useState(false);\n const [fieldErrors, setFieldErrors] = useState>({});\n const [alert, setAlert] = useState(token ? null : \"This invitation link is invalid or has expired.\");\n const [loading, setLoading] = useState(Boolean(token));\n const [submitting, setSubmitting] = useState(false);\n const [ssoRequired, setSsoRequired] = useState(false);\n const [ssoStarting, setSsoStarting] = useState(false);\n\n useEffect(() => {\n if (!token) return;\n authRequest(\"/users/invitation/accept\", { headers: { Authorization: `Bearer ${token}` } })\n .then((response) => {\n setEmail(response.email || \"\");\n setSsoRequired(response.status === \"sso_required\");\n setFirstName(response.first_name || \"\");\n setLastName(response.last_name || \"\");\n setRole(response.role || \"\");\n setCustomRole(response.custom_role || \"\");\n })\n .catch((error) => setAlert(error instanceof AuthApiError ? error.message : \"This invitation is unavailable.\"))\n .finally(() => setLoading(false));\n }, [token]);\n\n const submit = async (event: React.FormEvent) => {\n event.preventDefault();\n const nextErrors: Record = {};\n if (!firstName.trim()) nextErrors.first_name = [\"Enter your first name.\"];\n if (!lastName.trim()) nextErrors.last_name = [\"Enter your last name.\"];\n if (!role) nextErrors.role = [\"Select your role.\"];\n if (role === \"other\" && !customRole.trim()) nextErrors.custom_role = [\"Enter your role.\"];\n if (!passwordIsValid(password)) nextErrors.password = [\"Your password must meet every requirement.\"];\n if (!acceptedTos) nextErrors.accepted_tos = [\"You must accept the Terms of Service.\"];\n setFieldErrors(nextErrors);\n if (Object.keys(nextErrors).length > 0) {\n focusFirstAuthError(nextErrors, INVITATION_FIELD_IDS);\n return;\n }\n\n setAlert(null);\n setSubmitting(true);\n try {\n const response = await authRequest(\"/users/invitation/accept\", {\n method: \"PUT\",\n headers: { Authorization: `Bearer ${token}` },\n body: {\n user: {\n first_name: firstName,\n last_name: lastName,\n role,\n custom_role: role === \"other\" ? customRole : undefined,\n password,\n accepted_tos: acceptedTos,\n },\n },\n });\n window.location.assign(response.redirect_to || \"/\");\n } catch (error) {\n if (error instanceof AuthApiError) {\n setFieldErrors(error.fieldErrors);\n setAlert(error.message);\n focusFirstAuthError(error.fieldErrors, INVITATION_FIELD_IDS);\n } else {\n setAlert(\"Something went wrong. Try again.\");\n }\n } finally {\n setSubmitting(false);\n }\n };\n\n const continueWithSso = () => {\n setAlert(null);\n setSsoStarting(handOffToSso(email, setAlert));\n };\n\n return (\n \n {loading ? (\n \n \n \n ) : ssoRequired ? (\n : undefined}\n onClick={continueWithSso}\n >\n Continue with SSO\n \n ) : (\n \n \n \n setFirstName(event.target.value)}\n />\n setLastName(event.target.value)}\n />\n {\n setRole(nextRole);\n if (nextRole !== \"other\") setCustomRole(\"\");\n }}\n />\n {role === \"other\" && (\n setCustomRole(event.target.value)}\n />\n )}\n setPasswordFocused(true)}\n onBlur={() => setPasswordFocused(false)}\n onChange={(event) => setPassword(event.target.value)}\n />\n {\n setAcceptedTos(checked);\n setFieldErrors((current) => ({ ...current, accepted_tos: [] }));\n }}\n />\n \n Create account\n \n \n )}\n \n Already registered? Log in.\n \n \n );\n};\n", "export type McpOauthMode = \"autonomous\" | \"interactive\";\n\nexport interface McpOauthPermission {\n label: string;\n description: string;\n}\n\nexport interface McpOauthConsent {\n authorization_transaction_id: string;\n expires_in_seconds: number;\n consent_context: string;\n client_name: string;\n client_icon: string | null;\n verified: boolean;\n redirect_hostname: string;\n loopback_redirect: boolean;\n signed_in_email: string;\n account_name: string;\n requested_permissions: McpOauthPermission[];\n default_mode: McpOauthMode;\n reauthorization: boolean;\n existing_connection_mode: McpOauthMode | null;\n docket_connect_available: boolean;\n}\n\nexport type McpOauthErrorCode = \"authorization_expired\" | \"invalid_request\" | \"temporarily_unavailable\";\nconst MCP_OAUTH_ERROR_CODES: readonly McpOauthErrorCode[] = [\n \"authorization_expired\",\n \"invalid_request\",\n \"temporarily_unavailable\",\n];\n\nconst isMcpOauthErrorCode = (value: unknown): value is McpOauthErrorCode =>\n typeof value === \"string\" && MCP_OAUTH_ERROR_CODES.includes(value as McpOauthErrorCode);\n\nexport class McpOauthError extends Error {\n constructor(\n public readonly code: McpOauthErrorCode,\n message: string,\n public readonly retryable: boolean,\n ) {\n super(message);\n this.name = \"McpOauthError\";\n }\n}\n\nexport interface McpOauthDecision {\n authorizationTransactionId: string;\n consentContext: string;\n decision: \"allow\" | \"deny\";\n mode?: McpOauthMode;\n}\n\nconst csrfToken = (): string => document.querySelector(\"meta[name='csrf-token']\")?.content ?? \"\";\n\nexport const safeMcpOauthReturnTo = (search: string, origin: string): string => {\n const candidate = new URLSearchParams(search).get(\"return_to\");\n if (!candidate || !candidate.startsWith(\"/\") || candidate.startsWith(\"//\")) return \"/\";\n\n try {\n const parsed = new URL(candidate, origin);\n if (parsed.origin !== origin) return \"/\";\n if (parsed.pathname !== \"/oauth/authorize\" && !parsed.pathname.startsWith(\"/oauth/consent/\")) return \"/\";\n return `${parsed.pathname}${parsed.search}${parsed.hash}`;\n } catch {\n return \"/\";\n }\n};\n\nconst parseResponse = async (response: Response): Promise => {\n let body:\n | {\n error?: McpOauthErrorCode;\n error_description?: string;\n retryable?: boolean;\n }\n | T\n | undefined;\n try {\n if (typeof response.text === \"function\") {\n const text = await response.text();\n body = text ? JSON.parse(text) : undefined;\n } else {\n body = await response.json();\n }\n } catch {\n body = undefined;\n }\n if (!response.ok) {\n const failure = body as\n | {\n error?: McpOauthErrorCode;\n error_description?: string;\n retryable?: boolean;\n }\n | undefined;\n const serverCode = failure?.error;\n const recognizedCode = isMcpOauthErrorCode(serverCode);\n const code: McpOauthErrorCode = recognizedCode\n ? serverCode\n : response.status >= 500\n ? \"temporarily_unavailable\"\n : \"invalid_request\";\n const retryable = recognizedCode\n ? (failure?.retryable ?? code === \"temporarily_unavailable\")\n : response.status >= 500;\n const description =\n (recognizedCode ? failure?.error_description : undefined) ??\n (retryable\n ? \"Bench IQ can\u2019t connect right now. Try again in a moment.\"\n : \"This connection request is no longer valid.\");\n throw new McpOauthError(code, description, retryable);\n }\n if (body === undefined && typeof response.json === \"function\") body = await response.json();\n return body as T;\n};\n\nexport const fetchMcpOauthConsent = async (authorizationTransactionId: string): Promise => {\n const response = await fetch(\n `/api/mcp/oauth-authorization-transactions/${encodeURIComponent(authorizationTransactionId)}`,\n {\n method: \"GET\",\n credentials: \"same-origin\",\n headers: { Accept: \"application/json\" },\n },\n );\n return parseResponse(response);\n};\n\nexport const submitMcpOauthConsent = async (decision: McpOauthDecision): Promise<{ redirect_to: string }> => {\n const payload: Record = {\n authorization_transaction_id: decision.authorizationTransactionId,\n consent_context: decision.consentContext,\n decision: decision.decision,\n };\n if (decision.decision === \"allow\" && decision.mode) {\n payload.mode = decision.mode;\n }\n\n const response = await fetch(\n `/api/mcp/oauth-authorization-transactions/${encodeURIComponent(decision.authorizationTransactionId)}/decision`,\n {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"X-CSRF-Token\": csrfToken(),\n },\n body: JSON.stringify(payload),\n },\n );\n return parseResponse<{ redirect_to: string }>(response);\n};\n", "import React, { useState } from \"react\";\n\nimport useFetchHelpers from \"../../utils/fetchHelpers\";\nimport { AuthForm, AuthPage, AuthSubmitButton, AuthTermsAcceptance } from \"./AuthComponents\";\nimport { safeMcpOauthReturnTo } from \"../../api/mcpOAuth\";\n\nfunction TermsOfService() {\n const { fetchWithErrorHandling } = useFetchHelpers();\n\n const [acceptedTos, setAcceptedTos] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [alert, setAlert] = useState(null);\n\n const handleAcceptTermsOfService = async (event: React.FormEvent) => {\n event.preventDefault();\n if (!acceptedTos || isLoading) return;\n\n setAlert(null);\n setIsLoading(true);\n\n const fetchUrl = `/api/users/${window.currentUser.id}`;\n const options = {\n method: \"PUT\",\n body: { acceptedTos: true },\n suppressGlobalAlert: true,\n };\n\n try {\n await fetchWithErrorHandling(fetchUrl, options);\n window.location.href = safeMcpOauthReturnTo(window.location.search, window.location.origin);\n } catch (_error) {\n setAlert(\"We couldn't save your acceptance. Try again.\");\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n \n \n \n \n Accept\n \n \n \n );\n}\nexport default TermsOfService;\n", "import React, { useState } from \"react\";\n\nimport useFetchHelpers from \"../../utils/fetchHelpers\";\nimport { AuthForm, AuthPage, AuthSubmitButton, AuthTextField, RoleSelect } from \"./AuthComponents\";\nimport { safeMcpOauthReturnTo } from \"../../api/mcpOAuth\";\n\nexport default function ProfileSetup() {\n const { fetchWithErrorHandling } = useFetchHelpers();\n\n const [role, setRole] = useState(\"\");\n const [customRole, setCustomRole] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [alert, setAlert] = useState(null);\n\n const useCustomRole = role === \"other\";\n const canSubmit = Boolean(role) && (!useCustomRole || Boolean(customRole.trim()));\n\n const submit = async (event: React.FormEvent) => {\n event.preventDefault();\n if (!canSubmit || isLoading) return;\n\n setAlert(null);\n setIsLoading(true);\n\n const fetchUrl = `/api/users/${window.currentUser.id}`;\n const options = {\n method: \"PUT\",\n body: { role, customRole: useCustomRole ? customRole : undefined },\n suppressGlobalAlert: true,\n };\n\n try {\n await fetchWithErrorHandling(fetchUrl, options);\n window.location.href = safeMcpOauthReturnTo(window.location.search, window.location.origin);\n } catch (_error) {\n setAlert(\"We couldn't save your role. Try again.\");\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n \n \n {\n setRole(nextRole);\n if (nextRole !== \"other\") setCustomRole(\"\");\n }}\n />\n {useCustomRole && (\n setCustomRole(event.target.value)}\n />\n )}\n \n Continue\n \n \n \n );\n}\n", "import { alpha } from \"@mui/material/styles\";\nimport type { PaletteOptions } from \"@mui/material/styles\";\nimport { colors } from \"./tokens/colors\";\nimport { shadows } from \"./tokens/shadows\";\n\nconst PRIMARY_MAIN = colors.taupe[800]; // #2b2422\nconst SECONDARY_MAIN = colors.taupe[400]; // #aba09c\nconst ERROR_MAIN = colors.red[600]; // #e7000b\nconst WARNING_MAIN = colors.orange[600]; // #f54900\nconst INFO_MAIN = colors.sky[600]; // #0084d1\nconst SUCCESS_MAIN = colors.teal[600]; // #009689\n\n// `NEUTRAL` is the brand's \"text/UI on light surface\" base. It's the source for\n// every neutral overlay in the palette: text.primary/secondary/tertiary, all\n// action.* states, common.black, divider derivations, etc. Figma exports these\n// as flattened rgba values (e.g., `rgba(43, 36, 34, 0.87)`); per the brand-flip\n// rule, code reconstructs them as `alpha(NEUTRAL, X)` so they auto-update if\n// taupe/800 ever shifts.\nconst NEUTRAL = colors.taupe[800]; // #2b2422\n\nexport const palette: PaletteOptions = {\n primary: {\n main: PRIMARY_MAIN,\n dark: colors.taupe[900],\n light: colors.taupe[300],\n contrastText: colors.white,\n _states: {\n hover: alpha(PRIMARY_MAIN, 0.04),\n selected: alpha(PRIMARY_MAIN, 0.08),\n focus: alpha(PRIMARY_MAIN, 0.12),\n focusVisible: alpha(PRIMARY_MAIN, 0.3),\n outlinedBorder: alpha(PRIMARY_MAIN, 0.5),\n },\n },\n secondary: {\n main: SECONDARY_MAIN,\n dark: colors.taupe[600],\n light: colors.taupe[100],\n contrastText: colors.white,\n _states: {\n hover: alpha(SECONDARY_MAIN, 0.04),\n selected: alpha(SECONDARY_MAIN, 0.08),\n focus: alpha(SECONDARY_MAIN, 0.12),\n focusVisible: alpha(SECONDARY_MAIN, 0.3),\n outlinedBorder: alpha(SECONDARY_MAIN, 0.5),\n },\n },\n error: {\n main: ERROR_MAIN,\n dark: colors.red[800],\n light: colors.red[100],\n contrastText: colors.white,\n _states: {\n hover: alpha(ERROR_MAIN, 0.04),\n selected: alpha(ERROR_MAIN, 0.08),\n focus: alpha(ERROR_MAIN, 0.12),\n focusVisible: alpha(ERROR_MAIN, 0.3),\n outlinedBorder: alpha(ERROR_MAIN, 0.5),\n },\n },\n warning: {\n main: WARNING_MAIN,\n dark: colors.orange[800],\n light: colors.orange[100],\n contrastText: colors.white,\n _states: {\n hover: alpha(WARNING_MAIN, 0.04),\n selected: alpha(WARNING_MAIN, 0.08),\n focus: alpha(WARNING_MAIN, 0.12),\n focusVisible: alpha(WARNING_MAIN, 0.3),\n outlinedBorder: alpha(WARNING_MAIN, 0.5),\n },\n },\n info: {\n main: INFO_MAIN,\n dark: colors.sky[800],\n light: colors.sky[100],\n contrastText: colors.white,\n _states: {\n hover: alpha(INFO_MAIN, 0.04),\n selected: alpha(INFO_MAIN, 0.08),\n focus: alpha(INFO_MAIN, 0.12),\n focusVisible: alpha(INFO_MAIN, 0.3),\n outlinedBorder: alpha(INFO_MAIN, 0.5),\n },\n },\n success: {\n main: SUCCESS_MAIN,\n dark: colors.teal[800],\n light: colors.teal[100],\n contrastText: colors.white,\n _states: {\n hover: alpha(SUCCESS_MAIN, 0.04),\n selected: alpha(SUCCESS_MAIN, 0.08),\n focus: alpha(SUCCESS_MAIN, 0.12),\n focusVisible: alpha(SUCCESS_MAIN, 0.3),\n outlinedBorder: alpha(SUCCESS_MAIN, 0.5),\n },\n },\n text: {\n primary: NEUTRAL,\n // 0.6 alpha matches Figma's `text/secondary` token (#2b242299). Was 0.7\n // pre-PR 2; dropped 10% for parity with the design source.\n secondary: alpha(NEUTRAL, 0.6),\n tertiary: alpha(NEUTRAL, 0.38),\n disabled: alpha(NEUTRAL, 0.38),\n icon: alpha(NEUTRAL, 0.6),\n _states: {\n hover: alpha(NEUTRAL, 0.04),\n selected: alpha(NEUTRAL, 0.08),\n focus: alpha(NEUTRAL, 0.12),\n focusVisible: alpha(NEUTRAL, 0.3),\n },\n },\n action: {\n active: alpha(NEUTRAL, 0.56),\n hover: alpha(NEUTRAL, 0.04),\n selected: alpha(NEUTRAL, 0.08),\n focus: alpha(NEUTRAL, 0.12),\n focusVisible: alpha(NEUTRAL, 0.3),\n disabled: alpha(NEUTRAL, 0.38),\n disabledBackground: alpha(NEUTRAL, 0.12),\n // \"Applied\" surface states \u2014 used by FilterButton's applied variant and\n // any other selected/active-filter affordance. Per Figma spec\n // (FilterButton frame, node 474-19945): resting maps directly to the\n // taupe scale; hover steps to taupe[300]; pressed/focused uses the same\n // base as resting at 80% opacity, matching the Phase 2 contained-button\n // pressed pattern (`alpha(primary.main, 0.8)`).\n applied: colors.taupe[200],\n appliedHover: colors.taupe[300],\n appliedActive: alpha(colors.taupe[200], 0.8),\n // LEGACY \u2014 Phase 2 chunk 2.1 visual sweep triage. See docs/design-system.md\n // \u2192 \"Legacy palette tokens \u2014 visual sweep triage list\".\n subdued: \"rgba(0, 0, 0, 0.60)\",\n },\n common: {\n black: NEUTRAL,\n white: colors.white,\n },\n // Component-scoped chip tokens. Sourced from the Figma `_components/chip/...`\n // variable set \u2014 a softer brand palette specifically for the chip surface,\n // distinct from the full color scales. Each variant has bg / bgHover /\n // bgFocus / bgDisabled and text / textDisabled. Consumed by BIQChip.\n chip: {\n default: {\n bg: colors.taupe[100],\n bgHover: colors.taupe[200],\n bgFocus: colors.taupe[200],\n bgDisabled: colors.taupe[50],\n text: colors.taupe[800],\n textDisabled: alpha(colors.taupe[800], 0.38),\n },\n info: {\n bg: colors.sky[100],\n bgHover: colors.sky[200],\n bgFocus: colors.sky[200],\n bgDisabled: colors.taupe[50],\n text: colors.sky[900],\n textDisabled: alpha(colors.taupe[800], 0.38),\n },\n // Success uses the teal scale (Figma `_components/chip/success`), matching\n // `success.main` (also teal as of the semantic-token update).\n success: {\n bg: colors.teal[100],\n bgHover: colors.teal[200],\n bgFocus: colors.teal[200],\n bgDisabled: colors.taupe[50],\n text: colors.teal[900],\n textDisabled: alpha(colors.taupe[800], 0.38),\n },\n warning: {\n bg: colors.orange[100],\n bgHover: colors.orange[200],\n bgFocus: colors.orange[200],\n bgDisabled: colors.taupe[50],\n text: colors.orange[900],\n textDisabled: alpha(colors.taupe[800], 0.38),\n },\n error: {\n bg: colors.red[100],\n bgHover: colors.red[200],\n bgFocus: colors.red[200],\n bgDisabled: colors.taupe[50],\n text: colors.red[900],\n textDisabled: alpha(colors.taupe[800], 0.38),\n },\n },\n background: {\n default: colors.taupe[50],\n paper: colors.white,\n hover: colors.taupe[100],\n hoverPressed: colors.taupe[200],\n // LEGACY \u2014 Phase 2 chunk 2.1 visual sweep triage. See docs/design-system.md\n // \u2192 \"Legacy palette tokens \u2014 visual sweep triage list\".\n subdued: \"#FAFAFA\",\n focused: \"rgba(224, 224, 224, 1)\",\n },\n divider: alpha(SECONDARY_MAIN, 0.5),\n\n // LEGACY \u2014 Phase 2 chunk 2.1 visual sweep triage. Decide post-flip whether to\n // retire, retain (with refreshed values), or remap callsites to new tokens.\n // See docs/design-system.md \u2192 \"Legacy palette tokens \u2014 visual sweep triage list\".\n benchBlue: {\n 50: \"#D2D9E0\",\n 100: \"#BCC6D1\",\n 200: \"#A6B3C1\",\n 300: \"#90A1B2\",\n 400: \"#798EA3\",\n 500: \"#637B93\",\n 600: \"#4D6884\",\n 700: \"#365574\",\n 800: \"#204265\",\n 900: \"#1D3B5B\",\n A100: \"\",\n A200: \"\",\n A400: \"\",\n A700: \"\",\n },\n // Canonical treatment for inline navigation. Keep these semantic so links\n // can evolve without coupling callsites to the raw taupe scale.\n link: {\n main: colors.taupe[800],\n hover: colors.taupe[900],\n },\n // Brand-warm amber for user highlights. Used by HighlightStyles.tsx (every\n // in transcripts + Clerk sessions).\n highlight: {\n main: colors.amber[100], // saved highlight background\n hover: colors.amber[200], // hover state for annotated highlights\n active: colors.amber[300], // active selection background\n },\n\n // System (search) highlights \u2014 rendered as an underline rather than a fill so\n // they stay legible when overlapping a user highlight's background. Used by\n // MatchMark / ActivePassageMark in Turn.tsx + Annotation.tsx, and mirrored in\n // .passage-highlight / .active-passage-highlight in application.css.\n systemHighlight: {\n main: colors.taupe[300], // resting search-match underline\n active: colors.indigo[600], // focus-flash underline (on the navigated passage)\n focusBackground: colors.indigo[100], // focus-flash background fill\n },\n\n // Snippet block styling shared by NoteItem (notes + notes panel) and\n // QueryResultCard's transcript excerpt block. Light taupe field, no border.\n snippet: {\n background: colors.taupe[100],\n },\n\n // Citation marker pill. Two variants per Figma (11266-5318): `primary` for\n // agent conversations (the cube symbol), `secondary` for overviews + result\n // cards (number). `text` is the resting content color (number text, or the\n // symbol color via currentColor); `activeText` applies on hover/press.\n // Primary is a filled indigo pill (visible against the white message surface);\n // hover/press deepens the fill and keeps an indigo-tinted lift shadow.\n // Secondary keeps the taupe\u2192indigo fill.\n citation: {\n primary: {\n // Filled indigo pill so the agent inline citation reads clearly against\n // the message surface (the old white card was near-invisible). The cube\n // symbol is indigo at rest; hover/press deepens the fill and keeps the\n // indigo-tinted lift shadow \u2014 the same hover treatment as the Home logo button.\n background: colors.indigo[50], // #eef2ff \u2014 resting fill\n hoverBackground: colors.indigo[100], // #e0e7ff\n pressedBackground: colors.indigo[100], // #e0e7ff\n text: colors.indigo[600], // #4f39f6 \u2014 cube symbol at rest\n activeText: colors.indigo[600], // #4f39f6 \u2014 cube symbol on hover/press\n restingShadow: shadows.base, // 0 1 3 / 0 1 2, taupe @ 10/6%\n // Hover/pressed: the brand indigo lift, shared with the Home logo button.\n activeShadow: shadows.mdAccent,\n },\n secondary: {\n background: colors.taupe[100], // #f3f1f1\n hoverBackground: colors.indigo[50], // #eef2ff\n pressedBackground: colors.indigo[100], // #e0e7ff\n text: colors.taupe[400], // secondary.main #aba09c (number, enabled)\n activeText: colors.indigo[600], // #4f39f6 on hover/press\n },\n },\n\n // Brand accent \u2014 used as the BIQ logo vector color.\n brand: {\n accent: colors.indigo[600],\n },\n\n // System-wide focus ring color \u2014 used for keyboard-focus outlines on\n // interactive surfaces (chips, buttons, links). Same hex as `brand.accent`\n // by design but kept under its own semantic key so callsites read clearly.\n focus: {\n ring: colors.indigo[600],\n },\n\n // Folder chip styling \u2014 used by FolderChipRow on transcripts and Clerk\n // sessions. Light taupe field with a slightly darker hover state.\n // Agent prototype user message bubble. Light taupe field, no border.\n userbubble: {\n background: colors.taupe[100],\n },\n};\n", "import type { TypographyVariantsOptions } from \"@mui/material/styles\";\n\n// Per-variant typography spec landed from the Phase 2 Figma export.\n// Source: `/Users/lailee/Downloads/type.json` (Klim \"Test\" prefix dropped to\n// match our self-hosted @font-face declarations in `theme/fonts.ts`).\n//\n// Resolved Figma-spec gaps:\n// - lineHeight tokens S/M/L \u2192 1.2 / 1.5 / 1.6 (per designer; L tightened from\n// 1.75 to 1.6 during visual sweep)\n// - letterSpacing \u2014 Figma silent; MUI defaults persist per-variant\n// - h6 \u2014 not in spec; dropped from theme (callsites migrated to h4).\n// - h5 \u2014 dropped in Phase 2, re-introduced below as the Tiempos section-title\n// variant (examination dividers + sticky header) per a later Figma spec.\n// - button / overline \u2014 not in spec; left at MUI defaults + global S\u00F6hne cascade.\n\nconst SOHNE = '\"S\u00F6hne\", sans-serif';\nconst SOHNE_MONO = '\"S\u00F6hne Mono\", monospace';\nconst TIEMPOS = '\"Tiempos Headline\", serif';\n\nexport const typography: TypographyVariantsOptions = {\n fontFamily: SOHNE,\n\n // Display headings \u2014 Tiempos Headline\n h1: { fontFamily: TIEMPOS, fontSize: \"3rem\", fontWeight: 400, lineHeight: 1.2 },\n h2: { fontFamily: TIEMPOS, fontSize: \"2.5rem\", fontWeight: 400, lineHeight: 1.2 },\n h3: { fontFamily: TIEMPOS, fontSize: \"1.5rem\", fontWeight: 400, lineHeight: 1.2 },\n\n // UI heading \u2014 S\u00F6hne (also receives all h6 callsite migrations)\n h4: { fontFamily: SOHNE, fontSize: \"1.25rem\", fontWeight: 500, lineHeight: 1.3 },\n\n // Section title \u2014 Tiempos Headline. Used by the transcript-body examination\n // dividers (ExaminationSection) and the sticky-header title block. Figma\n // spec: _fontSize/1.25rem \u00B7 Test Tiempos Headline \u00B7 _fontWeight/Regular.\n // lineHeight 1.2 matches the other Tiempos headline variants (h1\u2013h3).\n h5: { fontFamily: TIEMPOS, fontSize: \"1.25rem\", fontWeight: 400, lineHeight: 1.2 },\n\n // Section labels.\n // Deferred: Figma spec is lineHeight 1.3 for both subtitle1 and subtitle2;\n // they're 1.5 today. Don't fix in feature PRs \u2014 pre-release visual-sweep PR\n // will land the change together with a full screenshot diff across every\n // subtitle{1,2} callsite.\n subtitle1: { fontFamily: SOHNE, fontSize: \"1rem\", fontWeight: 500, lineHeight: 1.5 },\n subtitle2: { fontFamily: SOHNE, fontSize: \"0.875rem\", fontWeight: 500, lineHeight: 1.5 },\n\n // Body\n body1: { fontFamily: SOHNE, fontSize: \"1rem\", fontWeight: 400, lineHeight: 1.6 },\n body2: { fontFamily: SOHNE, fontSize: \"0.875rem\", fontWeight: 400, lineHeight: 1.6 },\n\n // Metadata. Figma's Caption token uses 12px / 1.4 with no tracking.\n caption: { fontFamily: SOHNE, fontSize: \"0.75rem\", fontWeight: 400, lineHeight: 1.4, letterSpacing: 0 },\n\n // Code / numeric \u2014 new custom variant\n mono: { fontFamily: SOHNE_MONO, fontSize: \"0.75rem\", fontWeight: 400, lineHeight: 1.5 },\n\n // Button text \u2014 drop MUI's default `textTransform: uppercase` per brand spec\n // and lock letterSpacing to 0.5px across all sizes (Phase 2 brand decision \u2014\n // Figma frame had three different values per size; product designer chose to\n // unify at 0.5px). fontSize and lineHeight still inherit per-size MUI\n // defaults (Large 0.9375rem, Medium 0.875rem, Small 0.8125rem \u2014 all match\n // Figma). Cascades to \n);\n\nexport default HomeLogoButton;\n", "import type { LucideIcon } from \"lucide-react\";\nimport { Blocks, Folders, Highlighter, History, Plus, Star, StickyNote } from \"lucide-react\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { isCreditBillingLive } from \"@/utils/creditBilling\";\nimport { CREDIT_MATTER_LAUNCH_QUERY_PARAM } from \"@/utils/creditMatterLaunch\";\nimport { featureEnabled, isClerkAvailable } from \"@/utils/featureFlags\";\nimport { useLocation, useNavigate } from \"@/utils/urlHelpers\";\n\nexport type SideNavItemId =\n | \"folders\"\n | \"notes\"\n | \"starred\"\n | \"history\"\n | \"new_clerk_session\"\n | \"connected_apps_settings\";\n\nexport interface SideNavModelItem {\n id: SideNavItemId;\n icon: LucideIcon;\n label: string;\n active?: boolean;\n disabled?: boolean;\n onClick: () => void;\n}\n\nexport interface SideNavModel {\n beforeDivider: SideNavModelItem[];\n afterDivider: SideNavModelItem[];\n bottomItems: SideNavModelItem[];\n goHome: () => void;\n user: { name: string; email: string };\n}\n\n/**\n * The product-policy layer shared by the legacy and expandable renderers.\n * Visual components must consume this model rather than duplicating route,\n * eligibility, analytics, or attribution decisions.\n */\nexport const useSideNavModel = (): SideNavModel => {\n const navigate = useNavigate();\n const location = useLocation();\n const clerkAvailable = isClerkAvailable();\n const hasFoldersAndAnnotations = featureEnabled(\"folders_and_annotations\");\n const isHighlightNoteTakingDisabled = featureEnabled(\"disable_highlight_note_taking\");\n const historyPath = clerkAvailable ? \"/history\" : \"/activity-history\";\n\n const trackNav = (item: SideNavItemId) => {\n void recordUserEvent({ event_name: \"sidebar_nav_clicked\", event_properties: { nav_item: item } });\n };\n\n const isActive = (path: string): boolean => {\n if (path === \"/\") return location.pathname === \"/\";\n return location.pathname === path || location.pathname.startsWith(`${path}/`);\n };\n\n const goTo = (path: string, search?: string) => navigate({ pathname: path, ...(search ? { search } : {}) });\n\n const beforeDivider: SideNavModelItem[] = [];\n if (clerkAvailable) {\n beforeDivider.push({\n id: \"new_clerk_session\",\n icon: Plus,\n label: \"New session\",\n onClick: () => {\n trackNav(\"new_clerk_session\");\n if (isCreditBillingLive()) {\n goTo(\"/\", `?${CREDIT_MATTER_LAUNCH_QUERY_PARAM}=session`);\n } else {\n goTo(\"/agent\");\n }\n },\n });\n }\n\n if (hasFoldersAndAnnotations) {\n beforeDivider.push(\n {\n id: \"folders\",\n icon: Folders,\n label: \"Folders\",\n active: isActive(\"/folders\"),\n onClick: () => {\n trackNav(\"folders\");\n goTo(\"/folders\", \"?from=sidebar\");\n },\n },\n {\n id: \"notes\",\n icon: isHighlightNoteTakingDisabled ? Highlighter : StickyNote,\n label: isHighlightNoteTakingDisabled ? \"Highlights\" : \"Notes\",\n active: isActive(\"/notes\"),\n onClick: () => {\n trackNav(\"notes\");\n goTo(\"/notes\", \"?from=sidebar\");\n },\n },\n );\n }\n\n const afterDivider: SideNavModelItem[] = [];\n if (hasFoldersAndAnnotations) {\n afterDivider.push({\n id: \"starred\",\n icon: Star,\n label: \"Starred\",\n active: isActive(\"/starred\"),\n onClick: () => {\n trackNav(\"starred\");\n goTo(\"/starred\", \"?from=sidebar\");\n },\n });\n }\n afterDivider.push({\n id: \"history\",\n icon: History,\n label: clerkAvailable ? \"History\" : \"Activity History\",\n active: isActive(historyPath),\n disabled: !clerkAvailable && featureEnabled(\"incognito_queries\"),\n onClick: () => {\n if (clerkAvailable) trackNav(\"history\");\n goTo(historyPath);\n },\n });\n\n const bottomItems: SideNavModelItem[] = [];\n if (window.mcpConnectedAppsVisible === true) {\n bottomItems.push({\n id: \"connected_apps_settings\",\n icon: Blocks,\n label: \"Settings\",\n active: isActive(\"/settings\"),\n onClick: () => {\n trackNav(\"connected_apps_settings\");\n goTo(\"/settings/connected-apps\");\n },\n });\n }\n\n const firstName = window.currentUser?.first_name?.trim();\n const lastName = window.currentUser?.last_name?.trim();\n return {\n beforeDivider,\n afterDivider,\n bottomItems,\n goHome: () => goTo(\"/\"),\n user: {\n name: [firstName, lastName].filter(Boolean).join(\" \") || window.currentUser?.email || \"Account\",\n email: window.currentUser?.email || \"\",\n },\n };\n};\n", "import React, { useState } from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport Divider from \"@mui/material/Divider\";\nimport Menu from \"@mui/material/Menu\";\nimport MenuItem from \"@mui/material/MenuItem\";\nimport { LogOut, ScrollText } from \"lucide-react\";\nimport { styled } from \"@/utils/styled\";\nimport handleSignOut from \"@/utils/handleSignOut\";\nimport TermsOfServiceModal from \"../molecules/TermsOfServiceModal\";\nimport { layout } from \"../theme/tokens/layout\";\nimport { NavItem } from \"./NavItem\";\nimport { HomeLogoButton } from \"./HomeLogoButton\";\nimport { useSideNavModel } from \"./useSideNavModel\";\n\n/**\n * SideNav \u2014 left rail (Figma node 44:13589). Replaces today's `SideBar.tsx`.\n *\n * Structure (matches Figma exactly):\n * SideNav (flex-col, gap-24, items-center, px-8 py-12, w-56, bg/default, border-right)\n * \u251C\u2500\u2500 HomeLogo 40\u00D740, rounded-10, navigates to /\n * \u251C\u2500\u2500 TopMenu (gap-8)\n * \u2502 \u251C\u2500\u2500 NavItem(plus) \u2014 \"New session\" \u2192 Home launch flow for credit accounts, /agent otherwise\n * \u2502 \u251C\u2500\u2500 NavItem(folders) \u2014 \"/folders\" (flag-gated)\n * \u2502 \u251C\u2500\u2500 NavItem(sticky-note/highlighter) \u2014 \"Notes\"/\"Highlights\" \u2192 /notes (flag-gated)\n * \u2502 \u251C\u2500\u2500 Divider \u2014 1px line, py-4\n * \u2502 \u251C\u2500\u2500 NavItem(star) \u2014 \"Starred\" \u2192 /starred (flag-gated)\n * \u2502 \u2514\u2500\u2500 NavItem(history) \u2014 \"/history\" or \"/activity-history\"\n * \u2514\u2500\u2500 BottomMenu (flex-1, justify-end, gap-8)\n * \u251C\u2500\u2500 NavItem(scroll-text) \u2014 Policies dropdown menu\n * \u2514\u2500\u2500 NavItem(log-out) \u2014 handleSignOut\n *\n * The active NavItem's indicator pill is a shared `motion.div` with\n * `layoutId=\"sidenav-active\"` \u2014 see NavItem.tsx for the layout-FLIP animation.\n *\n * Behavior preserved 1:1 from the legacy `SideBar.tsx`:\n * - Clerk-gated: plus disabled when Clerk unavailable; history routes to\n * `/history` when available else `/activity-history` (also disabled when\n * `incognito_queries` flag is on AND Clerk is off)\n * - folders / sticky-note / star only render when `folders_and_annotations` is on\n * - Analytics: each navigation tracks a `sidebar_nav_clicked` userEvent\n * - Policies + Logout are page-level overlays anchored to the rail\n */\n\nconst Rail = styled(Box)`\n display: flex;\n flex-direction: column;\n align-items: center;\n width: ${layout.railWidth}px;\n height: 100%;\n gap: ${({ theme }) => theme.tokens.spacing[6]}px;\n padding: ${({ theme }) => theme.tokens.spacing[3]}px ${({ theme }) => theme.tokens.spacing[2]}px;\n background: ${({ theme }) => theme.palette.background.default};\n /* No border-right here \u2014 AppShell.RailSlot owns the right border so the\n wrapper / content layers don't both draw at the same pixel column\n (mirrors the SidePanel pattern where SidePanelMotion owns the divider\n and ReaderLayout doesn't). */\n box-sizing: border-box;\n`;\n\nconst Group = styled(Box)`\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: ${({ theme }) => theme.tokens.spacing[2]}px;\n flex-shrink: 0;\n width: 100%;\n`;\n\nconst BottomGroup = styled(Group)`\n flex: 1 0 0;\n justify-content: flex-end;\n min-height: 0;\n`;\n\nconst DividerWrap = styled(Box)`\n padding: ${({ theme }) => theme.tokens.spacing[1]}px 0;\n width: calc(100% - ${({ theme }) => theme.tokens.spacing[2] * 2}px);\n`;\n\nexport const SideNav: FC = () => {\n const model = useSideNavModel();\n\n const [policiesAnchor, setPoliciesAnchor] = useState(null);\n const [showTermsModal, setShowTermsModal] = useState(false);\n\n return (\n <>\n \n \n\n \n {model.beforeDivider.map((item) => (\n \n ))}\n\n \n \n \n\n {model.afterDivider.map((item) => (\n \n ))}\n \n\n \n {model.bottomItems.map((item) => (\n \n ))}\n setPoliciesAnchor(event.currentTarget)} />\n \n \n \n\n setPoliciesAnchor(null)}\n anchorOrigin={{ vertical: \"center\", horizontal: \"right\" }}\n transformOrigin={{ vertical: \"center\", horizontal: \"left\" }}\n >\n {\n window.location.href = \"https://benchiq.com/privacy-policy\";\n }}\n >\n Privacy Policy\n \n {\n setPoliciesAnchor(null);\n setShowTermsModal(true);\n }}\n >\n Terms of Service\n \n \n\n setShowTermsModal(false)} />\n \n );\n};\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport { styled } from \"@/utils/styled\";\n\n/**\n * StatusIcon \u2014 a fixed 24\u00D724 slot that centers a Recents status glyph (an `sm`\n * design-system icon or a StatusDot. Keeping every status in the same 24\u00D724\n * footprint means each SessionItem title starts on the same x.\n * Reusable wrapper \u2014 extend as new statuses appear.\n */\nexport const StatusIcon = styled(Box)`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n`;\n\ninterface StatusDotProps {\n /** Fill color \u2014 a theme palette path (\"primary.main\") or any CSS color. */\n color: string;\n /** Diameter in px. Defaults to 8. */\n size?: number;\n}\n\n/** StatusDot \u2014 a solid round status dot (default 8px), centered by StatusIcon. */\nexport const StatusDot: FC = ({ color, size = 8 }) => (\n \n);\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport { motion } from \"motion/react\";\nimport { CircleAlert, Hand } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport { styled } from \"@/utils/styled\";\nimport { colors } from \"../../theme/tokens/colors\";\nimport { StatusDot } from \"./StatusIcon\";\nimport type { SessionStatus } from \"./StatusIndicator\";\n\nexport type CollapsedRollupStatus = Exclude | null;\n\nconst STATUS_PRIORITY: Record = {\n read: 0,\n working: 1,\n error: 2,\n unread: 3,\n needs_input: 4,\n};\n\nexport const resolveCollapsedRollupStatus = (\n statuses: Array,\n): CollapsedRollupStatus => {\n const highest = statuses.reduce((current, status) => {\n if (!status || STATUS_PRIORITY[status] <= STATUS_PRIORITY[current ?? \"read\"]) return current;\n return status;\n }, null);\n return highest === \"read\" ? null : highest;\n};\n\nconst BadgeSlot = styled(Box)`\n position: absolute;\n top: ${({ theme }) => theme.tokens.spacing[0.5]}px;\n right: ${({ theme }) => theme.tokens.spacing[0.5]}px;\n width: ${({ theme }) => theme.tokens.spacing[3]}px;\n height: ${({ theme }) => theme.tokens.spacing[3]}px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: ${({ theme }) => theme.palette.secondary.main};\n background: ${({ theme }) => theme.palette.background.default};\n border-radius: ${({ theme }) => theme.tokens.radii.fullRadius}px;\n box-shadow: 0 0 0 ${({ theme }) => theme.tokens.spacing[0.5]}px ${({ theme }) => theme.palette.background.default};\n z-index: ${({ theme }) => theme.tokens.zIndex.raisedAbove};\n pointer-events: none;\n`;\n\nconst WorkingRoot = styled(Box)`\n position: relative;\n width: ${({ theme }) => theme.tokens.spacing[3]}px;\n height: ${({ theme }) => theme.tokens.spacing[3]}px;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst WorkingHalo = styled(motion.div)`\n position: absolute;\n inset: 0;\n border-radius: ${({ theme }) => theme.tokens.radii.fullRadius}px;\n background: ${({ theme }) => theme.palette.secondary.main};\n`;\n\nconst WorkingCore = styled(motion.div)`\n position: relative;\n width: ${({ theme }) => theme.tokens.spacing[2]}px;\n height: ${({ theme }) => theme.tokens.spacing[2]}px;\n border-radius: ${({ theme }) => theme.tokens.radii.fullRadius}px;\n background: ${({ theme }) => theme.palette.secondary.main};\n z-index: ${({ theme }) => theme.tokens.zIndex.raised};\n`;\n\nconst CompactWorkingPulse: FC = () => (\n \n \n \n \n);\n\ninterface CollapsedStatusRollupProps {\n status: CollapsedRollupStatus;\n}\n\nexport const CollapsedStatusRollup: FC = ({ status }) => {\n if (!status) return null;\n\n return (\n \n {status === \"needs_input\" && }\n {status === \"error\" && }\n {status === \"working\" && }\n {status === \"unread\" && }\n \n );\n};\n", "import React from \"react\";\nimport type { FC, ReactNode } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport ButtonBase from \"@mui/material/ButtonBase\";\nimport Typography from \"@mui/material/Typography\";\nimport { motion } from \"motion/react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { styled } from \"@/utils/styled\";\nimport { renderLucideOrNode } from \"@/components/icons\";\nimport { layout } from \"../theme/tokens/layout\";\nimport { spacing } from \"../theme/tokens/spacing\";\nimport { motion as motionPresets } from \"../theme/tokens/motion\";\nimport { CollapsedStatusRollup, type CollapsedRollupStatus } from \"./Recents/CollapsedStatusRollup\";\n\n/**\n * Leading icon-cell width = the collapsed rail's inner content width (railWidth\n * minus the panel's horizontal padding). Centering the icon here puts its centre\n * at 28px from the panel edge \u2014 identical to the collapsed rail \u2014 so icons don't\n * shift on expand.\n */\nexport const NAV_ICON_CELL = layout.expandableRailCollapsedWidth - 2 * spacing[2];\n\n/** Icon-button footprint (the 36\u00D736 hit area the active pill + hover states hug). */\nconst ICON_BUTTON = 36;\n\n/**\n * NavMenuRow \u2014 an expanded (labeled) nav row: a fixed icon cell aligned to the\n * collapsed rail's icon column, plus a `button/medium` label. The label starts at\n * the rail edge (56px) so the growing width clip-reveals it (no opacity fade).\n *\n * Hover / selected match the production `SideNav` `NavItem` exactly:\n * - no background fill; state is signalled by icon COLOUR\n * (rest `secondary.main` \u2192 hover `secondary.dark` \u2192 active `primary.main`)\n * - the selected item shows a `secondary._states.selected` pill that GLIDES\n * between items via a shared `layoutId` (motion layout animation).\n */\n\nconst Row = styled(ButtonBase)`\n position: relative;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: flex-start;\n /* No gap: the label sits directly after the icon cell (Figma 12192:5774), so it\n starts closer to the icon and lines up with the Recents session titles. In the\n collapsed rail the label overflows the 56px edge and peeks \u2014 the collapse\n transition fades it out (handled separately). */\n height: ${ICON_BUTTON}px;\n border-radius: ${({ theme }) => theme.tokens.radii.standardRadius}px;\n color: ${({ theme }) => theme.palette.secondary.main};\n\n /* Icon colour states (the lucide glyph inherits currentColor). No bg fill \u2014\n the active pill is the only background, matching NavItem. */\n &:hover:not([data-active=\"true\"]):not(:active) {\n color: ${({ theme }) => theme.palette.secondary.dark};\n }\n &:active,\n &[data-active=\"true\"] {\n color: ${({ theme }) => theme.palette.primary.main};\n }\n\n &.Mui-focusVisible {\n outline: 2px solid ${({ theme }) => theme.palette.secondary.dark};\n outline-offset: 1px;\n }\n`;\n\n// The gliding selected-indicator pill (shared layoutId \u2192 animates between rows).\n// It lives at the Row level so it can span the whole row (icon + label) when\n// expanded; in the collapsed rail it's sized/positioned to hug just the 36\u00D736\n// icon button (matching production NavItem). Sizing is set inline per state.\nconst ActiveBackground = styled(motion.div)`\n position: absolute;\n top: 0;\n bottom: 0;\n background: ${({ theme }) => theme.palette.secondary._states.selected};\n border-radius: ${({ theme }) => theme.tokens.radii.standardRadius}px;\n z-index: ${({ theme }) => theme.tokens.zIndex.base};\n pointer-events: none;\n`;\n\nconst IconCell = styled(Box)`\n position: relative;\n z-index: ${({ theme }) => theme.tokens.zIndex.raised};\n flex-shrink: 0;\n width: ${NAV_ICON_CELL}px;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst IconButtonSlot = styled(Box)`\n position: relative;\n width: ${ICON_BUTTON}px;\n height: ${ICON_BUTTON}px;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst IconGlyph = styled(Box)`\n position: relative;\n z-index: ${({ theme }) => theme.tokens.zIndex.raised};\n display: inline-flex;\n`;\n\nconst Label = styled(Typography)`\n position: relative;\n z-index: ${({ theme }) => theme.tokens.zIndex.raised};\n color: ${({ theme }) => theme.palette.text.primary};\n white-space: nowrap;\n /* Fade in on expand / out on collapse (opacity driven by showLabel). Slightly\n faster than the rail's 300ms width so the label is gone before the collapsed\n rail could show it peeking. */\n transition: opacity 180ms cubic-bezier(0.4, 0, 0.2, 1);\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n`;\n\ninterface NavMenuRowProps {\n icon: LucideIcon | ReactNode;\n label: string;\n active?: boolean;\n disabled?: boolean;\n /** When false, the label is faded out (collapsed rail). Defaults to true. */\n showLabel?: boolean;\n /** Highest-priority session status shown on the collapsed Chat/Recents icon. */\n statusRollup?: CollapsedRollupStatus;\n /** For rows that open a menu (e.g. the profile footer) \u2014 forwarded to the button. */\n ariaHasPopup?: React.AriaAttributes[\"aria-haspopup\"];\n ariaExpanded?: boolean;\n onPointerDown?: (event: React.PointerEvent) => void;\n onClick?: (event: React.MouseEvent) => void;\n}\n\nexport const NavMenuRow: FC = ({\n icon,\n label,\n active = false,\n disabled = false,\n showLabel = true,\n statusRollup = null,\n ariaHasPopup,\n ariaExpanded,\n onPointerDown,\n onClick,\n}) => {\n return (\n \n {active && !disabled && (\n \n )}\n \n \n {renderLucideOrNode(icon, \"md\")}\n \n \n \n \n \n );\n};\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport { motion } from \"motion/react\";\nimport { styled } from \"@/utils/styled\";\n\n/**\n * WorkingPulse \u2014 the \"agent still generating\" status glyph. A three-frame pulse\n * that loops (each segment is a 600ms ease-out):\n * 1. an 8px secondary.main core dot (same size as the unread dot)\n * 2. the dot beats larger \u2192 10px\n * 3. the dot returns to 8px while a `secondary.main` halo blooms out and fades\n *\n * Driven by `motion` so it inherits the app's global `MotionConfig\n * reducedMotion=\"user\"` \u2014 reduced-motion users get a static 8px dot.\n */\n\nconst Root = styled(Box)`\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n`;\n\n// The pulse ring \u2014 secondary.main, behind the core. 24px at scale 1; scale 0.33\n// \u2248 the 8px core, so it starts dot-sized and blooms outward.\nconst Halo = styled(motion.div)`\n position: absolute;\n inset: 0;\n border-radius: ${({ theme }) => theme.tokens.radii.fullRadius}px;\n background: ${({ theme }) => theme.palette.secondary.main};\n pointer-events: none;\n z-index: ${({ theme }) => theme.tokens.zIndex.base};\n`;\n\nconst Core = styled(motion.div)`\n position: relative;\n z-index: ${({ theme }) => theme.tokens.zIndex.raised};\n width: 8px;\n height: 8px;\n border-radius: ${({ theme }) => theme.tokens.radii.fullRadius}px;\n background: ${({ theme }) => theme.palette.secondary.main};\n`;\n\n// One 1200ms cycle = two 600ms ease-out beats.\nconst CYCLE = 1.2;\n\nexport const WorkingPulse: FC = () => (\n \n \n);\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport { CircleAlert, Dot, Hand } from \"lucide-react\";\nimport { Icon } from \"@/components/icons\";\nimport { colors } from \"../../theme/tokens/colors\";\nimport { StatusDot, StatusIcon } from \"./StatusIcon\";\nimport { WorkingPulse } from \"./WorkingPulse\";\n\n/** Status of a Recents session row. */\nexport type SessionStatus = \"working\" | \"unread\" | \"read\" | \"error\" | \"needs_input\";\n\n/**\n * StatusIndicator \u2014 the leading glyph on a SessionItem. A shared 24\u00D724 StatusIcon\n * slot centers each status (an sm/16px design-system icon or an 8px dot) so\n * every title starts on the same x:\n * - working \u2192 pulsing indigo dot (WorkingPulse)\n * - unread \u2192 8px indigo dot (StatusDot)\n * - read \u2192 decorative Dot, secondary.main\n * - error \u2192 CircleAlert, error.main\n * - needs_input \u2192 Hand, warning.main\n */\n\ninterface StatusIndicatorProps {\n status: SessionStatus;\n}\n\nexport const StatusIndicator: FC = ({ status }) => (\n \n {status === \"working\" && }\n {status === \"unread\" && }\n {status === \"read\" && }\n {status === \"error\" && }\n {status === \"needs_input\" && }\n \n);\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport ButtonBase from \"@mui/material/ButtonBase\";\nimport Typography from \"@mui/material/Typography\";\nimport { EllipsisVertical } from \"lucide-react\";\nimport { styled } from \"@/utils/styled\";\nimport { BIQIconButton } from \"../../atoms/BIQIconButton\";\nimport { colors } from \"../../theme/tokens/colors\";\nimport { StatusIndicator, type SessionStatus } from \"./StatusIndicator\";\n\n/**\n * SessionItem \u2014 a single Recents row (Figma node 12026:1535).\n *\n * [StatusIndicator] Title\u2026 \u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026 [\u22EE on hover/selected]\n *\n * - Title is `body2` (matches the nav menu); unread is medium (500), read/error 400.\n * - Hover and selected share the same `taupe/100` fill. The fill lives on the\n * Root so hovering the (primary) kebab lights the WHOLE row, not just the\n * button area.\n * - The kebab overlays the row end (absolute) so the title width never shifts;\n * it reveals on row hover and stays visible for the selected row.\n *\n * Opening a session is what marks it read \u2014 StatusIndicator is driven by the\n * `status` prop from the data layer, never toggled here.\n */\n\nconst Root = styled(Box)`\n position: relative;\n width: 100%;\n border-radius: ${({ theme }) => theme.tokens.radii.standardRadius}px;\n\n /* Whole-row hover/selected fill \u2014 keyed off the Root so hovering the kebab\n (a sibling of the row button) still lights the entire row. */\n &:hover {\n background: ${colors.taupe[100]};\n }\n\n &[data-selected=\"true\"] {\n background: ${colors.taupe[100]};\n }\n\n /* Reveal the kebab and give it a solid fill matching the row's current\n background, so the faded title never shows through behind it. */\n &:hover [data-kebab] {\n opacity: 1;\n background: ${colors.taupe[100]};\n }\n\n &[data-selected=\"true\"] [data-kebab] {\n opacity: 1;\n background: ${colors.taupe[100]};\n }\n\n &:focus-within [data-kebab] {\n opacity: 1;\n background: ${colors.taupe[100]};\n }\n\n @media (hover: none), (pointer: coarse) {\n [data-kebab] {\n opacity: 1;\n }\n }\n`;\n\nconst RowButton = styled(ButtonBase)`\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: flex-start;\n /* px-8 py-6; 8px gap between the 24px status slot and title (Figma 12192:5774),\n so the title lines up with the nav-menu labels. */\n gap: ${({ theme }) => theme.tokens.spacing[2]}px;\n padding: ${({ theme }) => theme.tokens.spacing[1.5]}px ${({ theme }) => theme.tokens.spacing[2]}px;\n border-radius: ${({ theme }) => theme.tokens.radii.standardRadius}px;\n text-align: left;\n`;\n\n// Session title \u2014 body2, matching the rest of the nav menu labels. Long titles\n// use the same single-line ellipsis behavior as the History session list.\nconst Title = styled(Typography)<{ $unread: boolean }>`\n flex: 1;\n min-width: 0;\n color: ${({ theme }) => theme.palette.text.primary};\n /* Unread titles are medium (500); read/error are regular (400). */\n font-weight: ${({ $unread }) => ($unread ? 500 : 400)};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nconst Kebab = styled(Box)`\n position: absolute;\n top: 50%;\n right: ${({ theme }) => theme.tokens.spacing[1]}px;\n transform: translateY(-50%);\n opacity: 0;\n transition: opacity ${({ theme }) => theme.transitions.duration.shortest}ms;\n`;\n\ninterface SessionItemProps {\n /** Session title. Long titles use a one-line ellipsis. */\n title: string;\n status: SessionStatus;\n /** The currently-open session (persistent highlight + visible kebab). */\n selected?: boolean;\n /** Open the session. */\n onClick?: () => void;\n /** Open the row's overflow menu. */\n onKebabClick?: (event: React.MouseEvent) => void;\n}\n\nexport const SessionItem: FC = ({ title, status, selected = false, onClick, onKebabClick }) => (\n \n \n \n \n {title}\n \n \n \n {\n event.stopPropagation();\n onKebabClick?.(event);\n }}\n />\n \n \n);\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport { BIQButton } from \"../../atoms/BIQButton\";\n\n/**\n * ShowMoreButton \u2014 \"Show N more\" affordance under the Recents list. Reveals the\n * next page of sessions inline (the list scrolls when it runs out of vertical\n * space); it does not navigate. A small tertiary (text) design-system button,\n * left-aligned under the rows.\n */\n\ninterface ShowMoreButtonProps {\n /** How many more will be revealed (label reads \"Show N more\"). */\n count?: number;\n onClick?: () => void;\n disabled?: boolean;\n}\n\nexport const ShowMoreButton: FC = ({ count = 20, onClick, disabled }) => (\n \n Show {count} more\n \n);\n", "import React, { useEffect, useRef, useState } from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\nimport { styled } from \"@/utils/styled\";\nimport { colors } from \"../../theme/tokens/colors\";\nimport { SessionItem } from \"./SessionItem\";\nimport { ShowMoreButton } from \"./ShowMoreButton\";\nimport type { RecentSession } from \"./mockSessions\";\n\n/**\n * RecentsList \u2014 the expanded-nav Recents section: a \"RECENTS\" overline, the\n * session rows, and a \"Show N more\" affordance. Starts with `initialCount` rows;\n * once revealed, the preference survives nav unmounts, page navigation, and\n * reloads in the current tab while additional pages are loaded automatically.\n * A new tab/window starts truncated. The rows scroll within whatever height the\n * panel gives (no fixed max \u2014 the parent constrains it).\n *\n * The overline and \"Show more\" indent to the session-title column so the section\n * reads as a header/footer for the titles. // \u2B1C confirm alignment with designer\n */\n\nconst Root = styled(Box)`\n display: flex;\n flex-direction: column;\n min-height: 0;\n flex: 1 1 auto;\n`;\n\nconst SectionLabel = styled(Typography)`\n /* \"Recents\" section label \u2014 caption text style, secondary.main, indented to\n the session-item status column (px-8). 24px section gap sits above; 4px\n below, between the label and the list. */\n padding: 0 ${({ theme }) => theme.tokens.spacing[2]}px ${({ theme }) => theme.tokens.spacing[1]}px;\n color: ${({ theme }) => theme.palette.secondary.main};\n`;\n\nconst ScrollArea = styled(Box)`\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n /* Rows set their own width: 100%; keep the fit-content \"Show more\" button from\n stretching to the full column width. */\n align-items: flex-start;\n /* 2px between recent rows (and before \"Show more\"). */\n gap: ${({ theme }) => theme.tokens.spacing[0.5]}px;\n\n /* Match the app's global scrollbar (index.tsx GlobalStyles), which Storybook\n doesn't load \u2014 thin, taupe300 thumb \u2192 taupe400 on hover. */\n scrollbar-width: thin;\n scrollbar-color: ${colors.taupe[300]} transparent;\n &::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n }\n &::-webkit-scrollbar-track {\n background: transparent;\n }\n &::-webkit-scrollbar-thumb {\n background-color: ${colors.taupe[300]};\n border-radius: 4px;\n border: 2px solid transparent;\n background-clip: padding-box;\n }\n &::-webkit-scrollbar-thumb:hover {\n background-color: ${colors.taupe[400]};\n }\n`;\n\ninterface RecentsListProps {\n sessions: RecentSession[];\n /** id of the currently-open session (persistent highlight). */\n selectedId?: string;\n onOpen?: (id: string) => void;\n onSessionMenu?: (id: string, event: React.MouseEvent) => void;\n initialCount?: number;\n pageSize?: number;\n hasNextPage?: boolean;\n isFetchingNextPage?: boolean;\n error?: string | null;\n onLoadMore?: () => void;\n onRetry?: () => void;\n}\n\nexport const getRecentsRevealedStorageKey = () =>\n `expandable_sidenav_recents_revealed:${window.currentUser?.id ?? \"unknown\"}`;\n\nconst readRecentsRevealed = () => {\n try {\n return window.sessionStorage.getItem(getRecentsRevealedStorageKey()) === \"true\";\n } catch {\n return false;\n }\n};\n\nexport const RecentsList: FC = ({\n sessions,\n selectedId,\n onOpen,\n onSessionMenu,\n initialCount = 5,\n pageSize = 20,\n hasNextPage = false,\n isFetchingNextPage = false,\n error,\n onLoadMore,\n onRetry,\n}) => {\n const [revealed, setRevealed] = useState(readRecentsRevealed);\n const requestedAtSessionCount = useRef(null);\n const shown = revealed ? sessions : sessions.slice(0, initialCount);\n const remaining = sessions.length - shown.length;\n\n useEffect(() => {\n const syncRevealed = (event: StorageEvent) => {\n if (event.storageArea === window.sessionStorage && event.key === getRecentsRevealedStorageKey()) {\n setRevealed(event.newValue === \"true\");\n }\n };\n window.addEventListener(\"storage\", syncRevealed);\n return () => window.removeEventListener(\"storage\", syncRevealed);\n }, []);\n\n useEffect(() => {\n if (!revealed || !hasNextPage || isFetchingNextPage || !onLoadMore) return;\n if (requestedAtSessionCount.current === sessions.length) return;\n\n requestedAtSessionCount.current = sessions.length;\n onLoadMore();\n }, [hasNextPage, isFetchingNextPage, onLoadMore, revealed, sessions.length]);\n\n const revealAll = () => {\n setRevealed(true);\n try {\n window.sessionStorage.setItem(getRecentsRevealedStorageKey(), \"true\");\n } catch {\n // Keep the current tab responsive when browser storage is unavailable.\n }\n };\n\n return (\n \n Recents\n \n {shown.map((session) => (\n onOpen?.(session.id)}\n onKebabClick={(event) => onSessionMenu?.(session.id, event)}\n />\n ))}\n {error && (\n \n {error} \n \n )}\n {!revealed && (remaining > 0 || hasNextPage) && (\n \n )}\n \n \n );\n};\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport ListItemIcon from \"@mui/material/ListItemIcon\";\nimport MenuItem from \"@mui/material/MenuItem\";\nimport Typography from \"@mui/material/Typography\";\nimport type { SxProps, Theme } from \"@mui/material/styles\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { styled } from \"@/utils/styled\";\n\n/**\n * Shared building blocks for the account menu (Figma nodes 12186:5636 and\n * 12196:7440), including the capability-gated Connectors item.\n *\n * Layout: an 8px MenuList gutter so item hover + divider sit inset from the\n * paper edge; each item adds 8px more \u2192 16px content inset (Figma px-16).\n */\n\n// Paper surface \u2014 white, taupe200 hairline border, standardRadius, shadow/md,\n// clipped. `width` matches the anchor (the full-width profile button) so the\n// menu fits the sidenav frame.\nexport const accountMenuPaperSx = (width?: number): SxProps => ({\n width,\n bgcolor: \"background.paper\",\n border: (t) => `1px solid ${t.border.default}`,\n borderRadius: (t) => `${t.tokens.radii.standardRadius}px`,\n boxShadow: (t) => t.tokens.shadows.md,\n overflow: \"hidden\",\n});\n\n// MenuList padding: 8px all round (Figma py-8 + the side gutter).\nexport const accountMenuListSx: SxProps = { px: 1, py: 1 };\n\n// Divider between the account-menu groups (Figma node 12186:5643): a light\n// (taupe100) line, ~16px reserved height. `border.*` is a custom theme key, not\n// a palette color, so it's resolved via a callback.\nexport const accountMenuDividerSx: SxProps = { my: \"7.5px\", borderColor: (t) => t.border.light };\n\n// Email header row \u2014 caption / text.secondary, px16 py4 (Figma node 12186:5640).\nexport const AccountMenuEmail = styled(Typography)`\n display: block;\n padding: ${({ theme }) => theme.spacing(0.5)} ${({ theme }) => theme.spacing(1)};\n color: ${({ theme }) => theme.palette.text.secondary};\n`;\n\n// Item row: 34px tall, 16px content inset, rounded hover, 20px left icon in a\n// 36px slot, label in menu/itemDense (14/400/24lh/0.17ls, text.primary).\nconst rowSx: SxProps = {\n minHeight: 34,\n px: 1,\n py: 0.5,\n borderRadius: (t) => `${t.tokens.radii.standardRadius}px`,\n \"&:hover\": { backgroundColor: \"background.hover\" },\n};\n\nconst labelSx: SxProps = {\n fontSize: \"0.875rem\",\n lineHeight: \"24px\",\n letterSpacing: \"0.17px\",\n color: \"text.primary\",\n};\n\ninterface AccountMenuRowProps {\n icon: LucideIcon;\n label: string;\n onClick?: (event: React.MouseEvent) => void;\n disabled?: boolean;\n}\n\nexport const AccountMenuRow: FC = ({ icon: Icon, label, onClick, disabled }) => (\n \n \n \n \n \n {label}\n \n \n);\n", "import React, { useState } from \"react\";\nimport type { FC } from \"react\";\nimport Divider from \"@mui/material/Divider\";\nimport Menu from \"@mui/material/Menu\";\nimport { Blocks, LogOut, ScrollText, ShieldCheck } from \"lucide-react\";\nimport handleSignOut from \"@/utils/handleSignOut\";\nimport TermsOfServiceModal from \"../../molecules/TermsOfServiceModal\";\nimport {\n AccountMenuEmail,\n AccountMenuRow,\n accountMenuDividerSx,\n accountMenuListSx,\n accountMenuPaperSx,\n} from \"./accountMenuParts\";\n\n/**\n * AccountMenu \u2014 the interactive account popover (Figma nodes 12186:5636 and\n * 12196:7440): email header, capability-gated Connectors, divider, Terms of\n * Service / Privacy Policy / Logout. Opens directly above its trigger with a\n * 4px gap. `centered` aligns it to the anchor's centre (the full-width expanded\n * button); left-aligned for the collapsed icon.\n */\n\ninterface AccountMenuProps {\n anchorEl: HTMLElement | null;\n open: boolean;\n onClose: () => void;\n email: string;\n showConnectors?: boolean;\n onConnectors?: () => void;\n onSignOut?: () => void;\n /** Paper width (px). Defaults to the anchor's width. */\n width?: number;\n /** Centre the paper on the anchor (expanded button) vs. left-align (collapsed icon). */\n centered?: boolean;\n}\n\nexport const AccountMenu: FC = ({\n anchorEl,\n open,\n onClose,\n email,\n showConnectors = false,\n onConnectors,\n onSignOut = handleSignOut,\n width,\n centered = true,\n}) => {\n const [showTerms, setShowTerms] = useState(false);\n const horizontal = centered ? \"center\" : \"left\";\n\n return (\n <>\n \n {email}\n {showConnectors && (\n {\n onClose();\n onConnectors?.();\n }}\n />\n )}\n \n {\n onClose();\n setShowTerms(true);\n }}\n />\n {\n onClose();\n window.location.href = \"https://benchiq.com/privacy-policy\";\n }}\n />\n {\n onClose();\n onSignOut();\n }}\n />\n \n\n setShowTerms(false)} />\n \n );\n};\n", "import React, { useEffect, useState } from \"react\";\nimport type { FC } from \"react\";\nimport { User } from \"lucide-react\";\nimport { layout } from \"../theme/tokens/layout\";\nimport { spacing } from \"../theme/tokens/spacing\";\nimport { NavMenuRow } from \"./NavMenuRow\";\nimport { AccountMenu } from \"./AccountMenu/AccountMenu\";\n\n/**\n * UserProfileFooter \u2014 the account control at the nav's bottom. It's just another\n * `NavMenuRow` (user icon + name), so the label uses the same body2 typography\n * and the same width-clip reveal/hide as every other nav item: it never peeks\n * through when collapsed and never changes weight. Collapsed, it's the icon only\n * (replacing the old Policies + Logout rail icons). Opens the account menu\n * (Connectors when eligible, Terms of Service, Privacy Policy, Logout) directly\n * above the trigger.\n */\n\n// Collapsed trigger is a 36px icon, so the menu can't borrow its width \u2014 give it\n// the expanded panel's inner content width (panel width minus its side padding).\nconst COLLAPSED_MENU_WIDTH = layout.railExpandedWidth - 2 * spacing[2];\n\ninterface UserProfileFooterProps {\n name: string;\n email: string;\n /** false \u2192 collapsed, icon-only trigger. */\n showLabel?: boolean;\n showConnectors?: boolean;\n onConnectors?: () => void;\n onSignOut?: () => void;\n onMenuOpenChange?: (open: boolean) => void;\n}\n\nexport const UserProfileFooter: FC = ({\n name,\n email,\n showLabel = true,\n showConnectors = false,\n onConnectors,\n onSignOut,\n onMenuOpenChange,\n}) => {\n const [anchor, setAnchor] = useState(null);\n const open = Boolean(anchor);\n const openMenu = (event: React.MouseEvent) => setAnchor(event.currentTarget);\n\n useEffect(() => {\n onMenuOpenChange?.(open);\n return () => onMenuOpenChange?.(false);\n }, [onMenuOpenChange, open]);\n\n return (\n <>\n \n\n setAnchor(null)}\n email={email}\n showConnectors={showConnectors}\n onConnectors={onConnectors}\n onSignOut={onSignOut}\n centered={showLabel}\n width={showLabel ? anchor?.offsetWidth : COLLAPSED_MENU_WIDTH}\n />\n \n );\n};\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport Tooltip from \"@mui/material/Tooltip\";\nimport { MessagesSquare, Pin, PinOff } from \"lucide-react\";\nimport { styled } from \"@/utils/styled\";\nimport { layout } from \"../theme/tokens/layout\";\nimport { motion as motionPresets, motionToCss } from \"../theme/tokens/motion\";\nimport { HomeLogoButton } from \"./HomeLogoButton\";\nimport { NavMenuRow, NAV_ICON_CELL } from \"./NavMenuRow\";\nimport { RecentsList } from \"./Recents/RecentsList\";\nimport type { RecentSession } from \"./Recents/mockSessions\";\nimport { resolveCollapsedRollupStatus, type CollapsedRollupStatus } from \"./Recents/CollapsedStatusRollup\";\nimport { UserProfileFooter } from \"./UserProfileFooter\";\nimport type { SideNavModelItem } from \"./useSideNavModel\";\nimport { BIQIconButton } from \"../atoms/BIQIconButton\";\n\nconst RAIL_WIDTH_TRANSITION = `width ${motionToCss(motionPresets.sidepanelExpand)}`;\n\nconst Root = styled(\"nav\")<{ $pinnedOpen: boolean }>`\n position: absolute;\n inset: 0 auto 0 0;\n transition: ${RAIL_WIDTH_TRANSITION};\n height: 100%;\n overflow: hidden;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n background: ${({ theme }) => theme.palette.background.default};\n border-right: 1px solid ${({ theme }) => theme.border.default};\n z-index: ${({ theme }) => theme.tokens.zIndex.topBar};\n\n /* MUI marks the app root aria-hidden while a modal owns interaction. The\n rail's top-bar z-index otherwise leaves it hoverable above the backdrop,\n so disable hit-testing for the whole hidden subtree. A pinned rail keeps\n its width (no background reflow) and pointer behavior restores as soon as\n the modal removes aria-hidden. */\n [aria-hidden=\"true\"] & {\n pointer-events: none;\n }\n\n &[aria-expanded=\"true\"] {\n box-shadow: ${({ theme, $pinnedOpen }) => ($pinnedOpen ? theme.tokens.shadows.none : theme.tokens.shadows.lg)};\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n`;\n\nconst Inner = styled(Box)`\n width: ${layout.railExpandedWidth}px;\n height: 100%;\n display: flex;\n flex-direction: column;\n padding: ${({ theme }) => theme.tokens.spacing[3]}px ${({ theme }) => theme.tokens.spacing[2]}px;\n box-sizing: border-box;\n`;\n\nconst Header = styled(Box)`\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: ${layout.appShellTopBarHeight - 2 * layout.topBarPaddingY}px;\n margin-bottom: ${({ theme }) => theme.tokens.spacing[6]}px;\n`;\n\nconst LogoCell = styled(Box)`\n width: ${NAV_ICON_CELL}px;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst NavGroup = styled(Box)`\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n gap: ${({ theme }) => theme.tokens.spacing[1.5]}px;\n margin-bottom: ${({ theme }) => theme.tokens.spacing[6]}px;\n`;\n\nconst BottomArea = styled(Box)`\n margin-top: auto;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n gap: ${({ theme }) => theme.tokens.spacing[1.5]}px;\n`;\n\ninterface ExpandableSideNavProps {\n expanded: boolean;\n pinnedOpen: boolean;\n onTogglePin: () => void;\n interactionProps?: React.HTMLAttributes;\n onTransientSurfaceOpenChange?: (open: boolean) => void;\n beforeDivider: SideNavModelItem[];\n afterDivider: SideNavModelItem[];\n bottomItems: SideNavModelItem[];\n onHome: () => void;\n sessions?: RecentSession[];\n selectedSessionId?: string;\n onOpenSession?: (id: string) => void;\n recentsRollupStatus?: CollapsedRollupStatus;\n hasNextPage?: boolean;\n isFetchingNextPage?: boolean;\n recentsError?: string | null;\n onLoadMore?: () => void;\n onRetryRecents?: () => void;\n onSessionMenu?: (id: string, event: React.MouseEvent) => void;\n onExpandRecents?: () => void;\n user: { name: string; email: string };\n}\n\nconst RenderRows: FC<{ items: SideNavModelItem[]; expanded: boolean }> = ({ items, expanded }) => (\n <>\n {items.map((item) => (\n \n ))}\n \n);\n\nexport const ExpandableSideNav: FC = ({\n expanded,\n pinnedOpen,\n onTogglePin,\n interactionProps,\n onTransientSurfaceOpenChange,\n beforeDivider,\n afterDivider,\n bottomItems,\n onHome,\n sessions,\n selectedSessionId,\n onOpenSession,\n recentsRollupStatus,\n hasNextPage,\n isFetchingNextPage,\n recentsError,\n onLoadMore,\n onRetryRecents,\n onSessionMenu,\n onExpandRecents,\n user,\n}) => {\n const recentSessions = sessions ?? [];\n const hasRecents = recentSessions.length > 0;\n // Row errors remain visible after acknowledgement; only the backend rollup knows whether they are unread.\n const localRollupStatuses = recentSessions.map((session) => session.status).filter((status) => status !== \"error\");\n const rollupStatus = resolveCollapsedRollupStatus([recentsRollupStatus, ...localRollupStatuses]);\n const connectorsItem = bottomItems.find((item) => item.id === \"connected_apps_settings\");\n const visibleBottomItems = bottomItems.filter((item) => item.id !== \"connected_apps_settings\");\n\n return (\n \n \n
    \n \n \n \n {expanded && (\n \n \n \n )}\n
    \n\n \n \n \n {hasRecents && !expanded && (\n event.stopPropagation()}\n onClick={onExpandRecents}\n />\n )}\n \n\n {hasRecents && expanded && (\n \n )}\n\n \n \n \n \n
    \n \n );\n};\n", "import React, { useEffect, useRef, useState } from \"react\";\nimport type { FC, ReactNode } from \"react\";\nimport { useInfiniteClerkRecents } from \"@/api/queries/agentPrototype\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { SaveToFolderPopover } from \"@/components/molecules/SaveToFolderPopover\";\nimport { useSaveToFolder } from \"@/hooks/useSaveToFolder\";\nimport { featureEnabled, isClerkAvailable } from \"@/utils/featureFlags\";\nimport { stripMarkdown } from \"@/utils/stripMarkdown\";\nimport { useLocation, useNavigate } from \"@/utils/urlHelpers\";\nimport { RenameSessionDialog } from \"./Recents/RenameSessionDialog\";\nimport type { RecentSession } from \"./Recents/mockSessions\";\nimport type { CollapsedRollupStatus } from \"./Recents/CollapsedStatusRollup\";\nimport { SessionActionsMenu } from \"./Recents/SessionActionsMenu\";\n\nexport interface RecentSessionsRenderProps {\n sessions?: RecentSession[];\n selectedSessionId?: string;\n rollupStatus: CollapsedRollupStatus;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n error: string | null;\n onOpenSession: (id: string) => void;\n onLoadMore: () => void;\n onRetry: () => void;\n onSessionMenu: (id: string, event: React.MouseEvent) => void;\n}\n\ninterface RecentSessionsContainerProps {\n children: (props: RecentSessionsRenderProps) => ReactNode;\n onSurfaceOpenChange?: (open: boolean) => void;\n}\n\nexport const RecentSessionsContainer: FC = ({ children, onSurfaceOpenChange }) => {\n const available = featureEnabled(\"expandable_sidenav\") && isClerkAvailable();\n const foldersEnabled = featureEnabled(\"folders_and_annotations\");\n const query = useInfiniteClerkRecents(available);\n const navigate = useNavigate();\n const location = useLocation();\n const selectedSessionId = location.pathname.match(/^\\/agent\\/([^/]+)$/)?.[1];\n const seen = new Set();\n const source = query.data?.pages.flatMap((page) => page.data) ?? [];\n const deduped = source.filter((session) => {\n if (seen.has(session.token)) return false;\n seen.add(session.token);\n return true;\n });\n const sessions: RecentSession[] = deduped.map((session) => ({\n id: session.token,\n sessionId: session.session_id,\n title: stripMarkdown(session.display_title) || \"New conversation\",\n status: session.sidenav_status ?? \"read\",\n }));\n const [menuAnchor, setMenuAnchor] = useState(null);\n const [actionSession, setActionSession] = useState(null);\n const [renameOpen, setRenameOpen] = useState(false);\n const actionTriggerRef = useRef(null);\n const saveToFolder = useSaveToFolder({\n folderableType: \"AgentPrototypeSession\",\n folderableId: actionSession?.sessionId ?? 0,\n sourceType: \"clerk_session\",\n enabled: foldersEnabled && Boolean(actionSession?.sessionId),\n });\n const anySurfaceOpen = Boolean(menuAnchor) || renameOpen || Boolean(saveToFolder.anchorEl);\n\n useEffect(() => {\n onSurfaceOpenChange?.(anySurfaceOpen);\n return () => onSurfaceOpenChange?.(false);\n }, [anySurfaceOpen, onSurfaceOpenChange]);\n\n const onOpenSession = (token: string) => {\n const index = deduped.findIndex((session) => session.token === token);\n const session = deduped[index];\n if (session) {\n void recordUserEvent({\n event_name: \"click_clerk_history_session\",\n event_properties: {\n session_id: session.session_id,\n message_count: session.message_count,\n position: index + 1,\n },\n });\n }\n navigate({ pathname: `/agent/${token}` });\n };\n\n const rendered = children({\n sessions: available ? sessions : undefined,\n selectedSessionId: actionSession?.id ?? selectedSessionId,\n rollupStatus: query.data?.pages[0]?.sidenav_rollup_status ?? null,\n hasNextPage: Boolean(query.hasNextPage),\n isFetchingNextPage: query.isFetchingNextPage,\n error: query.isError || query.isFetchNextPageError ? \"Recents couldn't be loaded.\" : null,\n onOpenSession,\n onLoadMore: () => void query.fetchNextPage(),\n onRetry: () => void (query.isFetchNextPageError ? query.fetchNextPage() : query.refetch()),\n onSessionMenu: (id, event) => {\n event.stopPropagation();\n setActionSession(sessions.find((session) => session.id === id) ?? null);\n actionTriggerRef.current = event.currentTarget;\n setMenuAnchor(event.currentTarget);\n },\n });\n\n const closeRename = () => {\n setRenameOpen(false);\n setActionSession(null);\n window.requestAnimationFrame(() => actionTriggerRef.current?.focus());\n };\n const closeFolders = () => {\n saveToFolder.closePopover();\n setActionSession(null);\n };\n\n return (\n <>\n {rendered}\n {\n setMenuAnchor(null);\n setActionSession(null);\n }}\n showMoveToFolder={foldersEnabled}\n onRename={() => {\n setMenuAnchor(null);\n setRenameOpen(true);\n }}\n onMoveToFolder={() => {\n if (menuAnchor) saveToFolder.openPopover(menuAnchor);\n setMenuAnchor(null);\n }}\n />\n \n {foldersEnabled && actionSession?.sessionId ? (\n \n ) : null}\n \n );\n};\n", "import React from \"react\";\nimport type { FC } from \"react\";\nimport { useExpandableRail } from \"../AppShell\";\nimport { ExpandableSideNav } from \"./ExpandableSideNav\";\nimport type { RecentSession } from \"./Recents/mockSessions\";\nimport { useSideNavModel } from \"./useSideNavModel\";\nimport { RecentSessionsContainer } from \"./RecentSessionsContainer\";\n\ninterface ExpandableSideNavContainerProps {\n /** Story override; production uses RecentSessionsContainer. */\n sessions?: RecentSession[];\n}\n\nexport const ExpandableSideNavContainer: FC = ({ sessions: storySessions }) => {\n const model = useSideNavModel();\n const rail = useExpandableRail();\n\n return (\n \n {(recents) => (\n \n )}\n \n );\n};\n", "import { useCallback, useEffect, useState } from \"react\";\n\nexport const getPinnedSidenavStorageKey = () => `expandable_sidenav_pinned:${window.currentUser?.id ?? \"unknown\"}`;\n\nconst readPinned = () => {\n try {\n return window.localStorage.getItem(getPinnedSidenavStorageKey()) === \"true\";\n } catch {\n return false;\n }\n};\n\nexport const usePinnedSidenavPreference = () => {\n const [pinned, setPinnedState] = useState(readPinned);\n\n useEffect(() => {\n const syncPinned = (event: StorageEvent) => {\n if (event.key === getPinnedSidenavStorageKey()) setPinnedState(event.newValue === \"true\");\n };\n window.addEventListener(\"storage\", syncPinned);\n return () => window.removeEventListener(\"storage\", syncPinned);\n }, []);\n\n const setPinned = useCallback((next: boolean) => {\n setPinnedState(next);\n try {\n window.localStorage.setItem(getPinnedSidenavStorageKey(), next.toString());\n } catch {\n // Keep the current tab responsive when browser storage is unavailable.\n }\n }, []);\n\n return { pinned, setPinned };\n};\n", "import React from \"react\";\nimport { Search } from \"lucide-react\";\nimport { useLocation } from \"@/utils/urlHelpers\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { useBooleanSearchBarState } from \"@/components/contexts/BooleanSearchBarControlContext\";\nimport { useCarriedQueryPrefill } from \"@/hooks/useCarriedQueryPrefill\";\n\n/**\n * OmnibarSearchTrigger \u2014 the persistent search-entry control that lives in the\n * AppShell topbar. Two rendered states:\n *\n * default \u2014 every route except `/transcripts` (and `/transcripts`\n * with no active query). Tertiary medium button with\n * search icon + \"Search transcripts\" label.\n * with-query \u2014 `/transcripts` with an active query in context.\n * Same button shape, label shows the active query\n * (truncated at 200px max-width).\n *\n * Click opens the SearchOverlay via the `onClick` prop.\n */\n\nconst TRANSCRIPTS_ROUTE = \"/transcripts\";\nconst BUTTON_MAX_WIDTH = 200;\n\ninterface OmnibarSearchTriggerProps {\n onClick: () => void;\n}\n\nexport const OmnibarSearchTrigger: React.FC = ({ onClick }) => {\n const location = useLocation();\n const { searchInput } = useBooleanSearchBarState();\n const prefillCarriedQuery = useCarriedQueryPrefill();\n\n const hasActiveQuery = location.pathname === TRANSCRIPTS_ROUTE && Boolean(searchInput?.trim());\n const label = hasActiveQuery ? searchInput! : \"Search transcripts\";\n\n const handleClick = () => {\n // Seed the search box with a locked user's carried-over question (`?q=`)\n // before opening \u2014 the overlay snapshots `searchInput` at open time, so the\n // value must be set first to appear prefilled.\n //\n // `q` is reserved for the locked-Clerk carry-over (only the locked landing\n // ever produces it) and read app-wide here, but we skip the seed when an\n // active /transcripts query is already committed so a crafted URL like\n // `/transcripts?queryText=X&q=Y` can't clobber `X` on click.\n if (!hasActiveQuery) {\n prefillCarriedQuery();\n }\n onClick();\n };\n\n return (\n \n {label}\n \n );\n};\n\nexport default OmnibarSearchTrigger;\n", "import React from \"react\";\nimport type { FC, ReactNode } from \"react\";\nimport Box from \"@mui/material/Box\";\nimport { styled } from \"@/utils/styled\";\nimport { OmnibarSearchTrigger } from \"./OmnibarSearchTrigger\";\n\ninterface TopBarLeftProps {\n /**\n * Click handler for the search icon button. Opens the omnibar search\n * overlay when provided; no-op if omitted.\n */\n onSearchClick?: () => void;\n /**\n * Optional status chip shown alongside the search button \u2014 e.g. the\n * \"Reviewing your query...\" indicator while the query corrector runs. Pass a\n * pre-built `` so callers control the icon + label without\n * TopBarLeft baking in any specific status copy.\n */\n statusChip?: ReactNode;\n}\n\n/**\n * TopBarLeft \u2014 left half of the AppShell topbar (Figma node 503:17234 /\n * 503:26940). Composes:\n *\n * \u250C\u2500 Container (flex-row, gap-8) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 \u250C\u2500 BIQIconButton (secondary, Search) \u2510 \u2502\n * \u2502 \u2502 (always rendered \u2014 persistent \u2502 \u2502\n * \u2502 \u2502 across every authenticated page) \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u2502 \u250C\u2500 statusChip slot \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2502 (optional \u2014 page renders a chip \u2502 \u2502\n * \u2502 \u2502 only when there's a status to \u2502 \u2502\n * \u2502 \u2502 surface) \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * The search button opens the omnibar overlay; pages pass `statusChip`\n * for the query corrector + similar indicators when something needs to\n * surface alongside it.\n */\n\nconst Container = styled(Box)`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.tokens.spacing[2]}px;\n`;\n\nexport const TopBarLeft: FC = ({ onSearchClick, statusChip }) => (\n \n undefined)} />\n {statusChip}\n \n);\n", "import React, { useRef } from \"react\";\nimport { Box, Stack, Typography, Tooltip } from \"@mui/material\";\nimport { motion } from \"motion/react\";\nimport { ArrowRight } from \"lucide-react\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { Icon } from \"@/components/icons\";\nimport { styled } from \"@/utils/styled\";\nimport { ImprovedQuery, QueryImprovementStage, STAGE_ICONS } from \"../types/queryImprovement\";\nimport { useSearchParams } from \"../../utils/urlHelpers\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { recordUserEvent } from \"../../api/userEvents\";\n\n/**\n * Inline motion-driven loading spinner \u2014 rotating arc on a transparent\n * background. Mirrors https://motion.dev/examples/react-loading-circle-spinner\n * patterns: a single arc segment rotated at constant velocity (linear ease,\n * 1s loop). Uses `currentColor` for stroke so callers can tint via parent\n * color.\n */\nconst LoadingSpinner: React.FC<{ size?: number }> = ({ size = 20 }) => (\n \n \n \n \n);\n\nconst Card = styled(Box)(({ theme }) => ({\n width: \"100%\",\n boxSizing: \"border-box\",\n boxShadow: theme.tokens.shadows.none,\n cursor: \"pointer\",\n border: `1px solid ${theme.border.light}`,\n borderRadius: theme.tokens.radii.smallRadius,\n padding: theme.spacing(2),\n backgroundColor: theme.palette.background.paper,\n transition: \"border-color 0.15s ease-out\",\n // Hover only deepens the border to border.hover \u2014 no background fill, no\n // selected-state accent. Click still populates the query into the search\n // input via onSelect; the picked state is tracked in SearchOverlay context\n // without a visual badge on the card itself.\n \"&:hover\": {\n borderColor: theme.border.hover,\n },\n}));\n\ninterface QueryImprovementCardProps {\n improvedQuery: ImprovedQuery | null;\n stage: QueryImprovementStage;\n originalQuery: string;\n title: string;\n tooltipText: string;\n runId?: string;\n /** Deprecated \u2014 picked state is tracked in SearchOverlay context now; no visual surface on the card. */\n isSelected?: boolean;\n onSelect?: (stage: QueryImprovementStage, query: string) => void;\n isLoading?: boolean;\n isError?: boolean;\n emptyStateMessage?: string;\n emptyStateColor?: \"error\" | \"success\";\n transcriptCount?: number | null;\n}\n\nconst QueryImprovementCard: React.FC = ({\n improvedQuery,\n stage,\n originalQuery,\n title,\n tooltipText,\n runId,\n onSelect,\n isLoading = false,\n isError = false,\n emptyStateMessage,\n emptyStateColor = \"error\",\n transcriptCount = null,\n}) => {\n const theme = useTheme();\n const [searchParams] = useSearchParams();\n\n const hasCount = transcriptCount !== null;\n const hasResults = hasCount && transcriptCount > 0;\n const isEmptyState = Boolean(emptyStateMessage);\n const emptyStateTextColor = theme.palette[emptyStateColor].main;\n\n const lastExitTimeRef = useRef(0);\n\n const handleTooltipHover = () => {\n const now = Date.now();\n if (now - lastExitTimeRef.current > 1000) {\n recordUserEvent({\n event_name: \"hover_query_improvement_card_tooltip\",\n event_properties: { stage },\n });\n }\n };\n\n const handleTooltipLeave = () => {\n lastExitTimeRef.current = Date.now();\n };\n\n const handleCardClick = () => {\n if (isLoading || !improvedQuery?.new_query) {\n return;\n }\n\n recordUserEvent({\n event_name: \"click_query_improvement_card\",\n event_properties: {\n stage,\n new_query: improvedQuery.new_query,\n rule_codes: improvedQuery.rule_codes?.length ? improvedQuery.rule_codes : undefined,\n original_query: originalQuery || undefined,\n run_id: runId || undefined,\n transcript_count: transcriptCount ?? undefined,\n },\n });\n\n if (onSelect) {\n onSelect(stage, improvedQuery.new_query);\n }\n };\n\n const handleViewClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n if (!improvedQuery?.new_query) return;\n\n recordUserEvent({\n event_name: \"click_query_corrector_view\",\n event_properties: {\n stage,\n new_query: improvedQuery.new_query,\n rule_codes: improvedQuery.rule_codes?.length ? improvedQuery.rule_codes : undefined,\n original_query: originalQuery || undefined,\n run_id: runId || undefined,\n transcript_count: transcriptCount ?? undefined,\n },\n });\n\n const queryParams = new URLSearchParams({\n queryType: \"keyword-boolean\",\n queryText: improvedQuery.new_query,\n disableAutoCorrections: \"true\",\n disableQueryImprovements: \"true\",\n });\n\n if (searchParams.get(\"judgeIds\")) queryParams.set(\"judgeIds\", searchParams.get(\"judgeIds\")!);\n if (searchParams.get(\"hearingDateFrom\")) queryParams.set(\"hearingDateFrom\", searchParams.get(\"hearingDateFrom\")!);\n if (searchParams.get(\"hearingDateTo\")) queryParams.set(\"hearingDateTo\", searchParams.get(\"hearingDateTo\")!);\n if (searchParams.get(\"caseNumber\")) queryParams.set(\"caseNumber\", searchParams.get(\"caseNumber\")!);\n if (searchParams.get(\"additionalQuery\")) queryParams.set(\"additionalQuery\", searchParams.get(\"additionalQuery\")!);\n if (searchParams.get(\"caseName\")) queryParams.set(\"caseName\", searchParams.get(\"caseName\")!);\n if (searchParams.get(\"motionType\")) queryParams.set(\"motionType\", searchParams.get(\"motionType\")!);\n\n window.open(`/transcripts?${queryParams.toString()}`, \"_blank\");\n };\n\n const renderTranscriptsAction = () => {\n // While the AI is still generating the improved query (or transcript\n // count hasn't arrived yet), hide the action entirely \u2014 showing a\n // \"0 transcripts\" count before the user can act reads as misleading.\n // Same call for error / empty states: the body of the card already\n // surfaces the failure, no need to duplicate it below.\n if (isError || isEmptyState) return null;\n if (isLoading || transcriptCount === null) return null;\n if (!hasResults) {\n return (\n \n No transcripts found\n \n );\n }\n // Count caption + arrow icon button (Figma suggestedQuery 11214:4427). The\n // arrow's onClick mirrors the old \"View N transcripts\" button exactly.\n return (\n \n \n {transcriptCount} transcripts found\n \n \n \n );\n };\n\n return (\n \n \n {/* Header \u2014 stage icon (sm) + caption label in text.secondary, wrapped\n in the stage tooltip for context (Figma suggestedQuery 11214:4427). */}\n \n \n \n \n \n {title}\n \n \n \n \n\n {/* Query text body \u2014 body2, text.primary; falls back to centered\n loading / error / empty messages. */}\n {isLoading ? (\n \n \n
    \n ) : isError || isEmptyState ? (\n \n {isEmptyState ? emptyStateMessage : \"Unable to generate the query\"}\n \n ) : (\n \n {improvedQuery?.new_query || \"\"}\n \n )}\n\n {/* Transcript-count caption + arrow icon button. Hidden while\n generating / on error so the card collapses cleanly and the Stack\n gap doesn't reserve space for an empty slot. */}\n {(() => {\n const action = renderTranscriptsAction();\n return action ? {action} : null;\n })()}\n \n \n );\n};\n\nexport default QueryImprovementCard;\n", "import React, { useEffect, useState } from \"react\";\nimport { Stack, Typography } from \"@mui/material\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport QueryImprovementCard from \"./QueryImprovementCard\";\nimport { Icon } from \"@/components/icons\";\nimport AnimatedEllipsis from \"@/components/atoms/AnimatedEllipsis\";\nimport { motion as motionPresets } from \"../theme/tokens/motion\";\nimport {\n QueryImprovementStage,\n QueryImprovementPayload,\n STAGE_DISPLAY_NAMES,\n STAGE_TOOLTIPS,\n STAGE_ICONS,\n STAGE_RUNNING_LABELS,\n STAGE_NO_SUGGESTION_LABELS,\n} from \"../types/queryImprovement\";\nimport { QueryImprovementStageStatus } from \"@/api/queries/queryImprovement.types\";\n\n// Module-level set of \"runId::stage\" keys for green \"no further X\" chips the\n// user has seen during this session. The chip auto-hides after 3 seconds, and\n// the dismissal is remembered here so re-opening the overlay with the same\n// suggestions (same runId \u2014 same Boolean query + filters) doesn't re-surface\n// chips the user already dismissed. Cleared by a page reload, which matches\n// expectations: a fresh page treats the suggestions as new.\nconst GREEN_PILL_AUTO_HIDE_MS = 3000;\nconst dismissedGreenPills = new Set();\n\n// Enter / exit poses for the chip-and-card swap inside this section. Pulled\n// from the same `chipEnter` / `chipExit` presets that FolderChipRow uses so\n// the appearance/disappearance of these pills matches the rest of the app's\n// motion language (fade + 0.9 \u2192 1 scale, 200ms in / 150ms out).\nconst VARIANT_INITIAL = { opacity: 0, scale: 0.9 };\nconst VARIANT_VISIBLE = { opacity: 1, scale: 1 };\n\n/**\n * Compact status row for a stage that is loading or settled with no suggestion\n * (Figma RightColumn 11214:3876) \u2014 replaces the old BIQChip pills. Stage icon\n * (sm) + label in text.primary, 8px gap; the loading variant appends an\n * animated ellipsis.\n */\nconst StageStatusRow: React.FC<{ stage: QueryImprovementStage; label: string; showEllipsis?: boolean }> = ({\n stage,\n label,\n showEllipsis = false,\n}) => (\n \n \n \n {label}\n {showEllipsis && }\n \n \n);\n\ninterface QueryImprovementSectionProps {\n stage: QueryImprovementStage;\n status?: QueryImprovementStageStatus;\n payload?: QueryImprovementPayload;\n originalQuery: string;\n runId?: string;\n selectedStage?: QueryImprovementStage;\n onSelectQuery?: (stage: QueryImprovementStage, query: string) => void;\n transcriptCount?: number | null;\n /**\n * When `true`, the \"No further is recommended\" green chip is\n * never rendered for `done_no_suggestion` stages. Used when the panel\n * is opened with already-settled suggestions (e.g. clicking \"view\n * suggestions\" from the topbar status chip) \u2014 the green chips are a\n * transient progress signal during the live load; replaying them on\n * a re-open of a settled run reads as noise.\n */\n suppressNoSuggestionChips?: boolean;\n}\n\ntype Variant = \"loading\" | \"no_suggestion\" | \"card\";\n\nconst QueryImprovementSection: React.FC = ({\n stage,\n status,\n payload,\n originalQuery,\n runId,\n selectedStage,\n onSelectQuery,\n transcriptCount,\n suppressNoSuggestionChips = false,\n}) => {\n const displayName = STAGE_DISPLAY_NAMES[stage];\n const tooltipText = STAGE_TOOLTIPS[stage];\n\n // Green-pill auto-hide. `dismissalKey` is null when there's no runId\n // (storybook / tests) \u2014 the chip still auto-hides on a timer, the\n // dismissal just doesn't survive an unmount.\n const dismissalKey = runId ? `${runId}::${stage}` : null;\n const previouslyDismissed = dismissalKey ? dismissedGreenPills.has(dismissalKey) : false;\n const [greenPillHidden, setGreenPillHidden] = useState(false);\n\n useEffect(() => {\n if (status !== \"done_no_suggestion\") return;\n if (dismissalKey && dismissedGreenPills.has(dismissalKey)) return;\n const timer = window.setTimeout(() => {\n if (dismissalKey) {\n dismissedGreenPills.add(dismissalKey);\n }\n setGreenPillHidden(true);\n }, GREEN_PILL_AUTO_HIDE_MS);\n return () => window.clearTimeout(timer);\n }, [status, dismissalKey]);\n\n // Resolve which variant this section should currently show. `null` means\n // the section renders nothing (errored / dismissed / unexpected status /\n // missing payload). Decoupled from the JSX so AnimatePresence below sees\n // only the resolved choice.\n let variant: Variant | null = null;\n if (status === \"error\") {\n // Hide errored stages \u2014 the panel-level guard already hides the whole\n // right column when ALL three errored.\n variant = null;\n } else if (!status || status === \"running\") {\n variant = \"loading\";\n } else if (status === \"done_no_suggestion\") {\n // Three independent reasons to hide the green chip:\n // - `suppressNoSuggestionChips` (parent says \"this is a re-open of\n // settled data; skip the transient progress signals\")\n // - `greenPillHidden` (auto-hide timer fired during this mount)\n // - `previouslyDismissed` (same runId+stage was already auto-hidden\n // earlier in the session)\n variant = suppressNoSuggestionChips || greenPillHidden || previouslyDismissed ? null : \"no_suggestion\";\n } else if (status === \"done_with_suggestion\" && payload?.improved_query?.new_query) {\n // Keep broaden/narrow as a stage-chip placeholder until transcript\n // counts arrive \u2014 they may still be hidden by\n // remove_improper_suggestions validation. `suggested` shows\n // immediately because it's always kept.\n if (transcriptCount === null && stage !== \"suggested\") {\n variant = \"loading\";\n } else {\n variant = \"card\";\n }\n }\n\n // Shared transition props applied to each variant's motion.div. `mode=\"wait\"`\n // on the parent AnimatePresence makes the outgoing variant fully exit before\n // the incoming variant enters, so the chip/card swap reads as a clean\n // hand-off instead of a momentary cross-blur.\n const motionProps = {\n initial: VARIANT_INITIAL,\n animate: VARIANT_VISIBLE,\n exit: { ...VARIANT_INITIAL, transition: motionPresets.chipExit },\n transition: motionPresets.chipEnter,\n };\n\n return (\n \n {variant === \"loading\" && (\n \n \n \n )}\n {variant === \"no_suggestion\" && (\n \n \n \n )}\n {variant === \"card\" && (\n \n \n \n )}\n \n );\n};\n\nexport default QueryImprovementSection;\n", "import React, { useEffect, useRef, useState } from \"react\";\nimport { Stack, Typography, Box, Dialog, Link } from \"@mui/material\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQChip } from \"@/components/atoms/BIQChip\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { ThumbsUp, ThumbsDown, X } from \"lucide-react\";\nimport { styled } from \"@/utils/styled\";\nimport QueryImprovementSection from \"../molecules/QueryImprovementSection\";\nimport { QueryImprovementPayload, QueryImprovementStage } from \"../types/queryImprovement\";\nimport { UseQueryResult } from \"@tanstack/react-query\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { useGlobalAlert } from \"@/contexts/GlobalAlertContext\";\nimport { QueryImprovementPollResponse } from \"@/api/queries/queryImprovement.types\";\nimport { MODAL_WIDTH } from \"@/utils/constants\";\nimport { isClerkAvailable } from \"@/utils/featureFlags\";\n\n// Wrapper around the suggestion list + thumbs footer (Figma RightColumn\n// 11219:2488): background.default fill, standardRadius, 12px padding.\nconst PanelContainer = styled(Box)(({ theme }) => ({\n boxSizing: \"border-box\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.spacing(1),\n padding: theme.spacing(1.5),\n backgroundColor: theme.palette.background.default,\n borderRadius: theme.tokens.radii.standardRadius,\n}));\n\ninterface QueryImprovementsPanelProps {\n query: string;\n /**\n * Identifier for the in-flight query-improvement run. Required \u2014 the\n * thumbs feedback events attach this id so analytics can match a\n * specific user reaction to the specific batch of suggestions they\n * were reacting to. Callers must only mount the panel after the run\n * has been created (i.e. `runId` is defined); SearchOverlay gates on\n * `suggestedQueriesReady && runId` for that reason.\n */\n runId: string;\n pollQuery: UseQueryResult; // Poll query result passed from parent\n selectedStage?: QueryImprovementStage;\n onSelectQuery?: (stage: QueryImprovementStage, query: string) => void;\n trackViewEvent?: boolean; // Control whether to track view event (default: true)\n /**\n * When `true`, suppresses the \"No further is recommended\" green\n * chips for `done_no_suggestion` stages. Pass-through to each\n * `QueryImprovementSection`. The caller (currently SearchOverlay) sets\n * this when the panel is opened with already-settled suggestions \u2014\n * e.g. clicking \"view suggestions\" from the topbar status chip \u2014\n * since the green chips are a live-progress signal that adds noise on\n * a re-open of a settled run.\n */\n suppressNoSuggestionChips?: boolean;\n}\n\nconst QueryImprovementsPanel: React.FC = ({\n query,\n runId,\n pollQuery,\n selectedStage,\n onSelectQuery,\n trackViewEvent = true,\n suppressNoSuggestionChips = false,\n}) => {\n const { setAlertWithOptions } = useGlobalAlert();\n const [feedbackQuestionnaireOpen, setFeedbackQuestionnaireOpen] = useState(false);\n const [feedbackModalOpen, setFeedbackModalOpen] = useState(false);\n\n // Track which run_id has been logged to prevent duplicate events\n const loggedRunIdRef = useRef(null);\n\n /**\n * Called when the user clicks the thumbs up feedback button.\n *\n * This method records a user event and renders a notification to thank the\n * user for submitting feedback.\n */\n function onThumbsUp() {\n recordUserEvent({ event_name: \"like_suggested_queries\", event_properties: { query_improvement_run_id: runId } });\n setAlertWithOptions(\"Thank you for your feedback\", \"success\", 5000);\n }\n\n /**\n * Called when the user clicks the thumbs down feedback button.\n *\n * This method displays an inline questionnaire to solicit additional\n * information about their feedback.\n */\n function onThumbsDown() {\n recordUserEvent({\n event_name: \"click_dislike_suggested_queries\",\n event_properties: { query_improvement_run_id: runId },\n });\n setFeedbackQuestionnaireOpen(true);\n }\n\n /**\n * Called when the user selects a reason for their negative feedback.\n *\n * This method records a user event and presents a modal that directs the user\n * to other methods of recourse.\n */\n function onSelectReason(reason: string) {\n recordUserEvent({\n event_name: \"dislike_suggested_queries\",\n event_properties: { query_improvement_run_id: runId, reason },\n });\n setFeedbackModalOpen(true);\n }\n\n /**\n * Called when a user closes the feedback modal.\n *\n * This method hides the modal and the feedback questionnaire.\n */\n function onCloseFeedbackModal() {\n setFeedbackQuestionnaireOpen(false);\n setFeedbackModalOpen(false);\n }\n\n // Track when improvements are received (only once per run_id)\n useEffect(() => {\n if (trackViewEvent && pollQuery.data?.status === \"done\" && runId && loggedRunIdRef.current !== runId) {\n loggedRunIdRef.current = runId;\n recordUserEvent({\n event_name: \"view_query_improvements\",\n event_properties: {\n run_id: runId,\n query,\n },\n });\n }\n }, [trackViewEvent, pollQuery.data?.status, runId, query]);\n\n const stages = pollQuery.data?.data?.stages;\n const transcriptCounts = pollQuery.data?.data?.transcript_counts;\n if (!stages) {\n return null;\n }\n\n const allNoSuggestions =\n stages.suggested?.status === \"done_no_suggestion\" &&\n stages.broaden?.status === \"done_no_suggestion\" &&\n stages.narrow?.status === \"done_no_suggestion\";\n\n if (allNoSuggestions) {\n return null;\n }\n\n // Thumbs feedback only makes sense once the user has something to react\n // TO \u2014 i.e. all stages have finished generating (or errored out) and at\n // least one stage has a real suggestion to feedback on. While the query\n // corrector is still reviewing or stages are still streaming, the thumbs\n // would be premature.\n const stageStatuses = [stages.suggested?.status, stages.broaden?.status, stages.narrow?.status];\n const allStagesSettled = stageStatuses.every(\n (s) => s === \"done_with_suggestion\" || s === \"done_no_suggestion\" || s === \"error\",\n );\n const anyStageHasSuggestion = stageStatuses.some((s) => s === \"done_with_suggestion\");\n const showThumbs = allStagesSettled && anyStageHasSuggestion;\n\n // Render the sections\n return (\n \n {/* suggestedList \u2014 8px gap between rows (cards or icon+text placeholders) */}\n \n {/* Suggested Section */}\n \n\n {/* Broaden Section */}\n \n\n {/* Narrow Section */}\n \n \n\n {/* Footer \u2014 thumbs feedback row. Hidden until every stage has\n finished (status === \"view_suggestions\" semantically \u2014 see\n `showThumbs` above) so the user only sees the feedback\n affordance once they have results to react to.\n NOTE: no `pt` here \u2014 PanelContainer's own `gap: spacing(1)`\n already provides 8px between the last suggestion and the\n thumbs row. Adding `pt: 1` again would stack to 16px. */}\n {showThumbs && (\n \n \n \n \n \n {feedbackQuestionnaireOpen && (\n \n \n \n )}\n \n )}\n\n \n \n );\n};\n\n/**\n * A feedback questionnaire.\n *\n * It presents options to the user that allow them to provide more information\n * about their negative feedback.\n */\nfunction FeedbackQuestionnaire(props: { onSelectReason: (reason: string) => void }) {\n return (\n \n What didn't work?\n \n {[\"Not relevant\", \"Too complex\", \"Missed terms\", \"Other\"].map((reason) => (\n props.onSelectReason(reason)}\n />\n ))}\n \n \n );\n}\n\n/**\n * A feedback modal.\n *\n * It thanks the user for submitting feedback and directs them to other methods\n * of recourse.\n */\nfunction FeedbackModal(props: { open: boolean; onClose: () => void }) {\n const clerkAvailable = isClerkAvailable();\n\n /**\n * Called when the user clicks the Clerk link.\n */\n function onClickClerk(e: React.MouseEvent) {\n e.preventDefault();\n if (clerkAvailable) {\n window.open(\"/agent\", \"_blank\", \"noopener,noreferrer\");\n }\n props.onClose();\n }\n\n return (\n ({ borderRadius: `${theme.tokens.radii.smallRadius}px`, maxWidth: MODAL_WIDTH }) }}\n data-top-bar-keep-open\n >\n \n \n Thanks!\n \n \n\n \n {clerkAvailable ? (\n <>\n You can try your question with{\" \"}\n \n the agent\n {\" \"}\n or Contact a Search Coach{\" \"}\n at Bench IQ who can help refine your query.\n \n ) : (\n <>\n Contact a Search Coach at\n Bench IQ who can help refine your query.\n \n )}\n \n\n \n \n Ok\n \n \n \n \n );\n}\n\nexport default QueryImprovementsPanel;\n", "import { skipToken, useQuery } from \"@tanstack/react-query\";\nimport { queries } from \"./queries\";\nimport { featureEnabled } from \"@/utils/featureFlags\";\nimport { useRef } from \"react\";\nimport { QueryImprovementPollParams, QueryImprovementPollResponse } from \"./queries/queryImprovement.types\";\n\nconst isQueryImprovementEnabled = () =>\n !featureEnabled(\"disable_generative_ai\") && !featureEnabled(\"incognito_queries\");\n\nconst isQueryImprovementComplete = (status?: string, stages?: QueryImprovementPollResponse[\"data\"][\"stages\"]) => {\n if (status === \"done\") {\n return true;\n }\n if (status === \"error\" && stages) {\n const allStagesFinished =\n stages.suggested?.status !== \"running\" &&\n stages.broaden?.status !== \"running\" &&\n stages.narrow?.status !== \"running\";\n return allStagesFinished;\n }\n return false;\n};\n\n// Maximum polling duration in milliseconds (2 minutes)\nconst MAX_POLLING_DURATION_MS = 120000;\n\nexport const useQueryQueryImprovementCreate = (query: string, enabled = true) => {\n return useQuery({\n queryKey: queries.queryImprovement.create({ query }).queryKey,\n queryFn: query.trim() !== \"\" ? queries.queryImprovement.create({ query }).queryFn : skipToken,\n enabled: enabled && query.trim() !== \"\" && isQueryImprovementEnabled(),\n retry: false,\n staleTime: Infinity,\n });\n};\n\nexport const useQueryQueryImprovementPoll = (runId: string, params?: QueryImprovementPollParams, enabled = true) => {\n const pollingStartTimeRef = useRef(null);\n\n return useQuery({\n ...queries.queryImprovement.poll(runId, params),\n enabled: enabled && isQueryImprovementEnabled(),\n refetchInterval: ({ state: reactQueryState }) => {\n const payload = reactQueryState.data;\n\n // Initialize polling start time on first successful fetch\n if (payload && pollingStartTimeRef.current === null) {\n pollingStartTimeRef.current = Date.now();\n }\n\n // Stop polling if complete\n if (isQueryImprovementComplete(payload?.status, payload?.data?.stages)) {\n pollingStartTimeRef.current = null;\n return false;\n }\n\n // Stop polling if we've exceeded max duration\n if (pollingStartTimeRef.current && Date.now() - pollingStartTimeRef.current > MAX_POLLING_DURATION_MS) {\n console.warn(\"GEN-265: Query improvement polling timed out.\");\n pollingStartTimeRef.current = null;\n return false;\n }\n\n // Continue polling at 1-second intervals\n return 1000;\n },\n refetchIntervalInBackground: false,\n staleTime: ({ state: reactQueryState }) => {\n const payload = reactQueryState.data;\n // if it's complete, it's complete forever, otherwise it's immediately stale\n return isQueryImprovementComplete(payload?.status, payload?.data?.stages) ? Infinity : 0;\n },\n });\n};\n", "import React, { useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { Box, Dialog, Stack, Tooltip, Typography } from \"@mui/material\";\nimport { alpha } from \"@mui/material/styles\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport { Lightbulb, Lock, Search, SlidersHorizontal, X } from \"lucide-react\";\nimport { colors } from \"@/components/theme/tokens\";\nimport { styled } from \"@/utils/styled\";\nimport { Icon } from \"@/components/icons\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport { BIQInputField } from \"@/components/atoms/BIQInputField\";\nimport SmartQuotesTextField from \"@/components/atoms/SmartQuotesTextField\";\nimport BooleanSearchTips from \"@/components/atoms/BooleanSearchTips\";\nimport AppliedFilters from \"@/components/molecules/AppliedFilters\";\nimport QueryImprovementsPanel from \"@/components/organisms/QueryImprovementsPanel\";\nimport {\n useBooleanSearchBarDispatch,\n useBooleanSearchBarState,\n} from \"@/components/contexts/BooleanSearchBarControlContext\";\nimport { useBooleanSearchValidation } from \"@/utils/useBooleanSearchValidation\";\nimport { useSearchParams } from \"@/utils/urlHelpers\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { useQueryQueryImprovementCreate, useQueryQueryImprovementPoll } from \"@/api/queryImprovement\";\nimport type { JudgesAPIJudge } from \"@/api/queries/judges.types\";\nimport { getStageStatuses, QueryImprovementStage } from \"@/components/types/queryImprovement\";\nimport { featureEnabled } from \"@/utils/featureFlags\";\nimport { isGenerativeAIAvailable } from \"@/utils/queryCorrectionUtils\";\nimport { FEATURE_DISABLED_MESSAGE } from \"@/components/atoms/FeatureDisabledByAdmin\";\nimport { useEffectiveRailWidth } from \"@/components/AppShell/EffectiveRailWidthContext\";\n\ntype WorkingValues = {\n searchInput: string;\n additionalQueryInput: string;\n hearingDateFromInput: string;\n hearingDateToInput: string;\n caseNumberInput: string;\n caseNameInput: string;\n motionTypeInput: string;\n selectedJudges: JudgesAPIJudge[];\n};\n\nexport interface SearchOverlayProps {\n open: boolean;\n onClose: () => void;\n /**\n * Optional asynchronous gate that must resolve true before the submitted\n * query is committed to global state. Credit accounts use this to assign a\n * matter before query correction or improvement work can begin.\n */\n onBeforeSearch?: () => Promise;\n /**\n * Fired after SearchOverlay commits its working values to the Boolean-search\n * context and closes itself. The optional `info` payload lets the consumer\n * know whether the submitted query came from a picked suggestion in the\n * right-column improvements panel \u2014 used to suppress the corrector +\n * suggestion-loop on the resulting `/transcripts` page.\n */\n onSearch: (info?: { isSelectedQueryImprovement: boolean }) => void;\n advancedSearch?: boolean;\n onToggleAdvancedSearch?: () => void;\n /**\n * Optional override for the right column. When set, renders this slot.\n * When omitted, the column auto-renders QueryImprovementsPanel and only\n * shows when there are real suggestions. Stories pass a mock to visualize\n * the 2-column layout without a backend.\n */\n rightColumn?: ReactNode;\n}\n\nconst RIGHT_COLUMN_WIDTH = 392;\nconst WIDTH_WITH_RIGHT = 1008;\nconst WIDTH_WITHOUT_RIGHT = 740;\n// Anchor the overlay 20px below the AppShell topbar (60 + 20 = 80px from viewport top).\nconst TOP_OFFSET_FROM_TOPBAR = 20;\n\nconst InputAreaBox = styled(Box)<{ $focused: boolean }>(({ theme, $focused }) => ({\n border: `1px solid ${$focused ? theme.palette.secondary.dark : theme.border.light}`,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n padding: theme.spacing(1),\n backgroundColor: theme.palette.background.paper,\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.spacing(1),\n boxSizing: \"border-box\",\n width: \"100%\",\n transition: \"border-color 0.15s ease-out\",\n}));\n\nconst AdvancedFiltersContainer = styled(Box)(({ theme }) => ({\n border: `1px solid ${theme.border.light}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n padding: theme.spacing(1.5),\n backgroundColor: theme.palette.background.paper,\n display: \"flex\",\n flexDirection: \"column\",\n gap: theme.spacing(3),\n boxSizing: \"border-box\",\n width: \"100%\",\n}));\n\nconst RightColumnContainer = styled(Box)(({ theme }) => ({\n width: \"100%\",\n flexShrink: 0,\n boxSizing: \"border-box\",\n [theme.breakpoints.up(\"md\")]: {\n width: RIGHT_COLUMN_WIDTH,\n },\n}));\n\nconst SearchOverlay: React.FC = ({\n open,\n onClose,\n onBeforeSearch,\n onSearch,\n advancedSearch = false,\n onToggleAdvancedSearch,\n rightColumn,\n}) => {\n const effectiveRailWidth = useEffectiveRailWidth();\n const {\n searchInput,\n selectedJudges,\n additionalQueryInput,\n hearingDateFromInput,\n hearingDateToInput,\n caseNumberInput,\n caseNameInput,\n motionTypeInput,\n } = useBooleanSearchBarState();\n const {\n setSearchInput,\n setSelectedJudges,\n setAdditionalQueryInput,\n setHearingDateFromInput,\n setHearingDateToInput,\n setCaseNumberInput,\n setCaseNameInput,\n setMotionTypeInput,\n } = useBooleanSearchBarDispatch();\n\n // shouldExecuteSearch is flipped true at the tail of handleSearch to defer\n // onSearch until the context dispatches have flushed. The ref carries the\n // payload (isSelectedQueryImprovement) across that tick.\n const [shouldExecuteSearch, setShouldExecuteSearch] = useState(false);\n const pendingSearchInfoRef = useRef<{ isSelectedQueryImprovement: boolean } | undefined>(undefined);\n const searchCloseResolverRef = useRef<(() => void) | null>(null);\n\n useEffect(() => {\n if (shouldExecuteSearch) {\n setShouldExecuteSearch(false);\n onSearch(pendingSearchInfoRef.current);\n pendingSearchInfoRef.current = undefined;\n }\n }, [shouldExecuteSearch, onSearch]);\n\n useEffect(\n () => () => {\n searchCloseResolverRef.current?.();\n searchCloseResolverRef.current = null;\n },\n [],\n );\n\n const [workingValues, setWorkingValues] = useState({\n searchInput: \"\",\n additionalQueryInput: \"\",\n hearingDateFromInput: \"\",\n hearingDateToInput: \"\",\n caseNumberInput: \"\",\n caseNameInput: \"\",\n motionTypeInput: \"\",\n selectedJudges: [],\n });\n\n // Decoupled state \u2014 input focus drives the border color, tips visibility is\n // controlled by the lightbulb button only (does not auto-open on focus).\n const [inputFocused, setInputFocused] = useState(false);\n const [tipsOpen, setTipsOpen] = useState(false);\n // The action-bar motion.div needs overflow:hidden so its height animation\n // clips cleanly, but at rest that clips the focus ring of the flush filter\n // buttons (judge chip + advanced-filters icon). Keep it hidden only while\n // animating, then release to visible so focus outlines aren't cut off.\n const [actionBarAnimating, setActionBarAnimating] = useState(false);\n const inputAreaRef = useRef(null);\n const actionBarRef = useRef(null);\n\n const booleanSearchValidationState = useBooleanSearchValidation(workingValues.searchInput);\n const {\n validation: searchValidation,\n showError: showSearchValidationError,\n hasViolation: hasSearchValidationViolation,\n revealValidation: revealSearchValidation,\n } = booleanSearchValidationState;\n\n const modalFilterValues = useMemo(\n () => ({\n selectedJudges: workingValues.selectedJudges,\n hearingDateFromInput: workingValues.hearingDateFromInput || undefined,\n hearingDateToInput: workingValues.hearingDateToInput || undefined,\n caseNumberInput: workingValues.caseNumberInput || undefined,\n }),\n [\n workingValues.selectedJudges,\n workingValues.hearingDateFromInput,\n workingValues.hearingDateToInput,\n workingValues.caseNumberInput,\n ],\n );\n\n const [hasInitialized, setHasInitialized] = useState(false);\n\n // Snapshot of `searchInput` at overlay-open time. Drives the right-column\n // suggestions polling so the panel populates for whatever query the user\n // had in context (e.g. coming from /transcripts with an active query) but\n // does NOT re-poll as they type. Matches legacy AdvancedSearchModal\n // behavior, where `initialValues.searchInput` from TopSearchBar served the\n // same purpose.\n const [suggestionsSeed, setSuggestionsSeed] = useState(\"\");\n\n useEffect(() => {\n if (open && !hasInitialized) {\n setTipsOpen(false);\n const newWorkingValues: WorkingValues = {\n searchInput,\n additionalQueryInput: additionalQueryInput || \"\",\n hearingDateFromInput: hearingDateFromInput || \"\",\n hearingDateToInput: hearingDateToInput || \"\",\n caseNumberInput: caseNumberInput || \"\",\n caseNameInput: caseNameInput || \"\",\n motionTypeInput: motionTypeInput || \"\",\n selectedJudges: [...selectedJudges],\n };\n setWorkingValues(newWorkingValues);\n setSuggestionsSeed(searchInput);\n setHasInitialized(true);\n } else if (!open) {\n setHasInitialized(false);\n }\n }, [open]);\n\n const updateWorkingValue = (field: K, value: WorkingValues[K]) => {\n setWorkingValues((prev) => ({ ...prev, [field]: value }));\n };\n\n const handleFilterChange = (updatedValues?: {\n caseNumber?: string | undefined;\n hearingDateFrom?: string | undefined;\n hearingDateTo?: string | undefined;\n judges?: any[];\n }) => {\n if (!updatedValues) return;\n setWorkingValues((prev) => ({\n ...prev,\n ...(updatedValues.judges !== undefined && { selectedJudges: updatedValues.judges }),\n ...(\"hearingDateFrom\" in updatedValues && { hearingDateFromInput: updatedValues.hearingDateFrom ?? \"\" }),\n ...(\"hearingDateTo\" in updatedValues && { hearingDateToInput: updatedValues.hearingDateTo ?? \"\" }),\n ...(\"caseNumber\" in updatedValues && { caseNumberInput: updatedValues.caseNumber ?? \"\" }),\n }));\n };\n\n const handleCancel = () => {\n onClose();\n };\n\n const handleResetFilters = () => {\n setWorkingValues((prev) => ({\n ...prev,\n selectedJudges: [],\n hearingDateFromInput: \"\",\n hearingDateToInput: \"\",\n caseNumberInput: \"\",\n caseNameInput: \"\",\n motionTypeInput: \"\",\n }));\n };\n\n const handleSearch = async () => {\n if (searchCloseResolverRef.current) return;\n\n if (hasSearchValidationViolation) {\n revealSearchValidation();\n return;\n }\n\n // Did the submitted query come from a picked suggestion? True when the\n // current input matches the most recently-clicked improvement card.\n const isSelectedQueryImprovement = Boolean(\n internalSelectedQueryImprovementText &&\n workingValues.searchInput.trim() === internalSelectedQueryImprovementText.trim(),\n );\n pendingSearchInfoRef.current = { isSelectedQueryImprovement };\n\n setTipsOpen(false);\n await new Promise((resolve) => {\n searchCloseResolverRef.current = resolve;\n onClose();\n });\n\n const searchAllowed = onBeforeSearch ? await onBeforeSearch() : true;\n if (!searchAllowed) {\n pendingSearchInfoRef.current = undefined;\n return;\n }\n\n recordUserEvent({ event_name: \"do_search_from_advanced_search_modal\", event_properties: {} });\n\n // Commit working values to context. setShouldExecuteSearch fires onSearch\n // on the next tick once the dispatches have flushed.\n setSearchInput(workingValues.searchInput);\n setAdditionalQueryInput(workingValues.additionalQueryInput?.trim() || undefined);\n setHearingDateFromInput(workingValues.hearingDateFromInput?.trim() || undefined);\n setHearingDateToInput(workingValues.hearingDateToInput?.trim() || undefined);\n setCaseNumberInput(workingValues.caseNumberInput?.trim() || undefined);\n setCaseNameInput(workingValues.caseNameInput?.trim() || undefined);\n setMotionTypeInput(workingValues.motionTypeInput?.trim() || undefined);\n setSelectedJudges(workingValues.selectedJudges);\n setShouldExecuteSearch(true);\n };\n\n // Count of currently-applied filters (judges, dates, case number, case name, motion)\n const appliedFilterCount =\n (workingValues.selectedJudges.length > 0 ? 1 : 0) +\n (workingValues.hearingDateFromInput || workingValues.hearingDateToInput ? 1 : 0) +\n (workingValues.caseNumberInput ? 1 : 0) +\n (workingValues.caseNameInput ? 1 : 0) +\n (workingValues.motionTypeInput ? 1 : 0);\n\n // Suggested-queries polling (auto right column)\n const isAIDisabled = featureEnabled(\"disable_generative_ai\");\n const queryImprovementsEnabled = isGenerativeAIAvailable();\n const [searchParams] = useSearchParams();\n const disableQueryImprovements = searchParams.get(\"disableQueryImprovements\") === \"true\";\n\n // Drives the right-column polling. Captured once at overlay-open time so the\n // panel populates for whatever query the user had on context \u2014 but does NOT\n // re-poll as they edit (matches legacy AdvancedSearchModal behavior).\n const suggestionsQueryText = suggestionsSeed;\n\n const pollParams = useMemo(\n () => ({\n judgeIds: searchParams.get(\"judgeIds\") || undefined,\n hearingDateFrom: searchParams.get(\"hearingDateFrom\") || undefined,\n hearingDateTo: searchParams.get(\"hearingDateTo\") || undefined,\n caseId: searchParams.get(\"caseId\") || undefined,\n caseNumber: searchParams.get(\"caseNumber\") || undefined,\n additionalQuery: searchParams.get(\"additionalQuery\") || undefined,\n caseName: searchParams.get(\"caseName\") || undefined,\n motionType: searchParams.get(\"motionType\") || undefined,\n }),\n [searchParams],\n );\n\n const shouldShowImprovements = Boolean(\n suggestionsQueryText && suggestionsQueryText.trim() && queryImprovementsEnabled && !disableQueryImprovements,\n );\n\n const createQuery = useQueryQueryImprovementCreate(suggestionsQueryText.trim(), shouldShowImprovements && open);\n const runId = createQuery.data?.run_id;\n\n const pollQuery = useQueryQueryImprovementPoll(\n runId || \"\",\n pollParams,\n Boolean(runId && shouldShowImprovements && open),\n );\n\n const stages = pollQuery.data?.data?.stages;\n const stageStatuses = getStageStatuses(stages);\n const allNoSuggestions = stageStatuses.every((status) => status === \"done_no_suggestion\");\n const allErrored = stageStatuses.every((status) => status === \"error\");\n const suggestedQueriesReady = shouldShowImprovements && Boolean(stages) && !allNoSuggestions && !allErrored;\n\n // Snapshot at open time: were all three stages already in a terminal state\n // when the overlay opened? If so, the user is \"viewing\" pre-loaded\n // suggestions (typically clicking \"view suggestions\" on the topbar status\n // chip) \u2014 in that flow the transient \"No further is recommended\"\n // green chips read as noise, so we suppress them and only render the real\n // suggestion cards. Captured once on the open transition and held until\n // the overlay closes, so newly-arriving data mid-overlay doesn't flip\n // the behavior.\n const [suppressNoSuggestionChipsOnOpen, setSuppressNoSuggestionChipsOnOpen] = useState(false);\n useEffect(() => {\n if (open) {\n const snapshotStages = pollQuery.data?.data?.stages;\n const allSettled = snapshotStages\n ? ([\"suggested\", \"broaden\", \"narrow\"] as const).every((key) => {\n const s = snapshotStages[key]?.status;\n return s === \"done_with_suggestion\" || s === \"done_no_suggestion\" || s === \"error\";\n })\n : false;\n setSuppressNoSuggestionChipsOnOpen(allSettled);\n } else {\n setSuppressNoSuggestionChipsOnOpen(false);\n }\n // Intentionally not dependent on pollQuery.data \u2014 we want the snapshot\n // taken at the moment of `open` going true, not re-evaluated as the\n // poll progresses during the overlay's lifetime.\n }, [open]);\n\n const [internalSelectedStage, setInternalSelectedStage] = useState(undefined);\n const [internalSelectedQueryImprovementText, setInternalSelectedQueryImprovementText] = useState(\n undefined,\n );\n\n const handleSelectQuery = (stage: QueryImprovementStage, query: string) => {\n setInternalSelectedStage(stage);\n setInternalSelectedQueryImprovementText(query);\n updateWorkingValue(\"searchInput\", query);\n };\n\n // Deselect when the user types over a picked suggestion. Prevents stale\n // \"isSelectedQueryImprovement=true\" on submit when the input no longer\n // matches the picked query.\n useEffect(() => {\n if (internalSelectedQueryImprovementText && workingValues.searchInput !== internalSelectedQueryImprovementText) {\n setInternalSelectedStage(undefined);\n setInternalSelectedQueryImprovementText(undefined);\n }\n }, [workingValues.searchInput, internalSelectedQueryImprovementText]);\n\n // Gate on `runId` in addition to `suggestedQueriesReady` so TypeScript\n // can narrow it to string when passing to QueryImprovementsPanel. In\n // practice the two conditions move together \u2014 `suggestedQueriesReady`\n // requires `stages` to exist, which requires the poll to have fired,\n // which requires `runId` to have been set \u2014 but the type system can't\n // infer that linkage, so make it explicit at the JSX site.\n const autoRightColumn =\n suggestedQueriesReady && runId ? (\n \n ) : null;\n const resolvedRightColumn = rightColumn !== undefined ? rightColumn : autoRightColumn;\n const hasRightColumn = resolvedRightColumn !== null && resolvedRightColumn !== undefined;\n const overlayWidth = hasRightColumn ? WIDTH_WITH_RIGHT : WIDTH_WITHOUT_RIGHT;\n\n return (\n {\n searchCloseResolverRef.current?.();\n searchCloseResolverRef.current = null;\n },\n }}\n // Inset the dialog root by the SideNav rail width so the overlay (and\n // its backdrop) sit inside AppShell's column 2 / MainArea. Keeps the\n // rail interactive and visually unobscured; the Paper auto-centers in\n // the remaining post-rail area.\n // Anchor to the top (not vertically centered) so expanding tips /\n // advanced doesn't shift the overlay's position.\n sx={{\n left: `${effectiveRailWidth}px`,\n \"& .MuiDialog-container\": { alignItems: \"flex-start\" },\n }}\n slotProps={{\n backdrop: {\n sx: {\n backgroundColor: alpha(colors.taupe[300], 0.2),\n left: `${effectiveRailWidth}px`,\n },\n },\n }}\n PaperProps={{\n sx: (theme) => ({\n width: { xs: \"calc(100% - 48px)\", md: overlayWidth },\n maxWidth: \"calc(100% - 48px)\",\n maxHeight: `calc(100vh - ${theme.tokens.layout.appShellTopBarHeight + TOP_OFFSET_FROM_TOPBAR + 24}px)`,\n marginTop: `${theme.tokens.layout.appShellTopBarHeight + TOP_OFFSET_FROM_TOPBAR}px`,\n padding: 0,\n display: \"flex\",\n flexDirection: \"column\",\n backgroundColor: \"background.paper\",\n border: `1px solid ${theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n boxShadow: theme.tokens.shadows.xl,\n overflow: \"hidden\",\n }),\n }}\n >\n {/* SectionHeader: 24px around except bottom, fixed at top of paper */}\n \n \n Search transcripts\n \n \n \n\n {/* MainContent: 8px top, 24px other sides, scrolls internally when content overflows */}\n \n \n \n {/* InputArea: input + lightbulb + animated tips, 8px padding/gap.\n Height is content-driven in every variant \u2014 no local override\n when the right column is visible, so the input collapses to\n its natural size and the suggestions column owns its own\n height independently. */}\n \n updateWorkingValue(\"searchInput\", e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void handleSearch();\n }\n }}\n onFocus={() => setInputFocused(true)}\n onBlur={() => setInputFocused(false)}\n value={workingValues.searchInput}\n sx={{\n \"& .MuiInputBase-root\": {\n // Inner input padding per Figma: 16px top/bottom, 12px left/right.\n // Outer InputAreaBox provides the 8px chrome around this.\n padding: \"16px 12px\",\n },\n ...(showSearchValidationError && {\n \"& .MuiInputBase-input\": {\n textDecorationLine: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationSkipInk: \"none\",\n textDecorationColor: \"var(--error-main, #D32F2F)\",\n textDecorationThickness: \"1.44px\",\n textUnderlinePosition: \"from-font\",\n },\n }),\n }}\n />\n {/* Actions row (Figma .SearchInputArea): tips lightbulb left, search submit right */}\n \n \n setTipsOpen((prev) => !prev)}\n icon={\n tipsOpen ? (\n \n ) : (\n \n )\n }\n />\n \n \n void handleSearch()}\n />\n \n \n \n {tipsOpen && (\n \n \n \n )}\n \n \n\n \n {showSearchValidationError && (\n \n \n {searchValidation.isValid ? \"\" : searchValidation.errorMessage}\n \n \n )}\n \n\n {/* ActionBar (default) \u2194 AdvancedFiltersContainer (when expanded) \u2014 never both */}\n \n {advancedSearch ? (\n \n \n \n \n Advanced Filters\n \n \n \n\n \n\n updateWorkingValue(\"caseNameInput\", event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n const next = (event.target as HTMLElement)\n .closest(\".MuiTextField-root\")\n ?.nextElementSibling?.querySelector(\"input\");\n if (next) {\n (next as HTMLElement).focus();\n } else {\n (event.target as HTMLElement).blur();\n }\n }\n }}\n />\n\n {!isAIDisabled && (\n \n \n \n ),\n }}\n value={workingValues.motionTypeInput}\n onChange={(event) => updateWorkingValue(\"motionTypeInput\", event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n (event.target as HTMLElement).blur();\n }\n }}\n />\n )}\n\n \n \n Reset filters\n \n void handleSearch()}>\n Search\n \n \n \n \n ) : (\n setActionBarAnimating(true)}\n onAnimationComplete={() => setActionBarAnimating(false)}\n style={{ overflow: actionBarAnimating ? \"hidden\" : \"visible\" }}\n >\n \n {/* Judge chip + any applied date / case-number chips */}\n \n \n 0\n ? `Advanced filters (${appliedFilterCount} applied)`\n : \"Advanced filters\"\n }\n onClick={onToggleAdvancedSearch}\n />\n \n \n \n )}\n \n \n\n {hasRightColumn && {resolvedRightColumn}}\n \n \n \n );\n};\n\nexport default SearchOverlay;\n", "const BROWSER_EXTENSION_PROTOCOLS = [\n \"chrome-extension://\",\n \"moz-extension://\",\n \"safari-extension://\",\n \"safari-web-extension://\",\n];\n\nconst SOURCE_PROTOCOL_PATTERN = /[a-z][a-z0-9+.-]*:\\/\\//i;\n\nconst findSourceProtocol = (value: string): { protocol: string; index: number } | undefined => {\n const match = value.match(SOURCE_PROTOCOL_PATTERN);\n\n return match?.index === undefined ? undefined : { protocol: match[0].toLowerCase(), index: match.index };\n};\n\nconst isBrowserExtensionProtocol = (protocol: string): boolean => BROWSER_EXTENSION_PROTOCOLS.includes(protocol);\n\nconst readProperty = (value: unknown, property: string): unknown => {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) return undefined;\n\n try {\n return (value as Record)[property];\n } catch (_error) {\n return undefined;\n }\n};\n\nconst classifyStackOrigin = (value: unknown): boolean | undefined => {\n if (typeof value !== \"string\" || value.trim() === \"\") return undefined;\n\n for (const line of value.split(/\\r?\\n/)) {\n const trimmedLine = line.trim();\n const sourceProtocol = findSourceProtocol(trimmedLine);\n\n if (\n sourceProtocol !== undefined &&\n (sourceProtocol.index === 0 ||\n trimmedLine.startsWith(\"at \") ||\n trimmedLine.lastIndexOf(\"@\", sourceProtocol.index) >= 0)\n ) {\n return isBrowserExtensionProtocol(sourceProtocol.protocol);\n }\n }\n\n return undefined;\n};\n\nconst classifyDirectSource = (value: unknown): boolean | undefined => {\n if (typeof value !== \"string\" || value.trim() === \"\") return undefined;\n\n const sourceProtocol = findSourceProtocol(value.trim());\n\n return sourceProtocol === undefined ? undefined : isBrowserExtensionProtocol(sourceProtocol.protocol);\n};\n\nconst classifyErrorOrigin = (value: unknown): boolean | undefined => {\n const directSources = [\"filename\", \"fileName\", \"sourceURL\"]\n .map((property) => classifyDirectSource(readProperty(value, property)))\n .filter((classification): classification is boolean => classification !== undefined);\n\n if (directSources.length > 0) return directSources.some(Boolean);\n\n return classifyStackOrigin(readProperty(value, \"stack\"));\n};\n\nconst firstDefined = (...values: Array): boolean =>\n values.find((value) => value !== undefined) ?? false;\n\nexport const shouldIgnoreCloudWatchRumError = (event: ErrorEvent | PromiseRejectionEvent): boolean =>\n firstDefined(\n classifyDirectSource(readProperty(event, \"filename\")),\n classifyErrorOrigin(readProperty(event, \"error\")),\n classifyErrorOrigin(readProperty(event, \"reason\")),\n );\n", "import React from \"react\";\nimport Fade from \"@mui/material/Fade\";\nimport { Check, AlertCircle, SearchCheck, RefreshCw, type LucideIcon } from \"lucide-react\";\nimport { useQueryQueryImprovementPoll } from \"@/api/queryImprovement\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport AnimatedEllipsis from \"./AnimatedEllipsis\";\nimport { BIQChip, type BIQChipColor } from \"./BIQChip\";\nimport { QueryImprovementStatus } from \"../types/queryImprovement\";\n\nconst chipForms: Record<\n Exclude,\n {\n icon?: LucideIcon;\n label: React.ReactNode;\n color?: BIQChipColor;\n }\n> = {\n reviewing: {\n icon: RefreshCw,\n label: (\n <>\n Reviewing your query\n \n \n ),\n },\n loading_suggestions: {\n icon: SearchCheck,\n label: (\n <>\n Loading suggestions\n \n \n ),\n color: \"info\",\n },\n view_suggestions: {\n icon: SearchCheck,\n label: \"View suggestions\",\n color: \"info\",\n },\n done_no_suggestions: {\n icon: Check,\n label: \"Your query follows best practices\",\n color: \"success\",\n },\n done_error: {\n icon: AlertCircle,\n label: \"Unable to load suggestions\",\n color: \"error\",\n },\n};\n\n// This is pulled out and exported to make it easier to test the Chip component in isolation\n// i.e. we can just pass in a status string to see the behavior rather than have to construct\n// a UseQueryResult.\nexport const computeQueryImprovementStatus = (\n pollResult: ReturnType,\n): QueryImprovementStatus => {\n if (pollResult.data === undefined) {\n return \"not_active\";\n }\n\n const runStatus = pollResult.data.data.run_status;\n return runStatus || \"not_active\";\n};\n\ninterface QueryImprovementChipProps {\n status: QueryImprovementStatus;\n hidden?: boolean;\n onClick?: () => void;\n}\n\nconst QueryImprovementChip: React.FC = ({ status, hidden = false, onClick }) => {\n if (status === \"not_active\") {\n return null;\n }\n\n const form = chipForms[status];\n const interactable = status === \"view_suggestions\" || status === \"reviewing\" || status === \"loading_suggestions\";\n\n return (\n \n {\n recordUserEvent({\n event_name: \"click_query_improvement_chip\",\n event_properties: { status },\n });\n if (interactable) {\n onClick?.();\n }\n }}\n size=\"medium\"\n />\n \n );\n};\n\nexport default QueryImprovementChip;\n", "import React, { useMemo } from \"react\";\nimport { useBooleanSearchBarState } from \"@/components/contexts/BooleanSearchBarControlContext\";\nimport { useLocation, useSearchParams } from \"@/utils/urlHelpers\";\nimport { useQueryQueryImprovementCreate, useQueryQueryImprovementPoll } from \"@/api/queryImprovement\";\nimport { isGenerativeAIAvailable } from \"@/utils/queryCorrectionUtils\";\nimport { isCreditBillingLive } from \"@/utils/creditBilling\";\nimport QueryImprovementChip, { computeQueryImprovementStatus } from \"./QueryImprovementChip\";\n\ninterface TopBarStatusChipProps {\n /**\n * Fires when the user clicks an interactable chip state (`reviewing`,\n * `loading_suggestions`, `view_suggestions`). Wired by AppShellLayout to\n * open the SearchOverlay so the user can see / interact with the\n * suggestions that the chip is announcing.\n */\n onClick: () => void;\n}\n\n/**\n * TopBarStatusChip \u2014 drives the persistent QueryImprovementChip in the\n * AppShell topbar. Runs its own create + poll against the Boolean-search\n * context's `searchInput` so the chip reflects the active page's query\n * regardless of whether the SearchOverlay is open. React Query's query-key\n * deduping shares the cached result with SearchOverlay's own polling when\n * both are mounted, so this doesn't double-fetch.\n *\n * On Home (empty searchInput) the chip is `not_active` \u2192 renders null.\n * On /transcripts with an active query it cycles through:\n * reviewing \u2192 loading_suggestions \u2192 view_suggestions | done_no_suggestions | done_error\n */\nexport const TopBarStatusChip: React.FC = ({ onClick }) => {\n const { searchInput } = useBooleanSearchBarState();\n const [searchParams] = useSearchParams();\n const location = useLocation();\n\n const trimmedQuery = searchInput?.trim() ?? \"\";\n const queryImprovementsEnabled = isGenerativeAIAvailable();\n const disableQueryImprovements = searchParams.get(\"disableQueryImprovements\") === \"true\";\n const isUnadmittedCreditSearch =\n isCreditBillingLive() && location.pathname === \"/transcripts\" && !searchParams.get(\"creditSearchExecutionId\");\n const shouldShowImprovements = Boolean(\n trimmedQuery && queryImprovementsEnabled && !disableQueryImprovements && !isUnadmittedCreditSearch,\n );\n\n const createQuery = useQueryQueryImprovementCreate(trimmedQuery, shouldShowImprovements);\n const runId = createQuery.data?.run_id;\n\n // Pass the current URL's filter params so the poll keys match what\n // QueryResultsPage's own poll uses (same run / same cache entry).\n const pollParams = useMemo(\n () => ({\n judgeIds: searchParams.get(\"judgeIds\") || undefined,\n hearingDateFrom: searchParams.get(\"hearingDateFrom\") || undefined,\n hearingDateTo: searchParams.get(\"hearingDateTo\") || undefined,\n caseId: searchParams.get(\"caseId\") || undefined,\n caseNumber: searchParams.get(\"caseNumber\") || undefined,\n additionalQuery: searchParams.get(\"additionalQuery\") || undefined,\n caseName: searchParams.get(\"caseName\") || undefined,\n motionType: searchParams.get(\"motionType\") || undefined,\n }),\n [searchParams],\n );\n\n const pollQuery = useQueryQueryImprovementPoll(runId || \"\", pollParams, Boolean(runId && shouldShowImprovements));\n\n const status = computeQueryImprovementStatus(pollQuery);\n\n return ;\n};\n\nexport default TopBarStatusChip;\n", "import React, { useEffect, useState } from \"react\";\nimport { Box, Dialog, Stack, Typography } from \"@mui/material\";\nimport { alpha } from \"@mui/material/styles\";\nimport { X } from \"lucide-react\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQIconButton } from \"@/components/atoms/BIQIconButton\";\nimport MatterCodeAutocomplete from \"@/components/molecules/MatterCodeAutocomplete\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { colors } from \"@/components/theme/tokens\";\nimport { useEffectiveRailWidth } from \"@/components/AppShell/EffectiveRailWidthContext\";\nimport { useClientMatter } from \"@/contexts/ClientMatterContext\";\nimport { MODAL_WIDTH } from \"@/utils/constants\";\n\nconst TOP_OFFSET_FROM_TOPBAR = 20;\nconst MODAL_BUTTON_SX = { paddingTop: \"7px\", paddingBottom: \"7px\" } as const;\n\ntype CreditMatterModalVariant = \"add\" | \"update_search\" | \"confirm_agent\" | \"expired\" | \"locked_agent_timeout\";\ntype MatterModalSubmitSource = \"button\" | \"enter_key\";\ntype MatterModalExitEventName =\n | \"credit_matter_modal_cancel_button_clicked\"\n | \"credit_matter_modal_close_button_clicked\"\n | \"credit_matter_modal_escape_key_pressed\"\n | \"credit_matter_modal_backdrop_clicked\";\n\nconst ClientMatterModal = () => {\n const effectiveRailWidth = useEffectiveRailWidth();\n const {\n activeMatterCode,\n prompt,\n lockedAgentMatter,\n setActiveMatter,\n clearActiveMatter,\n resolvePrompt,\n continueExpiredMatter,\n } = useClientMatter();\n const [displayPrompt, setDisplayPrompt] = useState(prompt);\n const [matterCode, setMatterCode] = useState(\"\");\n const [error, setError] = useState(null);\n const [submitting, setSubmitting] = useState(false);\n const open = Boolean(prompt);\n const renderedPrompt = prompt || displayPrompt;\n const locked = renderedPrompt?.mode === \"expired\" && Boolean(renderedPrompt.lockedMatterCode);\n const mode = locked ? \"locked_agent_session\" : renderedPrompt?.mode;\n const dismissible = mode !== \"expired\" && !locked;\n const modalVariant: CreditMatterModalVariant | null =\n mode === \"locked_agent_session\" ? \"locked_agent_timeout\" : mode || null;\n\n useEffect(() => {\n if (!open) return;\n setDisplayPrompt(prompt);\n setMatterCode(prompt?.lockedMatterCode || prompt?.initialCode || \"\");\n setError(null);\n }, [open, prompt]);\n\n const submit = async (source: MatterModalSubmitSource) => {\n if (modalVariant) {\n if (source === \"enter_key\") {\n if (modalVariant !== \"locked_agent_timeout\") {\n void recordUserEvent({\n event_name: \"credit_matter_modal_enter_key_pressed\",\n event_properties: { modal_variant: modalVariant },\n });\n }\n } else if (modalVariant === \"update_search\") {\n void recordUserEvent({\n event_name: \"credit_matter_modal_save_button_clicked\",\n event_properties: { modal_variant: \"update_search\" },\n });\n } else {\n void recordUserEvent({\n event_name: \"credit_matter_modal_continue_button_clicked\",\n event_properties: { modal_variant: modalVariant },\n });\n }\n }\n setSubmitting(true);\n setError(null);\n try {\n if (mode === \"locked_agent_session\") {\n const normalized = await continueExpiredMatter(matterCode);\n resolvePrompt(normalized);\n } else {\n const normalized = await setActiveMatter(matterCode);\n resolvePrompt(normalized);\n }\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : \"Enter a valid matter number.\");\n } finally {\n setSubmitting(false);\n }\n };\n\n const submitOnEnter = (event: React.KeyboardEvent) => {\n if (event.key !== \"Enter\") return;\n (event as React.KeyboardEvent & { defaultMuiPrevented?: boolean }).defaultMuiPrevented = true;\n event.preventDefault();\n event.currentTarget.closest(\"form\")?.requestSubmit();\n };\n\n const submitForm = (event: React.FormEvent) => {\n event.preventDefault();\n if (!matterCode.trim() || submitting) return;\n void submit(\"enter_key\");\n };\n\n const cancel = (eventName: MatterModalExitEventName) => {\n if (\n eventName === \"credit_matter_modal_cancel_button_clicked\" &&\n modalVariant &&\n modalVariant !== \"locked_agent_timeout\"\n ) {\n void recordUserEvent({\n event_name: \"credit_matter_modal_cancel_button_clicked\",\n event_properties: { modal_variant: modalVariant },\n });\n }\n const dismissibleModalVariant =\n modalVariant && modalVariant !== \"expired\" && modalVariant !== \"locked_agent_timeout\" ? modalVariant : null;\n if (dismissibleModalVariant) {\n if (eventName === \"credit_matter_modal_close_button_clicked\") {\n void recordUserEvent({\n event_name: \"credit_matter_modal_close_button_clicked\",\n event_properties: { modal_variant: dismissibleModalVariant },\n });\n } else if (eventName === \"credit_matter_modal_escape_key_pressed\") {\n void recordUserEvent({\n event_name: \"credit_matter_modal_escape_key_pressed\",\n event_properties: { modal_variant: dismissibleModalVariant },\n });\n } else if (eventName === \"credit_matter_modal_backdrop_clicked\") {\n void recordUserEvent({\n event_name: \"credit_matter_modal_backdrop_clicked\",\n event_properties: { modal_variant: dismissibleModalVariant },\n });\n }\n }\n if (mode === \"expired\") clearActiveMatter();\n resolvePrompt(null);\n };\n\n const handleDialogClose = (_event: object, reason: \"backdropClick\" | \"escapeKeyDown\") =>\n cancel(\n reason === \"escapeKeyDown\" ? \"credit_matter_modal_escape_key_pressed\" : \"credit_matter_modal_backdrop_clicked\",\n );\n\n const startNewSession = () => {\n void recordUserEvent({\n event_name: \"credit_matter_modal_start_new_session_button_clicked\",\n event_properties: { modal_variant: \"locked_agent_timeout\" },\n });\n clearActiveMatter();\n resolvePrompt(null);\n lockedAgentMatter?.startNewSession();\n };\n\n const title =\n mode === \"add\"\n ? \"Add matter number\"\n : mode === \"locked_agent_session\"\n ? \"Confirm active matter\"\n : mode === \"update_search\"\n ? \"Update active matter\"\n : \"Confirm active matter\";\n const body =\n mode === \"locked_agent_session\" ? (\n <>\n You've been inactive for a while. Before continuing, confirm that new credit usage in this session should remain\n assigned to Matter {renderedPrompt?.lockedMatterCode}. To use a different matter, start a new\n session.\n \n ) : mode === \"expired\" ? (\n <>\n You've been inactive for a while. Before continuing, confirm that new credit usage in Bench IQ should be\n assigned to Matter {renderedPrompt?.initialCode || activeMatterCode} or assign a new matter to\n continue.\n \n ) : mode === \"confirm_agent\" ? (\n \"Bench IQ agent uses credits. Usage for this new session will be assigned to the matter below.\"\n ) : mode === \"update_search\" ? (\n <>\n Search credits are currently assigned to Matter {activeMatterCode}. To assign new searches to a\n different matter, enter a new matter number to continue. Usage already recorded under Matter{\" \"}\n {activeMatterCode} will not be affected.\n \n ) : (\n \"Bench IQ uses credits when it performs research or retrieves results. Add a matter number to continue.\"\n );\n\n return (\n ({\n width: { xs: \"calc(100% - 48px)\", sm: MODAL_WIDTH },\n maxWidth: \"calc(100% - 48px)\",\n maxHeight: `calc(100vh - ${theme.tokens.layout.appShellTopBarHeight + TOP_OFFSET_FROM_TOPBAR + 24}px)`,\n marginTop: `${theme.tokens.layout.appShellTopBarHeight + TOP_OFFSET_FROM_TOPBAR}px`,\n padding: 0,\n display: \"flex\",\n flexDirection: \"column\",\n backgroundColor: \"background.paper\",\n border: `1px solid ${theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n boxShadow: theme.tokens.shadows.lg,\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n }),\n }}\n >\n \n \n {title}\n {dismissible && (\n cancel(\"credit_matter_modal_close_button_clicked\")}\n aria-label=\"Close\"\n sx={{ position: \"absolute\", top: 24, right: 23 }}\n />\n )}\n \n \n \n \n {body}\n \n \n {locked ? (\n \n Start a new session\n \n ) : (\n cancel(\"credit_matter_modal_cancel_button_clicked\")}\n sx={MODAL_BUTTON_SX}\n >\n Cancel\n \n )}\n void submit(\"button\")}\n sx={MODAL_BUTTON_SX}\n >\n {mode === \"update_search\" ? \"Save\" : \"Continue\"}\n \n \n \n \n \n );\n};\n\nexport default ClientMatterModal;\n", "import React from \"react\";\nimport { Alert, Box, Dialog, Stack, Typography } from \"@mui/material\";\nimport { alpha } from \"@mui/material/styles\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport MatterCodeAutocomplete from \"@/components/molecules/MatterCodeAutocomplete\";\nimport { colors } from \"@/components/theme/tokens\";\nimport { useEffectiveRailWidth } from \"@/components/AppShell/EffectiveRailWidthContext\";\nimport { useOptionalCreditAgentSpeedBump } from \"@/contexts/CreditAgentSpeedBumpContext\";\nimport { MODAL_WIDTH } from \"@/utils/constants\";\n\nconst TOP_OFFSET_FROM_TOPBAR = 20;\nconst MODAL_BUTTON_SX = { paddingTop: \"7px\", paddingBottom: \"7px\" } as const;\nconst usdFormatter = new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n});\n\nfunction formatUsd(value: string | number | undefined): string {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? usdFormatter.format(parsed) : \"the configured\";\n}\n\nconst CreditAgentSpeedBumpModal = () => {\n const effectiveRailWidth = useEffectiveRailWidth();\n const speedBump = useOptionalCreditAgentSpeedBump();\n const prompt = speedBump?.prompt;\n const requirement = prompt?.requirement;\n const matterCode = requirement?.clientMatterCode || prompt?.request.clientMatterCode || \"\";\n\n return (\n ({\n width: { xs: \"calc(100% - 48px)\", sm: MODAL_WIDTH },\n maxWidth: \"calc(100% - 48px)\",\n maxHeight: `calc(100vh - ${theme.tokens.layout.appShellTopBarHeight + TOP_OFFSET_FROM_TOPBAR + 24}px)`,\n marginTop: `${theme.tokens.layout.appShellTopBarHeight + TOP_OFFSET_FROM_TOPBAR}px`,\n padding: 0,\n backgroundColor: \"background.paper\",\n border: `1px solid ${theme.border.default}`,\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n boxShadow: theme.tokens.shadows.lg,\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n }),\n }}\n >\n \n \n \n Continue past {formatUsd(requirement?.warningLevelUsd)} on this conversation?\n \n \n This conversation has reached {formatUsd(requirement?.warningLevelUsd)}, billed to Matter{\" \"}\n {matterCode}. Bench IQ checks in at every {formatUsd(requirement?.thresholdUsd)} so spend\n stays visible.\n \n undefined}\n disabled\n placeholder=\"Enter a matter number...\"\n />\n {speedBump?.error && {speedBump.error}}\n \n \n Cancel request\n \n void speedBump?.confirm()}\n sx={MODAL_BUTTON_SX}\n >\n Continue\n \n \n \n \n \n );\n};\n\nexport default CreditAgentSpeedBumpModal;\n", "import { isCreditBillingLive } from \"@/utils/creditBilling\";\n\nconst needsClientMatter = () => Boolean(window.userSignedIn) && isCreditBillingLive();\n\nexport default needsClientMatter;\n", "import { useEffect } from \"react\";\nimport { useOptionalClientMatter } from \"@/contexts/ClientMatterContext\";\nimport { useLocation, useNavigate } from \"@/utils/urlHelpers\";\nimport { isCreditBillingLive } from \"@/utils/creditBilling\";\nimport {\n CREDIT_MATTER_LAUNCH_QUERY_PARAM,\n queueCreditSearchOverlay,\n type CreditMatterLaunch,\n} from \"@/utils/creditMatterLaunch\";\n\nconst launchFromSearch = (search: string): CreditMatterLaunch | null => {\n const value = new URLSearchParams(search).get(CREDIT_MATTER_LAUNCH_QUERY_PARAM);\n return value === \"session\" || value === \"search\" ? value : null;\n};\n\nconst CreditMatterLaunchHandler = () => {\n const location = useLocation();\n const navigate = useNavigate();\n const clientMatter = useOptionalClientMatter();\n const ensureMatter = clientMatter?.ensureMatter;\n\n useEffect(() => {\n const launch = location.pathname === \"/\" ? launchFromSearch(location.search) : null;\n if (!launch || !ensureMatter || !isCreditBillingLive()) return;\n\n let cancelled = false;\n void ensureMatter().then((matterCode) => {\n if (cancelled) return;\n\n const nextParams = new URLSearchParams(location.search);\n nextParams.delete(CREDIT_MATTER_LAUNCH_QUERY_PARAM);\n if (matterCode && launch === \"search\") queueCreditSearchOverlay();\n navigate(\n {\n pathname: location.pathname,\n search: nextParams.toString() ? `?${nextParams.toString()}` : undefined,\n },\n { replace: true },\n );\n });\n\n return () => {\n cancelled = true;\n };\n }, [ensureMatter, location.pathname, location.search, navigate]);\n\n return null;\n};\n\nexport default CreditMatterLaunchHandler;\n", "import React, { useCallback, useState } from \"react\";\nimport Box from \"@mui/material/Box\";\n\nexport type McpClientIconSize = \"compact\" | \"standard\";\n\nconst sizes: Record = {\n compact: 36,\n standard: 44,\n};\nconst approvedLogoPath = /^\\/mcp\\/client-icons\\/[A-Za-z0-9][A-Za-z0-9._-]*\\.(?:png|webp)$/;\nexport const isApprovedMcpClientLogoPath = (src?: string | null): src is string =>\n Boolean(src && approvedLogoPath.test(src));\n\ninterface McpClientIconProps {\n src?: string | null;\n size?: McpClientIconSize;\n onAvailabilityChange?: (available: boolean) => void;\n}\n\ninterface ApprovedClientImageProps extends Required> {\n src: string;\n onAvailabilityChange?: (available: boolean) => void;\n}\n\nconst ApprovedClientImage: React.FC = ({ src, size, onAvailabilityChange }) => {\n const [status, setStatus] = useState<\"loading\" | \"loaded\" | \"failed\">(\"loading\");\n const dimension = sizes[size];\n const handleImageRef = useCallback(\n (image: HTMLImageElement | null) => {\n if (!image) return;\n\n if (!image.complete) {\n onAvailabilityChange?.(false);\n return;\n }\n\n const loaded = image.naturalWidth > 0;\n setStatus(loaded ? \"loaded\" : \"failed\");\n onAvailabilityChange?.(loaded);\n },\n [onAvailabilityChange],\n );\n\n if (status === \"failed\") return null;\n\n return (\n {\n setStatus(\"loaded\");\n onAvailabilityChange?.(true);\n }}\n onError={() => {\n setStatus(\"failed\");\n onAvailabilityChange?.(false);\n }}\n sx={(theme) => ({\n display: status === \"loaded\" ? \"block\" : \"none\",\n width: dimension,\n height: dimension,\n flex: \"0 0 auto\",\n border: 0,\n borderRadius: `${theme.tokens.radii.smallRadius}px`,\n backgroundColor: \"transparent\",\n objectFit: \"contain\",\n })}\n />\n );\n};\n\nexport const McpClientIcon: React.FC = ({ src, size = \"compact\", onAvailabilityChange }) => {\n const approvedSrc = isApprovedMcpClientLogoPath(src) ? src : null;\n if (!approvedSrc) return null;\n\n return (\n \n );\n};\n", "import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport Alert from \"@mui/material/Alert\";\nimport Box from \"@mui/material/Box\";\nimport CircularProgress from \"@mui/material/CircularProgress\";\nimport Divider from \"@mui/material/Divider\";\nimport FormControl from \"@mui/material/FormControl\";\nimport Paper from \"@mui/material/Paper\";\nimport Radio from \"@mui/material/Radio\";\nimport RadioGroup from \"@mui/material/RadioGroup\";\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\nimport { visuallyHidden } from \"@mui/utils\";\nimport { CheckCircle2, CircleAlert, ShieldCheck } from \"lucide-react\";\nimport {\n fetchMcpOauthConsent,\n McpOauthConsent,\n McpOauthError,\n McpOauthMode,\n submitMcpOauthConsent,\n} from \"../../api/mcpOAuth\";\nimport { BIQButton } from \"../atoms/BIQButton\";\nimport { Icon } from \"../icons/Icon\";\nimport { McpClientIcon } from \"./McpClientIcon\";\nimport { colors } from \"../theme/tokens/colors\";\nimport { focusRing } from \"../theme/mixins/focusRing\";\n\ninterface Props {\n authorizationTransactionId?: string;\n onRedirect?: (location: string) => void;\n initialConsent?: McpOauthConsent;\n initialError?: string;\n initialExpired?: boolean;\n initialSubmitting?: boolean;\n motionPreference?: boolean;\n}\n\n// Interim copy, design to confirm. Neither mode asks about paid court filings (D10).\nconst MODE_COPY: Record = {\n autonomous: {\n title: \"Work automatically\",\n description: \"Bench IQ uses its best judgment instead of stopping to ask you questions.\",\n },\n interactive: {\n title: \"Ask when needed\",\n description: \"Bench IQ pauses to ask you a question when your request is unclear.\",\n },\n};\n\nconst oauthFailure = (reason: unknown): McpOauthError | undefined => {\n if (!reason || typeof reason !== \"object\") return undefined;\n const candidate = reason as Partial;\n if (\n typeof candidate.code !== \"string\" ||\n typeof candidate.message !== \"string\" ||\n typeof candidate.retryable !== \"boolean\"\n ) {\n return undefined;\n }\n return candidate as McpOauthError;\n};\n\nfunction ModeCard({ mode, selected, disabled }: { mode: McpOauthMode; selected: boolean; disabled: boolean }) {\n const copy = MODE_COPY[mode];\n const descriptionId = `mcp-oauth-${mode}-description`;\n return (\n ({\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 1,\n border: \"1px solid\",\n borderColor: selected ? \"primary._states.outlinedBorder\" : \"divider\",\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n bgcolor: selected ? \"primary._states.hover\" : \"background.paper\",\n px: 2,\n py: 1.5,\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n \"&:hover\": disabled\n ? undefined\n : {\n bgcolor: selected ? \"primary._states.selected\" : \"action.hover\",\n borderColor: \"primary._states.outlinedBorder\",\n },\n \"&:has(.Mui-focusVisible)\": focusRing(theme.palette.primary.main),\n })}\n >\n \n \n \n {copy.title}\n \n \n {copy.description}\n \n \n \n );\n}\n\nfunction Recovery({\n message,\n onRetry,\n retryRef,\n}: {\n message: string;\n onRetry: () => void;\n retryRef: React.RefObject;\n}) {\n return (\n \n \n \n \n \n We couldn\u2019t complete the connection\n \n \n \n {message}\n \n \n \n Try again\n \n \n \n \n );\n}\n\nfunction TerminalRecovery({ title, message }: { title: string; message: string }) {\n const titleRef = useRef(null);\n\n useEffect(() => {\n titleRef.current?.focus();\n }, []);\n\n return (\n \n \n \n \n \n {title}\n \n \n \n {message}\n \n \n \n );\n}\n\nfunction OAuthShell({ children }: { children: React.ReactNode }) {\n const scrollRegionRef = useRef(null);\n const [isScrollable, setIsScrollable] = useState(false);\n\n useLayoutEffect(() => {\n const scrollRegion = scrollRegionRef.current;\n if (!scrollRegion) return;\n\n const updateScrollable = () => {\n setIsScrollable(scrollRegion.scrollHeight > scrollRegion.clientHeight + 1);\n };\n updateScrollable();\n window.addEventListener(\"resize\", updateScrollable);\n const resizeObserver = typeof ResizeObserver === \"undefined\" ? null : new ResizeObserver(() => updateScrollable());\n resizeObserver?.observe(scrollRegion);\n return () => {\n window.removeEventListener(\"resize\", updateScrollable);\n resizeObserver?.disconnect();\n };\n }, [children]);\n\n return (\n ({\n minHeight: 0,\n height: \"100%\",\n boxSizing: \"border-box\",\n overflowY: \"auto\",\n bgcolor: \"background.default\",\n px: { xs: 2, sm: 4 },\n py: { xs: 2, sm: 6 },\n \"&:focus-visible\": {\n outline: \"none\",\n boxShadow: `inset 0 0 0 2px ${theme.palette.primary.main}`,\n },\n })}\n >\n ({\n maxWidth: 700,\n boxSizing: \"border-box\",\n mx: \"auto\",\n p: { xs: 2.5, sm: 4 },\n border: \"1px solid\",\n borderColor: \"divider\",\n borderRadius: `${theme.tokens.radii.standardRadius}px`,\n })}\n >\n {children}\n \n \n );\n}\n\nexport default function McpOauthConsentPage({\n authorizationTransactionId,\n onRedirect,\n initialConsent,\n initialError,\n initialExpired = false,\n initialSubmitting = false,\n motionPreference,\n}: Props) {\n const route = useParams<{ id: string }>();\n const transactionId = authorizationTransactionId ?? route.id ?? \"\";\n const [consent, setConsent] = useState(initialConsent);\n const [mode, setMode] = useState(initialConsent?.default_mode ?? \"autonomous\");\n const [error, setError] = useState(initialError);\n const [terminalError, setTerminalError] = useState();\n const [expired, setExpired] = useState(initialExpired || initialConsent?.expires_in_seconds === 0);\n const [pendingDecision, setPendingDecision] = useState<\"allow\" | \"deny\" | undefined>(\n initialSubmitting ? \"allow\" : undefined,\n );\n const [systemReducedMotion, setSystemReducedMotion] = useState(\n () => window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches ?? false,\n );\n const clientLogoSource = consent?.verified ? consent.client_icon : null;\n const [clientLogoState, setClientLogoState] = useState<{ src: string | null; available: boolean }>({\n src: null,\n available: false,\n });\n const handleClientLogoAvailability = useCallback(\n (available: boolean) => setClientLogoState({ src: clientLogoSource ?? null, available }),\n [clientLogoSource],\n );\n const clientLogoAvailable = Boolean(\n clientLogoSource && clientLogoState.src === clientLogoSource && clientLogoState.available,\n );\n const errorRef = useRef(null);\n const retryRef = useRef(null);\n const requestSequence = useRef(0);\n const submitting = pendingDecision !== undefined;\n const reducedMotion = motionPreference ?? systemReducedMotion;\n\n const load = useCallback(() => {\n const sequence = ++requestSequence.current;\n setError(undefined);\n setTerminalError(undefined);\n setExpired(false);\n setConsent(undefined);\n fetchMcpOauthConsent(transactionId)\n .then((value) => {\n if (sequence !== requestSequence.current) return;\n setConsent(value);\n setMode(value.default_mode);\n })\n .catch((reason: unknown) => {\n if (sequence !== requestSequence.current) return;\n const failure = oauthFailure(reason);\n if (failure?.code === \"authorization_expired\") {\n setExpired(true);\n return;\n }\n if (failure && !failure.retryable) {\n setTerminalError(failure.message);\n return;\n }\n setError(reason instanceof Error ? reason.message : \"Bench IQ can\u2019t connect right now. Try again in a moment.\");\n });\n }, [transactionId]);\n\n useEffect(() => {\n if (!initialConsent && !initialError) load();\n return () => {\n requestSequence.current += 1;\n };\n }, [initialConsent, initialError, load]);\n useEffect(() => {\n if (!consent || expired) return;\n\n const expiresAt = Date.now() + Math.max(0, consent.expires_in_seconds * 1_000);\n let timeout: number;\n const expire = () => {\n const remaining = expiresAt - Date.now();\n if (remaining > 0) {\n timeout = window.setTimeout(expire, remaining);\n return;\n }\n setPendingDecision(undefined);\n setError(undefined);\n setExpired(true);\n };\n timeout = window.setTimeout(expire, Math.max(0, expiresAt - Date.now()));\n return () => window.clearTimeout(timeout);\n }, [consent, expired]);\n useEffect(() => {\n if (motionPreference !== undefined) return;\n const query = window.matchMedia?.(\"(prefers-reduced-motion: reduce)\");\n if (!query) return;\n const update = () => setSystemReducedMotion(query.matches);\n update();\n query.addEventListener?.(\"change\", update);\n return () => query.removeEventListener?.(\"change\", update);\n }, [motionPreference]);\n useEffect(() => {\n if (!error) return;\n if (!consent) retryRef.current?.focus();\n else errorRef.current?.focus();\n }, [consent, error]);\n\n const decide = async (decision: \"allow\" | \"deny\") => {\n if (!consent || submitting || expired) return;\n setPendingDecision(decision);\n setError(undefined);\n try {\n const result = await submitMcpOauthConsent({\n authorizationTransactionId: transactionId,\n consentContext: consent.consent_context,\n decision,\n ...(decision === \"allow\" ? { mode } : {}),\n });\n if (onRedirect) onRedirect(result.redirect_to);\n else window.location.assign(result.redirect_to);\n } catch (reason) {\n const failure = oauthFailure(reason);\n if (failure?.code === \"authorization_expired\") {\n setPendingDecision(undefined);\n setExpired(true);\n return;\n }\n if (failure && !failure.retryable) {\n setPendingDecision(undefined);\n setTerminalError(failure.message);\n return;\n }\n setError(reason instanceof Error ? reason.message : \"Authorization could not be completed.\");\n setPendingDecision(undefined);\n }\n };\n\n if (expired) {\n return (\n \n );\n }\n if (terminalError) {\n return (\n \n );\n }\n if (error && !consent) return ;\n if (!consent)\n return (\n \n \n {reducedMotion ? : }\n Loading connection details\u2026\n \n \n );\n\n const verification = consent.verified ? \"Verified by Bench IQ\" : \"Not verified by Bench IQ\";\n return (\n \n \n \n \n \n {consent.reauthorization ? \"Reconnect Bench IQ\" : \"Connect Bench IQ\"}\n \n \n \n {clientLogoSource ? (\n \n ) : null}\n \n \n {consent.client_name}\n \n \n {verification}\n \n {consent.loopback_redirect ? (\n \n Returns to this device\n \n ) : (\n \n After you approve, you\u2019ll return to {consent.redirect_hostname}.\n \n )}\n \n \n {!consent.verified && (\n }>\n Bench IQ hasn\u2019t verified this app. Continue only if you recognize it and expected this request.\n \n )}\n {consent.loopback_redirect && (\n \n After you approve, this app will finish connecting on this device. This does not mean Bench IQ has verified\n the app.\n \n )}\n \n
    \n \n Requested permissions\n \n \n {consent.requested_permissions.map((permission) => (\n \n \n {permission.label}\n \n \n {permission.description}\n \n \n ))}\n \n
    \n \n \n Connection mode\n \n setMode(event.target.value as McpOauthMode)}>\n \n \n \n \n \n {consent.docket_connect_available && (\n \n {/* Interim copy, design to confirm. */}\n Bench IQ retrieves court records at no cost, up to your firm\u2019s monthly limit.\n \n )}\n \n {error && (\n \n {error}\n \n )}\n \n \n {`Signed in as ${consent.signed_in_email}`}\n \n \n {\n event.preventDefault();\n void decide(\"allow\");\n }}\n >\n {submitting && (\n \n {pendingDecision === \"allow\" ? \"Connecting\" : \"Denying\"}\n \n )}\n \n void decide(\"deny\")}\n >\n {pendingDecision === \"deny\" ? \"Denying\u2026\" : \"Deny access\"}\n \n \n ) : (\n CheckCircle2\n )\n }\n >\n {pendingDecision === \"allow\" ? \"Connecting\u2026\" : \"Allow access\"}\n \n \n \n
    \n
    \n );\n}\n", "export type McpConnectionStatus = \"active\" | \"blocked\" | \"expired\" | \"needs_reauthorization\";\nexport type McpConnectionMode = \"autonomous\" | \"interactive\";\nexport type McpConnectionOperation = \"set_interactive\" | \"remove_document_access\";\nexport type McpSetupPlatform = \"claude\" | \"chatgpt\" | \"gemini\" | \"harvey\" | \"legora\";\n\nexport interface McpConnection {\n id: string;\n client: {\n name: string;\n icon: string | null;\n verified: boolean;\n loopback_redirect: boolean;\n };\n status: McpConnectionStatus;\n mode: McpConnectionMode;\n permissions: string[];\n connected_at: string;\n last_used_at: string | null;\n document_access: { granted: boolean; usable: boolean };\n docket_connect: { usable: boolean; reconnect_available: boolean };\n}\n\nexport interface McpConnectionsResponse {\n eligible: boolean;\n server_url: string;\n account_capabilities: {\n document_service_available: boolean;\n docket_connect_service_available: boolean;\n };\n /** Ordered platforms whose setup instructions to show. Only sent when `eligible` is true. */\n setup_platforms?: McpSetupPlatform[];\n /** Display only: whether to show the Connected Apps page now. Only sent when `eligible` is true. */\n page_visible?: boolean;\n connections: McpConnection[];\n}\n\nexport class McpConnectionApiError extends Error {\n readonly status: number;\n\n constructor(status: number) {\n super(\n status === 401\n ? \"Your session has expired. Please sign in again.\"\n : \"We couldn\u2019t update this connection. Please try again.\",\n );\n this.name = \"McpConnectionApiError\";\n this.status = status;\n }\n}\n\nconst csrfToken = (): string => document.querySelector(\"meta[name='csrf-token']\")?.content ?? \"\";\n\nconst parseResponse = async (response: Response): Promise => {\n if (!response.ok) throw new McpConnectionApiError(response.status);\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n};\n\nexport const fetchMcpConnections = async (): Promise => {\n const response = await fetch(\"/api/mcp/connections\", {\n method: \"GET\",\n credentials: \"same-origin\",\n headers: { Accept: \"application/json\" },\n });\n return parseResponse(response);\n};\n\nexport const updateMcpConnection = async (\n connectionId: string,\n operation: McpConnectionOperation,\n): Promise => {\n const response = await fetch(`/api/mcp/connections/${encodeURIComponent(connectionId)}`, {\n method: \"PATCH\",\n credentials: \"same-origin\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"X-CSRF-Token\": csrfToken(),\n },\n body: JSON.stringify({ operation }),\n });\n return parseResponse(response);\n};\n\nexport const deleteMcpConnection = async (connectionId: string): Promise => {\n const response = await fetch(`/api/mcp/connections/${encodeURIComponent(connectionId)}`, {\n method: \"DELETE\",\n credentials: \"same-origin\",\n headers: { Accept: \"application/json\", \"X-CSRF-Token\": csrfToken() },\n });\n await parseResponse(response);\n};\n", "import React, { useCallback, useState } from \"react\";\nimport { Box, Stack, Typography } from \"@mui/material\";\nimport { ChevronDown, ChevronUp, FileText, RefreshCw, Unplug } from \"lucide-react\";\nimport { type McpConnection, type McpConnectionsResponse } from \"@/api/mcpConnections\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { BIQChip, type BIQChipColor } from \"@/components/atoms/BIQChip\";\nimport { isApprovedMcpClientLogoPath, McpClientIcon } from \"@/components/mcp/McpClientIcon\";\nimport { colors } from \"@/components/theme/tokens/colors\";\nimport { styled } from \"@/utils/styled\";\nimport type { DialogKind } from \"./ConnectedAppsDialogs\";\n\nconst Surface = styled(Box)`\n container-type: inline-size;\n border: 1px solid ${({ theme }) => theme.palette.divider};\n border-radius: ${({ theme }) => theme.tokens.radii.standardRadius}px;\n background: ${({ theme }) => theme.palette.background.paper};\n`;\n\nconst CardHeader = styled(Box)`\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n grid-template-areas:\n \"identity details\"\n \"statuses .\";\n align-items: flex-start;\n gap: ${({ theme }) => theme.tokens.spacing[3]}px;\n padding: ${({ theme }) => theme.tokens.spacing[4]}px;\n\n &[data-has-warning=\"true\"] {\n grid-template-areas:\n \"identity details\"\n \"statuses .\"\n \"warning .\";\n }\n\n &[data-has-logo=\"true\"] {\n grid-template-columns: auto minmax(0, 1fr) auto;\n grid-template-areas:\n \"icon identity details\"\n \". statuses .\";\n }\n\n &[data-has-logo=\"true\"][data-has-warning=\"true\"] {\n grid-template-areas:\n \"icon identity details\"\n \". statuses .\"\n \". warning .\";\n }\n\n @container (max-width: 420px) {\n grid-template-columns: minmax(0, 1fr);\n grid-template-areas:\n \"identity\"\n \"statuses\"\n \"details\";\n padding: ${({ theme }) => theme.tokens.spacing[3]}px;\n\n &[data-has-warning=\"true\"] {\n grid-template-areas:\n \"identity\"\n \"statuses\"\n \"warning\"\n \"details\";\n }\n\n &[data-has-logo=\"true\"] {\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-areas:\n \"icon identity\"\n \"statuses statuses\"\n \"details details\";\n }\n\n &[data-has-logo=\"true\"][data-has-warning=\"true\"] {\n grid-template-areas:\n \"icon identity\"\n \"statuses statuses\"\n \"warning warning\"\n \"details details\";\n }\n }\n`;\n\nconst ClientIconSlot = styled(Box)`\n grid-area: icon;\n`;\n\nconst ClientIdentity = styled(Stack)`\n grid-area: identity;\n min-width: 0;\n`;\n\nconst StatusRow = styled(Stack)`\n grid-area: statuses;\n min-width: 0;\n`;\n\nconst WarningRow = styled(Typography)`\n grid-area: warning;\n`;\n\nconst DetailsSlot = styled(Box)`\n grid-area: details;\n justify-self: end;\n`;\n\nconst CardDetails = styled(Box)`\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: ${({ theme }) => theme.tokens.spacing[3]}px ${({ theme }) => theme.tokens.spacing[5]}px;\n padding: ${({ theme }) => theme.tokens.spacing[4]}px;\n border-top: 1px solid ${({ theme }) => theme.palette.divider};\n\n @container (max-width: 520px) {\n grid-template-columns: 1fr;\n padding: ${({ theme }) => theme.tokens.spacing[3]}px;\n }\n`;\n\nconst ActionRow = styled(Box)`\n grid-column: 1 / -1;\n display: flex;\n flex-wrap: wrap;\n gap: ${({ theme }) => theme.tokens.spacing[2]}px;\n\n @container (max-width: 520px) {\n flex-direction: column;\n gap: ${({ theme }) => theme.tokens.spacing[3]}px;\n }\n`;\n\nconst ActionGroup = styled(Box)`\n display: flex;\n flex-wrap: wrap;\n gap: ${({ theme }) => theme.tokens.spacing[2]}px;\n\n @container (max-width: 520px) {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n\n & .MuiButton-root {\n justify-content: flex-start;\n min-height: 44px;\n width: 100%;\n }\n }\n`;\n\nconst DestructiveActionGroup = styled(ActionGroup)`\n @container (max-width: 520px) {\n border-top: 1px solid ${({ theme }) => theme.palette.divider};\n padding-top: ${({ theme }) => theme.tokens.spacing[3]}px;\n }\n`;\n\nconst statusCopy: Record = {\n active: { label: \"Active\", color: \"success\" },\n blocked: { label: \"Blocked\", color: \"warning\" },\n expired: { label: \"Expired\", color: \"error\" },\n needs_reauthorization: { label: \"Reconnect needed\", color: \"warning\" },\n};\n\n// Same wording as the consent screen (PERMISSIONS in oauth_authorization_transactions_controller.rb).\nconst permissionLabels: Record = {\n clerk:\n \"Research filings, hearing transcripts, and orders across all U.S. federal district and bankruptcy courts, and view or continue prior Bench IQ conversations\",\n documents: \"Upload documents\",\n offline_access: \"Stay connected\",\n};\n\nconst formatDate = (value: string | null): string => {\n if (!value) return \"Not yet used\";\n const date = new Date(value);\n return Number.isNaN(date.getTime())\n ? \"Unavailable\"\n : date.toLocaleString(undefined, { dateStyle: \"medium\", timeStyle: \"short\" });\n};\n\nconst permissionLabel = (permission: string): string => permissionLabels[permission] ?? \"Additional approved access\";\n\ninterface ConnectedAppsConnectionCardProps {\n connection: McpConnection;\n accountCapabilities: McpConnectionsResponse[\"account_capabilities\"];\n onOpenDialog: (kind: DialogKind, connection: McpConnection) => void;\n}\n\nexport const ConnectedAppsConnectionCard: React.FC = ({\n connection,\n accountCapabilities,\n onOpenDialog,\n}) => {\n const [expanded, setExpanded] = useState(false);\n const status = statusCopy[connection.status];\n const needsReauthorization = connection.status !== \"active\";\n const documentServiceUnavailable = !accountCapabilities.document_service_available;\n const docketServiceUnavailable = !accountCapabilities.docket_connect_service_available;\n const hasDocketWarning =\n !docketServiceUnavailable && connection.docket_connect.usable && connection.docket_connect.reconnect_available;\n const approvedLogo =\n connection.client.verified && isApprovedMcpClientLogoPath(connection.client.icon) ? connection.client.icon : null;\n const [logoState, setLogoState] = useState<{ src: string | null; available: boolean }>({\n src: null,\n available: false,\n });\n const handleLogoAvailability = useCallback(\n (available: boolean) => setLogoState({ src: approvedLogo, available }),\n [approvedLogo],\n );\n const hasLogoLayout = Boolean(approvedLogo && logoState.src === approvedLogo && logoState.available);\n\n const documentState = documentServiceUnavailable\n ? \"Document service unavailable for this account.\"\n : connection.document_access.usable\n ? \"Available now\"\n : connection.document_access.granted\n ? \"Granted; this connection needs a reconnect.\"\n : \"Document access isn\u2019t granted for this connection.\";\n const docketState = docketServiceUnavailable\n ? \"Docket and filing research is unavailable for this account.\"\n : connection.docket_connect.usable\n ? connection.docket_connect.reconnect_available\n ? \"Available. Automatic court-record retrieval is off until you reconnect.\" // Interim copy, design to confirm.\n : \"Available now\"\n : connection.docket_connect.reconnect_available\n ? \"Reconnect this app to restore docket and filing research.\"\n : \"Not available for this connection.\";\n\n return (\n \n \n {approvedLogo ? (\n \n \n \n ) : null}\n \n \n {connection.client.name}\n \n \n \n \n \n \n {hasDocketWarning ? (\n \n Reconnect to allow automatic filing retrieval\n \n ) : null}\n \n setExpanded((value) => !value)}\n >\n Details\n \n \n \n\n {expanded ? (\n \n \n \n Permissions\n \n \n {connection.permissions.length\n ? connection.permissions.map(permissionLabel).join(\" \u00B7 \")\n : \"No current permissions\"}\n \n \n \n \n Connected\n \n {formatDate(connection.connected_at)}\n \n \n \n Last used\n \n {formatDate(connection.last_used_at)}\n \n \n \n Documents\n \n {documentState}\n \n \n \n Dockets and filings\n \n {docketState}\n \n \n \n {needsReauthorization ? (\n onOpenDialog(\"reauthorize\", connection)}\n >\n Reconnect\n \n ) : null}\n {!documentServiceUnavailable && !connection.document_access.granted ? (\n onOpenDialog(\"documents\", connection)}\n >\n Add document access\n \n ) : null}\n {connection.mode === \"interactive\" ? (\n onOpenDialog(\"autonomous\", connection)}>\n Switch to Work automatically\n \n ) : (\n onOpenDialog(\"interactive\", connection)}\n >\n Switch to Ask when needed\n \n )}\n {!needsReauthorization && hasDocketWarning ? (\n onOpenDialog(\"docket\", connection)}>\n Allow automatic filing retrieval\n \n ) : null}\n \n \n onOpenDialog(\"disconnect\", connection)}\n >\n Disconnect\n \n \n \n \n ) : null}\n \n );\n};\n", "import React from \"react\";\nimport {\n Alert,\n CircularProgress,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Stack,\n Typography,\n} from \"@mui/material\";\nimport { visuallyHidden } from \"@mui/utils\";\nimport { Clock3 } from \"lucide-react\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { type McpConnection } from \"@/api/mcpConnections\";\n\nexport type DialogKind =\n | \"reauthorize\"\n | \"docket\"\n | \"documents\"\n | \"autonomous\"\n | \"interactive\"\n | \"remove_documents\"\n | \"disconnect\";\nexport interface ActiveDialog {\n kind: DialogKind;\n connection: McpConnection;\n}\n\nconst copy = ({ kind, connection }: ActiveDialog) => {\n switch (kind) {\n case \"reauthorize\":\n return {\n title: \"Reconnect this app\",\n body: `Open the app\u2019s connection settings and reconnect Bench IQ. You\u2019ll review the requested access there; this page does not start the connection.${\n connection.docket_connect.reconnect_available\n ? \" This reconnect also restores docket and filing research.\"\n : \"\"\n }`,\n action: \"Done\",\n guidance: true,\n };\n case \"docket\":\n return {\n title: \"Allow automatic filing retrieval\",\n // Interim copy, design to confirm.\n body: \"Reconnect Bench IQ from the app\u2019s connection settings and review the updated access. Then, in either mode, Bench IQ retrieves court records at no cost, up to your firm\u2019s monthly limit. Your connected app can\u2019t raise that limit.\",\n action: \"Done\",\n guidance: true,\n };\n case \"documents\":\n return {\n title: \"Add document access\",\n body: \"Reconnect this app from its settings and request document access. You\u2019ll review the requested access before anything changes.\",\n action: \"Done\",\n guidance: true,\n };\n case \"autonomous\":\n return {\n title: \"Switch to Work automatically\",\n body: \"Reconnect this app from its settings to choose Work automatically. You\u2019ll review the requested access there.\",\n action: \"Done\",\n guidance: true,\n };\n case \"interactive\":\n return {\n title: \"Switch to Ask when needed?\",\n // Interim copy, design to confirm.\n body: `Bench IQ will pause to ask you a question when your request is unclear.${\n // Switching keeps the connection's court-record consent, so only say it\n // retrieves when the card doesn't offer a reconnect for that.\n connection.docket_connect.usable && !connection.docket_connect.reconnect_available\n ? \" It still retrieves court records at no cost, up to your firm\u2019s monthly limit.\"\n : \"\"\n } Your existing connection will remain active.`,\n action: \"Confirm Ask when needed\",\n guidance: false,\n };\n case \"remove_documents\":\n return {\n title: \"Remove document access?\",\n body: \"This app will no longer be able to upload documents to Bench IQ. Reconnect it later if you want to restore this permission.\",\n action: \"Remove document access\",\n danger: true,\n guidance: false,\n };\n case \"disconnect\":\n return {\n title: \"Disconnect this app?\",\n body: \"This revokes the app\u2019s Bench IQ connection. You can reconnect it from the app\u2019s settings later.\",\n action: \"Disconnect app\",\n danger: true,\n guidance: false,\n };\n }\n};\n\ninterface ConnectedAppsDialogsProps {\n activeDialog: ActiveDialog | null;\n isPending: boolean;\n error: Error | null;\n onClose: () => void;\n onConfirm: (dialog: ActiveDialog) => void;\n onSignInAgain: () => void;\n reducedMotion: boolean;\n}\n\nexport const ConnectedAppsDialogs: React.FC = ({\n activeDialog,\n isPending,\n error,\n onClose,\n onConfirm,\n onSignInAgain,\n reducedMotion,\n}) => {\n if (!activeDialog) return null;\n const dialogCopy = copy(activeDialog);\n const sessionExpired = error && \"status\" in error && error.status === 401;\n const pendingLabel =\n activeDialog.kind === \"interactive\"\n ? \"Switching\u2026\"\n : activeDialog.kind === \"remove_documents\"\n ? \"Removing\u2026\"\n : activeDialog.kind === \"disconnect\"\n ? \"Disconnecting\u2026\"\n : dialogCopy.action;\n return (\n !isPending && onClose()}\n disableRestoreFocus\n transitionDuration={reducedMotion ? 0 : undefined}\n BackdropProps={{ transitionDuration: reducedMotion ? 0 : undefined }}\n aria-labelledby=\"connected-apps-dialog-title\"\n aria-describedby=\"connected-apps-dialog-description\"\n PaperProps={{\n \"aria-busy\": isPending,\n sx: (theme) => ({\n width: theme.tokens.layout.modalWidth,\n maxWidth: \"calc(100% - 32px)\",\n }),\n }}\n >\n {dialogCopy.title}\n \n \n {dialogCopy.body}\n {isPending ? (\n \n Updating connection\n \n ) : null}\n {error ? (\n \n {sessionExpired\n ? \"Your session has expired. Please sign in again.\"\n : \"We couldn\u2019t update this connection. Please try again.\"}\n \n ) : null}\n \n \n :not(style) ~ :not(style)\": { marginLeft: \"0 !important\" },\n \"@media (max-width: 420px)\": {\n flexDirection: \"column\",\n alignItems: \"stretch\",\n \"& > :not(style)\": { width: \"100%\" },\n },\n }}\n >\n {!dialogCopy.guidance ? (\n \n Cancel\n \n ) : null}\n {sessionExpired ? (\n \n Sign in again\n \n ) : null}\n {!sessionExpired ? (\n \n )\n ) : undefined\n }\n onClick={() => (dialogCopy.guidance ? onClose() : onConfirm(activeDialog))}\n >\n {isPending ? pendingLabel : dialogCopy.action}\n \n ) : null}\n \n \n );\n};\n", "import React, { useCallback, useRef, useState } from \"react\";\nimport { Alert, Box, CircularProgress, Stack, Typography, useMediaQuery } from \"@mui/material\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { Check, Copy, ShieldCheck, TriangleAlert } from \"lucide-react\";\nimport { BIQButton } from \"@/components/atoms/BIQButton\";\nimport { Icon } from \"@/components/icons/Icon\";\nimport { McpClientIcon } from \"@/components/mcp/McpClientIcon\";\nimport WindowTitle from \"@/components/atoms/WindowTitle\";\nimport { colors } from \"@/components/theme/tokens/colors\";\nimport {\n deleteMcpConnection,\n fetchMcpConnections,\n McpConnectionApiError,\n type McpConnection,\n type McpConnectionOperation,\n type McpConnectionsResponse,\n type McpSetupPlatform,\n updateMcpConnection,\n} from \"@/api/mcpConnections\";\nimport { recordUserEvent } from \"@/api/userEvents\";\nimport { isCreditAccount } from \"@/utils/creditBilling\";\nimport { styled } from \"@/utils/styled\";\nimport { ConnectedAppsConnectionCard } from \"./ConnectedAppsConnectionCard\";\nimport { ConnectedAppsDialogs, type ActiveDialog, type DialogKind } from \"./ConnectedAppsDialogs\";\n\nconst QUERY_KEY = [\"mcp\", \"connections\"] as const;\n\nconst Page = styled(Box)`\n height: 100%;\n min-height: 0;\n overflow-y: auto;\n background: ${({ theme }) => theme.palette.background.default};\n`;\n\nconst Column = styled(Box)`\n width: 100%;\n max-width: ${({ theme }) => theme.tokens.layout.pageContentMaxWidth}px;\n min-width: 0;\n margin: 0 auto;\n padding: ${({ theme }) => theme.tokens.spacing[6]}px ${({ theme }) => theme.tokens.spacing[4]}px\n ${({ theme }) => theme.tokens.spacing[8]}px;\n box-sizing: border-box;\n @media (max-width: 520px) {\n padding: ${({ theme }) => theme.tokens.spacing[4]}px ${({ theme }) => theme.tokens.spacing[3]}px\n ${({ theme }) => theme.tokens.spacing[6]}px;\n }\n`;\n\nconst Surface = styled(Box)`\n border: 1px solid ${({ theme }) => theme.palette.divider};\n border-radius: ${({ theme }) => theme.tokens.radii.standardRadius}px;\n background: ${({ theme }) => theme.palette.background.paper};\n`;\n\nconst InsetSurface = styled(Surface)`\n padding: ${({ theme }) => theme.tokens.spacing[4]}px;\n\n @media (max-width: 520px) {\n padding: ${({ theme }) => theme.tokens.spacing[3]}px;\n }\n`;\n\nconst SetupUrl = styled(Box)`\n min-width: 0;\n flex: 1;\n padding: ${({ theme }) => theme.tokens.spacing[3]}px;\n border-radius: ${({ theme }) => theme.tokens.radii.smallRadius}px;\n background: ${({ theme }) => theme.palette.action.hover};\n font-family: ${({ theme }) => theme.typography.mono.fontFamily};\n font-size: ${({ theme }) => theme.typography.mono.fontSize};\n line-height: ${({ theme }) => theme.typography.mono.lineHeight};\n overflow-wrap: anywhere;\n`;\n\n// interim copy, design to confirm\nconst NOT_TURNED_ON_COPY = \"Connected apps aren\u2019t turned on for your account.\";\n\n// Shown when no platform has its own setup turned on, and for platforms without their own steps yet.\nconst GENERIC_SETUP_STEPS = [\n \"Find the option in your AI app to add a custom MCP connection.\",\n \"Name it Bench IQ, paste this server URL, and add the connection.\",\n \"Select Connect or Authenticate for Bench IQ.\",\n \"Review the permissions in Bench IQ, then approve the connection.\",\n];\n\n// interim copy, design to confirm\nconst PLATFORM_SETUP: Record = {\n claude: {\n label: \"Claude\",\n logo: \"/mcp/client-icons/claude.webp\",\n steps: [\n \"In Claude, open Customize > Connectors and choose Add custom connector. On a Team or Enterprise plan, an Owner adds it under Organization settings > Connectors.\",\n \"Name it Bench IQ, paste the server URL above, and add it.\",\n \"Select Connect, then review and approve the connection in Bench IQ.\",\n ],\n },\n chatgpt: {\n label: \"ChatGPT\",\n logo: \"/mcp/client-icons/chatgpt.png\",\n steps: [\n \"In ChatGPT on the web, open Plugins, choose + > Add custom MCP server. On a Business or Enterprise plan, a workspace admin creates and publishes it.\",\n \"Name it Bench IQ, paste the server URL above, and create it.\",\n \"Connect it, then review and approve the connection in Bench IQ.\",\n ],\n },\n // No Gemini logo: Google's product icons need its approval.\n gemini: { label: \"Gemini\", steps: GENERIC_SETUP_STEPS },\n harvey: { label: \"Harvey\", logo: \"/mcp/client-icons/harvey.png\", steps: GENERIC_SETUP_STEPS },\n legora: { label: \"Legora\", logo: \"/mcp/client-icons/legora.png\", steps: GENERIC_SETUP_STEPS },\n};\n\nconst SetupSteps: React.FC<{ steps: string[] }> = ({ steps }) => (\n \n {steps.map((step) => (\n \n {step}\n \n ))}\n \n);\n\nconst recordConnectedAppsEvent = (\n eventName: \"connected_apps_server_url_copied\" | \"connected_apps_action_completed\",\n properties:\n | { outcome: \"succeeded\" | \"failed\" }\n | { action: \"interactive\" | \"remove_documents\" | \"disconnect\"; outcome: \"succeeded\" | \"failed\" },\n) => {\n void recordUserEvent(\n eventName === \"connected_apps_server_url_copied\"\n ? { event_name: eventName, event_properties: properties as { outcome: \"succeeded\" | \"failed\" } }\n : {\n event_name: eventName,\n event_properties: properties as {\n action: \"interactive\" | \"remove_documents\" | \"disconnect\";\n outcome: \"succeeded\" | \"failed\";\n },\n },\n );\n};\n\nexport interface ConnectedAppsPageProps {\n initialData?: McpConnectionsResponse;\n initialError?: boolean;\n initialLoading?: boolean;\n initialDialog?: ActiveDialog;\n initialDialogPending?: boolean;\n initialCopyStatus?: \"idle\" | \"copied\" | \"failed\";\n motionPreference?: boolean;\n}\n\nexport const ConnectedAppsPage: React.FC = ({\n initialData,\n initialError = false,\n initialLoading = false,\n initialDialog,\n initialDialogPending = false,\n initialCopyStatus = \"idle\",\n motionPreference,\n}) => {\n const systemReducedMotion = useMediaQuery(\"(prefers-reduced-motion: reduce)\", { noSsr: true });\n const reducedMotion = motionPreference ?? systemReducedMotion;\n const queryClient = useQueryClient();\n // The page-load flag can be stale (say, a connection made in another tab), so the\n // API's page_visible decides whether to show the page.\n const mcpAvailable = window.mcpEnabled === true;\n const { data, error, isPending, refetch } = useQuery({\n queryKey: QUERY_KEY,\n queryFn: fetchMcpConnections,\n retry: false,\n enabled: mcpAvailable && !initialData && !initialError && !initialLoading,\n initialData,\n });\n const [copyStatus, setCopyStatus] = useState<\"idle\" | \"copied\" | \"failed\">(initialCopyStatus);\n const [activeDialog, setActiveDialog] = useState(initialDialog ?? null);\n const dialogTriggerRef = useRef(null);\n\n const focusReplacement = useCallback((kind: DialogKind, connectionId: string) => {\n const targetId = kind === \"disconnect\" ? \"connections-title\" : `connection-${connectionId}`;\n requestAnimationFrame(() => document.getElementById(targetId)?.focus());\n }, []);\n\n const mutation = useMutation<\n McpConnection | undefined,\n Error,\n { connection: McpConnection; kind: Extract }\n >({\n mutationFn: async ({ connection, kind }) => {\n if (kind === \"disconnect\") return deleteMcpConnection(connection.id).then(() => undefined);\n const operation: McpConnectionOperation = kind === \"interactive\" ? \"set_interactive\" : \"remove_document_access\";\n return updateMcpConnection(connection.id, operation);\n },\n onSuccess: (updated, variables) => {\n queryClient.setQueryData(QUERY_KEY, (previous) => {\n if (!previous) return previous;\n if (variables.kind === \"disconnect\")\n return {\n ...previous,\n connections: previous.connections.filter((item) => item.id !== variables.connection.id),\n };\n return updated\n ? {\n ...previous,\n connections: previous.connections.map((item) => (item.id === variables.connection.id ? updated : item)),\n }\n : previous;\n });\n recordConnectedAppsEvent(\"connected_apps_action_completed\", { action: variables.kind, outcome: \"succeeded\" });\n dialogTriggerRef.current = null;\n setActiveDialog(null);\n focusReplacement(variables.kind, variables.connection.id);\n },\n onError: (_error, variables) =>\n recordConnectedAppsEvent(\"connected_apps_action_completed\", { action: variables.kind, outcome: \"failed\" }),\n });\n\n const copyServerUrl = useCallback(async () => {\n if (!data?.server_url) return;\n try {\n if (!navigator.clipboard?.writeText) throw new Error(\"Clipboard is unavailable\");\n await navigator.clipboard.writeText(data.server_url);\n setCopyStatus(\"copied\");\n recordConnectedAppsEvent(\"connected_apps_server_url_copied\", { outcome: \"succeeded\" });\n } catch {\n setCopyStatus(\"failed\");\n recordConnectedAppsEvent(\"connected_apps_server_url_copied\", { outcome: \"failed\" });\n }\n }, [data?.server_url]);\n\n const openDialog = useCallback(\n (kind: DialogKind, connection: McpConnection) => {\n dialogTriggerRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n setActiveDialog({ kind, connection });\n mutation.reset();\n },\n [mutation],\n );\n\n const closeDialog = useCallback(() => {\n const trigger = dialogTriggerRef.current;\n dialogTriggerRef.current = null;\n setActiveDialog(null);\n requestAnimationFrame(() => {\n if (trigger?.isConnected) trigger.focus();\n });\n }, []);\n const signInAgain = useCallback(() => window.location.reload(), []);\n const sessionExpired = (error as McpConnectionApiError | null)?.status === 401;\n\n const unavailable = (\n \n \n \n \n \n \n \n Connected apps isn\u2019t available\n \n \n {isCreditAccount()\n ? NOT_TURNED_ON_COPY\n : \"Connected apps are available for accounts using Bench IQ Credits.\"}\n \n Contact Bench IQ support if you need access.\n \n \n \n \n );\n\n if (!mcpAvailable) return unavailable;\n\n if (initialLoading || (!initialError && isPending))\n return (\n \n \n \n {reducedMotion ? : }\n Loading connected apps\u2026\n \n \n \n );\n\n if (initialError || error || !data)\n return (\n \n \n \n \n Sign in again\n \n ) : (\n void refetch()}>\n Retry\n \n )\n }\n >\n {sessionExpired\n ? \"Your session has expired. Please sign in again.\"\n : \"We couldn\u2019t load your connected apps.\"}\n \n \n \n );\n\n // A response from a server that predates page_visible leaves the page shown.\n if (!data.eligible || data.page_visible === false) return unavailable;\n\n // Skip a platform this bundle doesn't know yet instead of failing the page.\n const setupPlatforms = (data.setup_platforms ?? []).filter((platform) => Object.hasOwn(PLATFORM_SETUP, platform));\n\n return (\n \n \n \n \n \n \n Connected apps\n \n Review the apps that can work with your Bench IQ account.\n \n \n \n \n \n Set up a connected app\n \n \n Use this URL to connect Bench IQ to a compatible AI app.\n \n \n \n {data.server_url}\n void copyServerUrl()}\n >\n {copyStatus === \"copied\" ? \"Copied\" : \"Copy\"}\n \n \n {copyStatus !== \"idle\" ? (\n \n {copyStatus === \"failed\"\n ? \"Couldn\u2019t copy the connection URL. Copy it manually instead.\"\n : \"Connection URL copied.\"}\n \n ) : null}\n {setupPlatforms.length ? (\n setupPlatforms.map((platform) => (\n \n \n \n {PLATFORM_SETUP[platform].label}\n \n \n \n ))\n ) : (\n \n )}\n \n Need help? Tell Bench IQ Support which app you\u2019re connecting.\n \n \n \n \n \n \n Your connections\n \n \n {data.connections.length ? (\n data.connections.map((connection) => (\n \n ))\n ) : (\n \n No apps are connected yet.\n \n )}\n \n \n \n \n mutation.mutate({\n connection: dialog.connection,\n kind: dialog.kind as Extract,\n })\n }\n onSignInAgain={signInAgain}\n />\n \n );\n};\n", "import React, { useState } from \"react\";\nimport * as ReactDOM from \"react-dom/client\";\nimport { createBrowserRouter, Navigate, Outlet, RouterProvider } from \"react-router-dom\";\nimport { QueryClientProvider } from \"@tanstack/react-query\";\nimport { queryClient } from \"../api/queryClient\";\nimport * as FullStory from \"@fullstory/browser\";\nimport { AwsRum, AwsRumConfig } from \"aws-rum-web\";\nimport { ThemeProvider } from \"@mui/material/styles\";\nimport { GlobalStyles } from \"@mui/material\";\nimport createCache from \"@emotion/cache\";\n\nimport { fontFaces } from \"./theme/fonts\";\nimport { colors, docketConnectCssVariables } from \"./theme/tokens/colors\";\n\nimport { AdapterDayjs } from \"@mui/x-date-pickers/AdapterDayjs\";\nimport { LocalizationProvider } from \"@mui/x-date-pickers/LocalizationProvider\";\n\nimport Home from \"./Home\";\nimport AgentPrototypeLayout from \"./agent_prototype/AgentPrototypeLayout\";\nimport AgentPrototypeWelcome from \"./agent_prototype/AgentPrototypeWelcome\";\nimport AgentPrototypeConversation from \"./agent_prototype/AgentPrototypeConversation\";\nimport AgentPrototypeHistory from \"./agent_prototype/AgentPrototypeHistory\";\nimport AgentPrototypeShareResolver from \"./agent_prototype/AgentPrototypeShareResolver\";\nimport RedirectToAgent from \"./agent_prototype/RedirectToAgent\";\nimport LockedClerkLanding from \"./agent_prototype/LockedClerkLanding\";\nimport LockedClerkExampleSession from \"./agent_prototype/LockedClerkExampleSession\";\nimport QueryResultsPage from \"./organisms/QueryResultsPage\";\nimport ActivityHistoryPage from \"./organisms/ActivityHistoryPage\";\nimport TimeTrackingModal from \"./molecules/TimeTrackingModal\";\nimport { featureEnabled, isClerkAvailable } from \"../utils/featureFlags\";\nimport Alerts from \"./Alerts\";\nimport { LoginPage, SsoLoginPage } from \"./auth/LoginPages\";\nimport { SignupPage } from \"./auth/SignupPage\";\nimport {\n ExpiredResetLinkPage,\n ForgotPasswordPage,\n PasswordRequestedPage,\n ResetPasswordPage,\n} from \"./auth/PasswordPages\";\nimport { EmailVerificationResultPage, VerifyEmailPage } from \"./auth/ConfirmationPages\";\nimport { InvitationPage } from \"./auth/InvitationPage\";\nimport TermsOfService from \"./auth/TermsOfService\";\nimport ProfileSetup from \"./auth/ProfileSetup\";\nimport { GlobalAlertProvider, useGlobalAlert } from \"../contexts/GlobalAlertContext\";\nimport { TimeEntryProvider } from \"../contexts/TimeEntryContext\";\nimport Alert from \"@mui/material/Alert\";\nimport { Snackbar } from \"@mui/material\";\nimport { layout as layoutTokens } from \"./theme/tokens/layout\";\nimport { getTheme } from \"./theme\";\nimport { HighlightStyles } from \"./highlights/HighlightStyles\";\nimport UnifiedHistoryPage from \"./organisms/UnifiedHistoryPage\";\nimport StarredPage from \"./organisms/StarredPage\";\nimport FoldersPage from \"./organisms/FoldersPage\";\nimport FolderDetailPage from \"./organisms/FolderDetailPage\";\nimport NotesPage from \"./organisms/NotesPage\";\nimport FeatureDisabledByAdmin from \"./atoms/FeatureDisabledByAdmin\";\nimport PageViewTracker from \"./PageViewTracker\";\nimport { SessionExpiredModalProvider, useSessionExpiredModal } from \"../contexts/GlobalAlertContext\";\nimport SessionExpiredModal from \"./molecules/SessionExpiredModal\";\nimport { initializeLocalStorageCleanup } from \"../utils/localStorageCleanup\";\nimport { loadIntercom } from \"../utils/load_intercom\";\nimport { CacheProvider } from \"@emotion/react\";\nimport TopBarProvider from \"./contexts/TopBarProvider\";\nimport { AppShell, useExpandableRailOptional } from \"./AppShell\";\nimport { EffectiveRailWidthProvider, useEffectiveRailWidth } from \"./AppShell/EffectiveRailWidthContext\";\nimport { SideNav } from \"./SideNav/SideNav\";\nimport { ExpandableSideNavContainer } from \"./SideNav/ExpandableSideNavContainer\";\nimport { usePinnedSidenavPreference } from \"./SideNav/usePinnedSidenavPreference\";\nimport { TopBarLeft } from \"./AppShell/TopBarLeft\";\nimport { TopBarRight } from \"./AppShell/TopBarRight\";\nimport SearchOverlay from \"./organisms/SearchOverlay\";\nimport { useBooleanSearchBarState } from \"./contexts/BooleanSearchBarControlContext\";\nimport { useLocation, useNavigate } from \"@/utils/urlHelpers\";\nimport { isGenerativeAIAvailable } from \"@/utils/queryCorrectionUtils\";\nimport { shouldIgnoreCloudWatchRumError } from \"@/utils/browserExtensionErrors\";\nimport TopBarStatusChip from \"./atoms/TopBarStatusChip\";\nimport ActiveMatterButton from \"./atoms/ActiveMatterButton\";\nimport needsTimeTracker from \"@/utils/needsTimeTracker\";\nimport { ClientMatterProvider, useOptionalClientMatter } from \"@/contexts/ClientMatterContext\";\nimport { CreditAgentSpeedBumpProvider } from \"@/contexts/CreditAgentSpeedBumpContext\";\nimport ClientMatterModal from \"./molecules/ClientMatterModal\";\nimport CreditAgentSpeedBumpModal from \"./molecules/CreditAgentSpeedBumpModal\";\nimport { isCreditBillingLive } from \"@/utils/creditBilling\";\nimport needsClientMatter from \"@/utils/needsClientMatter\";\nimport CreditMatterLaunchHandler from \"./molecules/CreditMatterLaunchHandler\";\nimport { consumeCreditSearchOverlay } from \"@/utils/creditMatterLaunch\";\nimport { LucideProvider } from \"lucide-react\";\nimport { MotionConfig } from \"motion/react\";\nimport McpOauthConsentPage from \"./mcp/McpOauthConsentPage\";\nimport { BIQButton } from \"./atoms/BIQButton\";\nimport { ConnectedAppsPage } from \"./settings/ConnectedAppsPage\";\nimport { setCloudWatchRumClient } from \"../utils/cloudwatchRum\";\n\n// eslint-disable-next-line bench-iq/no-module-level-get-theme -- creates the theme for the ThemeProvider\nconst theme = getTheme();\n\n// Only enable FullStory in production\nif (window.environment === \"production\" && window.location.host === \"app.benchiq.com\") {\n if (window.currentUser && !window.currentUser.email.endsWith(\"@benchiq.com\")) {\n if (!featureEnabled(\"incognito_queries\")) {\n FullStory.init({ orgId: \"o-1R32C9-na1\" });\n FullStory.identify(String(window.currentUser.id), {\n displayName: `${window.currentUser.first_name} ${window.currentUser.last_name}`,\n email: window.currentUser.email,\n });\n }\n }\n}\n\n// CloudWatch RUM\nif (window.environment === \"production\" || window.environment === \"staging\") {\n if (!featureEnabled(\"incognito_queries\")) {\n try {\n const rumConfig: AwsRumConfig = {\n allowCookies: true,\n endpoint: `https://dataplane.rum.${window.cloudwatchRumRegion}.amazonaws.com`,\n identityPoolId: window.cloudwatchRumIdentityPoolId,\n guestRoleArn: window.cloudwatchRumGuestRoleArn,\n sessionSampleRate: 1,\n telemetries: [[\"errors\", { ignore: shouldIgnoreCloudWatchRumError }], \"performance\", \"http\"],\n enableXRay: false,\n };\n\n const awsRum = new AwsRum(window.cloudwatchRumAppMonitorId, \"1.0.0\", window.cloudwatchRumRegion, rumConfig);\n setCloudWatchRumClient(awsRum);\n\n if (window.currentUser) {\n awsRum.addSessionAttributes({\n user_id: String(window.currentUser.id),\n user_role: \"unknown\",\n });\n }\n } catch (_e) {}\n }\n}\n\n// Intercom - only load if settings are populated by application.html.erb\nif (window.intercomSettings) {\n loadIntercom();\n}\n\n// Initialize localStorage cleanup on app startup\ninitializeLocalStorageCleanup();\n\n/**\n * AppShellLayout \u2014 new authenticated-route wrapper, replacing LayoutWithSidebar.\n *\n * Renders the AppShell with the new SideNav rail, TopBarLeft (Search + optional\n * statusChip slot), and TopBarRight (optional actions slot + Timer). Page\n * content from renders inside AppShell's AppArea. Pages that need a\n * reader sidepanel (QueryResults, AgentPrototype) consume ``\n * via the `useReaderPanelState` hook.\n *\n * Drop-in replacement for LayoutWithSidebar \u2014 no topBarEnabled prop because\n * the new topbar is always rendered (slot-driven). Same wrapping order:\n * TopBarProvider for search-state contexts, TimeEntryProvider when the\n * time-tracker feature is on. GlobalAlertBar / Alerts / TimeTrackingModal\n * stay inside the layout so they pick up the same contexts (fixed-positioned\n * so they overlay regardless of DOM position).\n */\n/**\n * Hosts the SearchOverlay alongside AppShell. Reads the committed Boolean-\n * search context (live; SearchOverlay calls setSearchInput etc. before firing\n * onSearch) and navigates to /transcripts with those values as URL params.\n * Mirrors the executeSearchWithUpdatedValues pattern in TopSearchBar.tsx.\n *\n * Lives inside TopBarProvider so the context hook resolves; AppShellLayout\n * stays outside the provider so it can wrap content cleanly.\n */\nconst SearchOverlayHost: React.FC<{ open: boolean; onClose: () => void; onOpen: () => void }> = ({\n open,\n onClose,\n onOpen,\n}) => {\n const {\n searchInput,\n selectedJudges,\n additionalQueryInput,\n hearingDateFromInput,\n hearingDateToInput,\n caseNumberInput,\n caseNameInput,\n motionTypeInput,\n overlayRequestCounter,\n } = useBooleanSearchBarState();\n const navigate = useNavigate();\n const clientMatter = useOptionalClientMatter();\n\n // Open the overlay immediately when expandAndFocusQueryText is called\n // (e.g. clicking the \"showing results for\" link on the results page).\n const prevCounterRef = React.useRef(overlayRequestCounter);\n React.useEffect(() => {\n if (overlayRequestCounter !== prevCounterRef.current) {\n prevCounterRef.current = overlayRequestCounter;\n onOpen();\n }\n }, [overlayRequestCounter, onOpen]);\n\n // Close the overlay whenever the route changes \u2014 covers the case where\n // the user clicks a SideNav rail item or the topbar logo while the\n // overlay is open. The Dialog's backdrop already handles clicks inside\n // column 2; this effect handles clicks on the rail / nav surfaces that\n // sit outside the backdrop's reach.\n const location = useLocation();\n const prevPathnameRef = React.useRef(location.pathname);\n React.useEffect(() => {\n if (location.pathname !== prevPathnameRef.current) {\n prevPathnameRef.current = location.pathname;\n if (open) {\n onClose();\n }\n }\n }, [location.pathname, open, onClose]);\n\n // AdvancedFilters expand/collapse \u2014 toggled by the filter-icon button in\n // SearchOverlay's action bar. Auto-opens when case name or motion fields\n // have values so their content is visible. Resets to collapsed every time\n // the overlay closes (unless fields have values).\n const hasAdvancedValues = Boolean(caseNameInput?.trim()) || Boolean(motionTypeInput?.trim());\n const [advancedSearch, setAdvancedSearch] = useState(hasAdvancedValues);\n React.useEffect(() => {\n if (!open) {\n setAdvancedSearch(hasAdvancedValues);\n }\n }, [open, hasAdvancedValues]);\n\n const handleBeforeSearch = React.useCallback(async () => {\n if (!isCreditBillingLive()) return true;\n\n return Boolean(await clientMatter?.ensureMatter());\n }, [clientMatter]);\n\n const handleSearch = React.useCallback(\n async (info?: { isSelectedQueryImprovement: boolean }) => {\n const params = new URLSearchParams();\n params.set(\"queryType\", \"keyword-boolean\");\n if (isCreditBillingLive()) {\n params.set(\"creditSearchExecutionId\", crypto.randomUUID());\n }\n // When the submitted query came from a picked improvement, suppress the\n // corrector AND the right-column suggestion polling on the resulting\n // /transcripts page \u2014 otherwise the corrector might rewrite a query the\n // user explicitly chose, and the suggestions panel would re-offer\n // improvements on a query that already came from those exact cards.\n const isPicked = info?.isSelectedQueryImprovement === true;\n const quickCorrectionsEnabled = isGenerativeAIAvailable();\n if (!isPicked && quickCorrectionsEnabled && searchInput.trim() !== \"\") {\n // AI is on AND this wasn't a picked suggestion \u2192 route through\n // `pendingQuery` so QueryResultsPage's auto-correction effect runs.\n params.set(\"pendingQuery\", searchInput);\n } else {\n // Empty query, AI-disabled, or picked suggestion \u2192 use `queryText`\n // directly (no corrector).\n params.set(\"queryText\", searchInput);\n }\n if (isPicked) {\n params.set(\"disableAutoCorrections\", \"true\");\n params.set(\"disableQueryImprovements\", \"true\");\n }\n if (selectedJudges?.length) {\n params.set(\"judgeIds\", selectedJudges.map((judge) => judge.name).join(\",\"));\n }\n if (additionalQueryInput) params.set(\"additionalQuery\", additionalQueryInput);\n if (hearingDateFromInput) params.set(\"hearingDateFrom\", hearingDateFromInput);\n if (hearingDateToInput) params.set(\"hearingDateTo\", hearingDateToInput);\n if (caseNumberInput) params.set(\"caseNumber\", caseNumberInput);\n if (caseNameInput) params.set(\"caseName\", caseNameInput);\n if (motionTypeInput) params.set(\"motionType\", motionTypeInput);\n navigate({ pathname: \"/transcripts\", search: `?${params.toString()}` });\n // Close immediately. The pathname-change effect above only covers\n // cross-route navigation (`/` \u2192 `/transcripts`) and has a one-frame\n // delay even then; on a same-route submit (`/transcripts` \u2192\n // `/transcripts?queryText=\u2026`) it never fires and the overlay sits\n // open over the new results until the user ESCs.\n onClose();\n },\n [\n navigate,\n onClose,\n searchInput,\n selectedJudges,\n additionalQueryInput,\n hearingDateFromInput,\n hearingDateToInput,\n caseNumberInput,\n caseNameInput,\n motionTypeInput,\n ],\n );\n\n return (\n setAdvancedSearch((prev) => !prev)}\n />\n );\n};\n\nconst ClientMatterRouteActivity = () => {\n const location = useLocation();\n const markCreditActivity = useOptionalClientMatter()?.markCreditActivity;\n\n React.useEffect(() => {\n markCreditActivity?.();\n }, [location.pathname, location.search, markCreditActivity]);\n\n return null;\n};\n\nconst DefaultTopBarRight = () => {\n const location = useLocation();\n const showActiveMatter = needsClientMatter() && location.pathname === \"/\";\n\n return : undefined} />;\n};\n\nconst AppShellLayout = () => {\n const [searchOverlayOpen, setSearchOverlayOpen] = useState(false);\n const handleOpenOverlay = React.useCallback(() => setSearchOverlayOpen(true), []);\n const handleCloseOverlay = React.useCallback(() => setSearchOverlayOpen(false), []);\n const location = useLocation();\n const allowNarrowAppArea = location.pathname === \"/settings/connected-apps\";\n const expandableSidenavEnabled = featureEnabled(\"expandable_sidenav\");\n const pinPreference = usePinnedSidenavPreference();\n const [effectiveRailWidth, setEffectiveRailWidth] = useState(() =>\n expandableSidenavEnabled && pinPreference.pinned\n ? layoutTokens.railExpandedWidth\n : expandableSidenavEnabled\n ? layoutTokens.expandableRailCollapsedWidth\n : layoutTokens.railWidth,\n );\n\n React.useEffect(() => {\n if (!expandableSidenavEnabled) setEffectiveRailWidth(layoutTokens.railWidth);\n }, [expandableSidenavEnabled]);\n\n React.useEffect(() => {\n if (consumeCreditSearchOverlay()) handleOpenOverlay();\n }, [handleOpenOverlay, location.key]);\n\n const content = (\n <>\n \n \n \n \n : }\n topBarLeft={\n }\n />\n }\n topBarRight={}\n >\n \n \n {needsTimeTracker() && }\n \n \n \n \n \n );\n\n let providedContent = content;\n if (needsTimeTracker()) {\n providedContent = {content};\n } else if (needsClientMatter()) {\n providedContent = (\n \n \n {content}\n \n \n \n \n );\n }\n\n return {providedContent};\n};\n\n// Public and authentication pages must not mount providers that eagerly call\n// authenticated APIs (for example, the judges query in TopBarProvider) or\n// record signed-in page events.\nconst PublicPageLayout = () => (\n
    \n \n \n \n
    \n);\n\nconst AuthenticatedSetupLayout = () => (\n \n
    \n \n \n \n
    \n
    \n);\n\nconst GlobalAlertBar = () => {\n const { alertMessage, setAlertWithOptions, severity, displayTimeMs, position, alertAction } = useGlobalAlert();\n const effectiveRailWidth = useEffectiveRailWidth();\n const expandableRail = useExpandableRailOptional();\n const visibleRailWidth = expandableRail?.visibleWidth ?? effectiveRailWidth;\n\n if (!alertMessage) {\n return null;\n }\n\n return (\n setAlertWithOptions(null)}\n anchorOrigin={position}\n sx={(theme) => ({\n ...(position.vertical === \"bottom\" &&\n position.horizontal === \"left\" && {\n // TODO Phase 2 review: !important specificity hack still needed\n left: `${visibleRailWidth + theme.tokens.spacing[4]}px !important`,\n bottom: `${theme.tokens.spacing[4]}px !important`,\n transition: `left ${theme.transitions.duration.short}ms ${theme.transitions.easing.easeInOut}`,\n \"& .MuiAlert-root\": {\n // TODO Phase 2 review: 320px alert max-width \u2014 magic value, no token category\n maxWidth: \"320px\",\n width: \"100%\",\n },\n }),\n })}\n >\n setAlertWithOptions(null)}\n action={\n alertAction ? (\n {\n const action = alertAction.onClick;\n setAlertWithOptions(null);\n void action();\n }}\n >\n {alertAction.label}\n \n ) : undefined\n }\n >\n {alertMessage}\n \n \n );\n};\n\nconst GlobalSessionExpiredModal = () => {\n const { sessionExpiredOpen } = useSessionExpiredModal();\n return ;\n};\n\n// Route guards for the /agent family.\n//\n// `clerkRouteElement` is the welcome / history / share guard \u2014 when\n// the org has Clerk access, render the real element; when it doesn't,\n// render the new `LockedClerkLanding`.\n//\n// Note: locked accounts (no Clerk access) are routed to\n// `LockedClerkLanding` for the WHOLE `/agent` family \u2014 including\n// the session-view route `/agent/:token` \u2014 by\n// `AgentPrototypeRouteShell` below. They can't run a real session (the\n// backend rejects session creation for them), so even an old `:token`\n// bookmark or shared link renders the client-side locked experience\n// rather than a 403 error shell.\n//\n// `lockedOnlyRouteElement` is the mirror image of `clerkRouteElement`\n// \u2014 used by the three locked \"example\" routes\n// (/agent/example1|2|3). Those routes are only meaningful\n// for locked users; Clerk-enabled users that somehow land on them get\n// bounced back to the live Clerk welcome page.\nconst clerkRouteElement = (element: React.ReactElement) => (isClerkAvailable() ? element : );\nconst lockedOnlyRouteElement = (element: React.ReactElement) =>\n isClerkAvailable() ? : element;\n\n/**\n * Parent route for the `/agent` family.\n *\n * Renders `AgentPrototypeLayout` (which creates the Clerk session + owns\n * the `AgentPrototypeContext.Provider`) so that the SAME layout instance\n * hosts both the welcome (index) and the conversation (`:token`) child\n * routes. When the URL changes from `/agent` to\n * `/agent/:token`, only the `` content swaps \u2014 the\n * layout, its session state, and the topbar persist. This is the same\n * shape production uses, and it eliminates the welcome-page flash on\n * Home \u2192 submit (previously Welcome and :token were sibling routes, so\n * the navigation tore down Welcome's session and remounted a fresh\n * Layout, briefly rendering the welcome UI before settling into the\n * conversation view).\n *\n * Locked accounts (no Clerk access) ALWAYS see `LockedClerkLanding` for\n * every `/agent` URL \u2014 the index AND any `:token` (old bookmark\n * / shared link) \u2014 and never mount the layout. They can't run a real\n * session (the backend rejects session creation for them), so the locked\n * \"Clerk is responding\" experience is rendered entirely client-side by\n * `LockedClerkLanding`: it echoes any question carried over from Home as\n * a user bubble, types in the canned response, then reveals the\n * \"Search transcripts\" CTA + example cards. Zero network, zero LLM cost.\n */\nconst AgentPrototypeRouteShell: React.FC = () => {\n // Locked accounts get the client-side `LockedClerkLanding` for EVERY\n // `/agent` URL (index AND `:token`) \u2014 they can't run a real\n // session, so a `:token` bookmark / shared link must not mount the layout\n // (which would 403 the session endpoints and show an error shell).\n if (!isClerkAvailable()) {\n return ;\n }\n return ;\n};\n\nconst router = createBrowserRouter([\n {\n element: ,\n children: [\n {\n path: \"/users/sign_in\",\n element: ,\n },\n {\n path: \"/users/sign_up\",\n element: ,\n },\n {\n path: \"/users/sso/sign_in\",\n element: ,\n },\n {\n path: \"/users/password/new\",\n element: ,\n },\n {\n path: \"/users/password/requested\",\n element: ,\n },\n {\n path: \"/users/password/expired\",\n element: ,\n },\n {\n path: \"/users/password/edit\",\n element: ,\n },\n {\n path: \"/users/confirmation/new\",\n element: ,\n },\n {\n path: \"/users/confirmation/result\",\n element: ,\n },\n {\n path: \"/users/invitation/accept\",\n element: ,\n },\n {\n path: \"/oauth/consent/:id\",\n element: ,\n },\n { path: \"/users/invitation/new\", element: