UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

956 lines (942 loc) • 4.05 MB
import { jsx, jsxs, Fragment } from "react/jsx-runtime"; import { c } from "react-compiler-runtime"; import * as PathUtils from "@sanity/util/paths"; import { startsWith, isEqual as isEqual$3, trimLeft, pathFor, toString, get as get$1, fromString, FOCUS_TERMINATOR, trimChildPath as trimChildPath$1 } from "@sanity/util/paths"; import React, { useState, useReducer, useMemo, useRef, useLayoutEffect, memo, useContext, useEffect, forwardRef, useImperativeHandle, useCallback, Fragment as Fragment$1, useId, isValidElement, cloneElement, useSyncExternalStore, Suspense, startTransition, createElement, PureComponent, Children, Component, useInsertionEffect, createContext, useDebugValue, lazy, StrictMode } from "react"; import deepEquals from "react-fast-compare"; import { ChangeIndicatorTrackerContextStore, ChangeIndicatorTrackerContextGetSnapshot, ConnectorContext, ScrollContext, WorkspacesContext, LocaleContext, UserColorManagerContext, PresenceContext, FormBuilderContext, ValidationContext, PortableTextMarkersContext, PresenceTrackerContextStore, PresenceTrackerContextGetSnapshot, FormFieldPresenceContext, VirtualizerScrollInstanceContext, HoveredFieldContext, FieldActionsContext, FormCallbacksContext, DocumentFieldActionsContext, PortableTextMemberItemsContext, ReferenceInputOptionsContext, ReviewChangesContext, DocumentIdContext, PerspectiveContext, ReleasesUpsellContext, ResourceCacheContext, WorkspaceContext, SourceContext, TableContext, SearchContext, ReleasesMetadataContext, FormValueContext, ReferenceItemRefContext, SortableItemIdContext, TreeEditingEnabledContext, PortableTextMemberItemElementRefsContext, EventsContext, DocumentChangeContext, DiffContext, GetFormValueContext, CalendarContext, CommentsAuthoringPathContext, CommentsIntentContext, CommentsContext, CommentsEnabledContext, CommentsOnboardingContext, CommentsSelectedPathContext, CommentsUpsellContext, SanityCreateConfigContext, ScheduledPublishingEnabledContext, SchedulesContext, SchedulePublishUpsellContext, DocumentActionPropsContext, TasksEnabledContext, IsLastPaneContext, MentionUserContext, TasksNavigationContext, TasksContext, TasksUpsellContext, RouterHistoryContext, ActiveWorkspaceMatcherContext, AddonDatasetContext, ColorSchemeSetValueContext, ColorSchemeValueContext, NavbarContext, FreeTrialContext, StudioAnnouncementContext, CopyPasteContext, PreviewCardContext, ZIndexContext, zIndexContextDefaults, CommentInputContext } from "sanity/_singletons"; import debounce from "lodash/debounce.js"; import { useLayer, Flex, Box, Stack, Text as Text$1, Badge, Grid, rem, Card, Spinner, Layer, Dialog, useTheme, useToast, Heading, AvatarStack, Skeleton, Avatar, AvatarCounter, MenuDivider, Menu, useClickOutsideEvent, Code, useGlobalKeyDown, Inline, Autocomplete, TextInput as TextInput$1, Select, LayerProvider, MenuItem as MenuItem$1, Button as Button$1, TabPanel, TabList, Container as Container$2, Checkbox as Checkbox$1, Breadcrumbs, studioTheme, useMediaIndex, Portal, PortalProvider, Label, TextSkeleton, useElementRect, useElementSize, Switch as Switch$1, ElementQuery, TextArea, rgba, useBoundaryElement, BoundaryElementProvider, usePortal, isHTMLElement, Radio, _responsive, VirtualList as VirtualList$1, usePrefersDark, ThemeProvider, ToastProvider, useArrayProp, ThemeColorProvider, DialogProvider, focusLastDescendant, focusFirstDescendant } from "@sanity/ui"; import { ResizeObserver as ResizeObserver$1 } from "@juggle/resize-observer"; import createPubSub from "nano-pubsub"; import { Tooltip, Button, Dialog as Dialog$1, MenuItem, MenuButton as MenuButton$1, TooltipDelayGroupProvider, Popover, Tab, ErrorBoundary, ConditionalWrapper, generateHelpUrl } from "./_chunks-es/generate-help-url.esm.mjs"; import { Hotkeys } from "./_chunks-es/generate-help-url.esm.mjs"; import "./_singletons.mjs"; import { useTranslation as useTranslation$1, I18nextProvider, initReactI18next } from "react-i18next"; import { getTheme_v2, rgba as rgba$1, parseColor, rgbToHex, screen, multiply, createColorTheme, buildTheme } from "@sanity/ui/theme"; import { styled, css, keyframes, createGlobalStyle } from "styled-components"; import sortBy from "lodash/sortBy.js"; import { isKeyedObject, isIndexSegment, isKeySegment, isIndexTuple, isObjectSchemaType, isArraySchemaType, isNumberSchemaType, isBooleanSchemaType, isStringSchemaType, isPrimitiveSchemaType, isReference as isReference$1, isArrayOfBlocksSchemaType, isSlug, isTypedObject, isGlobalDocumentReference, isValidationErrorMarker, isPortableTextTextBlock, isCrossDatasetReferenceSchemaType, isReferenceSchemaType, isArrayOfObjectsSchemaType, isArrayOfPrimitivesSchemaType, isCrossDatasetReference, isTitledListValue, isImage, isPortableTextSpan, isSearchStrategy, searchStrategies as searchStrategies$1, isValidationWarningMarker, isValidationInfoMarker, defineType, defineField, isDeprecatedSchemaType, isFileSchemaType, isImageSchemaType, isBlockSchemaType, defineArrayMember } from "@sanity/types"; export * from "@sanity/types"; import { useVirtualizer, defaultRangeExtractor, elementScroll } from "@tanstack/react-virtual"; import throttle from "lodash/throttle.js"; import { ChevronRightIcon, EllipsisHorizontalIcon, DocumentIcon, ImageIcon, ErrorOutlineIcon, WarningOutlineIcon, InfoOutlineIcon, CheckmarkIcon, ToggleArrowRightIcon, BulbOutlineIcon, UnknownIcon, EditIcon, TrashIcon, CalendarIcon, DotIcon, SearchIcon, ChevronLeftIcon, EarthGlobeIcon, ChevronDownIcon, LockIcon, CopyIcon, AddIcon, CircleIcon, CheckmarkCircleIcon, PublishIcon, PinFilledIcon, PinIcon, RestoreIcon, ClockIcon, CloseCircleIcon, UnarchiveIcon, ArchiveIcon, ArrowUpIcon, CloseIcon, ControlsIcon, SpinnerIcon, ArrowLeftIcon, SortIcon, UnpublishIcon, AccessDeniedIcon, Icon, LinkIcon, LaunchIcon, HelpCircleIcon, SyncIcon, UploadIcon, DragHandleIcon, StackCompactIcon, PanelLeftIcon, InsertAboveIcon, InsertBelowIcon, AddDocumentIcon, ResetIcon, DownloadIcon, ReadOnlyIcon, BinaryDocumentIcon, CropIcon, UlistIcon, OlistIcon, CodeIcon, UnderlineIcon, StrikethroughIcon, ItalicIcon, BoldIcon, BlockElementIcon, InlineElementIcon, CollapseIcon, ExpandIcon, EyeOpenIcon, AddCircleIcon, ArrowRightIcon, ArrowDownIcon, RevertIcon, ClipboardIcon, ChevronUpIcon, DocumentsIcon, StringIcon, NumberIcon, BlockContentIcon, UndoIcon, AddCommentIcon, CommentIcon, SparklesIcon, EarthAmericasIcon, SelectIcon, TaskIcon, UserIcon, DesktopIcon, MoonIcon, SunIcon, EyeClosedIcon, DoubleChevronRightIcon, BoltIcon, AddUserIcon, CogIcon, LeaveIcon, UsersIcon, MenuIcon, LinkRemovedIcon } from "@sanity/icons"; import { COLOR_HUES, hues, white, red, gray, yellow, purple, black, green, blue } from "@sanity/color"; import { darken, lighten, hasBadContrast, readableColor } from "color2k"; import { of, concat, defer, EMPTY as EMPTY$5, map as map$1, Observable, merge, Subject, fromEvent, throwError, timer, NEVER, from, switchMap as switchMap$1, catchError as catchError$1, iif, startWith as startWith$1, bufferTime, filter as filter$1, BehaviorSubject, tap as tap$1, concatWith, scan as scan$1, shareReplay as shareReplay$1, pipe, count, finalize, share as share$1, ReplaySubject, combineLatest, asyncScheduler, mergeMap as mergeMap$1, firstValueFrom, lastValueFrom, partition as partition$1, timeout, distinctUntilChanged as distinctUntilChanged$1, expand, reduce as reduce$1, skip as skip$1, forkJoin, isObservable, asapScheduler, using, take as take$1, debounce as debounce$2 } from "rxjs"; import { switchMap, map, scan, distinctUntilChanged, catchError, tap, shareReplay, filter, startWith, mergeMapTo, takeUntil, take, mergeMap, first, publishReplay, refCount, withLatestFrom, share, concatMap, groupBy as groupBy$1, throttleTime, last, mergeAll, toArray as toArray$1, distinct, skip, debounceTime, debounce as debounce$1, expand as expand$1, reduce as reduce$2, switchAll, delay, auditTime, switchMapTo, mapTo } from "rxjs/operators"; import { createClient, connectEventSource } from "@sanity/client"; import isEqual$2 from "lodash/isEqual.js"; import memoize$1 from "lodash/memoize.js"; import { useObservable, useObservableEvent } from "react-rx"; import { observableCallback } from "observable-callback"; import uniqueId from "lodash/uniqueId.js"; import { createInstance } from "i18next"; import { defineEvent, createSessionId, createBatchedStore } from "@sanity/telemetry"; import QuickLRU from "quick-lru"; import { useTelemetry, TelemetryProvider } from "@sanity/telemetry/react"; import DataLoader from "dataloader"; import { customAlphabet, nanoid } from "nanoid"; import debug$8 from "debug"; import cloneObject from "date-fns/_lib/cloneObject/index.js"; import dateFnsFormat from "date-fns/format/index.js"; import toInteger from "date-fns/_lib/toInteger/index.js"; import getTimezoneOffsetInMilliseconds from "date-fns/_lib/getTimezoneOffsetInMilliseconds/index.js"; import { formatRelative, isValid, parse, isPast, addDays, startOfMonth, eachWeekOfInterval, lastDayOfMonth, getWeek, isSameDay, isSameMonth, setDate, setMonth, addMonths, setYear, setMinutes, setHours, format as format$2, parseISO, getMinutes, startOfHour, addHours, differenceInMonths, differenceInYears, differenceInWeeks, differenceInDays, differenceInHours, differenceInMinutes, differenceInSeconds, isBefore, startOfMinute, isWeekend, startOfDay, endOfDay, isAfter, set as set$1, startOfToday, endOfMinute, sub, formatDistance, isToday, isThisISOWeek, addWeeks } from "date-fns"; import FocusLock from "react-focus-lock"; import semver, { satisfies } from "semver"; import { SANITY_VERSION } from "./_chunks-es/version.mjs"; import omit from "lodash/omit.js"; import { Mutation, BufferedDocument, arrayToJSONMatchPath } from "@sanity/mutator"; import groupBy from "lodash/groupBy.js"; import partition from "lodash/partition.js"; import * as legacyDateFormat from "@sanity/util/legacyDateFormat"; import { DEFAULT_DATE_FORMAT, format as format$3, parse as parse$1, DEFAULT_TIME_FORMAT } from "@sanity/util/legacyDateFormat"; import { useDevicePixelRatio, getDevicePixelRatio } from "use-device-pixel-ratio"; import classNames from "classnames"; import { isValidElementType } from "react-is"; import { isImageSource, isFileSource, getImageDimensions, isDefaultHotspot, isDefaultCrop, isAssetObjectStub, isImageAssetId, isFileAssetId } from "@sanity/asset-utils"; import imageUrlBuilder from "@sanity/image-url"; import { useRouter, IntentLink, useIntentLink, route, useRouterState, useStateLink, StateLink, RouteScope, STICKY_PARAMS, RouterProvider } from "sanity/router"; import isString$1 from "lodash/isString.js"; import { motion, AnimatePresence } from "framer-motion"; import { isHotkey } from "is-hotkey-esm"; import { useEffectEvent } from "use-effect-event"; import flatten$1 from "lodash/flatten.js"; import last$1 from "lodash/last.js"; import uniqBy from "lodash/uniqBy.js"; import orderBy from "lodash/orderBy.js"; import { DEFAULT_MAX_FIELD_DEPTH, validateSchema, groupProblems, isActionEnabled } from "@sanity/schema/_internal"; import compact from "lodash/compact.js"; import flow from "lodash/flow.js"; import toLower from "lodash/toLower.js"; import trim from "lodash/trim.js"; import union from "lodash/union.js"; import uniq from "lodash/uniq.js"; import words from "lodash/words.js"; import { resolveTypeName as resolveTypeName$2, randomKey as randomKey$1, isShallowEmptyObject, isDeepEmpty } from "@sanity/util/content"; import get from "lodash/get.js"; import isPlainObject$1 from "lodash/isPlainObject.js"; import capitalize from "lodash/capitalize.js"; import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from "@dnd-kit/core"; import { restrictToHorizontalAxis, restrictToVerticalAxis } from "@dnd-kit/modifiers"; import { sortableKeyboardCoordinates, useSortable, SortableContext, horizontalListSortingStrategy, verticalListSortingStrategy } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import shallowEquals from "shallow-equals"; import { PortableText as PortableText$1, toPlainText } from "@portabletext/react"; import { usePortableTextEditor, PortableTextEditor, usePortableTextEditorSelection, PortableTextEditable, EditorProvider, useEditor, keyGenerator as keyGenerator$1 } from "@portabletext/editor"; import { Schema } from "@sanity/schema"; import { MarkdownPlugin, EventListenerPlugin } from "@portabletext/editor/plugins"; import startCase from "lodash/startCase.js"; import template from "lodash/template.js"; import { applyPatches, parsePatch, cleanupEfficiency, makeDiff, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL, makePatches } from "@sanity/diff-match-patch"; import scrollIntoView$1 from "scroll-into-view-if-needed"; import difference from "lodash/difference.js"; import range from "lodash/range.js"; import { useSyncExternalStore as useSyncExternalStore$1 } from "use-sync-external-store/shim/index.js"; import { uuid } from "@sanity/uuid"; import deburr from "lodash/deburr.js"; import { normalizeBlock } from "@portabletext/block-tools"; import keyBy from "lodash/keyBy.js"; import pick from "lodash/pick.js"; import sample from "lodash/sample.js"; import intersection from "lodash/intersection.js"; import isEmpty$1 from "lodash/isEmpty.js"; import { renderToString } from "react-dom/server"; import isFinite from "lodash/isFinite.js"; import Refractor from "react-refractor"; import bash from "refractor/lang/bash.js"; import javascript from "refractor/lang/javascript.js"; import json from "refractor/lang/json.js"; import jsx2 from "refractor/lang/jsx.js"; import typescript from "refractor/lang/typescript.js"; import isObject from "lodash/isObject.js"; import { makeFetchTransport, inboundFiltersIntegration, functionToStringIntegration, browserApiErrorsIntegration, breadcrumbsIntegration, globalHandlersIntegration, linkedErrorsIntegration, dedupeIntegration, httpContextIntegration, isInitialized, getClient, getCurrentScope, BrowserClient, defaultStackParser, Scope, init, withScope, captureException } from "@sentry/react"; import { createMemoryHistory, createBrowserHistory } from "history"; import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector.js"; import escapeRegExp$1 from "lodash/escapeRegExp.js"; import { fromUrl } from "@sanity/bifur-client"; import cloneDeep from "lodash/cloneDeep.js"; import { SanityLogo as SanityLogo$1, SanityMonogram } from "@sanity/logos"; import { useHotModuleReload } from "use-hot-module-reload"; import arrify from "arrify"; import { getPublishedId as getPublishedId$1 } from "@sanity/client/csm"; import castArray from "lodash/castArray.js"; import { parse as parse$2, evaluate } from "groq-js"; import { InsertMenu as InsertMenu$2 } from "@sanity/insert-menu"; import { applyPatch as applyPatch$1, incremental } from "mendoza"; import findIndex$1 from "lodash/findIndex.js"; import upperFirst from "lodash/upperFirst.js"; import find from "lodash/find.js"; import { MenuGroup } from "./_chunks-es/MenuGroup.mjs"; import getRandomValues from "get-random-values-esm"; import exif from "exif-component"; import clone from "lodash/clone.js"; import { exhaustMapWithTrailing } from "rxjs-exhaustmap-with-trailing"; import { mergeMapArray } from "rxjs-mergemap-array"; import { reduce } from "json-reduce"; import { createClientConcurrencyLimiter } from "@sanity/util/client"; import { ConcurrencyLimiter } from "@sanity/util/concurrency-limiter"; import speakingurl from "speakingurl"; import xor from "lodash/xor.js"; import { diffItem } from "@sanity/diff-patch"; import sortedIndex from "lodash/sortedIndex.js"; import identity$2 from "lodash/identity.js"; import values from "lodash/values.js"; import { diffInput, wrap as wrap$1 } from "@sanity/diff"; import raf from "raf"; import { createRoot } from "react-dom/client"; import { getLuminance, parseToRgb, rgb, mix } from "polished"; function createStore(reportedValues, publish2) { function add(id2, value) { reportedValues.has(id2), reportedValues.set(id2, value), publish2(); } function update(id2, value) { reportedValues.has(id2), reportedValues.set(id2, value), publish2(); } function remove2(id2) { reportedValues.has(id2), reportedValues.delete(id2), publish2(); } return { add, remove: remove2, update }; } function useTrackerStore() { const [reportedValues] = useState(() => /* @__PURE__ */ new Map()), [snapshot2, updateSnapshot] = useReducer(() => Array.from(reportedValues.entries()), []), debouncedUpdateSnapshot = useMemo(() => debounce(updateSnapshot, 10, { trailing: !0 }), []); return { store: useMemo(() => createStore(reportedValues, debouncedUpdateSnapshot), [debouncedUpdateSnapshot, reportedValues]), snapshot: snapshot2 }; } function useTrackerStoreReporter(store, id2, value, t0) { const $ = c(10), isEqual2 = t0 === void 0 ? Object.is : t0, idRef = useRef(null), previousRef = useRef(null); let t1, t2; $[0] !== id2 || $[1] !== store || $[2] !== value ? (t1 = () => { if (id2 === null || store === null) return; const nextValue = value(); return store.add(id2, nextValue), idRef.current = id2, previousRef.current = nextValue, () => { store.remove(id2), idRef.current = null, previousRef.current = null; }; }, t2 = [id2, store, value], $[0] = id2, $[1] = store, $[2] = value, $[3] = t1, $[4] = t2) : (t1 = $[3], t2 = $[4]), useLayoutEffect(t1, t2); let t3; $[5] !== id2 || $[6] !== isEqual2 || $[7] !== store || $[8] !== value ? (t3 = () => { if (id2 === null || idRef.current === null || store === null || id2 !== idRef.current) return; const nextValue_0 = value(); isEqual2(previousRef.current, nextValue_0) || (store.update(id2, nextValue_0), previousRef.current = nextValue_0); }, $[5] = id2, $[6] = isEqual2, $[7] = store, $[8] = value, $[9] = t3) : t3 = $[9], useLayoutEffect(t3); } function ChangeIndicatorsTrackerComponent(props2) { const $ = c(6), { children } = props2, { store, snapshot: snapshot2 } = useTrackerStore(); let t0; $[0] !== children || $[1] !== snapshot2 ? (t0 = /* @__PURE__ */ jsx(ChangeIndicatorTrackerContextGetSnapshot.Provider, { value: snapshot2, children }), $[0] = children, $[1] = snapshot2, $[2] = t0) : t0 = $[2]; let t1; return $[3] !== store || $[4] !== t0 ? (t1 = /* @__PURE__ */ jsx(ChangeIndicatorTrackerContextStore.Provider, { value: store, children: t0 }), $[3] = store, $[4] = t0, $[5] = t1) : t1 = $[5], t1; } const ChangeIndicatorsTracker = memo(ChangeIndicatorsTrackerComponent), EMPTY_ARRAY$C = []; function useChangeIndicatorsReportedValues() { const snapshot2 = useContext(ChangeIndicatorTrackerContextGetSnapshot); return snapshot2 === null ? (console.warn(new Error('No context provided for reporter. Make sure that the component calling "useChangeIndicatorsReportedValues()", is wrapped inside a <ChangeIndicatorsTracker> element')), EMPTY_ARRAY$C) : snapshot2; } const useChangeIndicatorsReporter = (id2, value, isEqual2) => { const store = useContext(ChangeIndicatorTrackerContextStore); store === null && console.warn(new Error('No context provided for reporter. Make sure that the component calling "useChangeIndicatorsReporter()", is wrapped inside a <ChangeIndicatorsTracker> element')), useTrackerStoreReporter(store, id2, value, isEqual2); }, ChangeFieldWrapper = (props2) => { const $ = c(13), { path, hasHover } = props2, { onSetFocus } = useContext(ConnectorContext), [isHover, setHover] = useState(!1); let t0; $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => { setHover(!0); }, $[0] = t0) : t0 = $[0]; const onMouseEnter = t0; let t1; $[1] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => { setHover(!1); }, $[1] = t1) : t1 = $[1]; const onMouseLeave = t1, [element, setElement] = useState(null); let t2; t2 = element ? `change-${PathUtils.toString(path)}` : null; const reporterId = t2; let t3; $[2] !== element || $[3] !== hasHover || $[4] !== isHover || $[5] !== path ? (t3 = () => ({ element, path, isChanged: !0, hasFocus: !1, hasHover: isHover, hasRevertHover: hasHover }), $[2] = element, $[3] = hasHover, $[4] = isHover, $[5] = path, $[6] = t3) : t3 = $[6], useChangeIndicatorsReporter(reporterId, t3, deepEquals); let t4; $[7] !== onSetFocus || $[8] !== path ? (t4 = (event) => { setFocusWithStopPropagation(event, onSetFocus, path); }, $[7] = onSetFocus, $[8] = path, $[9] = t4) : t4 = $[9]; const handleClick = t4; let t5; return $[10] !== handleClick || $[11] !== props2.children ? (t5 = /* @__PURE__ */ jsx("div", { ref: setElement, onClick: handleClick, onMouseLeave, onMouseEnter, children: props2.children }), $[10] = handleClick, $[11] = props2.children, $[12] = t5) : t5 = $[12], t5; }; function setFocusWithStopPropagation(event, onSetFocus, path) { event.stopPropagation(), onSetFocus(path); } function createHookFromObservableFactory(observableFactory, initialValue) { const initialLoadingTuple = [initialValue, !0], initialResult = { type: "tuple", tuple: initialLoadingTuple }; return function(arg) { const observable = useMemo(() => of(arg).pipe(switchMap((_arg) => concat(of({ type: "loading" }), observableFactory(_arg).pipe(map((value) => ({ type: "value", value }))))), scan(([prevValue], next) => next.type === "loading" ? [prevValue, !0] : [next.value, !1], initialLoadingTuple), distinctUntilChanged(([prevValue, prevIsLoading], [nextValue, nextIsLoading]) => !(prevValue !== nextValue || prevIsLoading !== nextIsLoading)), map((tuple) => ({ type: "tuple", tuple })), catchError((error) => of({ type: "error", error }))), [arg]), result = useObservable(observable, initialResult); if (result.type === "error") throw result.error; return result.tuple; }; } function isNonNullable$3(value) { return value != null; } const DRAFTS_FOLDER = "drafts", VERSION_FOLDER = "versions", PATH_SEPARATOR = ".", DRAFTS_PREFIX = `${DRAFTS_FOLDER}${PATH_SEPARATOR}`, VERSION_PREFIX = `${VERSION_FOLDER}${PATH_SEPARATOR}`; function documentIdEquals(documentId, equalsDocumentId) { return getPublishedId(documentId) === getPublishedId(equalsDocumentId); } function isDraft(document2) { return isDraftId(document2._id); } function isDraftId(id2) { return id2.startsWith(DRAFTS_PREFIX); } function isVersionId(id2) { return id2.startsWith(VERSION_PREFIX); } function getIdPair(id2, { version } = {}) { if (version === "drafts" || version === "published") throw new Error('Version can not be "published" or "drafts"'); return { publishedId: getPublishedId(id2), draftId: getDraftId(id2), ...version ? { versionId: getVersionId(id2, version) } : {} }; } function isPublishedId(id2) { return !isDraftId(id2) && !isVersionId(id2); } function getDraftId(id2) { if (isVersionId(id2)) { const publishedId = getPublishedId(id2); return DRAFTS_PREFIX + publishedId; } return isDraftId(id2) ? id2 : DRAFTS_PREFIX + id2; } const systemBundles = ["drafts", "published"]; function isSystemBundle(maybeSystemBundle) { return systemBundles.includes(maybeSystemBundle); } const systemBundleNames = ["draft", "published"]; function isSystemBundleName(maybeSystemBundleName) { return systemBundleNames.includes(maybeSystemBundleName); } function getVersionId(id2, version) { if (isSystemBundle(version)) throw new Error('Version can not be "published" or "drafts"'); return `${VERSION_PREFIX}${version}${PATH_SEPARATOR}${getPublishedId(id2)}`; } function idMatchesPerspective(perspectiveStack, documentId) { return isPublishedId(documentId) ? !0 : perspectiveStack.some((perspective) => perspective === "drafts" ? isDraftId(documentId) : getVersionFromId(documentId) === perspective); } function getVersionFromId(id2) { if (!isVersionId(id2)) return; const [_versionPrefix, versionId, ..._publishedId] = id2.split(PATH_SEPARATOR); return versionId; } function getPublishedId(id2) { return isVersionId(id2) ? id2.split(PATH_SEPARATOR).slice(2).join(PATH_SEPARATOR) : isDraftId(id2) ? id2.slice(DRAFTS_PREFIX.length) : id2; } function createDraftFrom(document2) { return { ...document2, _id: getDraftId(document2._id) }; } function newDraftFrom(document2) { return { ...document2, _id: DRAFTS_PREFIX }; } function createPublishedFrom(document2) { return { ...document2, _id: getPublishedId(document2._id) }; } function collate(documents) { const byId = documents.reduce((res, doc) => { const publishedId = getPublishedId(doc._id); let entry = res.get(publishedId); return entry || (entry = { id: publishedId, type: doc._type, published: void 0, draft: void 0, versions: [] }, res.set(publishedId, entry)), isPublishedId(doc._id) && (entry.published = doc), isDraftId(doc._id) && (entry.draft = doc), isVersionId(doc._id) && entry.versions.push(doc), res; }, /* @__PURE__ */ new Map()); return Array.from(byId.values()); } function removeDupes$3(documents) { return collate(documents).map((entry) => entry.draft || entry.published || entry.versions[0]).filter(isNonNullable$3); } const EMPTY_OBJECT = Object.freeze({}), EMPTY_ARRAY$B = Object.freeze([]), formatRelativeLocale = (...args) => { const dateFnsRelative = formatRelative(...args); if (isValid(parse(dateFnsRelative, "MM/dd/yyyy", /* @__PURE__ */ new Date()))) { const [dateTime] = args; return new Date(dateTime).toLocaleDateString(); } return dateFnsRelative; }; function getDocumentVariantType(documentId) { return isDraftId(documentId) ? "draft" : isVersionId(documentId) ? "version" : "published"; } function getGlobalScope() { if (typeof globalThis < "u") return globalThis; if (typeof window < "u") return window; if (typeof self < "u") return self; if (typeof global < "u") return global; throw new Error("@sanity/ui: could not locate global scope"); } const globalScope = getGlobalScope(); function isArray(value) { return Array.isArray(value); } function isRecord$4(value) { return !!value && typeof value == "object" && !Array.isArray(value); } function isString(value) { return typeof value == "string"; } function isTruthy(value) { return !!value; } const ResizeObserver = typeof document == "object" && typeof window == "object" && window.ResizeObserver ? window.ResizeObserver : ResizeObserver$1, createSharedResizeObserver = () => { const event = createPubSub(), resizeObserver2 = new ResizeObserver((entries) => event.publish(entries)); return { observe: (element, observer, options) => { const unsubscribe = event.subscribe((entries) => { const entry = entries.find((e) => e.target === element); entry && observer(entry); }); return resizeObserver2.observe(element, options), () => { unsubscribe(), resizeObserver2.unobserve(element); }; }, unobserve: (element) => resizeObserver2.unobserve(element) }; }, resizeObserver = createSharedResizeObserver(), createSWRCache = createLRUCache; function createSWR(options) { const cache2 = createSWRCache(options); return function(key) { return (input$) => concat(defer(() => cache2.has(key) ? of({ fromCache: !0, value: cache2.get(key) }) : EMPTY$5), input$.pipe(tap((result) => cache2.set(key, result)), map$1((value) => ({ fromCache: !1, value })))); }; } function createLRUCache(options) { const lru = new QuickLRU(options); return { get(key) { const entry = lru.get(key); if (!entry) throw new Error(`Key not found in LRU cache: ${key}`); return entry.value; }, set(key, value) { lru.set(key, { value }); }, delete(key) { lru.delete(key); }, has(key) { return lru.has(key); } }; } const BUNDLED_DOC_TYPES = ["sanity.imageAsset", "sanity.fileAsset"]; function _isSanityDocumentTypeDefinition(def) { return def.type === "document" && BUNDLED_DOC_TYPES.includes(def.name); } function _isCustomDocumentTypeDefinition(def) { return def.type === "document" && !_isSanityDocumentTypeDefinition(def); } const GROQ_KEYWORDS = ["match", "in", "asc", "desc", "true", "false", "null"], VALID_FIELD = /^[a-zA-Z_][a-zA-Z0-9_]*$/, fieldNeedsEscape = (fieldName) => !VALID_FIELD.test(fieldName) || GROQ_KEYWORDS.includes(fieldName), escapeField = (fieldName) => `["${fieldName}"]`, escapeFirst = (fieldName) => `@${escapeField(fieldName)}`, isEmptyArray = (value) => Array.isArray(value) && value.length === 0, joinPath = (pathArray) => { let path = ""; for (let i = 0; i < pathArray.length; i++) { const pathSegment = pathArray[i]; if (isEmptyArray(pathSegment)) { path += "[]"; continue; } if (typeof pathSegment == "number") { path += `[${pathSegment}]`; continue; } const isFirst = i === 0; fieldNeedsEscape(pathSegment) ? path = isFirst ? escapeFirst(pathSegment) : `${path}${escapeField(pathSegment)}` : path = isFirst ? pathSegment : `${path}.${pathSegment}`; } return path; }, supportsTouch = isTouchDevice$1(); function isTouchDevice$1() { return typeof window > "u" ? !1 : "ontouchstart" in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; } const FONT_SANS_SERIF = "-apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, \\'Helvetica Neue\\', Helvetica, Arial, system-ui, sans-serif", FONT_MONOSPACE = "-apple-system-ui-monospace, \\'SF Mono\\', Menlo, Monaco, Consolas, monospace", uncaughtErrorHandler = () => ( // prettier-ignore ["window.onerror = function(m,u,l,c,e) {", "var p=window.location.port;", "var h=window.location.protocol+'//'+window.location.hostname+(p?':'+p:'');", "var r=document.getElementById('sanity');", "while(r.firstChild){r.removeChild(r.firstChild);}", "var s=document.createElement('style');", "s.appendChild(document.createTextNode('", "html,body,#sanityBody,#sanity,#sanityError{height:100%;}", "body{-webkit-font-smoothing:antialiased;margin:0;}", `#sanityError{position:fixed;top:0;left:0;width:100%;height:100%;overflow:auto;background-color:#fff;color:#121923;font-family:${FONT_SANS_SERIF};font-size:16px;line-height:21px;min-height:100%;}`, "#sanityError>div{background-color:#fff;max-width:960px;margin:0 auto;padding:47px 32px 52px;}", "@media(min-width:512px){", "#sanityError>div{", "padding:47px 84px;", "}", "}", "#sanityError button{-webkit-font-smoothing:inherit;font:inherit;font-weight:500;background-color:#2276FC;color:#fff;padding:7px 12px;border-radius:3px;border:0;}", "#sanityError button:hover{background-color:#1E63D0;}", "#sanityError button:active{background-color:#1B50A5;}", "'));", "document.head.appendChild(s);", "var f=document.createElement('div');", "f.id='sanityError';", "f.innerHTML='", "<div>", '<h1 style="font-size:21px;line-height:27px;margin: 0 0 10px;">Unhandled error</h1>', '<p style="color:#66758D;margin:10px 0 14px;">Encountered an unhandled error in this Studio.</p>', '<button class="sanity-error-handler__reload-btn" type="button">Reload page</button>', '<pre style="background-color:#FDEBEA;color:#C3362C;font-size:13px;line-height:17px;padding:8px 12px;border-radius:3px;margin:32px 0 0;overflow:auto;">', `<code style="font-family:${FONT_MONOSPACE};">`, "'+e.stack.replaceAll(h,'')+'", "</code>", "</pre>", "</div>", "';", "var b=f.querySelector('.sanity-error-handler__reload-btn');", "if(b){", "b.onclick=function() {", "window.location.reload();", "}", "};", "r.appendChild(f);", "};"].join("") ), segmenter = typeof Intl == "object" && "Segmenter" in Intl ? new Intl.Segmenter() : void 0; function sliceString(str, start, end) { if (end < start) throw new Error("End must be greater than start, use `String.prototype.slice()` for negative values"); if (!segmenter) return str.slice(start, end); let i = 0, sliced = ""; for (const value of segmenter.segment(str)) { if (i === end) return sliced; sliced += value.segment, i++; } return sliced; } function truncateString(str, maxLength) { const truncated = sliceString(str, 0, maxLength); return truncated === str ? truncated : `${truncated}\u2026`; } const LOADING_STATE$1 = { isLoading: !0, value: void 0, error: null }; function useLoadable(value$, initialValue) { const $ = c(4); let t0; $[0] !== initialValue ? (t0 = typeof initialValue > "u" ? LOADING_STATE$1 : { isLoading: !1, value: initialValue, error: null }, $[0] = initialValue, $[1] = t0) : t0 = $[1]; const initial2 = t0; let t1, t2; return $[2] !== value$ ? (t2 = value$.pipe(asLoadable()), $[2] = value$, $[3] = t2) : t2 = $[3], t1 = t2, useObservable(t1, initial2); } function asLoadable() { return (value$) => value$.pipe(map((value) => ({ isLoading: !1, value, error: null })), catchError((error) => of({ isLoading: !1, value: void 0, error }))); } function userHasRole(user, roleId) { return user !== null && user.roles.some((role) => role.name === roleId); } function useThrottledCallback(callback, wait, options) { const $ = c(4); let t0, t1; return $[0] !== callback || $[1] !== options || $[2] !== wait ? (t1 = throttle(callback, wait, options), $[0] = callback, $[1] = options, $[2] = wait, $[3] = t1) : t1 = $[3], t0 = t1, t0; } function useUnique(value) { const [previous, setPrevious] = useState(value); return isEqual$2(previous, value) ? previous : (setPrevious(value), value); } const DEBUG_MODE$2 = typeof process > "u" ? !1 : process?.env?.SANITY_STUDIO_DEBUG_I18N, DEBUG_I18N = !!DEBUG_MODE$2, debugWrappers = { reverse: (str) => `\u202E${str}`, triangles: (str) => `\u25E4 ${str} \u25E2` }; function maybeWrapT(t) { const wrapper = DEBUG_MODE$2 === "reverse" || DEBUG_MODE$2 === "triangles" ? debugWrappers[DEBUG_MODE$2] : null; return wrapper ? (...args) => wrapper(t(...args)) : t; } const translationOptionOverrides = { // We're manually forcing a re-render with the locale key in the LocaleProvider, // so we don't need to bind to the i18n instance for language change events. bindI18n: !1 }; function useTranslation(ns, options) { const $ = c(6); let t0; $[0] !== options ? (t0 = options ? { keyPrefix: options.keyPrefix, lng: options.lng, ...translationOptionOverrides } : translationOptionOverrides, $[0] = options, $[1] = t0) : t0 = $[1]; const { t } = useTranslation$1(ns, t0); let t1; $[2] !== t ? (t1 = maybeWrapT(t), $[2] = t, $[3] = t1) : t1 = $[3]; let t2; return $[4] !== t1 ? (t2 = { t: t1 }, $[4] = t1, $[5] = t2) : t2 = $[5], t2; } const animationSpeed = 250, ChangeBarWrapper$1 = styled.div(({ $changed, $disabled, $hasFocus, $isReviewChangeOpen }) => $disabled ? css` ${ChangeBarMarker}:after { display: none; } ` : css` --change-bar-offset: 4px; display: flex; position: relative; ${ChangeBarMarker}:after { opacity: 0.5; } @media (hover: hover) { &:hover { z-index: 10; ${ChangeBarMarker}:after { opacity: 1; } } } /* hide when field is not changed */ ${$hasFocus && css` ${ChangeBarMarker}:after { opacity: 1; } `} /* hide when field is not changed */ ${!$changed && css` ${ChangeBarMarker}:after { opacity: 0; pointer-events: none; } `} /* hide hover effect when review changes is open */ ${$isReviewChangeOpen && css` ${ChangeBarButton} { opacity: 0; } `} `), FieldWrapper$1 = styled.div` flex-grow: 1; min-width: 0; `, ChangeBar = styled.div` position: relative; opacity: 1; transition: opacity 100ms; z-index: ${({ $zIndex }) => $zIndex}; `, ChangeBarMarker = styled.div((props2) => { const { media } = getTheme_v2(props2.theme); return css` position: absolute; top: -1px; left: var(--change-bar-offset); width: 1px; bottom: -1px; background-color: var(--card-bg-color); @media (min-width: ${media[0]}px) { display: unset; } &:after { content: ''; display: block; position: absolute; top: 1px; left: 0; width: 1px; bottom: 1px; background-color: var(--card-badge-caution-dot-color); border-radius: 0.5px; } `; }), ChangeBarButton = styled.button((props2) => { const { $withHoverEffect, $isInteractive } = props2; return css` appearance: none; border: 0; outline: 0; display: block; padding: 0; background: transparent; opacity: 0; position: absolute; height: 100%; ${$isInteractive && css` cursor: pointer; pointer-events: all; `} left: calc(-0.25rem + var(--change-bar-offset)); width: calc(1rem - 1px); transition: opacity ${animationSpeed}ms; &:focus { border: 0; outline: 0; } &:focus { border: 0; outline: 0; } ${$withHoverEffect && css` @media (hover: hover) { &:hover { opacity: 0.2; } } `} `; }); function ElementWithChangeBar(props2) { const $ = c(18), { children, disabled, hasFocus, isChanged, withHoverEffect: t0, isInteractive: t1 } = props2, withHoverEffect = t0 === void 0 ? !0 : t0, isInteractive = t1 === void 0 ? !0 : t1, { onOpenReviewChanges, isReviewChangesOpen } = useContext(ConnectorContext), { zIndex } = useLayer(), { t } = useTranslation(); let t2, t3; $[0] !== disabled || $[1] !== isChanged || $[2] !== isInteractive || $[3] !== isReviewChangesOpen || $[4] !== onOpenReviewChanges || $[5] !== t || $[6] !== withHoverEffect || $[7] !== zIndex ? (t3 = disabled || !isChanged ? null : /* @__PURE__ */ jsxs(ChangeBar, { "data-testid": "change-bar", $zIndex: zIndex, children: [ /* @__PURE__ */ jsx(ChangeBarMarker, { "data-testid": "change-bar__marker" }), /* @__PURE__ */ jsx(Tooltip, { content: t("changes.change-bar.aria-label"), portal: !0, disabled: !isInteractive, children: /* @__PURE__ */ jsx(ChangeBarButton, { "aria-label": t("changes.change-bar.aria-label"), "data-testid": "change-bar__button", onClick: isReviewChangesOpen ? void 0 : onOpenReviewChanges, tabIndex: -1, type: "button", $withHoverEffect: withHoverEffect, $isInteractive: isInteractive }) }) ] }), $[0] = disabled, $[1] = isChanged, $[2] = isInteractive, $[3] = isReviewChangesOpen, $[4] = onOpenReviewChanges, $[5] = t, $[6] = withHoverEffect, $[7] = zIndex, $[8] = t3) : t3 = $[8], t2 = t3; const changeBar = t2; let t4; $[9] !== children ? (t4 = /* @__PURE__ */ jsx(FieldWrapper$1, { "data-testid": "change-bar__field-wrapper", children }), $[9] = children, $[10] = t4) : t4 = $[10]; let t5; return $[11] !== changeBar || $[12] !== disabled || $[13] !== hasFocus || $[14] !== isChanged || $[15] !== isReviewChangesOpen || $[16] !== t4 ? (t5 = /* @__PURE__ */ jsxs(ChangeBarWrapper$1, { "data-testid": "change-bar-wrapper", $changed: isChanged, $disabled: disabled, $hasFocus: hasFocus, $isReviewChangeOpen: isReviewChangesOpen, children: [ t4, changeBar ] }), $[11] = changeBar, $[12] = disabled, $[13] = hasFocus, $[14] = isChanged, $[15] = isReviewChangesOpen, $[16] = t4, $[17] = t5) : t5 = $[17], t5; } const ChangeBarWrapper = memo(function(props2) { const $ = c(34); let children, disabled, hasFocus, isChanged, isInteractive, onMouseEnterProp, onMouseLeaveProp, restProps, t0, withHoverEffect; $[0] !== props2 ? ({ children, disabled, hasFocus, isChanged, onMouseEnter: onMouseEnterProp, onMouseLeave: onMouseLeaveProp, path: t0, withHoverEffect, isInteractive, ...restProps } = props2, $[0] = props2, $[1] = children, $[2] = disabled, $[3] = hasFocus, $[4] = isChanged, $[5] = isInteractive, $[6] = onMouseEnterProp, $[7] = onMouseLeaveProp, $[8] = restProps, $[9] = t0, $[10] = withHoverEffect) : (children = $[1], disabled = $[2], hasFocus = $[3], isChanged = $[4], isInteractive = $[5], onMouseEnterProp = $[6], onMouseLeaveProp = $[7], restProps = $[8], t0 = $[9], withHoverEffect = $[10]); const path = t0 === void 0 ? EMPTY_ARRAY$B : t0, layer = useLayer(), [hasHover, setHover] = useState(!1); let t1; $[11] !== onMouseEnterProp ? (t1 = (event) => { onMouseEnterProp?.(event), setHover(!0); }, $[11] = onMouseEnterProp, $[12] = t1) : t1 = $[12]; const onMouseEnter = t1; let t2; $[13] !== onMouseLeaveProp ? (t2 = (event_0) => { onMouseLeaveProp?.(event_0), setHover(!1); }, $[13] = onMouseLeaveProp, $[14] = t2) : t2 = $[14]; const onMouseLeave = t2, [element, setElement] = useState(null); let t3; t3 = disabled || !element ? null : `field-${PathUtils.toString(path)}`; const reporterId = t3; let t4; $[15] !== element || $[16] !== hasFocus || $[17] !== hasHover || $[18] !== isChanged || $[19] !== layer.zIndex || $[20] !== path ? (t4 = () => ({ element, path, isChanged, hasFocus, hasHover, zIndex: layer.zIndex }), $[15] = element, $[16] = hasFocus, $[17] = hasHover, $[18] = isChanged, $[19] = layer.zIndex, $[20] = path, $[21] = t4) : t4 = $[21], useChangeIndicatorsReporter(reporterId, t4, deepEquals); let t5; $[22] !== children || $[23] !== disabled || $[24] !== hasFocus || $[25] !== isChanged || $[26] !== isInteractive || $[27] !== withHoverEffect ? (t5 = /* @__PURE__ */ jsx(ElementWithChangeBar, { hasFocus, isChanged, disabled, withHoverEffect, isInteractive, children }), $[22] = children, $[23] = disabled, $[24] = hasFocus, $[25] = isChanged, $[26] = isInteractive, $[27] = withHoverEffect, $[28] = t5) : t5 = $[28]; let t6; return $[29] !== onMouseEnter || $[30] !== onMouseLeave || $[31] !== restProps || $[32] !== t5 ? (t6 = /* @__PURE__ */ jsx("div", { ...restProps, ref: setElement, onMouseEnter, onMouseLeave, children: t5 }), $[29] = onMouseEnter, $[30] = onMouseLeave, $[31] = restProps, $[32] = t5, $[33] = t6) : t6 = $[33], t6; }); function ChangeIndicator(props2) { const $ = c(15); let children, hasFocus, isChanged, path, restProps, withHoverEffect; $[0] !== props2 ? ({ children, hasFocus, isChanged, path, withHoverEffect, ...restProps } = props2, $[0] = props2, $[1] = children, $[2] = hasFocus, $[3] = isChanged, $[4] = path, $[5] = restProps, $[6] = withHoverEffect) : (children = $[1], hasFocus = $[2], isChanged = $[3], path = $[4], restProps = $[5], withHoverEffect = $[6]); const { isInteractive } = useContext(ConnectorContext); let t0; return $[7] !== children || $[8] !== hasFocus || $[9] !== isChanged || $[10] !== isInteractive || $[11] !== path || $[12] !== restProps || $[13] !== withHoverEffect ? (t0 = /* @__PURE__ */ jsx(ChangeBarWrapper, { ...restProps, path, hasFocus, isChanged, withHoverEffect, isInteractive, children }), $[7] = children, $[8] = hasFocus, $[9] = isChanged, $[10] = isInteractive, $[11] = path, $[12] = restProps, $[13] = withHoverEffect, $[14] = t0) : t0 = $[14], t0; } function useOnScroll(callback) { const $ = c(4), parentContext = useContext(ScrollContext); let t0, t1; $[0] !== callback || $[1] !== parentContext ? (t0 = () => parentContext?.subscribe(callback), t1 = [callback, parentContext], $[0] = callback, $[1] = parentContext, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), useEffect(t0, t1); } const ScrollContainerComponent = forwardRef(function(props2, forwardedRef) { const $ = c(22); let onScroll, rest, t0; $[0] !== props2 ? ({ as: t0, onScroll, ...rest } = props2, $[0] = props2, $[1] = onScroll, $[2] = rest, $[3] = t0) : (onScroll = $[1], rest = $[2], t0 = $[3]); const As = t0 === void 0 ? "div" : t0, ref = useRef(null); let t1; $[4] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => ref.current, $[4] = t1) : t1 = $[4], useImperativeHandle(forwardedRef, t1); const parentContext = useContext(ScrollContext), [childContext] = useState(_temp$2y); let t2, t3; $[5] !== childContext || $[6] !== onScroll ? (t2 = () => { if (onScroll) return childContext.subscribe(onScroll); }, t3 = [childContext, onScroll], $[5] = childContext, $[6] = onScroll, $[7] = t2, $[8] = t3) : (t2 = $[7], t3 = $[8]), useEffect(t2, t3); let t4, t5; $[9] !== childContext || $[10] !== parentContext ? (t4 = () => { if (parentContext) return childContext.subscribe(parentContext.publish); }, t5 = [parentContext, childContext], $[9] = childContext, $[10] = parentContext, $[11] = t4, $[12] = t5) : (t4 = $[11], t5 = $[12]), useEffect(t4, t5); let t6, t7; $[13] !== childContext ? (t6 = () => { const handleScroll = (event) => { childContext.publish(event); }, el = ref.current; if (el) return el.addEventListener("scroll", handleScroll, { passive: !0, capture: !0 }), () => { el.removeEventListener("scroll", handleScroll); }; }, t7 = [childContext, ref], $[13] = childContext, $[14] = t6, $[15] = t7) : (t6 = $[14], t7 = $[15]), useEffect(t6, t7); let t8; $[16] !== As || $[17] !== rest ? (t8 = /* @__PURE__ */ jsx(As, { "data-testid": "scroll-container", ...rest, ref }), $[16] = As, $[17] = rest, $[18] = t8) : t8 = $[18]; let t9; return $[19] !== childContext || $[20] !== t8 ? (t9 = /* @__PURE__ */ jsx(ScrollContext.Provider, { value: childContext, children: t8 }), $[19] = childContext, $[20] = t8, $[21] = t9) : t9 = $[21], t9; }), ScrollContainer = memo(ScrollContainerComponent); ScrollContainer.displayName = "Memo(Forwardref(ScrollContainer))"; function _temp$2y() { return createPubSub(); } const CORNER_RADIUS = 4, INTERACTIVE_STROKE_WIDTH = 16, CONNECTOR_MARGIN = 8, ARROW_MARGIN_X = 8, ARROW_MARGIN_Y = 2, ARROW_SIZE = 4, ARROW_THRESHOLD = 12, STROKE_WIDTH$2 = 1, DEBUG$1 = !1, DEBUG_LAYER_BOUNDS = !1; function findMostSpecificTarget(targetType, id2, values2) { const pathString = id2.slice(id2.indexOf("-") + 1) || "[]", path = PathUtils.fromString(pathString), exactId = `${targetType}-${PathUtils.toString(path)}`; if (values2.has(exactId)) return values2.get(exactId); let mostSpecific; for (const [targetId, target] of values2) { if (!("path" in target) || !targetId.startsWith(targetType)) continue; const numEqual = PathUtils.numEqualSegments(path, target.path), lastPathSegment = target.path[target.path.length - 1], pathOnlyDiffersByKey = numEqual === target.path.length - 1 && isKeyedObject(lastPathSegment); if (numEqual !== 0 && !(numEqual !== target.path.length && !pathOnlyDiffersByKey) && (mostSpecific = target, numEqual === path.length)) break; } return mostSpecific; } function hasOverflowScroll(el) { const overflow = getComputedStyle(el).overflow; return overflow.includes("auto") || overflow.includes("scroll"); } function isScrollable(el) { return (el.scrollHeight !== el.offsetHeight || el.scrollWidth !== el.offsetWidth) && hasOverflowScroll(el); } const getOffsetsTo$1 = (source, target) => { const bounds = { top: 0, left: 0, height: target.offsetHeight, width: target.offsetWidth }, rect = { top: 0, left: 0, height: source.offsetHeight, width: source.offsetWidth }; let foundScrollContainer = !1, el = source; for (; el && el !== target && target.contains(el); ) foundScrollContainer && (bounds.top += el.offsetTop, bounds.left += el.offsetLeft), hasOverflowScroll(el) && (bounds.top = el.offsetTop, bounds.height = el.offsetHeight, bounds.left = el.offsetLeft, bounds.width = el.offsetWidth, foundScrollContainer = !0), rect.top += el.offsetTop - el.scrollTop, rect.left += el.offsetLeft - el.scrollLeft, el = el.offsetParent; return { rect, bounds }; }; function isChangeBar(v) { return v[0] !== "changePanel"; } const SCROLL_INTO_VIEW_TOP_PADDING = -15; function scrollIntoView(field) { const element = field.element; if (!element) return; let parentElementWithScroll = element; for (; !isScrollable(parentElementWithScroll); ) if (parentElementWithScroll = parentElementWithScroll.parentElement, !parentElementWithScroll) return; parentElementWithScroll.scroll({ top: parentElementWithScroll.scrollTop + field.rect.top - field.bounds.top + SCROLL_INTO_VIEW_TOP_PADDING, left: 0, behavior: "smooth" }); } function ClampedRect(props2) { const $ = c(9); let bounds, rest; $[0] !== props2 ? ({ bounds, ...rest } = props2, $[0] = props2, $[1] = bounds, $[2] = rest) : (bounds = $[1], rest = $[2]); const x = Math.max(bounds.left, props2.left), y = Math.max(props2.top, bounds.top), height = Math.max(0, props2.height - (y - props2.top)), width = Math.max(0, props2.width - (x - props2.left)); let t0; return $[3] !== height || $[4] !== rest || $[5] !== width || $[6] !== x || $[7] !== y ? (t0 = /* @__PURE__ */ jsx("rect", { ...rest, x, y, height, width }), $[3] = height, $[4] = rest, $[5] = width, $[6] = x, $[7] = y, $[8] = t0) : t0 = $[8], t0; } styled.rect` stroke: #ccc; fill: none; pointer-events: none; stroke-linecap: round; `; const ConnectorPath = styled.path` fill: none; pointer-events: none; stroke-linejoin: round; stroke: var(--card-badge-caution-dot-color); `, InteractivePath = styled.path` fill: none; pointer-events: stroke; stroke: transparent; cursor: pointer; stroke-linecap: round; stroke-linejoin: round; opacity: 0; &:hover { opacity: 0.2; } `, RightBarWrapper = styled(ClampedRect)` stroke: none; pointer-events: none; fill: var(--card-badge-caution-dot-color); `; function arrowPath(x, y, dir) { return [`M ${x - ARROW_SIZE} ${y - ARROW_SIZE * dir} `, `L ${x} ${y}`, `L ${x + ARROW_SIZE} ${y - ARROW_SIZE * dir}`].join(""); } function moveTo(x, y) { return `M${x} ${y}`; } function lineTo(x, y) { return `L${x} ${y}`; } function join(strings2, delim = "") { return strings2.join(delim); } function quadCurve(x1, y1, x, y) { return `Q${x1} ${y1} ${x} ${y}`; } function gener