@dxos/react-ui-form 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/hooks/useAsyncFieldEffect.ts","../../src/hooks/useFormContext.ts","../../src/util/field.ts","../../src/util/omit.ts","../../src/util/properties.ts","../../src/util/refs.ts","../../src/hooks/useFormHandler.ts","../../src/hooks/useKeyHandler.tsx","../../src/hooks/useSubmitOnEnter.ts","../../src/components/layout/resolve-layout-field.ts","../../src/components/field-binding.tsx","../../src/components/FormFieldContext.ts","../../src/components/fields/numeric-constraints.ts","../../src/components/fields/default-value.ts","../../src/components/fields/ArrayField.tsx","../../src/components/presentation.tsx","../../src/components/fields/SelectField.tsx","../../src/components/fields/AsyncSelectField.tsx","../../src/components/fields/TextField.tsx","../../src/components/fields/AutofillField.tsx","../../src/components/fields/BooleanField.tsx","../../src/components/fields/ComboboxField.tsx","../../src/components/fields/createSelectField.tsx","../../src/components/fields/date-value.ts","../../src/components/fields/DateField.tsx","../../src/components/fields/GeoPointField.tsx","../../src/components/fields/HueField.tsx","../../src/components/FormFieldSet.tsx","../../src/components/FormRoot.tsx","../../src/components/fields/InlineRefField.tsx","../../src/components/fields/MarkdownField.tsx","../../src/components/fields/NumberField.tsx","../../src/components/fields/PasswordField.tsx","../../src/components/ObjectPicker.tsx","../../src/components/fields/find-ref-option.ts","../../src/components/meta-tags.ts","../../src/components/fields/ref-options.ts","../../src/components/fields/RefArrayField.tsx","../../src/components/fields/RefField.tsx","../../src/components/fields/SelectOptionField.tsx","../../src/components/fields/TextAreaField.tsx","../../src/components/layout/parser.ts","../../src/components/FormLayout.tsx","../../src/components/property-walk.ts","../../src/components/resolve-field.ts","../../src/components/FormFieldDispatch.tsx","../../src/components/FormField.tsx","../../src/components/Form.tsx","../../src/components/ObjectForm.tsx","../../src/components/ref-editor-extension.ts","../../src/components/useRefEditor.ts","../../src/components/RefEditor.tsx","../../src/components/FieldEditor.tsx","../../src/components/ViewEditor.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Cause from 'effect/Cause';\nimport * as Effect from 'effect/Effect';\nimport * as Exit from 'effect/Exit';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\n\n/** Picks the declared dependency fields from the form values — the subset a dynamic field subscribes to. */\nexport const pickValues = (values: AnyProperties | undefined, deps: readonly string[]): Record<string, unknown> => {\n const subset: Record<string, unknown> = {};\n for (const dep of deps) {\n subset[dep] = values?.[dep];\n }\n return subset;\n};\n\nexport type AsyncFieldEffectState<A> = {\n loading: boolean;\n error: unknown;\n data: A | undefined;\n};\n\nexport type UseAsyncFieldEffectOptions = {\n /** Debounce applied before running, so per-keystroke value changes coalesce into one run. */\n debounceMs?: number;\n /** When false, the effect is not run and prior data/error is cleared. */\n enabled?: boolean;\n};\n\n/**\n * Runs a self-contained Effect (`R = never`) whenever `key` changes, debounced and abortable. Used by\n * dynamic form fields to load select options, derive values, or validate against an external source from\n * the current form values. The latest `factory` is always used, but a run is only (re)triggered when\n * `key` changes — derive `key` from the inputs the factory actually reads. Re-running interrupts the\n * prior run (cancelling any in-flight request).\n */\nexport const useAsyncFieldEffect = <A>(\n factory: () => Effect.Effect<A, unknown>,\n key: string,\n { debounceMs = 400, enabled = true }: UseAsyncFieldEffectOptions = {},\n): AsyncFieldEffectState<A> => {\n const factoryRef = useRef(factory);\n factoryRef.current = factory;\n const [state, setState] = useState<AsyncFieldEffectState<A>>({ loading: false, error: undefined, data: undefined });\n\n useEffect(() => {\n if (!enabled) {\n setState({ loading: false, error: undefined, data: undefined });\n return;\n }\n\n let cancel: (() => void) | undefined;\n const timer = setTimeout(() => {\n setState((prev) => ({ ...prev, loading: true, error: undefined }));\n cancel = Effect.runCallback(factoryRef.current(), {\n onExit: (exit: Exit.Exit<A, unknown>) => {\n Exit.match(exit, {\n onSuccess: (data) => setState({ loading: false, error: undefined, data }),\n onFailure: (cause) => {\n // A superseding run interrupts this one; ignore the resulting interruption.\n if (!Cause.hasInterruptsOnly(cause)) {\n setState((prev) => ({ loading: false, error: Cause.squash(cause), data: prev.data }));\n }\n },\n });\n },\n });\n }, debounceMs);\n\n return () => {\n clearTimeout(timer);\n cancel?.();\n };\n }, [key, enabled, debounceMs]);\n\n return state;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { useEffect, useMemo, useRef } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { createContext } from '@dxos/react-hooks';\n\nimport { type FieldContext, type FormFieldStateProps } from '#types';\n\nimport { type FormHandler } from './useFormHandler.ts';\n\n/** Visual variants of a form: `settings` is the two-column settings-panel layout. */\nexport type FormVariant = 'default' | 'settings';\n\n//\n// Context\n//\n\nexport type FormContextValue<T extends AnyProperties = any> = {\n /**\n * Form handler.\n */\n form: FormHandler<T>;\n\n /**\n * Testing.\n */\n testId?: string;\n\n /** Visual variant applied across the form's parts (see Form.theme). */\n variant?: FormVariant;\n\n /** Editor extensions for the form's markdown fields, beyond their own (what a host's plugins contribute). */\n markdownExtensions?: Extension[];\n} & FieldContext;\n\nexport const [FormContextProvider, useFormContext] = createContext<FormContextValue>('Form');\n\n/**\n * Get the current form values.\n */\nexport const useFormValues: {\n <T extends AnyProperties>(componentName: string, path?: (string | number)[]): T;\n <T extends AnyProperties>(\n componentName: string,\n path: (string | number)[] | undefined,\n defaultValue: () => T,\n ): T | undefined;\n} = (componentName: string, path?: (string | number)[], defaultValue?: () => any) => {\n const stablePath = useMemo(() => path ?? [], [path ? path.join('.') : undefined]);\n const jsonPath = SchemaEx.createJsonPath(stablePath);\n const {\n form: { values, onValueChange },\n } = useFormContext(componentName);\n\n const value = SchemaEx.getValue(values, jsonPath);\n\n // Apply default value once when the field has no value. lastAppliedPathRef prevents\n // re-applying on every render (e.g. when defaultValue() returns null) and ensures\n // we apply per path when the hook is used for different fields.\n const lastAppliedPathRef = useRef<string | null>(null);\n useEffect(() => {\n if (value == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {\n lastAppliedPathRef.current = jsonPath;\n onValueChange(stablePath, SchemaAST.stringKeyword, defaultValue());\n }\n }, [value, defaultValue, onValueChange, stablePath, jsonPath]);\n\n return value;\n};\n\n/**\n * Get the state props for the given field.\n */\nexport const useFormFieldState = (componentName: string, path: (string | number)[] = []): FormFieldStateProps => {\n const stablePath = useMemo(() => path, [Array.isArray(path) ? path.join('.') : path]);\n const {\n form: { getStatus, getValue, onBlur, onValueChange },\n } = useFormContext(componentName);\n\n return useMemo(\n () => ({\n getStatus: () => getStatus(stablePath),\n getValue: () => getValue(stablePath),\n onBlur: () => onBlur(stablePath),\n onValueChange: (ast: SchemaAST.AST, value: any) => onValueChange(stablePath, ast, value),\n }),\n [getStatus, getValue, onBlur, onValueChange, stablePath],\n );\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { Format, GeoLocation, TypeEnum } from '@dxos/echo/Format';\nimport { type ValidationError } from '@dxos/schema';\n\n/**\n * Parse value by field value type.\n * Used by Table, Sheet, etc.\n * Handles various data types including booleans, numbers, dates, and strings.\n * Returns undefined for empty or null inputs.\n */\nexport type ParseProps = {\n type?: TypeEnum;\n format?: Format.TypeFormat;\n value: any;\n};\n\nexport const parseValue = ({ type, format, value }: ParseProps) => {\n if (value === undefined || value === null || value === '') {\n return undefined;\n }\n\n const parseScalar = (type?: TypeEnum) => {\n switch (type) {\n case TypeEnum.Boolean: {\n if (typeof value === 'string') {\n const lowercaseValue = value.toLowerCase();\n if (lowercaseValue === '0' || lowercaseValue === 'false') {\n return false;\n } else if (lowercaseValue === '1' || lowercaseValue === 'true') {\n return true;\n }\n }\n return Boolean(value);\n }\n\n case TypeEnum.Number: {\n const cleaned = typeof value === 'string' ? value.replace(/[^0-9.-]+/g, '') : value;\n const num = Number(cleaned);\n return Number.isNaN(num) ? null : num;\n }\n\n case TypeEnum.String:\n case TypeEnum.Ref:\n return String(value);\n\n default: {\n return value;\n }\n }\n };\n\n if (!format) {\n return parseScalar(type);\n }\n\n switch (format) {\n case Format.TypeFormat.Boolean:\n return parseScalar(TypeEnum.Boolean);\n\n case Format.TypeFormat.Number:\n case Format.TypeFormat.Percent:\n case Format.TypeFormat.Currency:\n return parseScalar(TypeEnum.Number);\n\n case Format.TypeFormat.String:\n case Format.TypeFormat.Markdown: {\n return parseScalar(TypeEnum.String);\n }\n\n case Format.TypeFormat.Ref:\n throw new Error(`unexpected format: ${Format.TypeFormat.Ref}`);\n\n case Format.TypeFormat.DateTime:\n case Format.TypeFormat.Date:\n case Format.TypeFormat.Time:\n case Format.TypeFormat.Timestamp: {\n const date = new Date(value as string | number);\n return isNaN(date.getTime()) ? null : date;\n }\n\n case Format.TypeFormat.GeoPoint: {\n // Parse string in format \"lat,long\" to GeoPoint [longitude, latitude].\n if (typeof value === 'string') {\n // Only keep digits, decimal points, minus signs, and commas.\n const cleaned = value.replace(/[^0-9.,-]+/g, '');\n const parts = cleaned.split(',');\n if (parts.length === 2) {\n const lat = parseFloat(parts[0]);\n const long = parseFloat(parts[1]);\n if (!isNaN(lat) && !isNaN(long)) {\n return GeoLocation.toGeoPoint({ latitude: lat, longitude: long });\n }\n }\n }\n\n return [0, 0];\n }\n\n default: {\n return value;\n }\n }\n};\n\n// TODO(burdon): Type and format.\nexport type CellClassesForFieldTypeProps = {\n type?: TypeEnum;\n format?: Format.TypeFormat;\n};\n\nexport const cellClassesForFieldType = ({ type, format }: CellClassesForFieldTypeProps): string[] | undefined => {\n switch (format || type) {\n case Format.TypeFormat.Markdown:\n return undefined;\n case Format.TypeFormat.Time:\n case Format.TypeFormat.Timestamp:\n case Format.TypeFormat.DateTime:\n case Format.TypeFormat.Date:\n case Format.TypeFormat.Duration:\n return ['font-mono', 'text-right'];\n case Format.TypeFormat.Currency:\n return ['text-right'];\n case Format.TypeFormat.JSON:\n case Format.TypeFormat.DID:\n return ['font-mono'];\n case TypeEnum.Number:\n case TypeEnum.Boolean:\n return ['text-right', 'font-mono'];\n case TypeEnum.String:\n return undefined;\n case TypeEnum.Ref:\n return undefined;\n default:\n return undefined;\n }\n};\n\n// TODO(ZaymonFC): How to do this with translations?\nexport const pathNotUniqueError = (path: string): ValidationError => ({\n path: 'path',\n message: `'${path}' is already present`,\n});\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, Type } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\n\n// TODO(burdon): Reconcile with @dxos/echo.\n// Distributive: applied per union member so `ExcludeId<A | B>` → `ExcludeId<A> | ExcludeId<B>` rather\n// than `Omit<InstanceType<A> | InstanceType<B>, 'id'>` (which would intersect away per-member narrowing).\nexport type ExcludeId<S extends Schema.Codec<any, any> | Type.AnyEntity> = S extends Type.AnyEntity\n ? Omit<Type.InstanceType<S>, 'id'>\n : S extends Schema.Codec<any, any>\n ? Omit<Schema.Schema.Type<S>, 'id'>\n : never;\n\n// TODO(burdon): Move to @dxos/schema (re-export here).\nexport const omitId = <S extends Schema.Codec<any, any> | Type.AnyEntity>(\n schemaOrType: S,\n): Schema.Codec<ExcludeId<S>, ExcludeId<S>> => {\n const schema: Schema.Top = Type.isType(schemaOrType) ? Type.getSchema(schemaOrType) : schemaOrType;\n // Cast: dropping a key cannot statically express the `ExcludeId<S>` result type, so the result is\n // a widened schema; the runtime shape matches the declared return type.\n return omitIdFromSchema(schema) as any;\n};\n\n/**\n * Removes the `id` field where present, preserving the schema's shape. Recurses into unions so a\n * discriminated (create) schema keeps its discriminant — `Schema.omit('id')` is a struct operation and\n * would otherwise flatten the union, breaking variant rendering. A no-op when there is no `id` (plain\n * create structs that never carried one).\n */\nconst omitIdFromSchema = (schema: Schema.Top): Schema.Top => {\n const ast = schema.ast;\n if (SchemaAST.isUnion(ast)) {\n return Schema.Union(ast.types.map((type) => omitIdFromSchema(Schema.make(type))));\n }\n const hasId = SchemaAST.getPropertySignatures(ast).some((prop) => prop.name === 'id');\n // `SchemaAST.omit`, not `mapFields(Struct.omit)`: the latter needs the key literals at the type\n // level, which a schema known only as a `Top` cannot supply.\n return hasId ? Schema.make<Schema.Top>(SchemaAST.omit(ast, ['id'])) : schema;\n};\n\n/**\n * Drop fields annotated with `FormInputAnnotation.set(false)` from a schema so\n * the form's validator doesn't trip on required-but-hidden fields. Used by\n * the picker's inline create form, where a `FactoryAnnotation` typically\n * supplies the hidden values (e.g. a backing-object Ref) outside the form.\n */\nexport const omitHiddenFormFields = <S extends Schema.Codec<any, any>>(schema: S): S => {\n const properties = SchemaAST.getPropertySignatures(schema.ast);\n const hidden = properties\n .filter((prop) => Option.getOrElse(Annotation.FormInputAnnotation.getFromAst(prop.type), () => true) === false)\n .map((prop) => prop.name as string);\n // Cast: omitting a dynamically-computed set of keys can't be expressed as the original `S`, but\n // the result is structurally a subset of `S` and callers treat it as `S`.\n return hidden.length === 0 ? schema : (Schema.make<Schema.Top>(SchemaAST.omit(schema.ast, hidden)) as any);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\n\nimport { Annotation } from '@dxos/echo';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\n/** The property's type with an optional `T | undefined` union unwrapped to its inner `T`. */\nconst unwrapOptional = (prop: SchemaAST.PropertySignature): SchemaAST.AST => {\n if (!SchemaAST.isOptional(prop.type) || !SchemaAST.isUnion(prop.type)) {\n return prop.type;\n }\n // Drop the `undefined` member, preserving the remaining union (don't collapse `A | B | undefined` to `A`).\n const defined = prop.type.types.filter((type) => type._tag !== 'Undefined');\n if (defined.length === 0) {\n return prop.type;\n }\n return defined.length === 1\n ? defined[0]\n : new SchemaAST.Union(defined, prop.type.options, prop.type.annotations, prop.type.checks);\n};\n\n/**\n * Discriminator values that open a root discriminated union on its first member.\n *\n * A union root with no discriminator value renders as a lone select and nothing else — no member's\n * fields, and no way to submit — so the form seeds the first member rather than presenting a dead\n * form. Member order is therefore the declaration order of `Schema.Union`: put the common case first.\n */\nexport const getDiscriminatorDefaults = (ast: SchemaAST.AST | undefined): Record<string, unknown> => {\n if (!ast || !SchemaEx.isDiscriminatedUnion(ast) || !SchemaAST.isUnion(ast)) {\n return {};\n }\n\n const discriminators = new Set(SchemaEx.getDiscriminatingProps(ast) ?? []);\n const [first] = ast.types;\n if (!first || discriminators.size === 0) {\n return {};\n }\n\n return Object.fromEntries(\n SchemaAST.getPropertySignatures(first)\n .filter((prop) => discriminators.has(prop.name.toString()) && SchemaAST.isLiteral(prop.type))\n .map((prop) => [prop.name.toString(), (prop.type as SchemaAST.Literal).literal]),\n );\n};\n\n/**\n * Resolve the properties to render for a field set's *root* schema, given the current form values.\n *\n * A top-level discriminated union is rendered flat: the fields of the member selected by the current\n * discriminator value, with the discriminator field keeping the union-wide set of literals so it stays\n * switchable. (`SchemaAST.getPropertySignatures` on a union returns only the common discriminator, so a\n * union root would otherwise render just that one field.) Non-union roots are unchanged. Nested unions are\n * unaffected — those are expanded per-field by `FormFieldDispatch`, which passes a single-member type literal here.\n */\nexport const getRootFormProperties = (\n ast: SchemaAST.AST,\n values: AnyProperties | undefined,\n): SchemaEx.SchemaProperty[] => {\n if (!SchemaEx.isDiscriminatedUnion(ast)) {\n return getFormProperties(ast);\n }\n\n const activeType = SchemaEx.getDiscriminatedType(ast, values ?? {});\n if (!activeType) {\n return getFormProperties(ast);\n }\n const activeProps = getFormProperties(activeType);\n\n const discriminators = new Set((SchemaEx.getDiscriminatingProps(ast) ?? []).map((name) => name.toString()));\n if (discriminators.size === 0) {\n return activeProps;\n }\n // The matched member types its discriminator as a single literal; swap in the union-wide literal so the\n // field renders as a full select rather than a fixed value.\n const fullType = SchemaEx.getDiscriminatedType(ast, {});\n const fullDiscriminatorProps = fullType ? getFormProperties(fullType) : activeProps;\n return activeProps.map((prop) =>\n discriminators.has(prop.name.toString())\n ? (fullDiscriminatorProps.find((candidate) => candidate.name === prop.name) ?? prop)\n : prop,\n );\n};\n\n/**\n * Get the property types of an AST and filter out properties that are not form inputs.\n *\n * The `FormInputAnnotation` is read from the raw property signature's AST (before\n * `encodedBoundAST` is applied by `SchemaEx.getProperties`), because `encodedBoundAST` strips\n * annotations from non-keyword inner types (e.g., `Schema.Struct`, `Schema.Array`).\n * Without this, fields like `Routine.input` (a JsonSchema struct) annotated\n * `FormInputAnnotation.set(false)` would still render in the form.\n *\n * For optional fields, `prop.type` is the union `T | undefined` — the annotation\n * lives on the inner `T`. Unwrap before reading so that the conventional pattern\n * `Schema.String.pipe(FormInputAnnotation.set(false), Schema.optional)` works.\n *\n * Container properties (nested structs, unions, arrays) keep their *raw* AST rather than\n * the `encodedBoundAST` produced by `SchemaEx.getProperties`. `encodedBoundAST` strips annotations\n * from non-keyword inner types, so a `FormInputAnnotation` nested beneath an encoded container\n * (e.g. `RouteLeg.geometry`, reached via `Segment → details → routes → Route → legs`) would\n * otherwise be lost by the time recursion reaches it. Leaf/transformation fields stay encoded\n * (e.g. a `DateTime` still renders as its encoded string input).\n */\nexport const getFormProperties = (ast: SchemaAST.AST): SchemaEx.SchemaProperty[] => {\n const signatures = SchemaAST.getPropertySignatures(ast);\n const rawByName = new Map<PropertyKey, SchemaAST.AST>(signatures.map((prop) => [prop.name, unwrapOptional(prop)]));\n const hidden = new Set(\n signatures\n .filter(\n (prop) =>\n Annotation.FormInputAnnotation.getFromAst(unwrapOptional(prop)).pipe(Option.getOrElse(() => true)) === false,\n )\n .map((prop) => prop.name),\n );\n return SchemaEx.getProperties(ast)\n .filter((prop) => !hidden.has(prop.name))\n .map((prop) => {\n const raw = rawByName.get(prop.name);\n return raw && (SchemaEx.isNestedType(raw) || SchemaEx.isArrayType(raw)) ? { ...prop, type: raw } : prop;\n });\n};\n\n/**\n * The object type at a path of the schema, for walking a nested object's properties: each segment\n * is a property name (an array index selects the element type), and a discriminated union is\n * resolved by the value at that path. `undefined` when the path leads to no object.\n */\nexport const getSchemaAtPath = (\n ast: SchemaAST.AST,\n path: (string | number)[],\n values: AnyProperties | undefined,\n): SchemaAST.AST | undefined => {\n let node: SchemaAST.AST = ast;\n for (const segment of path) {\n if (typeof segment === 'number') {\n const element = SchemaEx.getArrayElementType(node);\n if (!element) {\n return undefined;\n }\n node = element;\n continue;\n }\n const literal = SchemaEx.findNode(node, SchemaAST.isObjects);\n if (!literal) {\n return undefined;\n }\n const prop = SchemaAST.getPropertySignatures(literal).find((candidate) => String(candidate.name) === segment);\n if (!prop) {\n return undefined;\n }\n node = unwrapOptional(prop);\n }\n const union = SchemaEx.findNode(node, SchemaEx.isDiscriminatedUnion);\n return union\n ? SchemaEx.getDiscriminatedType(union, SchemaEx.getValue(values ?? {}, SchemaEx.createJsonPath(path)) ?? {})\n : SchemaEx.findNode(node, SchemaAST.isObjects);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { Ref } from '@dxos/echo';\nimport * as Annotation from '@dxos/echo/Annotation';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\ntype RefProps = {\n ast: SchemaAST.AST;\n isArray: boolean;\n typename?: string;\n};\n\nexport const getRefProps = (ast: SchemaAST.AST): RefProps | undefined => {\n // Array of references.\n if (SchemaEx.isArrayType(ast)) {\n const elementType = SchemaEx.getArrayElementType(ast);\n if (elementType) {\n if (Ref.isRefType(elementType)) {\n const typename = SchemaEx.findAnnotation<Annotation.ReferenceAnnotationValue>(\n elementType,\n Annotation.ReferenceAnnotationId,\n )?.typename;\n return { ast: elementType, isArray: true, typename };\n }\n }\n }\n\n // Direct reference.\n if (Ref.isRefType(ast)) {\n const typename = SchemaEx.findAnnotation<Annotation.ReferenceAnnotationValue>(\n ast,\n Annotation.ReferenceAnnotationId,\n )?.typename;\n return { ast, isArray: false, typename };\n }\n\n return undefined;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Equal from 'effect/Equal';\nimport type * as Schema from 'effect/Schema';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Ref } from '@dxos/echo';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { log } from '@dxos/log';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport { type ValidationError, validateSchema } from '@dxos/schema';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { type FormFieldOverride, type FormFieldStatus } from '#types';\n\nimport { getDiscriminatorDefaults } from '../util/index.ts';\n\n/**\n * Form properties.\n */\nexport interface FormHandlerProps<T extends AnyProperties> {\n /**\n * Effect schema (Type literal).\n */\n schema?: Schema.Codec<T, any>;\n\n /**\n * Source values. Fields the user is not editing reflect this value; in-progress edits (including intermediate\n * invalid values) are held locally and never snap back until they are committed and the source catches up. Persist\n * committed values from `onValuesChanged`/`onSave`. The form re-renders when a new value is passed, so to reflect\n * external/remote mutations pass a reactive source (e.g. a `useObject` snapshot that changes on mutation) rather\n * than a raw live object — a render-time read of an ECHO object does not itself subscribe to it.\n */\n values?: Partial<T>;\n\n /**\n * Seeds an uncontrolled form once at mount when `values` is not provided; not reconciled thereafter.\n */\n defaultValues?: Partial<T>;\n\n /** Per-field overrides by json-path (`style.hue`); see {@link FormFieldOverride}. */\n fieldOverrides?: Readonly<Record<string, FormFieldOverride>>;\n\n /**\n * Auto-save the form when the values change.\n */\n autoSave?: boolean;\n\n /**\n * Callback for value changes. Note: This is called even when values are invalid.\n * Sometimes the parent component may want to know about changes even if the form is\n * in an invalid state.\n */\n onValuesChanged?: (values: Partial<T>, meta: FormUpdateMeta<T>) => void;\n\n /**\n * Custom validation function that runs only after schema validation passes.\n * Use this for complex validation logic that can't be expressed in the schema.\n * @returns Array of validation errors, or undefined if validation passes\n */\n onValidate?: (values: T) => ValidationError[] | undefined;\n\n /**\n * Called when the form is submitted and passes validation.\n */\n onSave?: (values: T, meta: FormUpdateMeta<T>) => MaybePromise<void>;\n\n /**\n * Called when the form is canceled.\n */\n onCancel?: () => void;\n}\n\nexport type FormUpdateMeta<T extends AnyProperties> = {\n changed: FormHandler<T>['changed'];\n isValid: boolean;\n};\n\n/**\n * Form handler properties and methods.\n */\nexport type FormHandler<T extends AnyProperties> = Pick<FormHandlerProps<T>, 'schema' | 'autoSave'> & {\n /** Initial values (which may not pass validation). */\n values: Partial<T>;\n\n /** Fields whose value has been edited (set by `onValueChange`). Gates autosave-on-blur. */\n changed: Record<SchemaEx.JsonPath, boolean>;\n /** Fields the user has interacted with (set by `onBlur`). Gates error *visibility* — errors only surface once touched. */\n touched: Record<SchemaEx.JsonPath, boolean>;\n\n /** Map of error strings. */\n errors: Record<SchemaEx.JsonPath, string>;\n\n /** Whether the values pass validation (no errors at all). */\n isValid: boolean;\n /**\n * Whether the submit affordance should be enabled. Stricter than `isValid`: it also requires no save\n * in flight (`saving`) and only blocks on errors for *touched* fields, so a pristine form with\n * not-yet-touched required fields can still show an enabled control.\n */\n canSave: boolean;\n\n onSave: () => void;\n onCancel: () => void;\n\n //\n // Form field state management\n //\n\n getStatus: (path: string | (string | number)[]) => FormFieldStatus;\n /** The caller's override for the field at `path`, if any. */\n getOverride: (path: (string | number)[]) => FormFieldOverride | undefined;\n getValue: <V>(path: (string | number)[]) => V | undefined;\n onBlur: (path: (string | number)[]) => void;\n onValueChange: <V>(path: (string | number)[], type: SchemaAST.AST, value: V) => void;\n};\n\n/**\n * Creates a hook for managing form state, including values, validation, and submission.\n * Deeply integrated with `@dxos/schema` for schema-based validation.\n */\nexport const useFormHandler = <T extends AnyProperties>({\n schema,\n autoSave,\n fieldOverrides,\n values: valuesProp,\n defaultValues: defaultValuesProp,\n onValuesChanged,\n onValidate,\n onSave,\n onCancel,\n ...props\n}: FormHandlerProps<T>): FormHandler<T> => {\n const [changed, setChanged] = useState<Record<SchemaEx.JsonPath, boolean>>({});\n const [touched, setTouched] = useState<Record<SchemaEx.JsonPath, boolean>>({});\n const [errors, setErrors] = useState<Record<SchemaEx.JsonPath, string>>({});\n const [saving, setSaving] = useState(false);\n const seed = Hooks.useDefaultValue<Partial<T>>(defaultValuesProp, () => ({}));\n // A root discriminated union renders nothing but its select until the discriminator has a value, so\n // the form opens on the first member unless the caller seeded one of its own.\n const defaultValues = useMemo(\n () => ({ ...getDiscriminatorDefaults(schema?.ast), ...seed }) as Partial<T>,\n [schema, seed],\n );\n\n // The source the form reads from for every field the user is not actively editing. The form is a pure function of\n // this value and re-renders when the parent passes a new one; to reflect external/remote mutations the parent must\n // supply a reactive source (e.g. a `useObject` snapshot that changes on mutation). `defaultValues` seeds an\n // uncontrolled form once when no `values` are provided.\n const source = valuesProp ?? defaultValues;\n\n // Sparse local edits keyed by json-path. A path stays here — holding even an intermediate invalid value, so it\n // never snaps back — until the source catches up to it (typically once a valid edit has been persisted and echoed\n // back through `values`). Un-edited paths are never buffered, so they always reflect the current source.\n const [overrides, setOverrides] = useState<Record<SchemaEx.JsonPath, unknown>>({});\n\n // Merged view (source overlaid with local edits) for whole-form consumers: validation, save, and context/debug.\n // Computed each render (not memoized) so it stays fresh when the source value changes.\n const values = applyOverrides(source, overrides);\n\n // Validate.\n const validate = useCallback(\n (values: Partial<T>): values is T => {\n if (!schema) {\n return false;\n }\n\n let errors: ValidationError[] = validateSchema(schema, values) ?? [];\n log('validate', { values, errors });\n if (errors.length === 0 && onValidate) {\n const validatedValues = values as T;\n errors = onValidate(validatedValues) ?? [];\n }\n\n setErrors(flatMap(errors));\n const valid = errors.length === 0;\n return valid;\n },\n [schema, onValidate],\n );\n\n // Validate on schema change.\n const [schemaChanged, setSchemaChanged] = useState(false);\n useEffect(() => setSchemaChanged(true), [schema]);\n useEffect(() => {\n if (schemaChanged) {\n validate(values);\n setSchemaChanged(false);\n }\n }, [validate, values, schemaChanged]);\n\n // Drop an override once the source has caught up to it (the committed value has been echoed back), so the field\n // returns to reflecting the source. Edits the source has not yet reflected — including intermediate invalid values,\n // and in-progress edits to a field that changed remotely — are kept, so the form never snaps back. Runs on every\n // render (a new source value re-renders the form), reconciling against whatever the source currently holds.\n useEffect(() => {\n const reconciled = (Object.keys(overrides) as SchemaEx.JsonPath[]).filter((path) =>\n valuesEqual(SchemaEx.getValue(source, path), overrides[path]),\n );\n if (reconciled.length === 0) {\n return;\n }\n setOverrides((prev) => omitPaths(prev, reconciled));\n setChanged((prev) => omitPaths(prev, reconciled));\n setTouched((prev) => omitPaths(prev, reconciled));\n });\n\n const isValid = useMemo(() => {\n return Object.keys(errors).length === 0;\n }, [errors]);\n\n /**\n * NOTE: We can submit if there is no touched field that has an error.\n * If there's a validation message visible in the form, submit should be disabled.\n */\n const canSave = useMemo(\n () =>\n !saving &&\n // Check if any error paths that are touched have errors.\n !Object.entries(touched).some(\n ([path, isTouched]) =>\n isTouched &&\n Object.keys(errors).some(\n (errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`),\n ),\n ),\n [touched, errors, saving],\n );\n\n const handleSave = useCallback(async () => {\n if (validate(values)) {\n setSaving(true);\n try {\n await onSave?.(values, { changed, isValid });\n } finally {\n setSaving(false);\n }\n }\n }, [values, validate, onSave, changed, isValid]);\n\n const handleCancel = useCallback(() => {\n onCancel?.();\n }, [onCancel]);\n\n //\n // Fields.\n //\n\n const getStatus = useCallback<FormHandler<T>['getStatus']>(\n (path) => {\n const jsonPath = Array.isArray(path) ? SchemaEx.createJsonPath(path) : path;\n const [_, error] =\n Object.entries(errors).find(\n ([errorPath]) =>\n errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`),\n ) ?? [];\n\n const indeterminate = isIndeterminate(fieldOverrides, overrides, jsonPath);\n\n // Only show errors for touched fields.\n const isTouched = touched[jsonPath as SchemaEx.JsonPath];\n if (!isTouched) {\n return {\n status: undefined,\n error: undefined,\n indeterminate,\n };\n }\n\n return {\n status: error ? 'error' : undefined,\n error: error ? (error ?? undefined) : undefined,\n indeterminate,\n };\n },\n [errors, touched, fieldOverrides, overrides],\n );\n\n const getOverride = useCallback<FormHandler<T>['getOverride']>(\n (path) => fieldOverrides?.[SchemaEx.createJsonPath(path)],\n [fieldOverrides],\n );\n\n const getValue = useCallback<FormHandler<T>['getValue']>(\n (path) => {\n const jsonPath = SchemaEx.createJsonPath(path);\n if (Object.prototype.hasOwnProperty.call(overrides, jsonPath)) {\n return overrides[jsonPath] as any;\n }\n // An indeterminate value has none to show until it is edited.\n if (fieldOverrides?.[jsonPath]?.indeterminate) {\n return undefined;\n }\n // Un-edited fields reflect the current source value.\n return SchemaEx.getValue(source, jsonPath);\n },\n [source, overrides, fieldOverrides],\n );\n\n const onValueChange = useCallback<FormHandler<T>['onValueChange']>(\n (path, type, value) => {\n log('onValueChange', { path, value });\n\n const jsonPath = SchemaEx.createJsonPath(path);\n const pathArray = path;\n let parsedValue = value as any;\n try {\n if (type._tag === 'Number') {\n parsedValue = parseFloat(value as string) || 0;\n }\n } catch (err) {\n log.catch(err);\n parsedValue = undefined;\n }\n\n // Hold the edit locally as an override (including invalid values, so it never snaps back); un-edited paths keep\n // tracking the live source. The prune effect drops the override once the source catches up.\n const newOverrides = { ...overrides, [jsonPath]: parsedValue };\n setOverrides(newOverrides);\n\n // TODO(burdon): Check value has changed from original.\n const newChanged = { [jsonPath]: true };\n setChanged((prev) => ({ ...prev, ...newChanged }));\n\n // Merged values for validation and the callback. Form never mutates the source; the parent persists.\n const newValues = applyOverrides(source, newOverrides);\n\n // Validate.\n const isValid = validate(newValues);\n\n // Notify parent; parent is responsible for persisting the change (typically once valid).\n onValuesChanged?.(newValues, { isValid, changed: newChanged });\n },\n [source, overrides, validate, onValuesChanged],\n );\n\n // A blur commits the field. The validation and auto-save run in an effect, after the render that carries the\n // change, so a control that changes and blurs in one handler (a switch, a select, a picker) commits the value it\n // just set rather than the one rendered before it.\n const [committing, setCommitting] = useState(false);\n const onBlur = useCallback((path: (string | number)[]) => {\n const jsonPath = SchemaEx.createJsonPath(path);\n\n // TODO(burdon): Check value has changed from original.\n setTouched((touched) => ({ ...touched, [jsonPath]: true }));\n setCommitting(true);\n }, []);\n useEffect(() => {\n if (!committing) {\n return;\n }\n setCommitting(false);\n const isValid = validate(values);\n if (Object.keys(changed).length > 0 && isValid && autoSave) {\n void onSave?.(values as T, { changed, isValid });\n }\n }, [committing, validate, values, changed, autoSave, onSave]);\n\n return useMemo<FormHandler<T>>(\n () => ({\n // State.\n schema,\n values,\n errors,\n touched,\n changed,\n isValid,\n canSave,\n autoSave,\n\n // Actions.\n onSave: handleSave,\n onCancel: handleCancel,\n\n // Field utils.\n getStatus,\n getOverride,\n getValue,\n onBlur,\n onValueChange,\n\n ...props,\n }),\n [\n schema,\n autoSave,\n values,\n errors,\n touched,\n changed,\n canSave,\n isValid,\n getStatus,\n getOverride,\n getValue,\n onBlur,\n onValueChange,\n handleSave,\n handleCancel,\n ],\n );\n};\n\n/**\n * Creates a new object with value at path. Does not mutate source.\n * Preserves arrays when path segments are numeric indices.\n */\nconst mergeAtPath = (obj: any, path: readonly (string | number)[], value: any): any => {\n if (path.length === 0) {\n return value;\n }\n\n const [head, ...rest] = path;\n const child = rest.length === 0 ? value : mergeAtPath(obj?.[head], rest, value);\n\n if (Array.isArray(obj)) {\n const copy = [...obj];\n copy[head as number] = child;\n return copy;\n }\n\n return { ...obj, [head]: child };\n};\n\n/** Overlays sparse json-path edits onto a base value without mutating it; un-edited paths keep the base reference. */\nconst applyOverrides = <T>(base: Partial<T>, overrides: Record<SchemaEx.JsonPath, unknown>): Partial<T> => {\n let result: Partial<T> = base;\n for (const path of Object.keys(overrides) as SchemaEx.JsonPath[]) {\n result = mergeAtPath(result, SchemaEx.splitJsonPath(path), overrides[path]) as Partial<T>;\n }\n return result;\n};\n\n// Copied from `@dxos/echo` (internal `Obj.valuesEqual`): references compare by target URI, arrays and plain\n// object-shaped property bags (excluding `id`) compare recursively, and leaves fall back to Effect `Equal.equals`,\n// which is structural by default in Effect 4. Effect's `Schema.toEquivalence` is not a safe substitute — it returns false-positive\n// equality for dynamic/union/ref-array schemas, which would silently prune edits.\n// TODO(wittjosiah): Factor out into a shared util rather than duplicating echo's internal implementation.\nconst valuesEqual = (left: unknown, right: unknown): boolean => {\n if (left === right) {\n return true;\n }\n if (left === null || right === null) {\n return left === right;\n }\n if (typeof left !== 'object' || typeof right !== 'object') {\n return Equal.equals(left, right);\n }\n if (Ref.isRef(left) && Ref.isRef(right)) {\n return left.uri === right.uri;\n }\n if (Ref.isRef(left) || Ref.isRef(right)) {\n return false;\n }\n if (Array.isArray(left) && Array.isArray(right)) {\n if (left.length !== right.length) {\n return false;\n }\n return left.every((value, index) => valuesEqual(value, right[index]));\n }\n if (Array.isArray(left) || Array.isArray(right)) {\n return false;\n }\n const leftRecord = left as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n const keys = new Set([\n ...Object.keys(leftRecord).filter((key) => key !== 'id'),\n ...Object.keys(rightRecord).filter((key) => key !== 'id'),\n ]);\n for (const key of keys) {\n if (!valuesEqual(leftRecord[key], rightRecord[key])) {\n return false;\n }\n }\n return true;\n};\n\n/** Whether a path is indeterminate and still unedited: an edit is the user's own value, so it shows. */\nconst isIndeterminate = (\n fieldOverrides: FormHandlerProps<any>['fieldOverrides'],\n overrides: Record<SchemaEx.JsonPath, unknown>,\n jsonPath: string,\n): boolean => !!fieldOverrides?.[jsonPath]?.indeterminate && !Object.prototype.hasOwnProperty.call(overrides, jsonPath);\n\n/** Returns a copy of `record` without the given json-path keys. */\nconst omitPaths = <V>(\n record: Record<SchemaEx.JsonPath, V>,\n paths: SchemaEx.JsonPath[],\n): Record<SchemaEx.JsonPath, V> => {\n const omit = new Set<string>(paths);\n return Object.fromEntries(Object.entries(record).filter(([key]) => !omit.has(key))) as Record<SchemaEx.JsonPath, V>;\n};\n\nconst flatMap = (errors: ValidationError[]) => {\n return errors.reduce(\n (result, { path, message }) => {\n // Convert the validation error path format to our SchemaEx.JsonPath format.\n const jsonPath = SchemaEx.fromEffectValidationPath(path);\n if (!(jsonPath in result)) {\n result[jsonPath] = message;\n }\n return result;\n },\n {} as Record<SchemaEx.JsonPath, string>,\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type RefObject, useCallback, useLayoutEffect } from 'react';\n\nimport { addEventListener } from '@dxos/async';\n\nimport { type FormHandler } from './useFormHandler.ts';\n\n/**\n * Cmd+Enter on macOS, Ctrl+Enter elsewhere; both are accepted everywhere, as GitHub's forms do.\n * Not while an IME is composing, where the chord confirms the text being composed.\n */\nconst isSubmitChord = (event: KeyboardEvent) =>\n event.key === 'Enter' && (event.metaKey || event.ctrlKey) && !event.shiftKey && !event.altKey && !event.isComposing;\n\nexport type KeyHandlerOptions = {\n /** A readonly form has nothing to submit, so the chord passes through to whatever holds focus. */\n readonly?: boolean;\n};\n\n/**\n * Submits the form on Cmd/Ctrl+Enter from any field, including multi-line ones.\n */\nexport const useKeyHandler = (\n elRef: RefObject<HTMLDivElement | null>,\n form: FormHandler<any>,\n { readonly }: KeyHandlerOptions = {},\n) => {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n // An auto-saving form has no submit for the chord to mean.\n if (!isSubmitChord(event) || readonly || form.autoSave) {\n return;\n }\n\n // Capture runs outermost first, so a nested form's chord must be left to that form.\n const owner = event.target instanceof Element ? event.target.closest('[role=\"form\"]') : null;\n if (owner !== event.currentTarget) {\n return;\n }\n\n // Consumed even when nothing is saved, so a field's own binding (CodeMirror's Mod-Enter inserts\n // a blank line) never runs in its place.\n event.preventDefault();\n event.stopPropagation();\n\n // `isValid` as well as `canSave`: a required field the reader never touched carries no visible\n // error, so `canSave` alone would submit an empty form.\n if (form.canSave && form.isValid) {\n form.onSave();\n }\n },\n [readonly, form.autoSave, form.isValid, form.canSave, form.onSave],\n );\n\n useLayoutEffect(() => {\n const el = elRef.current;\n if (!el) {\n return;\n }\n\n // Capture phase, so the form sees the chord before the focused field's own key handling.\n return addEventListener(el, 'keydown', handleKeyDown, { capture: true });\n }, [elRef, handleKeyDown]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type RefObject, useEffect, useRef } from 'react';\n\nimport { addEventListener } from '@dxos/async';\n\n/** Input types whose Enter carries no meaning of its own, as in a native `<form>`'s implicit submission. */\nconst SINGLE_LINE_INPUT_TYPES = new Set(['', 'text', 'search', 'email', 'url', 'tel', 'password', 'number']);\n\nconst isSingleLineInput = (target: EventTarget | null): target is HTMLInputElement =>\n target instanceof HTMLInputElement &&\n SINGLE_LINE_INPUT_TYPES.has(target.type) &&\n // An autocompleting input (combobox, ref picker) spends Enter on choosing an option.\n !target.hasAttribute('aria-autocomplete') &&\n target.getAttribute('role') !== 'combobox';\n\nexport type SubmitOnEnterOptions = {\n disabled?: boolean;\n};\n\n/**\n * Calls `onSubmit` on a plain Enter in a single-line input inside `elRef`, the implicit submission a\n * native `<form>` gives; multi-line fields (textarea, markdown editors) and modified Enter keep their own meaning.\n */\nexport const useSubmitOnEnter = (\n elRef: RefObject<HTMLElement | null>,\n onSubmit: () => void,\n { disabled }: SubmitOnEnterOptions = {},\n) => {\n const onSubmitRef = useRef(onSubmit);\n onSubmitRef.current = onSubmit;\n\n useEffect(() => {\n const el = elRef.current;\n if (!el || disabled) {\n return;\n }\n\n // On the document, in the bubble phase, so a field that handles Enter itself (and says so with\n // `preventDefault`) has already run; content portaled out of `el` (popovers) is never a target.\n return addEventListener(el.ownerDocument, 'keydown', (event: KeyboardEvent) => {\n if (\n event.key !== 'Enter' ||\n event.defaultPrevented ||\n event.isComposing ||\n // Safari ends an IME composition with an Enter whose `isComposing` is false but `keyCode` is 229.\n event.keyCode === 229 ||\n event.shiftKey ||\n event.altKey ||\n event.metaKey ||\n event.ctrlKey ||\n !isSingleLineInput(event.target) ||\n !el.contains(event.target)\n ) {\n return;\n }\n\n event.preventDefault();\n onSubmitRef.current();\n });\n }, [elRef, disabled]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\n// Kept out of `FormLayout.tsx`: react-refresh only fast-refreshes a module whose\n// exports are all components, so values exported beside them force a full page reload on every edit.\n\nexport type ResolvedLayoutField = {\n /** Resolved leaf AST node for the field. */\n type: SchemaAST.AST;\n /** Path segments (dotted names split on `.`). */\n segments: string[];\n /** Last path segment; used to derive the field label when there is no `title` annotation. */\n leafName: string;\n /** Resolved `title` annotation for the field, if any. */\n title?: string;\n /**\n * Set when the field resolves to a nested struct carrying a `LabelAnnotation` —\n * the type literal whose computed label should render in place of the struct's\n * sub-fields. Undefined for ordinary (non-auto-labelled) fields.\n */\n labelType?: SchemaAST.AST;\n /** Whether the resolved property is required (non-optional). */\n required: boolean;\n};\n\n/**\n * Walks a dotted path of property names through nested struct ASTs, returning the\n * leaf `PropertySignature` (or `undefined` if any segment is missing).\n */\nconst resolvePropertySignature = (ast: SchemaAST.AST, segments: string[]): SchemaAST.PropertySignature | undefined => {\n let node: SchemaAST.AST = ast;\n for (let index = 0; index < segments.length; index++) {\n const typeLiteral = SchemaEx.findNode(node, SchemaAST.isObjects);\n if (!typeLiteral) {\n return undefined;\n }\n const prop = SchemaAST.getPropertySignatures(typeLiteral).find(\n (p) => globalThis.String(p.name) === segments[index],\n );\n if (!prop) {\n return undefined;\n }\n if (index === segments.length - 1) {\n return prop;\n }\n node = prop.type;\n }\n\n return undefined;\n};\n\n/**\n * Resolves a (possibly dotted) layout field name against a schema.\n * - `origin.code` drills through nested structs to the leaf field.\n * - A name resolving to a nested struct with a `LabelAnnotation` is flagged via\n * `labelType` so the layout can auto-convert it to a single read-only label.\n * Returns `undefined` when the name does not resolve to a property.\n */\nexport const resolveLayoutField = (schema: Schema.Schema<any>, name: string): ResolvedLayoutField | undefined => {\n const segments = name.split('.');\n const prop = resolvePropertySignature(schema.ast, segments);\n if (!prop) {\n return undefined;\n }\n\n // Normalized leaf type (optional unwrapped, refinements stripped, signature-level\n // annotations merged) — matches how `getProperties` feeds `FormFieldDispatch`.\n const { type: baseType } = SchemaEx.getBaseType(prop.type);\n // Key annotations (v3's `PropertySignature.annotations`) hang off the type's context in v4.\n const keyAnnotations = prop.type.context?.annotations;\n const type =\n keyAnnotations && Reflect.ownKeys(keyAnnotations).length > 0\n ? SchemaAST.annotate(baseType, keyAnnotations)\n : baseType;\n\n const title = SchemaEx.getAnnotation<string>(SchemaAST.TitleAnnotationId)(type);\n\n // Label detection reads the *raw* property type: `SchemaEx.getBaseType`'s `encodedBoundAST`\n // strips annotations from non-keyword inner types (e.g. nested structs), which would\n // drop the `LabelAnnotation` we rely on here.\n const labelType = SchemaEx.findNode(prop.type, SchemaAST.isObjects);\n const labelled = labelType != null && Option.isSome(Annotation.LabelAnnotation.getFromAst(labelType));\n\n return {\n type,\n segments,\n leafName: segments[segments.length - 1],\n title,\n labelType: labelled ? labelType : undefined,\n required: !SchemaAST.isOptional(prop.type),\n };\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { format as formatDate } from 'date-fns';\nimport * as Option from 'effect/Option';\nimport * as Str from 'effect/String';\nimport React, { Component, type PropsWithChildren, useMemo } from 'react';\n\nimport { Format } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport * as Banner from '@dxos/react-ui/Banner';\n\nimport { type FormPresentation } from '#types';\n\nimport { useFormContext, useFormFieldState } from '../hooks/index.ts';\nimport { type FormFieldBinding } from './FormFieldContext.ts';\nimport { resolveLayoutField } from './layout/resolve-layout-field.ts';\n\n/**\n * Formats a value for `static` (read-only, plain-DOM) presentation based on its\n * type `format`. Dates/times are rendered human-readable; everything else falls\n * back to `String(value)`.\n */\nexport const formatStaticValue = (value: unknown, format?: Format.TypeFormat): string => {\n if (value == null) {\n return '';\n }\n\n switch (format) {\n case Format.TypeFormat.DateTime:\n case Format.TypeFormat.Date:\n case Format.TypeFormat.Time: {\n const date = new Date(value as string);\n if (Number.isNaN(date.getTime())) {\n return String(value);\n }\n const pattern = format === Format.TypeFormat.DateTime ? 'PPp' : format === Format.TypeFormat.Date ? 'PP' : 'p';\n return formatDate(date, pattern);\n }\n default:\n return String(value);\n }\n};\n\n/** The schema property at a path of the form's schema: its type, and what the row derives from it. */\nexport const useFormSchemaProperty = (componentName: string, path: string) => {\n const { form } = useFormContext(componentName);\n return useMemo(() => {\n if (!form.schema) {\n return undefined;\n }\n const resolved = resolveLayoutField(form.schema, path);\n if (!resolved) {\n return undefined;\n }\n const description = SchemaEx.getAnnotation<string>(SchemaAST.DescriptionAnnotationId)(resolved.type);\n const format = Format.FormatAnnotation.getFromAst(resolved.type).pipe(Option.getOrUndefined);\n return {\n type: resolved.type,\n label: resolved.title ?? Str.capitalize(resolved.leafName),\n description,\n format,\n required: resolved.required,\n };\n }, [form.schema, path]);\n};\n\ntype SchemaProperty = ReturnType<typeof useFormSchemaProperty>;\n\n/** The binding for a row at a path, from the form handler. */\nexport const useFormFieldBindingAt = <T,>(\n componentName: string,\n path: string,\n property: SchemaProperty,\n { required, readonly, presentation }: { required?: boolean; readonly?: boolean; presentation?: FormPresentation },\n): FormFieldBinding<T> => {\n const { readonly: formReadonly, layout } = useFormContext(componentName);\n const segments = useMemo(() => (SchemaEx.isJsonPath(path) ? SchemaEx.splitJsonPath(path) : []), [path]);\n const { getStatus, getValue, onBlur, onValueChange } = useFormFieldState(componentName, segments);\n const { status, error, indeterminate } = getStatus();\n const value = getValue() as T | undefined;\n const type = property?.type ?? SchemaAST.unknownKeyword;\n return useMemo(\n () => ({\n path,\n type,\n value,\n setValue: (next: T | undefined) => onValueChange(type, next),\n onBlur,\n status,\n error,\n indeterminate,\n required: required ?? property?.required,\n readonly: readonly ?? formReadonly,\n presentation: presentation ?? layout,\n }),\n [\n path,\n type,\n value,\n onValueChange,\n onBlur,\n status,\n error,\n indeterminate,\n required,\n property?.required,\n readonly,\n formReadonly,\n presentation,\n layout,\n ],\n );\n};\n\n/** Whether a value counts as unfilled for the required marker. `false` and `0` are values. */\nexport const isEmptyValue = (value: unknown): boolean =>\n value == null || value === '' || (Array.isArray(value) && value.length === 0);\n\n//\n// FormFieldErrorBoundary\n//\n\ntype FormFieldErrorState = {\n error: Error | undefined;\n};\n\ntype FormFieldErrorBoundaryProps = PropsWithChildren<{\n path?: (string | number)[];\n}>;\n\nexport class FormFieldErrorBoundary extends Component<FormFieldErrorBoundaryProps, FormFieldErrorState> {\n static getDerivedStateFromError(error: Error): { error: Error } {\n return { error };\n }\n\n override state = { error: undefined };\n\n override componentDidUpdate(prevProps: FormFieldErrorBoundaryProps) {\n if (prevProps.path !== this.props.path) {\n this.resetError();\n }\n }\n\n override render() {\n if (this.state.error) {\n return (\n <Banner.Root valence='error'>\n <Banner.Body>{`ERROR ${String(this.props.path?.join('.'))}`}</Banner.Body>\n </Banner.Root>\n );\n }\n\n return this.props.children;\n }\n\n private resetError() {\n this.setState({ error: undefined });\n }\n}\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type FocusEvent } from 'react';\n\nimport type * as SchemaAST from '@dxos/effect/SchemaAST';\nimport { createContext } from '@dxos/react-hooks';\n\nimport { type FormFieldStatus, type FormPresentation } from '#types';\n\n// Kept out of `FormField.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a context and its hook exported beside them force a full page reload on every edit.\n\n/** What a bound row provides to the control inside it. */\nexport type FormFieldBinding<T = any> = {\n /** Dotted from the form's root. */\n path: string;\n type: SchemaAST.AST;\n value: T | undefined;\n setValue: (value: T | undefined) => void;\n onBlur: (event?: FocusEvent<HTMLElement>) => void;\n status: FormFieldStatus['status'];\n error?: string;\n /** The field shows no value until it is edited (see `FormFieldOverride.indeterminate`). */\n indeterminate?: boolean;\n required?: boolean;\n readonly?: boolean;\n presentation?: FormPresentation;\n};\n\nexport const [FormFieldBindingProvider, useFormFieldBinding] = createContext<FormFieldBinding>('Form.Field');\n\n/**\n * The binding of the enclosing `Form.Field path`, for a control written by hand inside a bound row:\n * the value to show, `setValue` to commit an edit, `onBlur` to mark it touched, and the row's status.\n */\nexport const useFormField = <T = any>(): FormFieldBinding<T> => useFormFieldBinding('useFormField');\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\n\n// Kept out of `NumberField.tsx`: react-refresh only fast-refreshes a module whose\n// exports are all components, so values exported beside them force a full page reload on every edit.\n\n/** The `representation` annotation a v4 check carries, naming the filter and its payload. */\ntype CheckRepresentation = { readonly id?: string; readonly payload?: Record<string, unknown> | null };\n\nconst representationOf = (check: SchemaAST.Check<any>): CheckRepresentation | undefined =>\n (check.annotations as { representation?: CheckRepresentation } | undefined)?.representation;\n\nconst numberAt = (payload: CheckRepresentation['payload'], key: string): number | undefined => {\n const value = payload?.[key];\n return typeof value === 'number' ? value : undefined;\n};\n\n/**\n * Extracts numeric constraints (`minimum`/`maximum` bounds and whether the value must be an integer)\n * from the checks attached to the node (e.g. produced by `Schema.isBetween` / `Schema.isInt`).\n * Returns empty constraints when none are declared.\n *\n * Effect 4 has no `Refinement` node: refinements are checks on the node itself, each carrying a\n * `representation` annotation naming the filter and its payload.\n */\nexport const getNumericConstraints = (ast: SchemaAST.AST): { min?: number; max?: number; integer: boolean } => {\n let min: number | undefined;\n let max: number | undefined;\n let integer = false;\n\n // Stacked checks intersect: keep the strictest bound (largest min, smallest max).\n const tighten = (lower?: number, upper?: number) => {\n if (lower !== undefined) {\n min = min === undefined ? lower : Math.max(min, lower);\n }\n if (upper !== undefined) {\n max = max === undefined ? upper : Math.min(max, upper);\n }\n };\n\n for (const check of SchemaAST.getChecks(ast)) {\n const representation = representationOf(check);\n switch (representation?.id) {\n case 'effect/schema/isBetween':\n tighten(numberAt(representation.payload, 'minimum'), numberAt(representation.payload, 'maximum'));\n break;\n case 'effect/schema/isGreaterThanOrEqualTo':\n tighten(numberAt(representation.payload, 'minimum'), undefined);\n break;\n case 'effect/schema/isLessThanOrEqualTo':\n tighten(undefined, numberAt(representation.payload, 'maximum'));\n break;\n case 'effect/schema/isInt':\n integer = true;\n break;\n case 'effect/schema/isMultipleOf':\n integer ||= numberAt(representation.payload, 'divisor') === 1;\n break;\n }\n }\n\n return { min, max, integer };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\nimport { getNumericConstraints } from './numeric-constraints.ts';\n\n// Kept out of `ArrayField.tsx`: react-refresh only fast-refreshes a module whose\n// exports are all components, so values exported beside them force a full page reload on every edit.\n\n/**\n * Returns the default empty value for a given AST.\n * Used for initializing new array values etc.\n */\n// TODO(wittjosiah): Factor out?\nexport const getDefaultValue = (ast?: SchemaAST.AST): any => {\n switch (ast?._tag) {\n case 'String': {\n return '';\n }\n case 'Number': {\n // v4 has no `Refinement` node: a refined number IS a `Number` node carrying checks, so the\n // declared minimum (e.g. `Schema.isBetween(1, 31)`) is read from them and used as the default\n // so new array items start within the valid range.\n return getNumericConstraints(ast).min ?? 0;\n }\n case 'Boolean': {\n return false;\n }\n case 'Suspend': {\n return getDefaultValue(ast.thunk());\n }\n default: {\n if (ast && SchemaEx.isNestedType(ast)) {\n return {};\n } else {\n throw new Error(`Unsupported type: ${ast?._tag}`);\n }\n }\n }\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport React, { useCallback, useRef } from 'react';\n\nimport { Annotation, Ref } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { log } from '@dxos/log';\nimport { OrderedList } from '@dxos/react-ui-list';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { arrayMove } from '@dxos/util';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldStateProps } from '#types';\n\nimport { useFormValues } from '../../hooks/index.ts';\nimport { getFormProperties } from '../../util/index.ts';\nimport { FormFieldDispatch } from '../FormFieldDispatch.tsx';\nimport { type FormFieldDispatchProps } from '../resolve-field.ts';\nimport { getDefaultValue } from './default-value.ts';\n\ntype Item = { id: string; index: number };\n\nexport type ArrayFieldProps = {\n label: string;\n fieldProps: FormFieldStateProps;\n} & FormFieldDispatchProps;\n\n/**\n * An array as a header row (label and an add Button) over a `react-ui-list` OrderedList whose rows hold the item's\n * control and a remove Button; a `FormOrderedAnnotation` array adds a DragHandle (pointer drag and keyboard moves).\n */\nexport const ArrayField = ({ type, path, label, readonly, layout, fieldProps, ...props }: ArrayFieldProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const elementType = SchemaEx.getArrayElementType(type);\n const { onValueChange } = fieldProps;\n const values = useFormValues<unknown[]>('Form.ArrayField', path, () => []);\n const ordered = Annotation.FormOrderedAnnotation.getFromAst(type).pipe(Option.getOrElse(() => false));\n const editable = !readonly && layout !== 'static';\n\n // Rows need identities that survive a reorder; values have none, so the field keeps a parallel id list.\n const idsRef = useRef<string[]>([]);\n const counterRef = useRef(0);\n const ids = idsRef.current;\n const count = values?.length ?? 0;\n while (ids.length < count) {\n ids.push(`item-${counterRef.current++}`);\n }\n ids.length = count;\n const items: Item[] = ids.map((id, index) => ({ id, index }));\n\n const handleAdd = useCallback(() => {\n let value: unknown;\n try {\n value =\n elementType && SchemaEx.isNestedType(elementType) ? defaultObject(elementType) : getDefaultValue(elementType);\n } catch (err) {\n log.catch(err);\n return;\n }\n onValueChange(type, [...(values ?? []), value]);\n }, [elementType, onValueChange, type, values]);\n\n const handleRemove = useCallback(\n (index: number) => {\n idsRef.current.splice(index, 1);\n onValueChange(\n type,\n (values ?? []).filter((_, candidate) => candidate !== index),\n );\n },\n [onValueChange, type, values],\n );\n\n const handleMove = useCallback(\n (from: number, to: number) => {\n const next = [...(values ?? [])];\n arrayMove(next, from, to);\n arrayMove(idsRef.current, from, to);\n onValueChange(type, next);\n },\n [onValueChange, type, values],\n );\n\n if (!elementType || (!editable && count === 0)) {\n return null;\n }\n\n const asObject = SchemaEx.isNestedType(elementType) && !Ref.isRefType(elementType);\n const columns = [ordered && editable && 'var(--dx-block-size)', 'minmax(0, 1fr)', editable && 'var(--dx-block-size)']\n .filter(Boolean)\n .join(' ');\n\n return (\n <>\n <Field.Header>\n <Typography.Text truncate>{label}</Typography.Text>\n {editable && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--plus--regular'\n label={t('add-item.button')}\n onClick={handleAdd}\n data-testid={`${SchemaEx.createJsonPath(path ?? [])}.add`}\n />\n )}\n </Field.Header>\n <OrderedList.Root\n items={items}\n getId={(item) => item.id}\n getLabel={(item) => `${label} ${item.index + 1}`}\n columns={columns}\n onMove={handleMove}\n readonly={!editable}\n >\n {({ items }) => (\n <OrderedList.Content scroll={false} gutter='inherit' gap='sm' aria-label={label}>\n {items.map((item) => (\n <OrderedList.Item key={item.id} id={item.id} canDrag={ordered && editable}>\n {ordered && editable && <OrderedList.DragHandle />}\n {/* A cell holding a nested group must be a template root, so the group's subgrid finds `content`. */}\n <Layout.Container gutter='none'>\n <FormFieldDispatch\n {...props}\n type={elementType}\n name={null}\n label={asObject ? undefined : label}\n path={[...(path ?? []), item.index]}\n readonly={!editable}\n layout={asObject ? layout : 'inline'}\n />\n </Layout.Container>\n {editable && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--x--regular'\n label={t('remove-item.button')}\n onClick={() => handleRemove(item.index)}\n />\n )}\n </OrderedList.Item>\n ))}\n </OrderedList.Content>\n )}\n </OrderedList.Root>\n </>\n );\n};\n\nconst defaultObject = (typeNode: SchemaAST.AST): Record<string, unknown> => {\n const baseNode = SchemaEx.findNode(typeNode, SchemaEx.isDiscriminatedUnion);\n const typeLiteral = baseNode\n ? SchemaEx.getDiscriminatedType(baseNode, {})\n : SchemaEx.findNode(typeNode, SchemaAST.isObjects);\n return typeLiteral\n ? Object.fromEntries(\n getFormProperties(typeLiteral).map((prop) => [prop.name, SchemaAST.getDefaultAnnotation(prop.type)]),\n )\n : {};\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type FormPresentation } from '#types';\n\n/**\n * Resolved presentation strategy for a field — which parts render, derived from {@link FormPresentation}.\n * Visual chrome (borders, grid, spacing) is owned by the Form theme recipe, not here.\n */\nexport type FormFieldPresentation = {\n layout?: FormPresentation;\n /** Render the value as read-only plain DOM rather than an editable control. */\n isStatic: boolean;\n /** Render the field's label row. */\n showLabel: boolean;\n /** Render the inline validation/error block beneath the control. */\n showError: boolean;\n};\n\n/**\n * Derive the {@link FormFieldPresentation} for a layout.\n * - `static` renders read-only plain DOM.\n * - `inline` drops the label (the control stands alone, e.g. an array row).\n * - `full` adds the inline error block.\n */\nexport const presentationFor = (layout?: FormPresentation): FormFieldPresentation => ({\n layout,\n isStatic: layout === 'static',\n showLabel: layout !== 'inline',\n showError: layout === 'full',\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Select from '@dxos/react-ui/Select';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { presentationFor } from '../presentation.tsx';\n\nexport type SelectFieldOption = { value: string | number; label?: string; icon?: string };\n\nexport type SelectFieldProps = FormFieldRendererProps & {\n options?: SelectFieldOption[];\n};\n\n/**\n * `Select` over literal options. Next options are strings (AUDIT 2.14), so the field keeps the map back to each\n * literal; the popup inherits the row's size (Phase 4 decision 2).\n */\nexport const SelectField = ({\n type,\n readonly,\n placeholder,\n options = [],\n presentation,\n getValue,\n onValueChange,\n onBlur,\n}: SelectFieldProps) => {\n const items = useMemo<Select.Option[]>(\n () => options.map(({ value, label, icon }) => ({ value: String(value), label: label ?? String(value), icon })),\n [options],\n );\n const { t } = Hooks.useTranslation(translationKey);\n const value = getValue();\n if (presentationFor(presentation).isStatic) {\n return (\n <Typography.Text truncate>\n {options.find((option) => option.value === value)?.label ?? String(value ?? '')}\n </Typography.Text>\n );\n }\n\n return (\n <SelectControl\n items={items}\n value={value == null ? undefined : String(value)}\n placeholder={placeholder ?? t('select.placeholder')}\n readonly={readonly}\n onValueChange={(next) => {\n // A choice is a commit: the select never blurs, so it commits itself.\n onValueChange(type, options.find((option) => String(option.value) === next)?.value);\n onBlur();\n }}\n />\n );\n};\n\ntype SelectControlProps = {\n items: Select.Option[];\n value?: string;\n placeholder?: string;\n readonly?: boolean;\n /** Options are still loading: the trigger shows a spinner and is `aria-busy`. */\n loading?: boolean;\n onValueChange: (value: string | undefined) => void;\n};\n\n/** The Select a field row holds: Ark reads the enclosing `Field.Root` for the label and state ids. */\nexport const SelectControl = ({ items, value, placeholder, readonly, loading, onValueChange }: SelectControlProps) => (\n <Select.Root\n items={items}\n value={value === undefined ? [] : [value]}\n disabled={!!readonly}\n onValueChange={({ value: [next] }) => onValueChange(next)}\n >\n <Select.Trigger placeholder={placeholder} loading={loading} />\n <Select.Content>\n {items.map((item) => (\n <Select.Item key={item.value} item={item} />\n ))}\n </Select.Content>\n </Select.Root>\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useEffect, useMemo, useRef } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport type * as Select from '@dxos/react-ui/Select';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { type OptionsLookup, type OptionsLookupEntry } from '../../annotations.ts';\nimport { pickValues, useAsyncFieldEffect, useFormValues } from '../../hooks/index.ts';\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { SelectControl } from './SelectField.tsx';\n\nexport type AsyncSelectFieldProps = FormFieldRendererProps<string | undefined> & {\n /** Loads the options from the lookup's declared dependency fields. */\n lookup: OptionsLookup;\n};\n\n/**\n * A Select whose options load (debounced) from the fields the lookup declares in `deps`; the trigger shows a spinner\n * while they load, and the sole option is chosen when exactly one resolves and nothing is chosen yet.\n */\nexport const AsyncSelectField = ({\n lookup,\n type,\n format,\n readonly,\n placeholder,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n}: AsyncSelectFieldProps) => {\n const values = useFormValues<AnyProperties>('Form.AsyncSelectField');\n const subset = useMemo(() => pickValues(values, lookup.deps), [values, lookup.deps]);\n const key = useMemo(() => JSON.stringify(subset), [subset]);\n const { loading, data } = useAsyncFieldEffect<readonly OptionsLookupEntry[]>(() => lookup.load(subset), key);\n const items = useMemo<Select.Option[]>(\n () => (data ?? []).map(({ value, label, icon }) => ({ value, label: label ?? value, icon })),\n [data],\n );\n\n // Held in refs so the auto-select depends only on the resolved options, not on accessors that change every edit.\n const current = getValue();\n const onValueChangeRef = useRef(onValueChange);\n onValueChangeRef.current = onValueChange;\n const autoSelectedRef = useRef<typeof data>(undefined);\n useEffect(() => {\n if ((current == null || current === '') && data?.length === 1 && data !== autoSelectedRef.current) {\n autoSelectedRef.current = data;\n onValueChangeRef.current(type, data[0].value);\n }\n }, [current, data, type]);\n\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={items.find((item) => item.value === current)?.label ?? current} format={format} />;\n }\n\n return (\n <SelectControl\n items={items}\n value={current || undefined}\n placeholder={placeholder}\n readonly={readonly}\n loading={loading}\n onValueChange={(next) => {\n onValueChange(type, next);\n onBlur();\n }}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Format } from '@dxos/echo';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\nexport const TextField = ({\n type,\n format,\n readonly,\n placeholder,\n presentation,\n autoFocus,\n jsonPath,\n getValue,\n onBlur,\n onValueChange,\n}: FormFieldRendererProps<string>) => {\n const value = getValue() ?? '';\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value} format={format} />;\n }\n\n // An opaque identifier is not prose: no spellcheck squiggles, no autocorrect, no capitalisation.\n const key = format === Format.TypeFormat.Key;\n return (\n <Input.Root\n noAutoFill\n autoFocus={autoFocus}\n disabled={!!readonly}\n placeholder={placeholder}\n value={value}\n onBlur={onBlur}\n onChange={(event) => onValueChange(type, event.target.value)}\n // Enter commits the field as leaving it does, so an auto-saving form saves without the user tabbing away.\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.nativeEvent.isComposing) {\n onBlur();\n }\n }}\n data-testid={jsonPath}\n {...(key && { variant: 'mono', spellCheck: false, autoCorrect: 'off', autoCapitalize: 'none' })}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useEffect, useMemo, useRef } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { type Autofill } from '../../annotations.ts';\nimport { pickValues, useAsyncFieldEffect, useFormValues } from '../../hooks/index.ts';\nimport { TextField } from './TextField.tsx';\n\nexport type AutofillFieldProps = FormFieldRendererProps<string> & {\n /** Derives this field's value from the autofill's declared dependency fields (e.g. a sibling URL). */\n autofill: Autofill;\n};\n\n/**\n * A text field that pre-fills (debounced) from the fields its {@link Autofill} declares in `deps`, writing only while\n * the user has not typed their own value (empty, or still the last fill), so a manual edit is never clobbered.\n */\nexport const AutofillField = ({ autofill, ...fieldProps }: AutofillFieldProps) => {\n const values = useFormValues<AnyProperties>('Form.AutofillField');\n const subset = useMemo(() => pickValues(values, autofill.deps), [values, autofill.deps]);\n const key = useMemo(() => JSON.stringify(subset), [subset]);\n const { data } = useAsyncFieldEffect<string | undefined>(() => autofill.derive(subset), key);\n\n // Read through refs so the write depends only on the derived value; the accessors change on every edit and would\n // re-fire the effect after its own write.\n const { type } = fieldProps;\n const getValueRef = useRef(fieldProps.getValue);\n getValueRef.current = fieldProps.getValue;\n const onValueChangeRef = useRef(fieldProps.onValueChange);\n onValueChangeRef.current = fieldProps.onValueChange;\n const lastFilledRef = useRef<string | undefined>(undefined);\n useEffect(() => {\n const current = getValueRef.current();\n if (typeof data !== 'string' || data.length === 0) {\n // A derivation that stops returning a value clears a fill the user has not edited.\n if (lastFilledRef.current != null && current === lastFilledRef.current) {\n lastFilledRef.current = undefined;\n onValueChangeRef.current(type, '');\n }\n return;\n }\n if (current === data) {\n lastFilledRef.current = data;\n return;\n }\n if (current == null || current === '' || current === lastFilledRef.current) {\n lastFilledRef.current = data;\n onValueChangeRef.current(type, data);\n }\n }, [data, type]);\n\n return <TextField {...fieldProps} />;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { useFormContext } from '../../hooks/index.ts';\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\n/** A Switch that labels itself, except in a settings row, whose header column holds the label. */\nexport const BooleanField = ({\n type,\n format,\n label,\n readonly,\n presentation,\n indeterminate,\n getValue,\n onValueChange,\n onBlur,\n}: FormFieldRendererProps<boolean>) => {\n const { t } = Hooks.useTranslation(translationKey);\n const { variant } = useFormContext('Form.BooleanField');\n const value = getValue();\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value} format={format} />;\n }\n\n return (\n <Input.Switch\n // A switch has no third state: an indeterminate one is dimmed and says so, and the first press sets it.\n indeterminate={indeterminate}\n label={\n variant === 'settings' ? undefined : indeterminate ? `${label} (${t('indeterminate.placeholder')})` : label\n }\n disabled={!!readonly}\n checked={!!value}\n // A toggle is a commit: the switch never blurs, so it commits itself.\n onCheckedChange={({ checked }) => {\n onValueChange(type, checked);\n onBlur();\n }}\n />\n );\n};\n\nBooleanField.labelPlacement = 'beside' as const;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo, useState } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as Combobox from '@dxos/react-ui/Combobox';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { type OptionsLookup, type OptionsLookupEntry } from '../../annotations.ts';\nimport { pickValues, useAsyncFieldEffect, useFormValues } from '../../hooks/index.ts';\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\nexport type ComboboxFieldProps = FormFieldRendererProps<string | undefined> & {\n /** Loads suggestions from the lookup's declared dependency fields (typically the field's own value). */\n lookup: OptionsLookup;\n};\n\n// The lookup's suggestions are already narrowed by the query, so the Combobox keeps every item it is given.\nconst keepAll = () => true;\n\n/**\n * An editable `Combobox` (input mode) whose suggestions load (debounced) from an {@link OptionsLookup}; when the\n * field's own path is among the lookup's `deps`, the typed text drives the lookup. The typed text is offered last as a\n * free value unless a suggestion already is it; nothing is listed before typing unless the lookup is `eager`.\n */\nexport const ComboboxField = ({\n lookup,\n type,\n format,\n readonly,\n placeholder,\n presentation,\n jsonPath,\n getValue,\n onValueChange,\n onBlur,\n}: ComboboxFieldProps) => {\n const values = useFormValues<AnyProperties>('Form.ComboboxField');\n const [query, setQuery] = useState('');\n const lookupValues = useMemo(() => {\n const subset = pickValues(values, lookup.deps);\n if (jsonPath && lookup.deps.includes(jsonPath)) {\n subset[jsonPath] = query;\n }\n return subset;\n }, [values, lookup.deps, jsonPath, query]);\n const key = useMemo(() => JSON.stringify(lookupValues), [lookupValues]);\n const { data } = useAsyncFieldEffect<readonly OptionsLookupEntry[]>(() => lookup.load(lookupValues), key);\n\n const value = getValue() ?? '';\n const trimmed = query.trim();\n const items = useMemo<Combobox.Option[]>(() => {\n const loaded = (data ?? []).map((option) => ({ value: option.value, label: option.label ?? option.value }));\n const results =\n trimmed.length === 0\n ? lookup.eager\n ? loaded\n : []\n : loaded.filter((option) => option.label.toLowerCase().includes(trimmed.toLowerCase()));\n const free = trimmed.length > 0 && !results.some((option) => option.value === trimmed);\n // The current value stays an item, so the input can show its label before anything is typed.\n const current = value && !results.some((option) => option.value === value);\n return [\n ...(current ? [loaded.find((option) => option.value === value) ?? { value, label: value }] : []),\n ...results,\n ...(free ? [{ value: trimmed, label: trimmed }] : []),\n ];\n }, [data, trimmed, lookup.eager, value]);\n\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={items.find((item) => item.value === value)?.label ?? value} format={format} />;\n }\n\n return (\n <Combobox.Root\n items={items}\n filter={keepAll}\n disabled={!!readonly}\n value={value ? [value] : []}\n onInputValueChange={({ inputValue, reason }) => reason === 'input-change' && setQuery(inputValue)}\n onOpenChange={({ open }) => !open && setQuery('')}\n onValueChange={({ value: [next] }) => {\n onValueChange(type, next);\n onBlur();\n }}\n >\n <Combobox.Control>\n <Combobox.Input placeholder={placeholder} />\n <Combobox.Trigger />\n </Combobox.Control>\n <Combobox.Content />\n </Combobox.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { invariant } from '@dxos/invariant';\nimport type * as Select from '@dxos/react-ui/Select';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { type FormFieldRenderer, type FormFieldRendererProps } from '#types';\n\nimport { FormField } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { SelectControl } from './SelectField.tsx';\n\nexport type CreateSelectFieldOptions = {\n /** Options to display. Strings are used as both value and label. */\n options: ReadonlyArray<string | { value: string; label?: string }>;\n /** Label for the sentinel option that maps to `undefined`. Defaults to `'Default'`. Pass `null` to omit. */\n defaultLabel?: string | null;\n};\n\n// A value outside every option, since Ark reads an empty value as no selection.\nconst SENTINEL = '__default__';\n\n/** The current `createSelectField`, same signature, on `Select`; the renderer owns its row as before. */\nexport const createSelectField = ({\n options,\n defaultLabel = 'Default',\n}: CreateSelectFieldOptions): FormFieldRenderer => {\n const normalized = options.map((option) => (typeof option === 'string' ? { value: option, label: option } : option));\n invariant(\n !normalized.some((option) => option.value === SENTINEL),\n `createSelectField: option value '${SENTINEL}' is reserved.`,\n );\n const hasDefault = defaultLabel !== null;\n const items: Select.Option[] = [\n ...(hasDefault ? [{ value: SENTINEL, label: defaultLabel }] : []),\n ...normalized.map((option) => ({ value: option.value, label: option.label ?? option.value })),\n ];\n\n const SelectFieldRenderer = ({\n type,\n label,\n jsonPath,\n readonly,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n }: FormFieldRendererProps<string | undefined>) => {\n const value = getValue();\n return (\n <FormField path={jsonPath} label={label} readonly={readonly} presentation={presentation}>\n {presentationFor(presentation).isStatic ? (\n <Typography.Text truncate>\n {normalized.find((option) => option.value === value)?.label ?? String(value ?? '')}\n </Typography.Text>\n ) : (\n <SelectControl\n items={items}\n value={value ?? (hasDefault ? SENTINEL : undefined)}\n readonly={readonly}\n onValueChange={(next) => {\n onValueChange(type, hasDefault && next === SENTINEL ? undefined : next);\n onBlur();\n }}\n />\n )}\n </FormField>\n );\n };\n return SelectFieldRenderer;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { format as formatDate } from 'date-fns';\n\n/** ISO 8601 → `YYYY-MM-DDTHH:mm` in the user's local timezone. */\nexport const isoToLocalDateTime = (value: string | undefined): string => {\n if (!value) {\n return '';\n }\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n return formatDate(date, \"yyyy-MM-dd'T'HH:mm\");\n};\n\n/** `YYYY-MM-DDTHH:mm` (local) → ISO 8601 with timezone. */\nexport const localDateTimeToIso = (value: string): string | undefined => {\n if (!value) {\n return undefined;\n }\n // Treat the input as local time. `new Date('YYYY-MM-DDTHH:mm')` parses as local.\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : date.toISOString();\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Format } from '@dxos/echo';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { isoToLocalDateTime, localDateTimeToIso } from './date-value.ts';\n\n/**\n * Stored shapes: `Format.DateTime` is ISO 8601, `Format.Date` `YYYY-MM-DD`, `Format.Time` `HH:mm:ss`; DateInput takes\n * the native strings, so a date-time converts through local time and a time keeps its seconds.\n */\nexport const DateField = ({\n type,\n format,\n readonly,\n presentation,\n getValue,\n onValueChange,\n}: FormFieldRendererProps<string | undefined>) => {\n const value = getValue();\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value} format={format} />;\n }\n\n switch (format) {\n case Format.TypeFormat.Date:\n return (\n <Input.Date\n type='date'\n disabled={!!readonly}\n value={value ?? ''}\n onValueChange={(next) => onValueChange(type, next || undefined)}\n />\n );\n case Format.TypeFormat.Time:\n return (\n <Input.Date\n type='time'\n granularity='second'\n disabled={!!readonly}\n value={value ?? ''}\n onValueChange={(next) => onValueChange(type, next || undefined)}\n />\n );\n default:\n return (\n <Input.Date\n type='datetime-local'\n disabled={!!readonly}\n value={isoToLocalDateTime(value)}\n onValueChange={(next) => onValueChange(type, localDateTimeToIso(next))}\n />\n );\n }\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useEffect, useMemo, useState } from 'react';\n\nimport { GeoLocation, type GeoPoint } from '@dxos/echo/Format';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { safeParseFloat } from '@dxos/util';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { presentationFor } from '../presentation.tsx';\n\ntype Coordinate = keyof Pick<GeoLocation, 'latitude' | 'longitude'>;\n\n/** Two labelled coordinates in a row Container of two equal tracks, each its own `Field.Root`. */\nexport const GeoPointField = ({\n type,\n readonly,\n presentation,\n getValue,\n onValueChange,\n}: FormFieldRendererProps<GeoPoint>) => {\n const { t } = Hooks.useTranslation(translationKey);\n const geoPoint = getValue();\n const location = useMemo(() => GeoLocation.fromGeoPoint(geoPoint ?? [0, 0]), [geoPoint]);\n const [text, setText] = useState({\n latitude: location.latitude?.toString() ?? '',\n longitude: location.longitude?.toString() ?? '',\n });\n useEffect(() => {\n setText({ latitude: location.latitude?.toString() ?? '', longitude: location.longitude?.toString() ?? '' });\n }, [location]);\n\n const resolved = presentationFor(presentation);\n if (resolved.isStatic) {\n return !location.latitude && !location.longitude ? null : (\n <Typography.Text truncate>\n {Math.abs(location.latitude ?? 0).toFixed(5)}°{(location.latitude ?? 0) >= 0 ? 'N' : 'S'}{' '}\n {Math.abs(location.longitude ?? 0).toFixed(5)}°{(location.longitude ?? 0) >= 0 ? 'E' : 'W'}\n </Typography.Text>\n );\n }\n\n const handleChange = (coordinate: Coordinate, input: string) => {\n setText((previous) => ({ ...previous, [coordinate]: input }));\n const parsed = safeParseFloat(input);\n if (input !== '-' && parsed !== undefined && !Number.isNaN(parsed)) {\n onValueChange(type, GeoLocation.toGeoPoint({ ...location, [coordinate]: parsed }));\n }\n };\n\n const coordinate = (name: Coordinate, bound: number) => (\n <Field.Root>\n {resolved.showLabel && (\n <Field.Header>\n <Field.Label>{t(`${name}.label`)}</Field.Label>\n </Field.Header>\n )}\n <Input.Root\n type='number'\n step='0.00001'\n min={-bound}\n max={bound}\n disabled={!!readonly}\n placeholder={t(`${name}.placeholder`)}\n value={text[name]}\n onChange={(event) => handleChange(name, event.target.value)}\n />\n </Field.Root>\n );\n\n return (\n <Layout.Container layout='row' gutter='inherit' columns='minmax(0, 1fr) minmax(0, 1fr)' gap='sm'>\n {coordinate('latitude', 90)}\n {coordinate('longitude', 180)}\n </Layout.Container>\n );\n};\n\nGeoPointField.standalone = true;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport type * as Select from '@dxos/react-ui/Select';\nimport { hues } from '@dxos/ui-types';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { SelectControl } from './SelectField.tsx';\n\nconst capitalize = (hue: string) => hue.charAt(0).toUpperCase() + hue.slice(1);\n\n/** Every theme hue as a Select option: a filled swatch in the hue, named by the hue. */\nexport const HUE_OPTIONS: Select.Option[] = hues.map((hue) => ({\n value: hue,\n label: capitalize(hue),\n icon: 'ph--circle--fill',\n iconHue: hue,\n}));\n\nexport type HueSelectProps = {\n value?: string;\n placeholder?: string;\n readonly?: boolean;\n onValueChange: (hue: string | undefined) => void;\n};\n\n/** A Select over the theme hues; the current `HuePicker` (react-ui-pickers) has no Next counterpart yet. */\nexport const HueSelect = ({ value, placeholder, readonly, onValueChange }: HueSelectProps) => (\n <SelectControl\n items={HUE_OPTIONS}\n value={value}\n placeholder={placeholder}\n readonly={readonly}\n onValueChange={onValueChange}\n />\n);\n\n/** A field whose value is one of the theme's hues. */\nexport const HueField = ({\n type,\n format,\n placeholder,\n readonly,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n}: FormFieldRendererProps<string | undefined>) => {\n const value = getValue();\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value && capitalize(value)} format={format} />;\n }\n\n return (\n <HueSelect\n value={value}\n placeholder={placeholder}\n readonly={readonly}\n onValueChange={(hue) => {\n // A pick is a commit: the select never blurs, so it commits itself.\n onValueChange(type, hue);\n onBlur();\n }}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { Children, type PropsWithChildren, type ReactNode, useState } from 'react';\n\nimport * as Collapsible from '@dxos/react-ui/Collapsible';\nimport * as Fieldset from '@dxos/react-ui/Fieldset';\nimport * as SystemButton from '@dxos/react-ui/SystemButton';\n\nimport { useFormContext } from '../hooks/index.ts';\n\nconst FORM_FIELDSET_NAME = 'Form.FieldSet';\n\nexport type FormFieldSetProps = PropsWithChildren<{\n 'label'?: string;\n /** Plain text under the legend (the current FieldSet renders markdown; see SPIKE.md). */\n 'description'?: string;\n /** The legend ends with a disclosure button that folds the body. */\n 'collapsible'?: boolean;\n 'defaultOpen'?: boolean;\n /** Controls acting on the group, at the end of its legend row. */\n 'actions'?: ReactNode;\n /** A nested object's group: its fields bordered and indented under the legend. Set by the dispatcher, never read from context. */\n 'nested'?: boolean;\n 'data-testid'?: string;\n}>;\n\n/**\n * A grid `Fieldset` (`gutter='inherit'`): a `group` named by its legend that is a subgrid of the enclosing grid, so\n * fields keep the form's columns at any depth. A nested object's fields are an `inset` set under its legend (bordered and\n * indented on its host's surface, never a surface step); a collapsible set ends its legend with a disclosure button and folds a Collapsible\n * Content that is itself a subgrid.\n */\nexport const FormFieldSet = ({\n children,\n label,\n description,\n collapsible,\n defaultOpen = true,\n actions,\n nested,\n 'data-testid': testId,\n}: FormFieldSetProps) => {\n const { layout } = useFormContext(FORM_FIELDSET_NAME);\n const [open, setOpen] = useState(defaultOpen);\n const showLabel = layout !== 'inline' && !!label;\n const canCollapse = !!collapsible && showLabel && Children.toArray(children).length > 0;\n const helper = description && <Fieldset.HelperText>{description}</Fieldset.HelperText>;\n const legend = showLabel && (\n <Fieldset.Legend size={nested ? undefined : 'md'} variant={nested ? undefined : 'section'}>\n {label}\n {actions}\n {canCollapse && (\n <SystemButton.Disclosure variant='ghost' label={label} expanded={open} onExpandedChange={setOpen} />\n )}\n </Fieldset.Legend>\n );\n\n // A nested object's legend (and its disclosure) heads the border rather than sitting inside it: only the fields are\n // bordered, so the label lines up with the host's other labels.\n const fields = nested ? (\n <Fieldset.Root gutter='inherit' inset>\n {children}\n </Fieldset.Root>\n ) : (\n children\n );\n\n if (canCollapse) {\n return (\n <Collapsible.Root asChild open={open} onOpenChange={({ open }) => setOpen(open)}>\n <Fieldset.Root gutter='inherit' data-testid={testId}>\n {legend}\n {helper}\n <Collapsible.Content gutter='inherit'>{fields}</Collapsible.Content>\n </Fieldset.Root>\n </Collapsible.Root>\n );\n }\n\n return (\n <Fieldset.Root gutter='inherit' data-testid={testId}>\n {legend}\n {helper}\n {fields}\n </Fieldset.Root>\n );\n};\n\nFormFieldSet.displayName = FORM_FIELDSET_NAME;\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { type PropsWithChildren } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport { type Merge } from '@dxos/util';\n\nimport {\n FormContextProvider,\n type FormContextValue,\n type FormHandlerProps,\n type FormUpdateMeta,\n useFormHandler,\n} from '../hooks/index.ts';\nimport { type FormFieldsProps } from './property-walk.ts';\n\n//\n// Root\n//\n\nexport type FormRootProps<T extends AnyProperties = AnyProperties> = Merge<\n Omit<FormContextValue<T>, 'form'>,\n Pick<\n FormHandlerProps<T>,\n 'schema' | 'autoSave' | 'fieldOverrides' | 'values' | 'defaultValues' | 'onValidate' | 'onValuesChanged'\n >,\n Omit<FormFieldsProps<T>, 'path' | 'schema'>,\n PropsWithChildren<{\n /**\n * Called when the form is submitted and passes validation.\n */\n onSave?: (values: T, meta: FormUpdateMeta<T>) => void;\n\n /**\n * Called when the form is canceled to abandon/undo any pending changes.\n */\n onCancel?: () => void;\n }>\n>;\n\nexport const FormRoot = <T extends AnyProperties = AnyProperties>({\n children,\n schema,\n values,\n onSave,\n onCancel,\n ...props\n}: FormRootProps<T>) => {\n const form = useFormHandler({ schema, values, onSave, onCancel, ...props });\n\n return (\n <FormContextProvider form={form} {...props}>\n {children}\n </FormContextProvider>\n );\n};\n\nFormRoot.displayName = 'Form.Root';\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport React, { useCallback, useMemo } from 'react';\n\nimport { type Database, Obj, Ref, Type } from '@dxos/echo';\nimport { useType as defaultUseType } from '@dxos/echo-react';\nimport * as Annotation from '@dxos/echo/Annotation';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { DXN, type URI } from '@dxos/keys';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps, type RefFieldDataProps } from '#types';\n\nimport { omitId } from '../../util/index.ts';\nimport { FormFields } from '../FormFieldDispatch.tsx';\nimport { FormFieldSet } from '../FormFieldSet.tsx';\nimport { FormRoot } from '../FormRoot.tsx';\n\ntype UseType = (db?: Database.Database, typeUri?: URI.URI) => Type.AnyEntity | undefined;\n\nexport type InlineRefFieldProps = FormFieldRendererProps &\n Pick<RefFieldDataProps, 'onCreate'> & {\n useType?: UseType;\n };\n\n/**\n * A referenced object's own fields inline (`FormInlineAnnotation`), as a nested group bound to the target: each\n * changed path is written back to it with `Obj.setValue` in one `Obj.update`. An empty ref offers to create the target.\n */\nexport const InlineRefField = ({\n type,\n readonly,\n label,\n db,\n getValue,\n onValueChange,\n onCreate,\n useType = defaultUseType,\n}: InlineRefFieldProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const reference = getValue();\n const typename = useMemo(\n () =>\n SchemaEx.findAnnotation<Annotation.ReferenceAnnotationValue>(type, Annotation.ReferenceAnnotationId)?.typename,\n [type],\n );\n const createType = useType(db, typename ? DXN.make(typename) : undefined);\n const handleCreate = useCallback(async () => {\n if (!createType || !onCreate) {\n return;\n }\n const created = await onCreate(createType, {});\n if (created) {\n onValueChange(type, Ref.make(created));\n }\n }, [createType, onCreate, onValueChange, type]);\n\n if (readonly && !Ref.isRef(reference)) {\n return null;\n }\n\n return (\n <FormFieldSet label={label} collapsible nested>\n {Ref.isRef(reference) ? (\n <InlineForm reference={reference} db={db} readonly={readonly} useType={useType} />\n ) : (\n !readonly &&\n onCreate && (\n <Button.Group fill>\n <Button.Root\n icon='ph--plus--regular'\n label={label || t('ref-field.placeholder')}\n disabled={!createType}\n onClick={() => void handleCreate()}\n />\n </Button.Group>\n )\n )}\n </FormFieldSet>\n );\n};\n\ntype InlineFormProps = {\n reference: Ref.Ref<any>;\n db?: Database.Database;\n readonly?: boolean;\n useType?: UseType;\n};\n\n/** The target's form: its fields render straight into the enclosing group, sharing its tracks. */\nconst InlineForm = ({ reference, db, readonly, useType = defaultUseType }: InlineFormProps) => {\n const target = useAtomValue(useMemo(() => reference.atom, [reference]));\n const typeFromRegistry = useType(db, target ? Obj.getTypeURI(target) : undefined);\n const targetType = (target && Obj.getType(target)) || typeFromRegistry;\n const schema = useMemo(() => (targetType ? omitId(Type.getSchema(targetType)) : undefined), [targetType]);\n const defaultValues = useMemo(() => (target ? { ...target } : {}), [target]);\n const handleChange = useCallback(\n (\n values: AnyProperties,\n { isValid, changed }: { isValid: boolean; changed: Record<SchemaEx.JsonPath, boolean> },\n ) => {\n if (!isValid || !target) {\n return;\n }\n const paths = (Object.keys(changed) as SchemaEx.JsonPath[]).filter((path) => changed[path]);\n if (paths.length > 0) {\n Obj.update(target, (target) => {\n for (const path of paths) {\n const parts = SchemaEx.splitJsonPath(path);\n Obj.setValue(target, parts, SchemaEx.getValue(values, path));\n }\n });\n }\n },\n [target],\n );\n\n if (!target || !schema) {\n return null;\n }\n\n return (\n <FormRoot db={db} schema={schema} defaultValues={defaultValues} onValuesChanged={handleChange}>\n <FormFields readonly={readonly} />\n </FormRoot>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { EditorView } from '@codemirror/view';\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport React, { useMemo } from 'react';\n\nimport { type Database, Obj, Ref } from '@dxos/echo';\nimport { Doc } from '@dxos/echo-doc';\nimport { Editor, useBasicMarkdownExtensions } from '@dxos/react-ui-editor';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { Text } from '@dxos/schema';\nimport { createDataExtensions } from '@dxos/ui-editor';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { useFormContext } from '../../hooks/index.ts';\nimport { presentationFor } from '../presentation.tsx';\n\n/** The editor's minimum height in lines, as the current field's `min-h-[6lh]`. */\nconst ROWS = 6;\n\n/**\n * Fits the editor to the field: a long unbroken token (an inline-code URL) breaks anywhere rather than widening the\n * content, and the editor fills the frame's height, so its scroller ends at the frame's foot instead of mid-field.\n */\nconst fieldTheme = EditorView.theme({\n '&': { minHeight: '100%' },\n '.cm-content': { overflowWrap: 'anywhere' },\n // Elsewhere inline code is one clipped line (fixed height, no wrapping), which in a field widens the content instead.\n '& .cm-content .cm-code-inline': { whiteSpace: 'break-spaces', height: 'auto', overflow: 'visible' },\n});\n\n/**\n * A markdown value in a CodeMirror editor framed by a multi-line `ControlFrame`. The value is either a string\n * (`Format.TypeFormat.Markdown`), edited as plain text, or a `Ref<Text>`, edited in place through its document; an empty\n * ref offers a button that creates the Text.\n */\nexport const MarkdownField = ({\n type,\n readonly,\n placeholder,\n presentation,\n db,\n getValue,\n onValueChange,\n}: FormFieldRendererProps) => {\n const value: unknown = getValue();\n const isStatic = presentationFor(presentation).isStatic;\n if (Ref.isRefType(type)) {\n const reference = Ref.isRef(value) ? value : undefined;\n if (reference) {\n return isStatic ? (\n <RefStaticText reference={reference} />\n ) : (\n <RefMarkdownEditor reference={reference} placeholder={placeholder} readonly={!!readonly} />\n );\n }\n\n return isStatic || readonly ? null : (\n <CreateTextButton db={db} onCreate={(created) => onValueChange(type, created)} />\n );\n }\n\n const text = typeof value === 'string' ? value : '';\n return isStatic ? (\n <Typography.Text>{text}</Typography.Text>\n ) : (\n <StringMarkdownEditor\n value={text}\n placeholder={placeholder}\n readonly={!!readonly}\n onChange={(next) => onValueChange(type, next)}\n />\n );\n};\n\ntype StringMarkdownEditorProps = {\n value: string;\n placeholder?: string;\n readonly?: boolean;\n onChange: (value: string) => void;\n};\n\nconst StringMarkdownEditor = ({ value, placeholder, readonly, onChange }: StringMarkdownEditorProps) => {\n const { markdownExtensions } = useFormContext('MarkdownField');\n // Memoised: a new list each render would reconfigure the editor on every keystroke and drop its focus.\n const fieldExtensions = useMemo(() => [fieldTheme, ...(markdownExtensions ?? [])], [markdownExtensions]);\n const extensions = useBasicMarkdownExtensions({ placeholder, readonly, extensions: fieldExtensions });\n return (\n <Input.Frame rows={ROWS} disabled={readonly}>\n <Editor.Root>\n <Editor.View extensions={extensions} value={value} onChange={readonly ? undefined : onChange} />\n </Editor.Root>\n </Input.Frame>\n );\n};\n\n/** A `Ref<Text>`'s content, resolved, as read-only text. */\nconst RefStaticText = ({ reference }: { reference: Ref.Unknown }) => {\n const target = useAtomValue(useMemo(() => reference.atom, [reference]));\n const content = Obj.instanceOf(Text.Text, target) ? target.content : undefined;\n return content ? <Typography.Text>{content}</Typography.Text> : null;\n};\n\ntype RefMarkdownEditorProps = {\n reference: Ref.Unknown;\n placeholder?: string;\n readonly?: boolean;\n};\n\nconst RefMarkdownEditor = ({ reference, placeholder, readonly }: RefMarkdownEditorProps) => {\n const target = useAtomValue(useMemo(() => reference.atom, [reference]));\n const text = Obj.instanceOf(Text.Text, target) ? target : undefined;\n const dataExtensions = useMemo(\n () => (text ? [createDataExtensions({ id: reference.uri, text: Doc.createAccessor(text, ['content']) })] : []),\n [text, reference],\n );\n const { markdownExtensions } = useFormContext('MarkdownField');\n const fieldExtensions = useMemo(\n () => [fieldTheme, ...dataExtensions, ...(markdownExtensions ?? [])],\n [dataExtensions, markdownExtensions],\n );\n const extensions = useBasicMarkdownExtensions({ placeholder, readonly, extensions: fieldExtensions });\n if (!text) {\n return null;\n }\n\n return (\n <Input.Frame rows={ROWS} disabled={readonly}>\n <Editor.Root>\n <Editor.View extensions={extensions} />\n </Editor.Root>\n </Input.Frame>\n );\n};\n\ntype CreateTextButtonProps = {\n db?: Database.Database;\n onCreate: (ref: Ref.Ref<Text.Text>) => void;\n};\n\nconst CreateTextButton = ({ db, onCreate }: CreateTextButtonProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n return (\n <Button.Root icon='ph--plus--regular' disabled={!db} onClick={() => db && onCreate(Ref.make(db.add(Text.make())))}>\n {t('create-text.label')}\n </Button.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport React, { useEffect, useState } from 'react';\n\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { StepAnnotation } from '../../annotations.ts';\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { getNumericConstraints } from './numeric-constraints.ts';\n\n/** A fractional field without a declared step moves by 0.01 below magnitude 1, else by 0.1. */\nconst defaultStep = (value: number | undefined, integer: boolean): number =>\n integer ? 1 : value !== undefined && Math.abs(value) < 1 ? 0.01 : 0.1;\n\n/** Ark's number input parses, steps and clamps on blur; the field commits every value that parses. */\nexport const NumberField = ({\n type,\n format,\n readonly,\n placeholder,\n presentation,\n min: minProp,\n max: maxProp,\n step: stepProp,\n getValue,\n onValueChange,\n onBlur,\n}: FormFieldRendererProps<number>) => {\n const constraints = getNumericConstraints(type);\n // A caller's override narrows the schema's bounds for this form; a whole-number step reads as an integer.\n const min = minProp ?? constraints.min;\n const max = maxProp ?? constraints.max;\n const integer = constraints.integer || (stepProp !== undefined && Number.isInteger(stepProp));\n const committed = getValue();\n // The text is kept locally so a partial edit (\"1.\", \"-\") survives until it parses.\n const [text, setText] = useState(committed === undefined ? '' : String(committed));\n useEffect(() => {\n if (committed !== undefined && Number(text) !== committed) {\n setText(String(committed));\n }\n }, [committed]); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={committed} format={format} />;\n }\n\n return (\n <Input.Number\n disabled={!!readonly}\n placeholder={placeholder}\n min={min}\n max={max}\n step={stepProp ?? Option.getOrElse(StepAnnotation.getFromAst(type), () => defaultStep(committed, integer))}\n formatOptions={integer ? { maximumFractionDigits: 0 } : { useGrouping: false }}\n value={text}\n onValueChange={(next, valueAsNumber) => {\n setText(next);\n if (!Number.isNaN(valueAsNumber)) {\n onValueChange(type, valueAsNumber);\n // A stepper press never blurs, so every value that parses commits itself, as a pick does.\n onBlur();\n }\n }}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\nexport const PasswordField = ({\n type,\n format,\n readonly,\n placeholder,\n presentation,\n getValue,\n onValueChange,\n}: FormFieldRendererProps<string>) => {\n const value = getValue() ?? '';\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={'•'.repeat(value.length)} format={format} />;\n }\n\n return (\n <Input.Password\n ignorePasswordManagers\n disabled={!!readonly}\n placeholder={placeholder}\n value={value}\n onValueChange={(next) => onValueChange(type, next)}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport type * as Schema from 'effect/Schema';\nimport React, {\n type DragEvent,\n type KeyboardEvent,\n type ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport * as Combobox from '@dxos/react-ui/Combobox';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Tag from '@dxos/react-ui/Tag';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { hues } from '@dxos/ui-types';\nimport { arrayMove } from '@dxos/util';\n\nimport { type CreateOptions, type RefOption } from '#types';\n\nimport { FormActions, FormContent } from './Form.tsx';\nimport { FormFields } from './FormFieldDispatch.tsx';\n// The parts, not the `Form` namespace: RefField renders this picker inside the Form's module cycle, and the namespace\n// object reads every part when its module is evaluated.\nimport { FormRoot } from './FormRoot.tsx';\n\ntype PickerCreateProps = Pick<CreateOptions, 'createInitialValuePath' | 'createFieldMap'> & {\n /** The inline create form's schema; with `onCreate`, the popup offers a create row for an unmatched query. */\n createSchema?: Schema.Codec<any, any>;\n /** The create row's text for the query (the translated `createOptionLabel`); `Create “{query}”` by default. */\n createLabel?: (query: string) => string;\n /** The create row's icon (`createOptionIcon`); a plus by default. */\n createIcon?: string;\n /** Persists the create form's values; awaited before the form closes. */\n onCreate?: (values: any) => unknown | Promise<unknown>;\n};\n\ntype PickerBaseProps = PickerCreateProps & {\n options: RefOption[];\n loading?: boolean;\n};\n\n/**\n * The popup state shared by the pickers: open, and the query a chosen create row turned into a create form. Choosing\n * the create row also asks the popup to close, so `startCreate` reopens it in the same batch.\n */\nconst usePickerState = ({ options, createSchema, onCreate }: PickerBaseProps) => {\n const [open, setOpen] = useState(false);\n const [creating, setCreating] = useState<string>();\n const items = useMemo<Combobox.Option[]>(\n () => options.map(({ id, label, description }) => ({ value: id, label, description })),\n [options],\n );\n const handleOpenChange = useCallback(({ open }: { open: boolean }) => {\n setOpen(open);\n if (!open) {\n setCreating(undefined);\n }\n }, []);\n const startCreate =\n createSchema !== undefined && onCreate !== undefined\n ? (query: string) => {\n setCreating(query);\n setOpen(true);\n }\n : undefined;\n return { open, setOpen, creating, setCreating, items, handleOpenChange, startCreate };\n};\n\ntype CreateFormProps = Pick<PickerCreateProps, 'createInitialValuePath' | 'createFieldMap'> & {\n schema: Schema.Codec<any, any>;\n query: string;\n onSave: (values: any) => Promise<void>;\n onCancel: () => void;\n};\n\n/** The create form a picker's popup swaps its list for, seeded with the query at `createInitialValuePath`. */\nconst CreateForm = ({ schema, query, createInitialValuePath, createFieldMap, onSave, onCancel }: CreateFormProps) => (\n <FormRoot\n testId='create-referenced-object-form'\n schema={schema}\n defaultValues={createInitialValuePath ? { [createInitialValuePath]: query } : {}}\n fieldMap={createFieldMap}\n onSave={onSave}\n onCancel={onCancel}\n >\n <Layout.Container gutter='inset'>\n <FormContent>\n <FormFields />\n <FormActions />\n </FormContent>\n </Layout.Container>\n </FormRoot>\n);\n\nexport type ObjectPickerProps = PickerBaseProps & {\n /** The selected option's id. */\n value?: string;\n placeholder?: string;\n /** Replaces the selection button, e.g. a toolbar's add button that picks an object to insert. */\n trigger?: ReactElement;\n /** Called with the picked id, or `undefined` when the selected option is picked again. */\n onSelect: (id: string | undefined) => void;\n};\n\n/**\n * Picks one object with `Combobox` in trigger mode: a button showing the selection opens a popup whose search\n * field narrows the options (each with its description). Choosing the create row swaps the list for a create form.\n */\nexport const ObjectPicker = ({\n value,\n placeholder,\n trigger,\n loading,\n createSchema,\n createInitialValuePath,\n createFieldMap,\n createLabel,\n createIcon,\n onCreate,\n onSelect,\n options,\n}: ObjectPickerProps) => {\n const { setOpen, creating, setCreating, items, open, handleOpenChange, startCreate } = usePickerState({\n options,\n createSchema,\n onCreate,\n });\n const handleSave = useCallback(\n async (values: any) => {\n await onCreate?.(values);\n setCreating(undefined);\n setOpen(false);\n },\n [onCreate],\n );\n\n return (\n <Combobox.Root\n items={items}\n loading={loading}\n open={open}\n onOpenChange={handleOpenChange}\n value={value ? [value] : []}\n onSelect={({ itemValue }) => {\n if (options.some((option) => option.id === itemValue)) {\n onSelect(itemValue === value ? undefined : itemValue);\n }\n }}\n onCreate={startCreate}\n createLabel={createLabel}\n createIcon={createIcon}\n >\n {trigger ? (\n <Combobox.Trigger asChild>{trigger}</Combobox.Trigger>\n ) : (\n <Combobox.Trigger placeholder={placeholder} />\n )}\n <Combobox.Content>\n {creating !== undefined && createSchema ? (\n <CreateForm\n schema={createSchema}\n query={creating}\n createInitialValuePath={createInitialValuePath}\n createFieldMap={createFieldMap}\n onSave={handleSave}\n onCancel={() => setCreating(undefined)}\n />\n ) : undefined}\n </Combobox.Content>\n </Combobox.Root>\n );\n};\n\nexport type ObjectMultiPickerProps = Omit<PickerBaseProps, 'onCreate'> & {\n /** The selected options' ids, in order. */\n 'value': string[];\n /** Shown in place of chips while nothing is selected. */\n 'placeholder'?: string;\n /** Chips reorder by drag, or Alt+ArrowLeft/Right on a focused chip. */\n 'ordered'?: boolean;\n 'data-testid'?: string;\n 'onValueChange': (ids: string[]) => void;\n /** Persists the create form's values and returns the new option's id, which is then selected. */\n 'onCreate'?: (values: any) => Promise<string | undefined>;\n};\n\n/**\n * Picks several objects with `Combobox` in `multiple` mode: the selection is a wrapping row of removable\n * `Tag` chips (in each option's hue) whose caret opens a search popup; picking toggles an option and keeps the\n * popup open, and the create row swaps the list for a create form whose new object joins the selection.\n */\nexport const ObjectMultiPicker = ({\n value,\n placeholder,\n loading,\n createSchema,\n createInitialValuePath,\n createFieldMap,\n createLabel,\n createIcon,\n onCreate,\n onValueChange,\n options,\n ordered,\n 'data-testid': testId,\n}: ObjectMultiPickerProps) => {\n const { creating, setCreating, items, open, handleOpenChange, startCreate } = usePickerState({\n options,\n createSchema,\n onCreate,\n });\n const handleSave = useCallback(\n async (values: any) => {\n const id = await onCreate?.(values);\n if (id) {\n onValueChange([...value, id]);\n }\n setCreating(undefined);\n },\n [onCreate, onValueChange, value],\n );\n\n const selected = value.map((id) => options.find((option) => option.id === id) ?? { id, label: id });\n const { chipProps } = useChipOrder({ value, onValueChange });\n return (\n <Combobox.Root\n items={items}\n loading={loading}\n multiple\n closeOnSelect={false}\n open={open}\n onOpenChange={handleOpenChange}\n value={value}\n onValueChange={({ value }) => onValueChange(value)}\n onCreate={startCreate}\n createLabel={createLabel}\n createIcon={createIcon}\n >\n <Combobox.Control wrap data-testid={testId}>\n {selected.length === 0 && placeholder && <Typography.Text tone='muted'>{placeholder}</Typography.Text>}\n {selected.map((option) => (\n <Tag.Tag\n key={option.id}\n hue={hues.find((hue) => hue === option.hue)}\n onDelete={() => onValueChange(value.filter((id) => id !== option.id))}\n {...(ordered && chipProps(option.id))}\n >\n {option.label}\n </Tag.Tag>\n ))}\n <Combobox.Trigger />\n </Combobox.Control>\n <Combobox.Content>\n {creating !== undefined && createSchema ? (\n <CreateForm\n schema={createSchema}\n query={creating}\n createInitialValuePath={createInitialValuePath}\n createFieldMap={createFieldMap}\n onSave={handleSave}\n onCancel={() => setCreating(undefined)}\n />\n ) : (\n <>\n <Combobox.Input />\n <Combobox.List />\n </>\n )}\n </Combobox.Content>\n </Combobox.Root>\n );\n};\n\ntype ChipOrderOptions = Pick<ObjectMultiPickerProps, 'value' | 'onValueChange'>;\n\n/** The data attribute naming a chip's id, so focus can follow a moved chip. */\nconst CHIP_ID = 'data-chip-id';\n\n/**\n * Reordering for a wrapping row of chips: each chip is a native drag source and drop target (dropping moves the dragged\n * chip to its place) and, focused, moves by Alt+ArrowLeft/Right, keeping focus as React moves its element.\n */\nconst useChipOrder = ({ value, onValueChange }: ChipOrderOptions) => {\n const [focusId, setFocusId] = useState<string>();\n const rowRef = useRef<HTMLElement | null>(null);\n useEffect(() => {\n if (focusId) {\n rowRef.current?.querySelector<HTMLElement>(`[${CHIP_ID}=\"${CSS.escape(focusId)}\"]`)?.focus();\n setFocusId(undefined);\n }\n }, [focusId, value]);\n\n const move = (id: string, to: number) => {\n const from = value.indexOf(id);\n if (from < 0 || to < 0 || to >= value.length || from === to) {\n return;\n }\n const next = [...value];\n arrayMove(next, from, to);\n onValueChange(next);\n };\n\n const chipProps = (id: string) => ({\n [CHIP_ID]: id,\n 'draggable': true,\n 'tabIndex': 0,\n 'aria-keyshortcuts': 'Alt+ArrowLeft Alt+ArrowRight',\n 'onKeyDown': (event: KeyboardEvent<HTMLElement>) => {\n const step = event.key === 'ArrowLeft' ? -1 : event.key === 'ArrowRight' ? 1 : 0;\n if (event.altKey && step !== 0 && event.target === event.currentTarget) {\n event.preventDefault();\n rowRef.current = event.currentTarget.parentElement;\n move(id, value.indexOf(id) + step);\n setFocusId(id);\n }\n },\n 'onDragStart': (event: DragEvent<HTMLElement>) => {\n event.dataTransfer.setData(CHIP_MIME, id);\n event.dataTransfer.effectAllowed = 'move';\n },\n 'onDragOver': (event: DragEvent<HTMLElement>) => {\n if (event.dataTransfer.types.includes(CHIP_MIME)) {\n event.preventDefault();\n }\n },\n 'onDrop': (event: DragEvent<HTMLElement>) => {\n const dragged = event.dataTransfer.getData(CHIP_MIME);\n if (dragged) {\n event.preventDefault();\n move(dragged, value.indexOf(id));\n }\n },\n });\n\n return { chipProps };\n};\n\n/** The drag payload type of a chip, so a row only accepts its own chips. */\nconst CHIP_MIME = 'application/x-dxos-chip';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport '@dxos/lit-ui/dx-tag-picker.pcss';\nimport { Ref } from '@dxos/echo';\nimport { EID } from '@dxos/keys';\n\nimport { type RefOption } from '#types';\n\n// Kept out of `RefField.tsx`: react-refresh only fast-refreshes a module whose\n// exports are all components, so values exported beside them force a full page reload on every edit.\n\nconst isRefSnapshot = (val: any): val is { '/': string } => {\n return typeof val === 'object' && typeof (val as any)?.['/'] === 'string';\n};\n\n/**\n * Find the option a ref-like form value points at. Matches on the local (entity-id) form so a bare local EID\n * (`echo:///<id>`, produced by `Ref.make`) still resolves against an option keyed by the entity's qualified\n * self URI (`echo://<space>/<id>`). Returns `undefined` when the value is not a ref or no option matches.\n *\n * Comparing by entity id is only sound within one space (ids are unique there, not globally). Two EIDs that\n * both carry a space authority must therefore agree on it: a qualified value and a qualified option from\n * different spaces never match, even when their entity ids coincide.\n */\nexport const findRefOption = (value: unknown, options: RefOption[]): RefOption | undefined => {\n const isRef = Ref.isRef(value);\n if (!isRef && !isRefSnapshot(value)) {\n return undefined;\n }\n const valueUri = isRef ? value.uri : value['/'];\n // Keyed/registry entities (skills, operations) are referenced by a named DXN rather than an\n // entity-id, so they carry no parseable EID; match those by direct URI equality against the option id.\n const directMatch = options.find((option) => option.id === valueUri);\n if (directMatch) {\n return directMatch;\n }\n const valueEid = EID.tryParse(valueUri);\n if (!valueEid) {\n return undefined;\n }\n const valueSpaceId = EID.getSpaceId(valueEid);\n const valueLocal = EID.toLocal(valueEid);\n return options.find((option) => {\n const optionEid = EID.tryParse(option.id);\n if (!optionEid) {\n return false;\n }\n const optionSpaceId = EID.getSpaceId(optionEid);\n if (valueSpaceId != null && optionSpaceId != null && valueSpaceId !== optionSpaceId) {\n return false;\n }\n return EID.equals(EID.toLocal(optionEid), valueLocal);\n });\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Obj, Ref, Tag } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport { EID } from '@dxos/keys';\n\nimport { omitId } from '../util/index.ts';\n\n/**\n * Form-field key for the synthetic meta-tags array spliced into property/create forms.\n *\n * An object's tags live in `Obj.getMeta(obj).tags` (off-schema), so the form surfaces them as an\n * extra field rather than reading the schema. The key is underscore-prefixed so it never collides\n * with a `tags` field an object schema declares itself — e.g. a `TagIndex` record on a feed host,\n * whose `tags` is `Record<tagId, objectId[]>`, not an array. Extending such a schema with a `tags`\n * array threw \"overlapping types at path: [\\\"tags\\\"]\"; the disjoint `_tags` key avoids it. The\n * human-facing label is restored via the `title` annotation on {@link withMetaTags}.\n */\nexport const META_TAGS_KEY = '_tags';\n\n/**\n * Splices the synthetic meta-tags array (an object's `meta.tags`, surfaced as {@link Tag} refs) onto\n * a schema for editing and drops `id`. Keyed by {@link META_TAGS_KEY} so it never collides with a\n * `tags` field the schema declares itself.\n */\nexport const withMetaTags = (schema: Schema.Codec<any, any>) =>\n omitId(\n // `SchemaAST.assignFields`, not v4's `Schema.fieldsAssign`: the latter needs both sides' fields\n // at the type level, which a schema known only as a `Codec` cannot supply.\n Schema.make<Schema.Codec<any, any>>(\n SchemaAST.assignFields(\n Schema.Struct({\n [META_TAGS_KEY]: Schema.Array(Ref.Ref(Tag.Tag)).pipe(Schema.annotate({ title: 'Tags' }), Schema.optional),\n }).ast,\n schema.ast,\n ),\n ),\n );\n\nconst isTag = Obj.instanceOf(Tag.Tag);\n\n/**\n * Narrows a tag picker's candidates to the tags a user may apply by hand: those with no origin.\n *\n * A tag that carries an origin is owned by whoever put it there — a Gmail label or a JMAP folder is\n * sync's to apply, and a canonical DXOS tag (`starred`, `sent`, `draft`) is applied by a purpose-built\n * affordance such as the star button or the draft lifecycle. Offering either in a generic picker\n * invites an attribution that nothing maintains: on a synced object the next delta silently strips it,\n * and on an unsynced one it never gets corrected at all. See `Tag.md` §\"Tag origin\".\n *\n * Non-tag candidates pass through untouched, so this is safe to apply to any ref field's results —\n * hence generic in the element type rather than narrowed to `Entity.Any`, which concrete instances are\n * deliberately not assignable to.\n */\nexport const filterTagCandidates = <T>(results: readonly T[]): T[] =>\n results.filter((result) => !isTag(result) || Tag.isUserTag(result));\n\n/**\n * A ref's target entity id, ignoring whether the uri is local (`echo:///<id>`) or qualified\n * (`echo://<space>/<id>`) — `Ref.make` produces the former while `Obj.getURI` produces the latter, so\n * the two forms must compare equal. Same reason as `findRefOption`.\n */\nconst entityIdOf = (uri: string): string | undefined => {\n const parsed = EID.tryParse(uri);\n return parsed ? EID.getEntityId(parsed) : undefined;\n};\n\n/**\n * Splits an object's meta tags into the ones a form may edit and the ones a provider owns.\n *\n * Provider-owned tags are held back rather than shown read-only: the tags field is a generic array of\n * refs whose delete affordance knows nothing about tags, so the only way to make one non-removable\n * would be to thread tag-specific policy through a type-agnostic renderer. Holding them out of the\n * form value instead keeps them off the picker *and* out of reach of the delete button, and matches\n * where they are already surfaced — as chips on the object's own views.\n *\n * The caller must write `preserved` back alongside whatever the form returns: `meta.tags` is replaced\n * wholesale on save, so omitting them would delete the object's provider tags on the first edit.\n *\n * `candidates` is the space's tag set (each tag's origin lives on the tag, not on the ref); non-tag\n * entries are ignored, so a caller may pass a broader query result.\n */\nexport const partitionMetaTags = (\n refs: readonly Ref.Ref<Tag.Tag>[],\n candidates: readonly unknown[],\n): { editable: Ref.Ref<Tag.Tag>[]; preserved: Ref.Ref<Tag.Tag>[] } => {\n const providerIds = new Set<string>();\n for (const candidate of candidates) {\n if (isTag(candidate) && Tag.isProviderTag(candidate)) {\n const id = entityIdOf(Obj.getURI(candidate).toString());\n if (id !== undefined) {\n providerIds.add(id);\n }\n }\n }\n\n const editable: Ref.Ref<Tag.Tag>[] = [];\n const preserved: Ref.Ref<Tag.Tag>[] = [];\n for (const ref of refs) {\n const id = entityIdOf(ref.uri);\n (id !== undefined && providerIds.has(id) ? preserved : editable).push(ref);\n }\n\n return { editable, preserved };\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useCallback, useMemo } from 'react';\n\nimport { type Database, DXN, Entity, Filter, Obj, Query, Scope, Tag, Type } from '@dxos/echo';\nimport { useType as defaultUseType, useQuery } from '@dxos/echo-react';\nimport { ANY_OBJECT_TYPENAME, ReferenceAnnotationId, type ReferenceAnnotationValue } from '@dxos/echo/internal';\nimport type * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport { hues } from '@dxos/ui-types';\n\nimport { type CreateOptions, type RefFieldDataProps } from '#types';\n\nimport { omitHiddenFormFields, omitId } from '../../util/index.ts';\nimport { filterTagCandidates } from '../meta-tags.ts';\n\n/** The typename of the meta-tags field's targets, whose rows are a multiple selection of chips. */\nexport const TAG_TYPENAME = Type.getTypename(Tag.Tag);\n\n/**\n * The candidates for a ref field: objects of its type in the space and the registry (space objects only for an untyped\n * ref); tag candidates are the user tags only (`filterTagCandidates`).\n */\nexport const defaultUseResults: NonNullable<RefFieldDataProps['useResults']> = (db, typename) => {\n const results = useQuery(\n db,\n !typename\n ? Query.select(Filter.nothing())\n : typename === ANY_OBJECT_TYPENAME\n ? Query.select(Filter.everything())\n : Query.select(Filter.type(DXN.make(typename))).from(Scope.space(), Scope.registry()),\n );\n const isTagField = typename === TAG_TYPENAME;\n return useMemo(() => (isTagField ? filterTagCandidates(results) : results), [isTagField, results]);\n};\n\n/** Each candidate as an option labelled by its label (else its URI), with a tag's hue. */\nexport const defaultGetOptions: NonNullable<RefFieldDataProps['getOptions']> = (results) =>\n results.map((result) => {\n const id = Entity.getURI(result, { prefer: 'named' });\n const hue = Obj.instanceOf(Tag.Tag, result) ? hues.find((hue) => hue === result.hue) : undefined;\n return { id, label: Entity.getLabel(result) ?? id, ...(hue && { hue }) };\n });\n\nexport type RefCandidatesOptions = RefFieldDataProps &\n Pick<CreateOptions, 'createOptionLabel'> & {\n /** The ref type (a single ref's, or an array's element). */\n refType: SchemaAST.AST;\n db?: Database.Database;\n };\n\n/**\n * The data path a ref picker shares: the ref's typename, its candidates as options, and, when the caller can persist\n * one, the inline create form's schema, a `create` that persists its values, and the create row's translated label.\n */\nexport const useRefCandidates = (options: RefCandidatesOptions) => {\n const {\n refType,\n db,\n useType = defaultUseType,\n useResults = defaultUseResults,\n getOptions = defaultGetOptions,\n createOptionLabel,\n onCreate,\n resolveCreateEntry,\n } = options;\n const { t } = Hooks.useTranslation();\n const typename = useMemo(\n () => SchemaEx.findAnnotation<ReferenceAnnotationValue>(refType, ReferenceAnnotationId)?.typename,\n [refType],\n );\n const results = useResults(db, typename);\n const candidates = useMemo(() => getOptions(results), [results, getOptions]);\n const entity = useType(db, typename && typename !== ANY_OBJECT_TYPENAME ? DXN.make(typename) : undefined);\n // A plugin-registered entry (e.g. `SpaceCapabilities.CreateObjectEntry`) replaces the raw type's schema and create.\n const createEntry = typename ? resolveCreateEntry?.(typename) : undefined;\n const createSchema = useMemo(\n () => createEntry?.inputSchema ?? (entity && omitHiddenFormFields(omitId(Type.getSchema(entity)))),\n [createEntry, entity],\n );\n\n const persist = useCallback(\n async (values: any) =>\n createEntry?.createObject && db\n ? await createEntry.createObject(values, db)\n : entity && onCreate\n ? await onCreate(entity, values)\n : undefined,\n [createEntry, db, entity, onCreate],\n );\n\n const createLabel = useMemo(() => {\n if (!createOptionLabel) {\n return undefined;\n }\n const [key, { ns }] = createOptionLabel;\n return (query: string) => t(key, { ns, text: query, interpolation: { escapeValue: false } });\n }, [createOptionLabel, t]);\n\n return {\n typename,\n entity,\n results,\n options: candidates,\n createSchema,\n createLabel,\n // A resolvable type alone is not enough (operation refs cannot be created ad hoc): the caller must persist it.\n create: onCreate || createEntry?.createObject ? persist : undefined,\n };\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport React, { type KeyboardEvent, type MouseEvent, useMemo } from 'react';\n\nimport { Annotation, Entity, Obj, Ref, Type } from '@dxos/echo';\nimport type * as SchemaAST from '@dxos/effect/SchemaAST';\nimport { URI } from '@dxos/keys';\nimport { OrderedList } from '@dxos/react-ui-list';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as SystemButton from '@dxos/react-ui/SystemButton';\nimport * as Tag from '@dxos/react-ui/Tag';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { DxAnchorActivate, hues } from '@dxos/ui-types';\nimport { arrayMove } from '@dxos/util';\n\nimport { translationKey } from '#translations';\nimport { type CreateOptions, type FormFieldRendererProps, type RefFieldDataProps, type RefOption } from '#types';\n\nimport { ObjectMultiPicker, ObjectPicker } from '../ObjectPicker.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { findRefOption } from './find-ref-option.ts';\nimport { TAG_TYPENAME, useRefCandidates } from './ref-options.ts';\n\n/**\n * How an array of refs is presented: its `ArrayPresentationAnnotation`, else (and per option) chips for Tag refs and\n * title rows for any other type, unordered unless annotated (`ordered`, or the older `FormOrderedAnnotation`).\n */\nexport const getArrayPresentation = (type: SchemaAST.AST, typename: string | undefined) => {\n const presentation = Option.getOrUndefined(Annotation.ArrayPresentationAnnotation.getFromAst(type));\n return {\n display: presentation?.display ?? (typename === TAG_TYPENAME ? 'tag' : 'title'),\n ordered:\n presentation?.ordered ?? Annotation.FormOrderedAnnotation.getFromAst(type).pipe(Option.getOrElse(() => false)),\n description: presentation?.description,\n } as const;\n};\n\nexport type RefArrayFieldProps = FormFieldRendererProps<readonly unknown[] | undefined> &\n RefFieldDataProps &\n CreateOptions & {\n /** The array's element: the ref type. */\n elementType: SchemaAST.AST;\n };\n\n/**\n * An array of references, presented per {@link getArrayPresentation}:\n * - `tag`: one multiple selection of removable chips in the targets' hues (draggable within the row when ordered);\n * - `title`: a row per target (its type's icon, its label, an optional description, a Remove) that opens the object\n * when activated, with a DragHandle when ordered, and below them a picker that adds one, with inline create.\n */\nexport const RefArrayField = ({\n type,\n elementType,\n readonly,\n label,\n placeholder,\n presentation,\n jsonPath,\n getValue,\n onValueChange,\n createInitialValuePath,\n createFieldMap,\n createOptionIcon,\n ...props\n}: RefArrayFieldProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const { typename, entity, options, createSchema, createLabel, create } = useRefCandidates({\n ...props,\n refType: elementType,\n });\n const { display, ordered, description } = getArrayPresentation(type, typename);\n const refs = (getValue() ?? []).filter(Ref.isRef).flatMap((ref) => {\n const id = findRefOption(ref, options)?.id;\n return id ? [{ id, ref }] : [];\n });\n const ids = refs.map(({ id }) => id);\n const setIds = (next: readonly string[]) =>\n onValueChange(\n type,\n next.map((id) => Ref.fromURI(URI.make(id))),\n );\n const persist =\n create &&\n (async (values: any) => {\n const created = await create(values);\n return created ? Entity.getURI(created, { prefer: 'named' }) : undefined;\n });\n const pickerProps = {\n options,\n createSchema,\n createInitialValuePath,\n createFieldMap,\n createLabel,\n createIcon: createOptionIcon,\n };\n const isStatic = readonly || presentationFor(presentation).isStatic;\n if (!typename) {\n return null;\n }\n\n if (display === 'title') {\n return (\n <TitleRows\n label={label}\n ids={ids}\n options={options}\n targets={new Map(refs.map(({ id, ref }) => [id, ref.peek()]))}\n icon={entity && Option.getOrUndefined(Annotation.IconAnnotation.get(Type.getSchema(entity)))}\n description={description}\n ordered={ordered}\n readonly={isStatic}\n testId={jsonPath}\n onChange={setIds}\n >\n {!isStatic && (\n <ObjectPicker\n {...pickerProps}\n options={options.filter((option) => !ids.includes(option.id))}\n placeholder={placeholder || t('ref-field.placeholder')}\n onSelect={(id) => id && setIds([...ids, id])}\n onCreate={\n persist &&\n (async (values) => {\n const id = await persist(values);\n if (id) {\n setIds([...ids, id]);\n }\n })\n }\n />\n )}\n </TitleRows>\n );\n }\n\n if (isStatic) {\n const selected = ids.flatMap((id) => options.find((option) => option.id === id) ?? []);\n return selected.length === 0 ? (\n <Typography.Text tone='muted'>{t('empty-readonly-ref-field.label')}</Typography.Text>\n ) : (\n <Button.Group>\n {selected.map((option) => (\n <Tag.Tag key={option.id} hue={hues.find((hue) => hue === option.hue)}>\n {option.label}\n </Tag.Tag>\n ))}\n </Button.Group>\n );\n }\n\n return (\n <ObjectMultiPicker\n {...pickerProps}\n value={ids}\n ordered={ordered}\n placeholder={placeholder || label}\n data-testid={jsonPath}\n onCreate={persist}\n onValueChange={setIds}\n />\n );\n};\n\ntype TitleRowsProps = {\n label?: string;\n ids: readonly string[];\n options: RefOption[];\n /** The loaded target of each id, for the configured description field. */\n targets: ReadonlyMap<string, unknown>;\n icon?: { icon: string; hue?: string };\n description?: string;\n ordered: boolean;\n readonly: boolean;\n testId?: string;\n onChange: (ids: readonly string[]) => void;\n /** The add picker, in a row below the rows. */\n children?: React.ReactNode;\n};\n\n/** Opens a target as its anchor would (the app's preview), from the row standing in for it. */\nconst activate = (option: RefOption, row: HTMLElement) =>\n row.dispatchEvent(new DxAnchorActivate({ eid: option.id, label: option.label, trigger: row }));\n\n/** The `title` rows: a header with the label, an OrderedList of the targets, then the add picker. */\nconst TitleRows = ({\n label,\n ids,\n options,\n targets,\n icon,\n description,\n ordered,\n readonly,\n testId,\n onChange,\n children,\n}: TitleRowsProps) => {\n const rows = useMemo(\n () =>\n ids.flatMap((id) => {\n const option = options.find((option) => option.id === id);\n if (!option) {\n return [];\n }\n // The configured description field of the target, else the option's own description.\n const target = targets.get(id);\n const field = description && Obj.isObject(target) ? Obj.getValue(target, [description]) : undefined;\n return [{ ...option, description: typeof field === 'string' ? field : option.description }];\n }),\n [ids, options, targets, description],\n );\n const iconHue = hues.find((hue) => hue === icon?.hue);\n\n const handleMove = (from: number, to: number) => {\n const next = [...ids];\n arrayMove(next, from, to);\n onChange(next);\n };\n\n // A click on the row (not on one of its buttons) opens the target.\n const handleClick = (option: RefOption) => (event: MouseEvent<HTMLElement>) => {\n if (!(event.target instanceof Element && event.target.closest('button'))) {\n activate(option, event.currentTarget);\n }\n };\n\n // Enter on the highlighted row (focus is on the list, the row is its active descendant) opens its target.\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key !== 'Enter' || event.target !== event.currentTarget) {\n return;\n }\n const row = event.currentTarget.querySelector<HTMLElement>('[data-part=\"item\"][data-highlighted]');\n const option = rows.find((option) => option.id === row?.dataset.value);\n if (row && option) {\n event.preventDefault();\n activate(option, row);\n }\n };\n\n return (\n <>\n <Field.Header>\n <Typography.Text truncate>{label}</Typography.Text>\n </Field.Header>\n {rows.length > 0 && (\n <OrderedList.Root\n items={rows}\n getId={(option) => option.id}\n getLabel={(option) => option.label}\n onMove={handleMove}\n readonly={readonly || !ordered}\n >\n {({ items }) => (\n <OrderedList.Content\n scroll={false}\n gutter='inherit'\n aria-label={label}\n data-testid={testId}\n onKeyDown={handleKeyDown}\n >\n {items.map((option) => (\n <OrderedList.Item\n key={option.id}\n id={option.id}\n canDrag={ordered && !readonly}\n onClick={handleClick(option)}\n >\n {ordered && !readonly && <OrderedList.DragHandle />}\n {icon && <OrderedList.ItemIcon icon={icon.icon} hue={iconHue} />}\n <OrderedList.ItemText>{option.label}</OrderedList.ItemText>\n {option.description && (\n <OrderedList.ItemDescription>{option.description}</OrderedList.ItemDescription>\n )}\n {!readonly && (\n <SystemButton.Remove\n variant='ghost'\n onClick={() => onChange(ids.filter((id) => id !== option.id))}\n />\n )}\n </OrderedList.Item>\n ))}\n </OrderedList.Content>\n )}\n </OrderedList.Root>\n )}\n {children}\n </>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Ref } from '@dxos/echo';\nimport { URI } from '@dxos/keys';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { translationKey } from '#translations';\nimport { type CreateOptions, type FormFieldRendererProps, type RefFieldDataProps } from '#types';\n\nimport { ObjectPicker } from '../ObjectPicker.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { findRefOption } from './find-ref-option.ts';\nimport { useRefCandidates } from './ref-options.ts';\n\nexport type RefFieldProps = FormFieldRendererProps & RefFieldDataProps & CreateOptions;\n\n/**\n * A single reference picked with the next `ObjectPicker` (Combobox trigger mode): a button showing the target opens a\n * searchable list of candidates with their descriptions and, when the caller can persist one, an inline create form\n * whose row takes `createOptionLabel` and `createOptionIcon`.\n */\nexport const RefField = ({\n type,\n readonly,\n label,\n placeholder,\n presentation,\n getValue,\n onValueChange,\n createInitialValuePath,\n createFieldMap,\n createOptionIcon,\n ...props\n}: RefFieldProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const { typename, options, createSchema, createLabel, create } = useRefCandidates({ ...props, refType: type });\n const selected = findRefOption(getValue(), options);\n if (!typename) {\n return null;\n }\n if (readonly || presentationFor(presentation).isStatic) {\n return (\n <Typography.Text truncate tone={selected ? 'default' : 'muted'}>\n {selected?.label ?? t('empty-readonly-ref-field.label')}\n </Typography.Text>\n );\n }\n\n return (\n <ObjectPicker\n options={options}\n value={selected?.id}\n placeholder={placeholder || label || t('ref-field.placeholder')}\n createSchema={createSchema}\n createInitialValuePath={createInitialValuePath}\n createFieldMap={createFieldMap}\n createLabel={createLabel}\n createIcon={createOptionIcon}\n onCreate={\n create &&\n (async (values) => {\n const created = await create(values);\n if (created) {\n onValueChange(type, Ref.make(created));\n }\n })\n }\n onSelect={(id) => onValueChange(type, id ? Ref.fromURI(URI.make(id)) : undefined)}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { type SelectOption } from '@dxos/echo/Format';\nimport { PublicKey } from '@dxos/keys';\nimport { OrderedList } from '@dxos/react-ui-list';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Tag from '@dxos/react-ui/Tag';\nimport { hues } from '@dxos/ui-types';\nimport { arrayMove } from '@dxos/util';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { HueSelect } from './HueField.tsx';\n\n/** A hue no option uses yet, else one the last three options do not use. */\nconst nextHue = (options: readonly SelectOption[]) => {\n const used = new Set(options.map((option) => option.color));\n const unused = hues.filter((hue) => !used.has(hue));\n if (unused.length > 0) {\n return unused[Math.floor(Math.random() * unused.length)];\n }\n const recent = new Set(options.slice(-3).map((option) => option.color));\n const available = hues.filter((hue) => !recent.has(hue));\n return available[Math.floor(Math.random() * available.length)] ?? hues[0];\n};\n\n/**\n * The options of a single- or multi-select property: an `OrderedList` of disclosure rows, each a hued `Tag` that opens\n * to its label and hue, with a remove action; options reorder by drag or Alt+Arrow, and \"Add option\" appends one\n * opened for editing.\n */\nexport const SelectOptionField = ({\n type,\n label,\n readonly,\n getValue,\n onValueChange,\n}: FormFieldRendererProps<SelectOption[] | undefined>) => {\n const { t } = Hooks.useTranslation(translationKey);\n const options = getValue();\n const [expandedId, setExpandedId] = useState<string>();\n\n useEffect(() => {\n if (options === undefined) {\n onValueChange(type, []);\n }\n }, [options, type, onValueChange]);\n\n const update = useCallback(\n (id: string, change: Partial<SelectOption>) =>\n onValueChange(\n type,\n (options ?? []).map((option) => (option.id === id ? { ...option, ...change } : option)),\n ),\n [options, type, onValueChange],\n );\n\n const handleAdd = useCallback(() => {\n const id = PublicKey.random().truncate();\n onValueChange(type, [...(options ?? []), { id, title: '', color: nextHue(options ?? []) }]);\n setExpandedId(id);\n }, [options, type, onValueChange]);\n\n const handleMove = useCallback(\n (from: number, to: number) => {\n const next = [...(options ?? [])];\n arrayMove(next, from, to);\n onValueChange(type, next);\n },\n [options, type, onValueChange],\n );\n\n return (\n <>\n <OrderedList.Root\n items={options ?? []}\n getId={(option) => option.id}\n getLabel={(option) => option.title}\n onMove={handleMove}\n readonly={!!readonly}\n >\n {({ items }) => (\n <OrderedList.Content scroll={false} gutter='inherit' aria-label={label}>\n {items.map((option) => (\n <OrderedList.Item\n key={option.id}\n id={option.id}\n canDrag={!readonly}\n open={expandedId === option.id}\n onOpenChange={(open) => setExpandedId(open ? option.id : undefined)}\n data-testid={`option-${option.id}`}\n >\n <OrderedList.DragHandle />\n <OrderedList.ItemText>\n <Tag.Tag hue={hues.find((hue) => hue === option.color)}>{option.title || '\\u200b'}</Tag.Tag>\n </OrderedList.ItemText>\n {!readonly && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--x--regular'\n label={t('select-option-delete.button')}\n onClick={() =>\n onValueChange(\n type,\n (options ?? []).filter((item) => item.id !== option.id),\n )\n }\n />\n )}\n <OrderedList.Detail>\n <Layout.Container layout='row' gutter='none' columns='minmax(0, 1fr) minmax(0, 1fr)' gap='sm'>\n <Field.Root>\n <Field.Label>{t('select-option.label')}</Field.Label>\n <Input.Root\n autoFocus={expandedId === option.id && option.title === ''}\n disabled={!!readonly}\n placeholder={t('select-option-label.placeholder')}\n value={option.title}\n onChange={(event) => update(option.id, { title: event.target.value })}\n onKeyDown={(event) => event.key === 'Enter' && setExpandedId(undefined)}\n />\n </Field.Root>\n <Field.Root>\n <Field.Label>{t('select-option-color.label')}</Field.Label>\n <HueSelect\n value={option.color}\n readonly={readonly}\n onValueChange={(color) => color && update(option.id, { color })}\n />\n </Field.Root>\n </Layout.Container>\n </OrderedList.Detail>\n </OrderedList.Item>\n ))}\n </OrderedList.Content>\n )}\n </OrderedList.Root>\n {!readonly && (\n <Button.Group>\n <Button.Root icon='ph--plus--regular' label={t('select-option-add.button')} onClick={handleAdd} />\n </Button.Group>\n )}\n </>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\nexport const TextAreaField = ({\n type,\n format,\n readonly,\n placeholder,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n}: FormFieldRendererProps<string>) => {\n const value = getValue() ?? '';\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value} format={format} />;\n }\n\n return (\n <Input.Textarea\n autoResize\n disabled={!!readonly}\n placeholder={placeholder}\n value={value}\n onChange={(event) => onValueChange(type, event.target.value)}\n onBlur={onBlur}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n/**\n * Minimal XML-style DSL for laying out schema fields in a grid.\n *\n * Grammar:\n * <grid cols=\"N\" [fixed=\"true\"]> ...children... </grid>\n * <field name=\"x\" span=\"N\"/>\n *\n * - Attributes accept `\"…\"`, `'…'`, or unquoted integers.\n * - Whitespace between tags is ignored. Text content (between tags) is forbidden.\n * - Self-closing form (`<field … />`) is required for `field`; `grid` must use a closing tag.\n *\n * The parser is hand-rolled (no HTML parser) because the grammar is tiny.\n */\n\n/** Node type for the parsed layout tree. */\nexport type LayoutNode =\n | {\n readonly kind: 'grid';\n readonly cols: number;\n /** Keeps the columns in a narrow pane rather than stacking the cells. */\n readonly fixed?: boolean;\n readonly children: readonly LayoutNode[];\n }\n | { readonly kind: 'field'; readonly name: string; readonly span?: number };\n\nexport class LayoutParseError extends Error {\n readonly _tag = 'LayoutParseError';\n constructor(\n message: string,\n readonly position?: number,\n ) {\n super(position !== undefined ? `${message} (at position ${position})` : message);\n }\n}\n\nconst TAG_RE = /<\\s*(\\/?)\\s*(\\w+)([^>]*?)(\\/?)\\s*>/g;\nconst ATTR_RE = /([\\w-]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|(\\d+))/g;\n\ntype Token =\n | { type: 'open'; name: string; attrs: Record<string, string>; selfClosing: boolean; position: number }\n | { type: 'close'; name: string; position: number };\n\nconst parseAttrs = (raw: string): Record<string, string> => {\n const attrs: Record<string, string> = {};\n ATTR_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = ATTR_RE.exec(raw)) !== null) {\n const [, key, doubleQuoted, singleQuoted, bare] = match;\n attrs[key] = doubleQuoted ?? singleQuoted ?? bare;\n }\n return attrs;\n};\n\nconst tokenize = (input: string): Token[] => {\n const tokens: Token[] = [];\n TAG_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n let cursor = 0;\n while ((match = TAG_RE.exec(input)) !== null) {\n // Validate that any text between the previous tag and this one is whitespace-only.\n const between = input.slice(cursor, match.index);\n if (between.trim().length > 0) {\n throw new LayoutParseError(`unexpected text content: ${JSON.stringify(between.trim())}`, cursor);\n }\n const [, slash, name, attrsRaw, selfSlash] = match;\n if (slash) {\n tokens.push({ type: 'close', name, position: match.index });\n } else {\n tokens.push({\n type: 'open',\n name,\n attrs: parseAttrs(attrsRaw),\n selfClosing: selfSlash === '/',\n position: match.index,\n });\n }\n cursor = match.index + match[0].length;\n }\n // Any trailing text after the last tag must also be whitespace.\n const trailing = input.slice(cursor);\n if (trailing.trim().length > 0) {\n throw new LayoutParseError(`unexpected text content: ${JSON.stringify(trailing.trim())}`, cursor);\n }\n return tokens;\n};\n\nconst requireAttr = (attrs: Record<string, string>, key: string, tag: string, position: number): string => {\n const value = attrs[key];\n if (value === undefined) {\n throw new LayoutParseError(`<${tag}> missing required attribute \"${key}\"`, position);\n }\n return value;\n};\n\nconst parseInteger = (value: string, attr: string, tag: string, position: number): number => {\n if (!/^\\d+$/.test(value)) {\n throw new LayoutParseError(\n `<${tag}> attribute \"${attr}\" expects an integer, got ${JSON.stringify(value)}`,\n position,\n );\n }\n return Number.parseInt(value, 10);\n};\n\n/** Parses a layout template string into a single root node. The root must be `<grid>`. */\nexport const parseLayout = (template: string): LayoutNode => {\n const tokens = tokenize(template);\n if (tokens.length === 0) {\n throw new LayoutParseError('empty template');\n }\n\n let index = 0;\n\n const parseNode = (): LayoutNode => {\n const token = tokens[index];\n if (!token || token.type !== 'open') {\n throw new LayoutParseError(`expected an opening tag, got ${JSON.stringify(token)}`, token?.position);\n }\n\n if (token.name === 'field') {\n if (!token.selfClosing) {\n throw new LayoutParseError('<field> must be self-closing (e.g. <field name=\"x\"/>)', token.position);\n }\n const name = requireAttr(token.attrs, 'name', 'field', token.position);\n const spanRaw = token.attrs.span;\n const span = spanRaw !== undefined ? parseInteger(spanRaw, 'span', 'field', token.position) : undefined;\n index += 1;\n return { kind: 'field', name, span };\n }\n\n if (token.name === 'grid') {\n if (token.selfClosing) {\n throw new LayoutParseError('<grid> must wrap children (cannot self-close)', token.position);\n }\n const cols = parseInteger(\n requireAttr(token.attrs, 'cols', 'grid', token.position),\n 'cols',\n 'grid',\n token.position,\n );\n index += 1;\n const children: LayoutNode[] = [];\n while (index < tokens.length && !(tokens[index].type === 'close' && tokens[index].name === 'grid')) {\n children.push(parseNode());\n }\n const closing = tokens[index];\n if (!closing || closing.type !== 'close' || closing.name !== 'grid') {\n throw new LayoutParseError('<grid> not closed', token.position);\n }\n index += 1;\n const fixed = token.attrs.fixed === 'true';\n return { kind: 'grid', cols, ...(fixed ? { fixed } : {}), children };\n }\n\n throw new LayoutParseError(`unknown element <${token.name}>`, token.position);\n };\n\n const root = parseNode();\n if (index !== tokens.length) {\n const trailing = tokens[index];\n throw new LayoutParseError(\n `unexpected trailing tag <${trailing.type === 'open' ? '' : '/'}${trailing.name}>`,\n trailing.position,\n );\n }\n if (root.kind !== 'grid') {\n throw new LayoutParseError('root element must be <grid>');\n }\n return root;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as String from 'effect/String';\nimport React, { Fragment, useMemo } from 'react';\n\nimport { Annotation } from '@dxos/echo';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { type FormPresentation } from '#types';\n\nimport { useFormContext, useFormFieldState } from '../hooks/index.ts';\nimport { FormFieldErrorBoundary } from './field-binding.tsx';\nimport { FormFieldRow } from './FormField.tsx';\nimport { FormFieldDispatch } from './FormFieldDispatch.tsx';\nimport { type LayoutNode, LayoutParseError, parseLayout } from './layout/parser.ts';\nimport { resolveLayoutField } from './layout/resolve-layout-field.ts';\nimport { type FormFieldDispatchProps } from './resolve-field.ts';\n\nconst FORM_LAYOUT_NAME = 'Form.Layout';\n\nexport type FormLayoutProps = {\n /** Template in the FormLayout DSL (`<grid cols=…><field name=… span=…/></grid>`); else the schema's annotation. */\n template?: string;\n /** The named layout in `FormLayoutAnnotation` when there is no `template`; `'default'` by default. */\n name?: string;\n schema: Schema.Codec<AnyProperties, any>;\n} & Pick<FormFieldDispatchProps, 'path' | 'readonly' | 'layout' | 'projection' | 'fieldMap' | 'fieldProvider'>;\n\n/**\n * Lays out schema fields by a FormLayout DSL template: a `<grid cols=N>` is a row Container of N equal tracks, and a\n * `<field span=N>` a cell spanning N of them (Container `span`). Only the fields the template names render; a dotted\n * name drills into a nested struct, and a struct with a `LabelAnnotation` renders as its label, read-only.\n */\nexport const FormLayout = ({\n schema,\n template,\n name = Annotation.DEFAULT_LAYOUT_NAME,\n path,\n ...props\n}: FormLayoutProps) => {\n const annotated = Option.getOrUndefined(Annotation.FormLayoutAnnotation.get(schema));\n const source = template ?? annotated?.[name];\n if (source === undefined) {\n throw new LayoutParseError(\n annotated\n ? `no layout named \"${name}\" on schema (available: ${Object.keys(annotated).join(', ') || '∅'})`\n : 'no template provided and schema has no FormLayoutAnnotation',\n );\n }\n\n const tree = useMemo(() => parseLayout(source), [source]);\n return <LayoutNodeView node={tree} schema={schema} basePath={path ?? []} {...props} />;\n};\n\nFormLayout.displayName = FORM_LAYOUT_NAME;\n\ntype LayoutNodeViewProps = Omit<FormLayoutProps, 'template' | 'name' | 'path'> & {\n node: LayoutNode;\n basePath: (string | number)[];\n};\n\nconst LayoutNodeView = ({ node, schema, basePath, ...props }: LayoutNodeViewProps) => {\n if (node.kind === 'grid') {\n return (\n <Layout.Container\n layout='row'\n gutter='inherit'\n align='start'\n gap='md'\n columns={`repeat(${node.cols}, minmax(0, 1fr))`}\n fixed={node.fixed}\n >\n {node.children.map((child, index) => (\n <Fragment key={index}>\n <LayoutNodeView node={child} schema={schema} basePath={basePath} {...props} />\n </Fragment>\n ))}\n </Layout.Container>\n );\n }\n\n const resolved = resolveLayoutField(schema, node.name);\n if (!resolved) {\n throw new LayoutParseError(`field \"${node.name}\" not found on schema`);\n }\n\n const { type, segments, leafName, title, labelType, required } = resolved;\n const path = [...basePath, ...segments];\n return (\n // A cell is its own template root, so a group inside it (a nested object) finds the `content` lines.\n <Layout.Container gutter='none' span={node.span}>\n <FormFieldErrorBoundary path={path}>\n {labelType ? (\n <LabelField\n schema={Schema.make(labelType)}\n label={title ?? String.capitalize(leafName)}\n path={path}\n layout={props.layout}\n />\n ) : (\n <FormFieldDispatch type={type} name={leafName} path={path} required={required} {...props} />\n )}\n </FormFieldErrorBoundary>\n </Layout.Container>\n );\n};\n\ntype LabelFieldProps = {\n schema: Schema.Schema<any>;\n label: string;\n path: (string | number)[];\n layout?: FormPresentation;\n};\n\n/** A nested struct value as its computed label (`LabelAnnotation`), read-only; an empty value renders nothing. */\nconst LabelField = ({ schema, label, path, layout }: LabelFieldProps) => {\n const { getValue } = useFormFieldState(FORM_LAYOUT_NAME, path);\n const value = getValue();\n const text = value == null ? undefined : Annotation.getLabelWithSchema(schema, value);\n if (text == null || text.trim().length === 0) {\n return null;\n }\n\n return (\n <FormFieldRow label={label} readonly standalone presentation={layout}>\n <Typography.Text truncate>{text}</Typography.Text>\n </FormFieldRow>\n );\n};\n\n/** `Form.Layout`: the form's own schema laid out by a template (or the schema's annotation). */\nexport const FormLayoutController = ({\n schema,\n ...props\n}: Omit<FormLayoutProps, 'schema'> & Partial<Pick<FormLayoutProps, 'schema'>>) => {\n const { form, variant: _variant, testId: _testId, ...context } = useFormContext(FORM_LAYOUT_NAME);\n const resolved = schema ?? form.schema;\n return resolved ? <FormLayout schema={resolved} {...context} {...props} /> : null;\n};\n\nFormLayoutController.displayName = FORM_LAYOUT_NAME;\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as Schema from 'effect/Schema';\nimport { useMemo } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { type Merge } from '@dxos/util';\n\nimport { type FieldContext } from '#types';\n\nimport { getRootFormProperties } from '../util/index.ts';\nimport { type FormFieldDispatchProps } from './resolve-field.ts';\n\n/** A path into the form values: dotted from the root, or its segments. */\nexport type FormPath = string | (string | number)[];\n\nexport const toPathSegments = (path: FormPath | undefined): (string | number)[] =>\n path === undefined\n ? []\n : typeof path === 'string'\n ? SchemaEx.isJsonPath(path)\n ? SchemaEx.splitJsonPath(path)\n : []\n : path;\n\nexport type FormFieldsProps<T extends AnyProperties = AnyProperties> = Merge<\n {\n /** The object property whose fields to render; the root by default. */\n path?: FormPath;\n /** Renders these properties only, in schema order. */\n include?: string[];\n exclude?: string[];\n /** Property names in the order to render them. */\n sort?: string[];\n filter?: (props: SchemaEx.SchemaProperty[]) => SchemaEx.SchemaProperty[];\n /**\n * Picks a named layout out of `Annotation.FormLayoutAnnotation` when present. Falls back to `'default'`.\n * Ignored when the schema has no annotation (linear rendering then takes over).\n */\n layoutName?: string;\n /** The schema to walk in place of the form's, at the same path. */\n schema?: Schema.Codec<T, any>;\n },\n Pick<FormFieldDispatchProps, 'autoFocus'>,\n FieldContext\n>;\n\nexport type UseFormFieldsPropertiesParams = Pick<\n FormFieldsProps<any>,\n 'schema' | 'include' | 'exclude' | 'filter' | 'projection' | 'sort'\n> & {\n values: AnyProperties | undefined;\n};\n\n/**\n * Resolves ordered schema properties for a walk (projection order, include/exclude, filter, sort).\n */\nexport const useFormFieldsProperties = ({\n schema,\n include,\n exclude,\n filter,\n projection,\n values,\n sort,\n}: UseFormFieldsPropertiesParams): SchemaEx.SchemaProperty[] => {\n // TODO(burdon): Updates on every value change.\n // Remove values dep if can remove from getSchemaProperties.\n return useMemo(() => {\n if (!schema) {\n return [];\n }\n\n // TODO(wittjosiah): Reconcile FormInputAnnotation with projection hidden properties & filter function.\n const schemaProps = getRootFormProperties(schema.ast, values);\n const included = include ? schemaProps.filter((prop) => include.includes(prop.name.toString())) : schemaProps;\n const excluded = exclude ? included.filter((prop) => !exclude.includes(prop.name.toString())) : included;\n const filteredProps = filter ? filter(excluded) : excluded;\n\n // Use projection-based field management when view and projection are available.\n if (projection) {\n const fieldProjections = projection.getFieldProjections();\n const hiddenProperties = new Set(projection.getHiddenProperties());\n\n // Filter properties to only include visible ones and order by projection.\n const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));\n const orderedProps: SchemaEx.SchemaProperty[] = [];\n\n // Add properties in projection field order.\n for (const fieldProjection of fieldProjections) {\n const fieldPath = String(fieldProjection.field.path);\n const prop = visibleProps.find((prop) => prop.name === fieldPath);\n if (prop) {\n orderedProps.push(prop);\n }\n }\n\n // Add any remaining properties not in projection.\n const projectionPaths = new Set(fieldProjections.map((projection) => String(projection.field.path)));\n const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));\n orderedProps.push(...remainingProps);\n return orderedProps;\n }\n\n // Fallback to legacy filter/sort behavior.\n return sort\n ? [...filteredProps].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString()))\n : filteredProps;\n }, [schema, values, include, exclude, filter, sort, projection]);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Match from 'effect/Match';\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport { type ReactNode } from 'react';\n\nimport { Annotation, Format } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\nimport { type FieldContext, type FormFieldRenderer, type FormFieldRendererProps } from '#types';\n\nimport {\n type Autofill,\n AutofillAnnotation,\n HueAnnotation,\n type OptionsLookup,\n OptionsLookupAnnotation,\n} from '../annotations.ts';\nimport { getRefProps } from '../util/index.ts';\n\n/** The built-in control a scalar property gets. */\nexport type ScalarKind = 'text' | 'number' | 'boolean' | 'date' | 'geo-point' | 'markdown' | 'password' | 'text-area';\n\nexport type FormFieldDispatchProps = {\n /**\n * AST of the property to render.\n */\n type: SchemaAST.AST;\n\n /**\n * Name of the property. Used to derive a default label\n * (`title ?? capitalize(name)`) and as the projection lookup key. Pass\n * `null` to suppress the header label entirely -- the form still renders\n * the field/struct, but `FormFieldSet`'s top-level `<FormFieldLabel>` is\n * skipped. Used by `ArrayField` for object-array items, where every item\n * would otherwise repeat the array's parent name.\n */\n name: string | null;\n\n /**\n * Explicit label, overriding the `title ?? capitalize(name)` derivation. Used by `ArrayField` to\n * give scalar/ref items the array's resolved title (e.g. `Tags`) rather than re-capitalizing the\n * raw array property name (e.g. `_tags`), since the element type carries no title of its own.\n */\n label?: string;\n\n /**\n * Path to the current object from the root. Used with nested forms.\n */\n path?: (string | number)[];\n autoFocus?: boolean;\n /** Whether the field is required (non-optional in the schema). Drives the label asterisk. */\n required?: boolean;\n /**\n * Force a `Ref` field to render its target inline (a nested form) instead of the picker.\n * Set by `ArrayField` for owned-ref arrays (`FormCreateAnnotation`); equivalent to\n * `FormInlineAnnotation` but driven by the parent array rather than the element's own AST.\n */\n refInline?: boolean;\n} & FieldContext;\n\n/**\n * Decides which renderer a schema property gets, in priority order: a custom renderer from the form,\n * an annotation that names one (options lookup, autofill, hue), then the shape of the type (array,\n * scalar by format or tag, literal options, reference, nested object). Pure, so the decision can be\n * tested without rendering; {@link FormFieldDispatch} turns the result into an element.\n */\nexport const resolveFieldRenderer = ({\n type,\n name,\n jsonPath,\n value,\n fieldMap,\n fieldProvider,\n fieldProps,\n refInline,\n}: ResolveFieldRendererOptions): FieldRendererResolution | undefined => {\n const custom = fieldMap?.[jsonPath];\n if (custom) {\n return { kind: 'custom', component: custom };\n }\n\n if (fieldProvider) {\n const element = fieldProvider({ schema: Schema.make<Schema.Codec<any, any>>(type), prop: name ?? '', fieldProps });\n if (element) {\n return { kind: 'provided', element };\n }\n }\n\n const lookup = Option.getOrUndefined(OptionsLookupAnnotation.getFromAst(type));\n if (lookup) {\n return { kind: 'lookup', lookup, combobox: !!lookup.combobox };\n }\n\n const autofill = Option.getOrUndefined(AutofillAnnotation.getFromAst(type));\n if (autofill) {\n return { kind: 'autofill', autofill };\n }\n\n if (Option.getOrUndefined(HueAnnotation.getFromAst(type))) {\n return { kind: 'hue' };\n }\n\n if (SchemaEx.isArrayType(type)) {\n return { kind: 'array' };\n }\n\n const scalar = getScalarKind({ type, format: fieldProps.format });\n if (scalar) {\n return { kind: 'scalar', scalar };\n }\n\n const options = getSelectOptions(type);\n if (options) {\n return { kind: 'select', options };\n }\n\n const refProps = getRefProps(type);\n if (refProps) {\n const inline =\n refInline || Annotation.FormInlineAnnotation.getFromAst(refProps.ast).pipe(Option.getOrElse(() => false));\n return { kind: 'ref', refProps, inline: inline && !refProps.isArray };\n }\n\n if (SchemaEx.isNestedType(type)) {\n const baseNode = SchemaEx.findNode(type, SchemaEx.isDiscriminatedUnion);\n const typeLiteral = baseNode\n ? SchemaEx.getDiscriminatedType(baseNode, value as any)\n : SchemaEx.findNode(type, SchemaAST.isObjects);\n if (typeLiteral) {\n return { kind: 'object', schema: Schema.make<Schema.Codec<any, any>>(typeLiteral) };\n }\n }\n\n return undefined;\n};\n\nexport type ResolveFieldRendererOptions = {\n type: SchemaAST.AST;\n name: string | null;\n jsonPath: string;\n /** The property's current value; a discriminated union picks its member by it. */\n value: unknown;\n fieldProps: FormFieldRendererProps;\n refInline?: boolean;\n} & Pick<FieldContext, 'fieldMap' | 'fieldProvider'>;\n\ntype RefProps = NonNullable<ReturnType<typeof getRefProps>>;\n\nexport type FieldRendererResolution =\n | { kind: 'custom'; component: FormFieldRenderer }\n | { kind: 'provided'; element: ReactNode }\n | { kind: 'lookup'; lookup: OptionsLookup; combobox: boolean }\n | { kind: 'autofill'; autofill: Autofill }\n | { kind: 'hue' }\n | { kind: 'array' }\n | { kind: 'scalar'; scalar: ScalarKind }\n | { kind: 'select'; options: Format.Options[] }\n | { kind: 'ref'; refProps: RefProps; inline: boolean }\n | { kind: 'object'; schema: Schema.Codec<any, any> };\n\n/** The kind of control for a scalar: by its format first, then by the type's tag. */\nconst getScalarKind = ({ type, format }: Pick<FormFieldRendererProps, 'type' | 'format'>): ScalarKind | undefined => {\n // v4 has no `Refinement` node: `Schema.Number.pipe(Schema.check(...))` IS a `Number` node\n // carrying checks, so the base-type cases below already match it.\n\n //\n // Standard formats.\n //\n\n const formatField = Match.value(format).pipe(\n Match.withReturnType<ScalarKind | undefined>(),\n Match.when(Format.TypeFormat.Date, () => 'date'),\n Match.when(Format.TypeFormat.DateTime, () => 'date'),\n Match.when(Format.TypeFormat.GeoPoint, () => 'geo-point'),\n Match.when(Format.TypeFormat.Markdown, () => 'markdown'),\n Match.when(Format.TypeFormat.Password, () => 'password'),\n Match.when(Format.TypeFormat.Text, () => 'text-area'),\n Match.when(Format.TypeFormat.Time, () => 'date'),\n Match.orElse(() => undefined),\n );\n if (formatField) {\n return formatField;\n }\n\n //\n // Standard types.\n //\n\n switch (type._tag) {\n // TODO(wittjosiah): Schema.Any is currently used to represent template inputs.\n case 'Any':\n case 'String':\n return 'text';\n case 'Number':\n return 'number';\n case 'Boolean':\n return 'boolean';\n }\n\n return undefined;\n};\n\nconst getSelectOptions = (ast: SchemaAST.AST): Format.Options[] | undefined => {\n if (SchemaEx.isLiteralUnion(ast)) {\n return ast.types.map((type) => type.literal).filter((v): v is string | number => v !== null);\n }\n\n return Format.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option.getOrUndefined(annotation));\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as String from 'effect/String';\nimport React, { type ReactNode, useMemo } from 'react';\n\nimport { Annotation, Format } from '@dxos/echo';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport * as Hooks from '@dxos/react-ui/Hooks';\n\nimport { translationKey } from '#translations';\nimport { type CreateOptions, type FormFieldRenderer, type FormFieldRendererProps } from '#types';\n\nimport { useFormContext, useFormFieldState, useFormValues } from '../hooks/index.ts';\nimport { getRefProps, getSchemaAtPath } from '../util/index.ts';\nimport { FormFieldErrorBoundary } from './field-binding.tsx';\nimport {\n ArrayField,\n AsyncSelectField,\n AutofillField,\n BooleanField,\n ComboboxField,\n DateField,\n GeoPointField,\n HueField,\n InlineRefField,\n MarkdownField,\n NumberField,\n PasswordField,\n RefArrayField,\n RefField,\n SelectField,\n TextAreaField,\n TextField,\n getArrayPresentation,\n} from './fields/index.ts';\nimport { FormFieldRow } from './FormField.tsx';\nimport { type FormFieldBinding } from './FormFieldContext.ts';\nimport { FormFieldSet } from './FormFieldSet.tsx';\nimport { FormLayout } from './FormLayout.tsx';\nimport { type FormFieldsProps, toPathSegments, useFormFieldsProperties } from './property-walk.ts';\nimport {\n type FieldRendererResolution,\n type FormFieldDispatchProps,\n type ScalarKind,\n resolveFieldRenderer,\n} from './resolve-field.ts';\n\n/**\n * The control for each scalar kind `resolveFieldRenderer` answers. A function, not a module-level table, so nothing\n * imported is read while the modules of this recursion evaluate.\n */\nconst scalarField = (kind: ScalarKind): FormFieldRenderer => {\n switch (kind) {\n case 'text':\n return TextField;\n case 'number':\n return NumberField;\n case 'boolean':\n return BooleanField;\n case 'date':\n return DateField;\n case 'geo-point':\n return GeoPointField;\n case 'password':\n return PasswordField;\n case 'text-area':\n return TextAreaField;\n case 'markdown':\n return MarkdownField;\n }\n};\n\nexport type { FormFieldDispatchProps, FormFieldsProps };\n\n/** One schema property, rendered by the Next renderer for whatever `resolveFieldRenderer` picks. */\nexport const FormFieldDispatch = (props: FormFieldDispatchProps) => {\n const {\n type,\n name,\n label: labelProp,\n path,\n required,\n projection,\n fieldMap,\n fieldProvider,\n readonly: readonlyProp,\n hideEmpty = true,\n layout,\n createTypename,\n createOptionLabel,\n createOptionIcon,\n createInitialValuePath,\n createFieldMap,\n db,\n useType,\n getOptions,\n onCreate,\n resolveCreateEntry,\n refInline,\n } = props;\n const { t } = Hooks.useTranslation(translationKey);\n const { variant, form } = useFormContext(FormFieldDispatch.displayName);\n // The caller's per-field override wins over what the schema says.\n const override = form.getOverride(path ?? []);\n const title = SchemaEx.getAnnotation<string>(SchemaAST.TitleAnnotationId)(type);\n const description = override?.description ?? SchemaEx.getAnnotation<string>(SchemaAST.DescriptionAnnotationId)(type);\n const examples = SchemaEx.getAnnotation<string[]>(SchemaAST.ExamplesAnnotationId)(type);\n const label = useMemo(\n () => override?.label ?? labelProp ?? title ?? (name == null ? '' : String.capitalize(name)),\n [override?.label, labelProp, title, name],\n );\n const readonly = override?.readonly ?? readonlyProp;\n // A settings row shows its description beside the control, so the description never doubles as the placeholder.\n const placeholder = useMemo(\n () =>\n examples?.length\n ? `${t('example.placeholder')}: ${examples[0]}`\n : variant === 'settings'\n ? undefined\n : (description ?? label),\n [examples, description, label, variant, t],\n );\n\n const fieldState = useFormFieldState(FormFieldDispatch.displayName, path);\n const jsonPath = SchemaEx.createJsonPath(path ?? []);\n const indeterminate = fieldState.getStatus().indeterminate;\n const fieldProps: FormFieldRendererProps = {\n type,\n format: Format.FormatAnnotation.getFromAst(type).pipe((annotation) => Option.getOrUndefined(annotation)),\n readonly,\n label,\n description,\n jsonPath,\n // An indeterminate value reads as none, so its placeholder says why rather than naming the field.\n placeholder: indeterminate\n ? (override?.placeholder ?? t('indeterminate.placeholder'))\n : (override?.placeholder ?? placeholder),\n presentation: layout,\n required,\n indeterminate,\n min: override?.min,\n max: override?.max,\n step: override?.step,\n db,\n ...fieldState,\n };\n\n if (override?.hidden || ((readonly || layout === 'static') && hideEmpty && fieldState.getValue() == null)) {\n return null;\n }\n\n const resolution = resolveFieldRenderer({\n type,\n name,\n jsonPath,\n value: fieldState.getValue(),\n fieldMap,\n fieldProvider,\n fieldProps,\n refInline,\n });\n if (!resolution) {\n return null;\n }\n\n if (resolution.kind === 'custom') {\n const CustomField = resolution.component;\n return <CustomField {...fieldProps} />;\n }\n if (resolution.kind === 'provided') {\n return resolution.element;\n }\n // An array of refs the form does not own (`FormCreateAnnotation` targets render inline per element) is a\n // RefArrayField: chips (`tag`) in a field row, or (`title`) rows under a header of their own.\n const refProps = resolution.kind === 'array' ? getRefProps(type) : undefined;\n const refArray =\n refProps?.isArray && Option.isNone(Annotation.FormCreateAnnotation.getFromAst(type)) ? refProps : undefined;\n if (resolution.kind === 'array' && !refArray) {\n return <ArrayField fieldProps={fieldState} label={label} {...props} />;\n }\n const refArrayField = refArray && (\n <RefArrayField\n {...fieldProps}\n {...createOptionsFor(refArray.typename)}\n elementType={refArray.ast}\n db={db}\n useType={useType}\n getOptions={getOptions}\n onCreate={onCreate}\n resolveCreateEntry={resolveCreateEntry}\n />\n );\n if (refArray && getArrayPresentation(type, refArray.typename).display === 'title') {\n return refArrayField;\n }\n if (resolution.kind === 'object') {\n return (\n <FormFieldSet label={label} collapsible nested data-testid={`group.${jsonPath}`}>\n <FormFields\n schema={resolution.schema}\n path={path}\n readonly={readonly}\n layout={layout}\n projection={projection}\n fieldMap={fieldMap}\n fieldProvider={fieldProvider}\n db={db}\n useType={useType}\n getOptions={getOptions}\n onCreate={onCreate}\n resolveCreateEntry={resolveCreateEntry}\n />\n </FormFieldSet>\n );\n }\n\n if (resolution.kind === 'ref' && resolution.inline) {\n return <InlineRefField {...fieldProps} db={db} useType={useType} onCreate={onCreate} />;\n }\n\n const control = renderControl(resolution);\n if (control === undefined) {\n return null;\n }\n\n const { status, error } = fieldState.getStatus();\n const binding: FormFieldBinding = {\n path: jsonPath,\n type,\n value: fieldState.getValue(),\n setValue: (next) => fieldState.onValueChange(type, next),\n onBlur: fieldState.onBlur,\n status,\n error,\n indeterminate,\n required: fieldProps.required,\n readonly,\n presentation: layout,\n };\n const scalar = resolution.kind === 'scalar' ? scalarField(resolution.scalar) : undefined;\n return (\n <FormFieldRow\n label={label}\n description={description}\n format={fieldProps.format}\n binding={binding}\n standalone={refArray ? true : scalar?.standalone}\n labelPlacement={scalar?.labelPlacement}\n renderStatic={resolution.kind === 'select' ? renderSelectStatic(resolution.options, projection, name) : undefined}\n >\n {control}\n </FormFieldRow>\n );\n\n /** The form's create options (e.g. a tag's), which apply only to refs of `createTypename`. */\n function createOptionsFor(typename: string | undefined): CreateOptions {\n return !createTypename || typename === createTypename\n ? { createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap }\n : {};\n }\n\n function renderControl(resolution: FieldRendererResolution): ReactNode | undefined {\n switch (resolution.kind) {\n case 'scalar': {\n const ScalarField = scalarField(resolution.scalar);\n return ScalarField ? <ScalarField {...fieldProps} /> : undefined;\n }\n case 'select':\n return <SelectField {...fieldProps} options={selectOptions(resolution.options, projection, name)} />;\n case 'lookup':\n return resolution.combobox ? (\n <ComboboxField {...fieldProps} lookup={resolution.lookup} />\n ) : (\n <AsyncSelectField {...fieldProps} lookup={resolution.lookup} />\n );\n case 'autofill':\n return <AutofillField {...fieldProps} autofill={resolution.autofill} />;\n case 'hue':\n return <HueField {...fieldProps} />;\n case 'array':\n return refArrayField;\n case 'ref': {\n return (\n <RefField\n {...fieldProps}\n {...resolution.refProps}\n {...createOptionsFor(resolution.refProps.typename)}\n db={db}\n useType={useType}\n getOptions={getOptions}\n onCreate={onCreate}\n resolveCreateEntry={resolveCreateEntry}\n />\n );\n }\n default:\n return undefined;\n }\n }\n};\n\nFormFieldDispatch.displayName = 'Form.FieldDispatch';\n\n/** The literal options, labelled by the projection's option titles where it has them. */\nconst selectOptions = (\n options: Format.Options[],\n projection: FormFieldDispatchProps['projection'],\n name: string | null,\n) => {\n const titles = projection?.getFieldProjections().find((candidate) => candidate.field.path === name)?.props.options;\n return options.map((option) => ({\n value: option,\n label: titles?.find((candidate) => candidate.id === globalThis.String(option))?.title ?? option.toString(),\n }));\n};\n\nconst renderSelectStatic =\n (options: Format.Options[], projection: FormFieldDispatchProps['projection'], name: string | null) =>\n (value: unknown) =>\n selectOptions(options, projection, name).find((candidate) => candidate.value === value)?.label ??\n globalThis.String(value ?? '');\n\n//\n// Fields\n//\n\nconst FORM_FIELDS_NAME = 'Form.Fields';\n\n/**\n * Walks the schema at `path`: one row per property, a nested group per object. Renders no element of its own, so its\n * rows are direct children of the enclosing grid. The layout DSL (`Form.Layout`) is out of the spike's scope.\n */\nexport const FormFields = ({\n path: pathProp,\n include,\n exclude,\n sort,\n filter,\n schema: schemaProp,\n layoutName = Annotation.DEFAULT_LAYOUT_NAME,\n ...props\n}: FormFieldsProps<any>) => {\n const { form, variant: _variant, testId: _testId, ...contextProps } = useFormContext(FORM_FIELDS_NAME);\n const path = useMemo(() => toPathSegments(pathProp), [typeof pathProp === 'string' ? pathProp : pathProp?.join('.')]);\n const values = useFormValues<AnyProperties>(FORM_FIELDS_NAME, path);\n const { readonly, layout, projection, ...fieldContext } = { ...contextProps, ...props };\n const schema = useMemo(() => {\n if (schemaProp) {\n return schemaProp;\n }\n if (!form.schema) {\n return undefined;\n }\n const ast = path.length ? getSchemaAtPath(form.schema.ast, path, form.values) : form.schema.ast;\n return ast ? Schema.make<Schema.Codec<any, any>>(ast) : undefined;\n // The AST at a path changes only with the discriminator value it depends on, which `values` carries.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [schemaProp, form.schema, path, values]);\n const properties = useFormFieldsProperties({ schema, values, include, exclude, filter, sort, projection });\n if ((readonly || layout === 'static') && values == null) {\n return null;\n }\n\n // A schema carrying a layout template renders by the DSL instead of one row per property.\n const layouts = schema ? Option.getOrUndefined(Annotation.FormLayoutAnnotation.get(schema)) : undefined;\n if (schema && layouts?.[layoutName] !== undefined) {\n return (\n <FormLayout\n schema={schema}\n name={layoutName}\n path={path}\n readonly={readonly}\n layout={layout}\n projection={projection}\n {...fieldContext}\n />\n );\n }\n\n return (\n <>\n {properties.map((property) => {\n const name = property.name.toString();\n return (\n <FormFieldErrorBoundary key={name} path={[...path, name]}>\n <FormFieldDispatch\n type={property.type}\n name={name}\n path={[...path, name]}\n required={!property.isOptional}\n readonly={readonly}\n layout={layout}\n projection={projection}\n {...fieldContext}\n />\n </FormFieldErrorBoundary>\n );\n })}\n </>\n );\n};\n\nFormFields.displayName = FORM_FIELDS_NAME;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { type PropsWithChildren, type ReactNode } from 'react';\n\nimport { type Format } from '@dxos/echo';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { type FormFieldLabelPlacement, type FormPresentation } from '#types';\n\nimport { useFormContext } from '../hooks/index.ts';\nimport { formatStaticValue, isEmptyValue, useFormFieldBindingAt, useFormSchemaProperty } from './field-binding.tsx';\nimport { type FormFieldBinding, FormFieldBindingProvider } from './FormFieldContext.ts';\nimport { FormFieldDispatch } from './FormFieldDispatch.tsx';\nimport { presentationFor } from './presentation.tsx';\n\nconst FORM_FIELD_NAME = 'Form.Field';\n\n/** A bound value rendered as text: what a `static` presentation shows in place of the control. */\nexport const FormStaticValue = ({ value, format }: { value: unknown; format?: Format.TypeFormat }) => (\n <Typography.Text truncate>{formatStaticValue(value, format)}</Typography.Text>\n);\n\nexport type FormFieldProps<T = any> = PropsWithChildren<{\n /** Binds the row to the form model at this path; with no children the dispatcher picks the control. */\n path?: string;\n label?: string;\n description?: string;\n error?: string;\n required?: boolean;\n readonly?: boolean;\n /** The label is text rather than a `<label>`: the row holds no single control. */\n standalone?: boolean;\n /** Read-only content after the label text, a sibling of the label so its text stays exactly `label`. */\n labelEnd?: ReactNode;\n /** `beside`: the control carries its own label (a Switch), so the row draws no header. */\n labelPlacement?: FormFieldLabelPlacement;\n presentation?: FormPresentation;\n renderStatic?: (value: T | undefined) => ReactNode;\n}>;\n\n/** The leaf row, bound (`path`) or not; same contract as the current `Form.Field`. */\nexport const FormField = <T,>({ path, children, ...props }: FormFieldProps<T>) => {\n if (path !== undefined) {\n return children === undefined ? (\n <FormBoundFieldDispatch path={path} {...props} />\n ) : (\n <FormBoundField<T> path={path} {...props}>\n {children}\n </FormBoundField>\n );\n }\n return <FormFieldRow<T> {...props}>{children}</FormFieldRow>;\n};\n\nFormField.displayName = FORM_FIELD_NAME;\n\ntype FormBoundFieldProps<T> = Omit<FormFieldProps<T>, 'path'> & { path: string };\n\nconst FormBoundField = <T,>({ path, children, ...props }: FormBoundFieldProps<T>) => {\n const property = useFormSchemaProperty(FORM_FIELD_NAME, path);\n const binding = useFormFieldBindingAt<T>(FORM_FIELD_NAME, path, property, props);\n return (\n <FormFieldRow<T>\n label={props.label ?? property?.label ?? ''}\n description={props.description ?? property?.description}\n format={property?.format}\n {...props}\n binding={binding}\n >\n {children}\n </FormFieldRow>\n );\n};\n\nconst FormBoundFieldDispatch = <T,>({ path, ...props }: FormBoundFieldProps<T>) => {\n const { form: _form, variant: _variant, testId: _testId, ...context } = useFormContext(FORM_FIELD_NAME);\n const property = useFormSchemaProperty(FORM_FIELD_NAME, path);\n if (!property) {\n return null;\n }\n const segments = SchemaEx.isJsonPath(path) ? SchemaEx.splitJsonPath(path) : [];\n return (\n <FormFieldDispatch\n {...context}\n type={property.type}\n name={String(segments[segments.length - 1])}\n label={props.label}\n path={segments}\n required={props.required ?? property.required}\n readonly={props.readonly ?? context.readonly}\n layout={props.presentation ?? context.layout}\n />\n );\n};\n\nexport type FormFieldRowProps<T = any> = Omit<FormFieldProps<T>, 'path'> & {\n format?: Format.TypeFormat;\n binding?: FormFieldBinding<T>;\n};\n\n/**\n * The row: `Field.Root` holding the header (label, `labelEnd`, error mark), the description, the control and the\n * error text. In the `settings` variant it is a bordered row of the content's two tracks (AUDIT §3.2 option 1).\n */\nexport const FormFieldRow = <T,>({\n children,\n label,\n description,\n error: errorProp,\n required: requiredProp,\n readonly: readonlyProp,\n standalone,\n labelEnd,\n labelPlacement = 'above',\n presentation: presentationProp,\n renderStatic,\n format,\n binding,\n}: FormFieldRowProps<T>) => {\n const { variant = 'default', layout } = useFormContext(FORM_FIELD_NAME);\n const settings = variant === 'settings';\n const resolved = presentationFor(presentationProp ?? binding?.presentation ?? layout);\n const error = binding?.error ?? errorProp;\n const readonly = binding?.readonly ?? readonlyProp;\n // An indeterminate value is unset only for display, not missing.\n const required = binding ? binding.required && !binding.indeterminate && isEmptyValue(binding.value) : requiredProp;\n\n let control: ReactNode = children;\n if (binding && resolved.isStatic) {\n if (binding.value == null) {\n return null;\n }\n control = renderStatic?.(binding.value) ?? <FormStaticValue value={binding.value} format={format} />;\n }\n\n // A toggle labels itself, except in a settings row, whose header column holds every label.\n const showHeader = resolved.showLabel && !!label && (labelPlacement !== 'beside' || settings);\n const row = (\n <Field.Root\n layout={settings ? 'row' : 'stack'}\n level={settings ? '+1' : undefined}\n invalid={!!error}\n required={!!required}\n readOnly={readonly}\n // Focus leaving the row (not moving between its segments, steppers or triggers) marks it touched, so controls need\n // no onBlur of their own.\n onBlur={\n binding\n ? (event) => {\n if (!(event.relatedTarget instanceof Node && event.currentTarget.contains(event.relatedTarget))) {\n binding.onBlur(event);\n }\n }\n : undefined\n }\n >\n {showHeader && (\n <Field.Header>\n {standalone || readonly ? (\n <Typography.Text truncate>{label}</Typography.Text>\n ) : (\n <Field.Label>{label}</Field.Label>\n )}\n {labelEnd}\n {error && (\n <Layout.Block>\n <Icon.Icon icon='ph--warning--regular' valence='error' label={error} />\n </Layout.Block>\n )}\n </Field.Header>\n )}\n {settings && description && <Field.HelperText>{description}</Field.HelperText>}\n {control}\n {resolved.showError && error && <Field.ErrorText>{error}</Field.ErrorText>}\n </Field.Root>\n );\n\n return binding ? <FormFieldBindingProvider {...binding}>{row}</FormFieldBindingProvider> : row;\n};\n\nFormFieldRow.displayName = 'Form.FieldRow';\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { type PropsWithChildren, forwardRef, useRef } from 'react';\n\nimport { useComposedRefs } from '@dxos/react-hooks';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Dialog from '@dxos/react-ui/Dialog';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Panel from '@dxos/react-ui/Panel';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as SystemButton from '@dxos/react-ui/SystemButton';\nimport * as Util from '@dxos/react-ui/Util';\n\nimport { translationKey } from '#translations';\n\nimport { useFormContext, useKeyHandler } from '../hooks/index.ts';\nimport { FormField } from './FormField.tsx';\nimport { FormFields } from './FormFieldDispatch.tsx';\nimport { FormFieldSet } from './FormFieldSet.tsx';\nimport { FormLayoutController } from './FormLayout.tsx';\nimport { FormRoot, type FormRootProps } from './FormRoot.tsx';\n\n/** The settings variant's two tracks (AUDIT §3.2 option 1): label and description, then the control. */\nexport const SETTINGS_COLUMNS = 'minmax(0, 1fr) [control] minmax(0, 1fr)';\n\n//\n// Viewport\n//\n\nexport type FormViewportProps = PropsWithChildren<{\n /**\n * Fill the parent and scroll: the form becomes its own pane (a `Panel` whose Body is a ScrollArea around the\n * gutter Container), so it is sized, collapses its rails against its own width and hosts the scrollbar in its end\n * rail. A form already inside a scrolling gutter Container needs no Viewport.\n */\n scroll?: boolean;\n /** The pane's size when `scroll`; otherwise the form inherits its host's. */\n size?: Panel.RootProps['size'];\n /** The form keeps the reading width (`document`, the default), centred in a wider host; `full` spans the host. */\n width?: 'document' | 'full';\n gutter?: Layout.Gutter;\n}>;\n\n/**\n * The gutter Container that owns the form's rails; with `scroll`, the Body of a pane of its own. Composable, so a\n * form component can be the `asChild` child of a host that merges its layout props and ref onto it. The gutter defaults\n * to the host's: a panel's (`sm`, the form inset) or a dialog or popover body's (`inherit`, joining its rails), else `sm`.\n */\nexport const FormViewport = Util.composable<HTMLDivElement, FormViewportProps>(\n ({ children, scroll, size, width = 'document', gutter, ...props }, forwardedRef) => {\n const defaultGutter = Layout.useDefaultGutter();\n const documentWidth = width === 'document' ? width : undefined;\n return scroll ? (\n <Panel.Root\n {...props}\n size={size}\n width={documentWidth}\n gutter={gutter === 'inherit' ? undefined : gutter}\n ref={forwardedRef}\n >\n <Panel.Body asChild>\n <ScrollArea.Root>\n <ScrollArea.Viewport asChild>\n {/* The block inset keeps the last section off the pane's bottom edge when scrolled to the end. */}\n <Layout.Container padBlock>{children}</Layout.Container>\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Panel.Body>\n </Panel.Root>\n ) : (\n <Layout.Container {...props} gutter={gutter ?? defaultGutter ?? 'sm'} width={documentWidth} ref={forwardedRef}>\n {children}\n </Layout.Container>\n );\n },\n);\n\nFormViewport.displayName = 'Form.Viewport';\n\n//\n// Content\n//\n\nexport type FormContentProps = PropsWithChildren<{}>;\n\n/**\n * The `form` element: a subgrid of its host, or in the `settings` variant a fresh template of two tracks that every\n * settings row and section below it shares. Forwards its ref so a consumer can scope its own key handling to the form.\n */\nexport const FormContent = forwardRef<HTMLDivElement, FormContentProps>(({ children }, forwardedRef) => {\n const { form, readonly, testId, variant } = useFormContext('Form.Content');\n const localRef = useRef<HTMLDivElement>(null);\n const ref = useComposedRefs(forwardedRef, localRef);\n useKeyHandler(localRef, form, { readonly });\n const settings = variant === 'settings';\n // A settings form is a reading-width column of its own tracks (the current Form's `dx-document` settings content).\n return (\n <Layout.Container\n role='form'\n gutter={settings ? 'none' : 'inherit'}\n width={settings ? 'document' : undefined}\n gap={settings ? 'lg' : 'sm'}\n columns={settings ? SETTINGS_COLUMNS : undefined}\n data-testid={testId}\n ref={ref}\n >\n {children}\n </Layout.Container>\n );\n});\n\nFormContent.displayName = 'Form.Content';\n\n//\n// Actions\n//\n\nexport type FormActionsProps = {\n submitLabel?: string;\n submitIcon?: string;\n submitDisabled?: boolean;\n};\n\nexport const FormActions = ({ submitLabel, submitDisabled }: FormActionsProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const {\n form: { canSave, onSave, onCancel },\n readonly,\n layout,\n } = useFormContext('Form.Actions');\n if (readonly || layout === 'static') {\n return null;\n }\n\n return (\n <Button.Group justify='end'>\n {onCancel && (\n <SystemButton.Cancel\n iconOnly={false}\n label={t('cancel-button.label')}\n onClick={onCancel}\n data-testid='cancel-button'\n // Inside a dialog this claims the initial focus, so a reflexive Enter dismisses rather than commits.\n {...{ [Dialog.DIALOG_AUTOFOCUS_ATTRIBUTE]: '' }}\n />\n )}\n {onSave && (\n <SystemButton.Save\n iconOnly={false}\n type='submit'\n label={submitLabel ?? t('save-button.label')}\n disabled={!canSave || submitDisabled}\n onClick={() => onSave()}\n data-testid='save-button'\n />\n )}\n </Button.Group>\n );\n};\n\nFormActions.displayName = 'Form.Actions';\n\n//\n// Submit\n//\n\nexport type FormSubmitProps = {\n label?: string;\n disabled?: boolean;\n /** Replaces Save's check, for a submit that is not a save (e.g. send). */\n icon?: string;\n /** Spins the icon while the submission is in flight. */\n busy?: boolean;\n};\n\nexport const FormSubmit = ({ label, disabled, icon, busy }: FormSubmitProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const {\n form: { canSave, onSave },\n readonly,\n layout,\n } = useFormContext('Form.Submit');\n if (readonly || layout === 'static') {\n return null;\n }\n\n const buttonProps = {\n 'type': 'submit',\n 'label': label ?? t('save-button.label'),\n 'disabled': disabled ?? !canSave,\n 'onClick': () => onSave(),\n 'data-testid': 'save-button',\n } as const;\n\n return (\n <Button.Group fill>\n {icon || busy ? (\n <Button.Root {...buttonProps} variant='primary' icon={icon ?? 'ph--check--regular'} spin={busy} />\n ) : (\n <SystemButton.Save {...buttonProps} iconOnly={false} />\n )}\n </Button.Group>\n );\n};\n\nFormSubmit.displayName = 'Form.Submit';\n\n//\n// ErrorText\n//\n\nexport const FormErrorText = ({ children }: PropsWithChildren) =>\n children ? (\n <Field.Root invalid>\n <Field.ErrorText data-testid='form.error'>{children}</Field.ErrorText>\n </Field.Root>\n ) : null;\n\nFormErrorText.displayName = 'Form.ErrorText';\n\n/** The `Form` namespace of `@dxos/react-ui-form`, rendered with the `Next` namespace of `@dxos/react-ui`; `Root` is the shared one. */\nexport const Form = {\n Root: FormRoot,\n Viewport: FormViewport,\n Content: FormContent,\n FieldSet: FormFieldSet,\n Fields: FormFields,\n Layout: FormLayoutController,\n Field: FormField,\n Actions: FormActions,\n Submit: FormSubmit,\n ErrorText: FormErrorText,\n};\n\nexport type { FormRootProps };\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport type * as Schema from 'effect/Schema';\nimport React, { type PropsWithChildren, useCallback, useMemo } from 'react';\n\nimport { type Database, Filter, Obj, Ref, Tag, Type } from '@dxos/echo';\nimport { useObject, useQuery, useType } from '@dxos/echo-react';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { invariant } from '@dxos/invariant';\nimport * as Util from '@dxos/react-ui/Util';\nimport { FactoryAnnotation } from '@dxos/schema';\n\nimport { translationKey } from '#translations';\nimport { type CreateOptions, type FormFieldMap, type RefFieldDataProps } from '#types';\n\nimport { omitId } from '../util/index.ts';\nimport { HueField } from './fields/index.ts';\nimport { Form } from './Form.tsx';\nimport { FormField } from './FormField.tsx';\nimport { META_TAGS_KEY, partitionMetaTags, withMetaTags } from './meta-tags.ts';\n\n/** The tags row's create option: `Add tag “{query}”`. */\nconst CREATE_TAG_LABEL: CreateOptions['createOptionLabel'] = ['add-tag-query.label', { ns: translationKey }];\n\n/** The create form for a tag (the meta-tags row's create target): its `hue` as a hue Select. */\nconst createFieldMap: FormFieldMap = {\n hue: (props) => (\n <FormField path={props.jsonPath} label={props.label} presentation={props.presentation}>\n <HueField {...props} />\n </FormField>\n ),\n};\n\n/** The form's values: the object's properties, and its editable meta tags (an array of Tag refs, per `withMetaTags`). */\ntype ObjectFormValues = { [META_TAGS_KEY]?: readonly Ref.Ref<Tag.Tag>[] } & Record<string, unknown>;\n\ntype ObjectFormModelOptions = {\n object: Obj.Unknown;\n /** The object's snapshot; a fresh value whenever the object changes. */\n snapshot: object;\n db: Database.Database | undefined;\n};\n\n/**\n * The form model shared by `ObjectForm` and `ObjectProperties`: the object's values with its editable meta tags under\n * {@link META_TAGS_KEY}, a change handler writing changed paths (and tags) back through `Obj.update`, and a create\n * handler that adds a ref field's new target to the object's database.\n */\nconst useObjectFormModel = ({ object, snapshot, db }: ObjectFormModelOptions) => {\n const meta = Obj.getMeta(object);\n // Provider-owned tags are held out of the form and written back untouched (see `partitionMetaTags`).\n const spaceTags = useQuery(db, Filter.type(Tag.Tag));\n const { editable: tags, preserved: preservedTags } = useMemo(\n () => partitionMetaTags([...meta.tags], spaceTags),\n [meta.tags, spaceTags],\n );\n const values = useMemo(() => ({ [META_TAGS_KEY]: tags, ...snapshot }), [snapshot, tags]);\n\n // A type whose structure `Obj.make` alone cannot produce (a required backing ref) declares a `FactoryAnnotation`.\n const handleCreate = useCallback(\n (type: Type.AnyEntity, values: any): Obj.Unknown => {\n invariant(db);\n invariant(Type.isObject(type));\n const factory = Option.getOrUndefined(FactoryAnnotation.get(Type.getSchema(type)));\n const made = factory ? factory(values) : Obj.make(type, values);\n invariant(Obj.isObject(made));\n const added = db.add(made);\n invariant(Obj.isObject(added));\n return added;\n },\n [db],\n );\n\n const handleChange = useCallback(\n (\n { [META_TAGS_KEY]: metaTags, ...values }: ObjectFormValues,\n { isValid, changed }: { isValid: boolean; changed: Record<SchemaEx.JsonPath, boolean> },\n ) => {\n if (!isValid) {\n return;\n }\n\n const changedPaths = Object.keys(changed)\n .filter(SchemaEx.isJsonPath)\n .filter((path) => changed[path]);\n const isTagPath = (path: SchemaEx.JsonPath) => SchemaEx.splitJsonPath(path)[0] === META_TAGS_KEY;\n if (changedPaths.some(isTagPath)) {\n Obj.update(object, (object) => {\n // A copy, so later in-place form edits stay outside `Obj.update`; this replaces `tags`, so restore the rest.\n Obj.getMeta(object).tags = [...preservedTags, ...(metaTags ?? [])];\n });\n }\n\n const propertyPaths = changedPaths.filter((path) => !isTagPath(path));\n if (propertyPaths.length > 0) {\n Obj.update(object, (object) => {\n for (const path of propertyPaths) {\n Obj.setValue(object, SchemaEx.splitJsonPath(path), SchemaEx.getValue(values, path));\n }\n });\n }\n },\n [object, preservedTags],\n );\n\n return { values, handleCreate, handleChange };\n};\n\nexport type ObjectFormProps = {\n type: Type.AnyEntity;\n object: Obj.Unknown;\n /**\n * Overrides the rendered fields, e.g. a projection of `type`'s schema; values are still read from and written to\n * `object` by path. Defaults to `type`'s schema.\n */\n schema?: Schema.Codec<any, any>;\n /** Render the meta-tags field. Defaults to `true`. */\n showTags?: boolean;\n};\n\n/** An object's properties (and meta tags) as a next Form in its host's grid, writing each change back. */\nexport const ObjectForm = ({ object, type, schema, showTags = true }: ObjectFormProps) => {\n const db = Obj.getDatabase(object);\n // ECHO reactivity is atom-based: reading the raw object in render does not subscribe, so subscribe explicitly.\n const [snapshot] = useObject(object);\n const { values, handleCreate, handleChange } = useObjectFormModel({ object, snapshot, db });\n const formSchema = useMemo(() => {\n const base = schema ?? Type.getSchema(type);\n return showTags ? withMetaTags(base) : omitId(base);\n }, [schema, type, showTags]);\n\n return (\n <Form.Root\n schema={formSchema}\n values={values}\n db={db}\n createTypename={Type.getTypename(Tag.Tag)}\n createOptionLabel={CREATE_TAG_LABEL}\n createOptionIcon='ph--tag--regular'\n createInitialValuePath='label'\n createFieldMap={createFieldMap}\n onValuesChanged={handleChange}\n onCreate={handleCreate}\n >\n <Form.Content>\n <Form.Fields />\n </Form.Content>\n </Form.Root>\n );\n};\n\nexport type ObjectPropertiesProps = PropsWithChildren<\n { object: Obj.Unknown } & Pick<RefFieldDataProps, 'getCreateDefaults' | 'resolveCreateEntry'>\n>;\n\n/**\n * An object's properties pane: its type's fields and meta tags in a scrolling form, then `children` (e.g. a plugin's\n * extra rows) in a set of their own. Composable, so a host's `Panel.Body asChild` merges its slot props and ref onto\n * the form's viewport.\n */\nexport const ObjectProperties = Util.composable<HTMLDivElement, ObjectPropertiesProps>(\n ({ children, object, getCreateDefaults, resolveCreateEntry, ...props }, forwardedRef) => {\n const db = Obj.getDatabase(object);\n const [snapshot] = useObject(object);\n const { values, handleCreate, handleChange } = useObjectFormModel({ object, snapshot, db });\n // `Obj.getType` misses database-registered (dynamic) schemas, which `useType` resolves by the stored type URI.\n const registered = useType(db, Obj.getTypeURI(object));\n const type = Obj.getType(object) ?? registered;\n const formSchema = useMemo(() => (type ? withMetaTags(Type.getSchema(type)) : undefined), [type]);\n if (!formSchema) {\n return null;\n }\n\n return (\n <Form.Root\n schema={formSchema}\n values={values}\n db={db}\n createTypename={Type.getTypename(Tag.Tag)}\n createOptionLabel={CREATE_TAG_LABEL}\n createOptionIcon='ph--tag--regular'\n createInitialValuePath='label'\n createFieldMap={createFieldMap}\n onValuesChanged={handleChange}\n onCreate={handleCreate}\n getCreateDefaults={getCreateDefaults}\n resolveCreateEntry={resolveCreateEntry}\n >\n <Form.Viewport {...props} scroll ref={forwardedRef}>\n <Form.Content>\n <Form.Fields />\n {children && <Form.FieldSet>{children}</Form.FieldSet>}\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n },\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport {\n EditorState,\n type Extension,\n RangeSetBuilder,\n StateEffect,\n StateField,\n type TransactionSpec,\n} from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, WidgetType } from '@codemirror/view';\n\nimport { Domino } from '@dxos/ui';\nimport { getHashHue, getStyles, mx } from '@dxos/ui-theme';\n\n/**\n * Display info for a resolved object reference.\n */\nexport type RefInfo = {\n label: string;\n hue?: string;\n};\n\n/**\n * Content model:\n * - `'ref'`: whitespace-separated tokens; `@<id>` references to existing objects (and raw tokens\n * accepted by the pluggable {@link RefEditorExtensionOptions.match} regexp).\n * - `'email'`: comma-separated RFC 5322 mailboxes (`Name <email>` or bare `email`); the comma\n * separators are consumed into the atomic tags so they are not visible.\n */\nexport type RefEditorMode = 'ref' | 'email';\n\n/** Matches an object reference token (`@<object id>`). */\nexport const REF_REGEX = /^@([A-Za-z0-9]+)$/;\n\n/** Matches a well-formed email address token. */\nexport const EMAIL_REGEX = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$/;\n\n/** Matches an RFC 5322 name-addr (`Name <email>`); group 1 = display name, group 2 = addr-spec. */\nexport const NAME_ADDR_REGEX = /^(.*?)\\s*<([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})>$/;\n\n/** Formats an RFC 5322 mailbox (`Name <email>`). */\nexport const formatMailbox = (name: string | undefined, email: string): string => (name ? `${name} <${email}>` : email);\n\n/**\n * Effect dispatched when reference data changes out-of-band (e.g. objects finish loading) so that\n * already-rendered reference decorations re-resolve without a document change.\n */\nexport const refEditorRedecorate = StateEffect.define<null>();\n\nexport type RefEditorExtensionOptions = {\n mode?: RefEditorMode;\n /** Resolve an object id referenced as `@<id>` to display info. */\n getRef?: (id: string) => RefInfo | undefined;\n /** Pluggable raw-token matcher (e.g. {@link EMAIL_REGEX}); matching tokens render as neutral tags. */\n match?: RegExp;\n colorize?: boolean;\n};\n\n/**\n * CodeMirror extension rendering reference-editor tokens as tags. Tags are atomic: the cursor\n * cannot enter them and deletion removes the whole token.\n * - `'ref'` mode: `@<id>` references resolve to the object's label (via\n * {@link RefEditorExtensionOptions.getRef}); tokens accepted by the pluggable `match` regexp\n * render as neutral tags.\n * - `'email'` mode: RFC 5322 mailboxes render as tags labelled with the display name (falling\n * back to the address); the trailing comma separator is hidden inside the tag's atomic range.\n */\nexport const refEditor = ({ mode = 'ref', getRef, match, colorize }: RefEditorExtensionOptions = {}): Extension => {\n // Forward declaration: the field is defined below but the widgets' delete affordance (built inside\n // the field's `create`/`update`) needs to read it back at click time.\n let decoField: StateField<DecorationSet>;\n\n /** Delete the tag whose delete affordance (`node`) was clicked, keeping the delimited list well-formed. */\n const removeToken = (view: EditorView, node: HTMLElement) => {\n // Tags render in document order, so the button's index among all delete affordances selects the\n // matching decoration. (A replace-widget's inner DOM has no reliable document position to query.)\n const index = [...view.contentDOM.querySelectorAll('button[aria-label=\"Remove\"]')].indexOf(node);\n if (index < 0) {\n return;\n }\n const cursor = view.state.field(decoField).iter();\n let range: { from: number; to: number } | undefined;\n for (let current = 0; cursor.value; current++, cursor.next()) {\n if (current === index) {\n range = { from: cursor.from, to: cursor.to };\n break;\n }\n }\n if (!range) {\n return;\n }\n\n const doc = view.state.doc.toString();\n let { from } = range;\n const { to } = range;\n if (mode === 'email' && !/,\\s*$/.test(doc.slice(from, to))) {\n // A last segment carries no trailing \", \"; drop the one left dangling by the previous segment.\n const dangling = doc.slice(0, from).match(/,\\s*$/);\n if (dangling) {\n from -= dangling[0].length;\n }\n }\n view.dispatch({ changes: { from, to }, selection: { anchor: from } });\n };\n\n const buildRefDecorations = (state: EditorState) => {\n const deco = new RangeSetBuilder<Decoration>();\n const text = state.doc.toString();\n const tokenRegex = /\\S+/g;\n let tokenMatch: RegExpExecArray | null;\n while ((tokenMatch = tokenRegex.exec(text))) {\n const token = tokenMatch[0];\n const from = tokenMatch.index;\n const to = from + token.length;\n\n const refMatch = token.match(REF_REGEX);\n if (refMatch) {\n const ref = getRef?.(refMatch[1]);\n if (ref) {\n deco.add(\n from,\n to,\n Decoration.replace({\n widget: new RefWidget(\n ref.label,\n ref.hue ?? (colorize ? getHashHue(refMatch[1]) : undefined),\n removeToken,\n ),\n }),\n );\n }\n continue;\n }\n\n if (match?.test(token)) {\n deco.add(\n from,\n to,\n Decoration.replace({\n widget: new RefWidget(token, undefined, removeToken),\n }),\n );\n }\n }\n\n return deco.finish();\n };\n\n const buildEmailDecorations = (state: EditorState) => {\n const addrRegex = match ?? EMAIL_REGEX;\n const deco = new RangeSetBuilder<Decoration>();\n const text = state.doc.toString();\n // Segments are comma-separated; a segment's atomic range includes its trailing comma (and\n // following whitespace) so the separator never renders.\n const segmentRegex = /[^,]+(?:,\\s*)?|,\\s*/g;\n let segmentMatch: RegExpExecArray | null;\n while ((segmentMatch = segmentRegex.exec(text))) {\n const segment = segmentMatch[0];\n const commaIndex = segment.indexOf(',');\n const content = (commaIndex === -1 ? segment : segment.slice(0, commaIndex)).trim();\n if (!content) {\n continue;\n }\n // Only tag committed segments (those with a trailing comma). The final segment being typed has\n // no comma yet, so a valid-looking address stays plain text until the user commits it (comma,\n // space, or Enter) — otherwise the tag would pop in mid-typing.\n if (commaIndex === -1) {\n continue;\n }\n const leading = segment.length - segment.trimStart().length;\n const from = segmentMatch.index + leading;\n const to = segmentMatch.index + segment.length;\n\n const nameAddr = content.match(NAME_ADDR_REGEX);\n if (nameAddr) {\n deco.add(\n from,\n to,\n Decoration.replace({\n widget: new RefWidget(\n nameAddr[1] || nameAddr[2],\n colorize ? getHashHue(nameAddr[2]) : undefined,\n removeToken,\n ),\n }),\n );\n } else if (addrRegex.test(content)) {\n deco.add(\n from,\n to,\n Decoration.replace({\n widget: new RefWidget(content, undefined, removeToken),\n }),\n );\n }\n }\n\n return deco.finish();\n };\n\n const buildDecorations = mode === 'email' ? buildEmailDecorations : buildRefDecorations;\n\n decoField = StateField.define<DecorationSet>({\n create: (state) => buildDecorations(state),\n update: (deco, tr) => {\n if (tr.docChanged || tr.effects.some((effect) => effect.is(refEditorRedecorate))) {\n return buildDecorations(tr.state);\n }\n\n return deco;\n },\n provide: (field) => [\n EditorView.decorations.from(field),\n // Every tag is atomic: arrow motion skips the whole range and deletion removes the whole token.\n EditorView.atomicRanges.of((view) => view.state.field(field)),\n ],\n });\n\n const separator = mode === 'email' ? ', ' : ' ';\n\n // Typing immediately before a tag would otherwise re-tokenize into it (e.g. `x` + `bob@e.com`\n // parses as the single email `xbob@e.com`); inject the delimiter after the inserted text so the\n // new characters begin their own token (and open a fresh completion) rather than joining the tag.\n const separatorFilter = EditorState.transactionFilter.of((tr) => {\n if (!tr.docChanged || !tr.isUserEvent('input')) {\n return tr;\n }\n const tags = tr.startState.field(decoField, false);\n if (!tags) {\n return tr;\n }\n\n let extra: TransactionSpec | undefined;\n tr.changes.iterChanges((fromA, toA, _fromB, toB, inserted) => {\n if (extra || fromA !== toA) {\n return;\n }\n const text = inserted.toString();\n if (!text || /[\\s,]$/.test(text)) {\n return;\n }\n // A tag starting exactly at the insertion point means the new text abuts it.\n let abutsTag = false;\n for (const cursor = tags.iter(); cursor.value; cursor.next()) {\n if (cursor.from === fromA) {\n abutsTag = true;\n break;\n }\n if (cursor.from > fromA) {\n break;\n }\n }\n if (abutsTag) {\n extra = { changes: { from: toB, insert: separator }, sequential: true, selection: { anchor: toB } };\n }\n });\n\n return extra ? [tr, extra] : tr;\n });\n\n return [styles, decoField, separatorFilter];\n};\n\n/** Delete an atomic tag given the DOM node of its widget. */\ntype RemoveToken = (view: EditorView, node: HTMLElement) => void;\n\n/**\n * The outer span vertically aligns the tag with the surrounding line and adds a trailing gap so\n * adjacent tags don't touch. The inner span carries the border; `overflow-hidden` clips the child\n * fills to its radius (a square-cornered fill otherwise peeks past the rounded border).\n */\nconst container = (classNames: string, ...children: Domino<HTMLElement>[]) => {\n const inner = Domino.of('span')\n .classNames(mx('inline-flex items-stretch border rounded-xs overflow-hidden', classNames))\n .append(...children);\n return Domino.of('span').classNames('inline-flex align-middle pe-1').append(inner).root;\n};\n\n/** Trailing `x` affordance that deletes the tag it belongs to. */\nconst deleteButton = (view: EditorView, remove: RemoveToken) => {\n const button = Domino.of('button')\n .classNames('flex items-center px-1 text-fg-muted hover:text-error cursor-pointer')\n .attributes({ 'type': 'button', 'aria-label': 'Remove' })\n .append(Domino.svg('ph--x--bold').classNames('shrink-0 w-3.5 h-3.5'))\n // `mousedown` + preventDefault so clicking the affordance does not move the editor selection.\n .on('mousedown', (event) => {\n event.preventDefault();\n remove(view, button.root);\n });\n return button;\n};\n\n/**\n * Resolved reference (object reference or RFC 5322 mailbox), rendered as the object's label with a\n * trailing delete affordance.\n */\nclass RefWidget extends WidgetType {\n constructor(\n private readonly _label: string,\n private readonly _hue: string | undefined,\n private readonly _remove: RemoveToken,\n ) {\n super();\n }\n\n override eq(other: this) {\n return this._label === other._label && this._hue === other._hue;\n }\n\n override toDOM(view: EditorView) {\n const styles = this._hue ? getStyles(this._hue) : undefined;\n return container(\n mx('border-separator rounded-sm', styles?.border),\n Domino.of('span').classNames('flex items-center ps-2 pe-1').text(this._label),\n deleteButton(view, this._remove),\n );\n }\n}\n\nconst styles = EditorView.theme({\n // Single-line editor: lay the line out as a centered flex row so text runs and the atomic tag\n // widgets share a vertical center (avoids `vertical-align` baseline guesswork between the two).\n '.cm-line': {\n padding: '0',\n display: 'flex',\n alignItems: 'center',\n },\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Extension, Prec } from '@codemirror/state';\nimport { type EditorView } from '@codemirror/view';\nimport { type ForwardedRef, useCallback, useEffect, useMemo, useRef } from 'react';\n\nimport { type Database, Filter, Obj, type Type } from '@dxos/echo';\nimport { useQuery } from '@dxos/echo-react';\nimport {\n type EditorController,\n type EditorMenuProviderProps,\n type EditorViewProps,\n type UseEditorMenuProps,\n} from '@dxos/react-ui-editor';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport type * as Util from '@dxos/react-ui/Util';\nimport { createBasicExtensions, createThemeExtensions, insertAtCursor, keymap } from '@dxos/ui-editor';\nimport { getHashHue } from '@dxos/ui-theme';\n\nimport { translationKey } from '#translations';\n\nimport {\n EMAIL_REGEX,\n NAME_ADDR_REGEX,\n type RefEditorMode,\n type RefInfo,\n formatMailbox,\n refEditor,\n refEditorRedecorate,\n} from './ref-editor-extension.ts';\n\nexport type RefEditorProps = Util.ThemedClassName<\n {\n /** Database queried for objects of {@link RefEditorProps.type}. */\n db?: Database.Database;\n /** ECHO object type whose instances are offered in the typeahead and referenced as `@<id>`. */\n type: Type.AnyObj;\n value?: string;\n readonly?: boolean;\n /**\n * Content model:\n * - `'ref'` (default): the picker only matches existing objects; selection inserts an\n * `@<id>` reference (raw tokens accepted by `match` are also allowed).\n * - `'email'`: the picker shows one item per (object, value) pair and selection captures the\n * value; the content is an RFC 5322 mailbox list (`Name <email>, ...`) with the comma\n * separators hidden inside the tags.\n */\n mode?: RefEditorMode;\n /** Pluggable raw-token matcher (e.g. {@link EMAIL_REGEX}); matching tokens are accepted as values. */\n match?: RegExp;\n /** Display label for an object; defaults to `Obj.getLabel` falling back to the id. */\n getLabel?: (object: Obj.Unknown) => string;\n /** Values an object can be captured as in `'email'` mode (e.g. a person's email addresses). */\n getValues?: (object: Obj.Unknown) => readonly string[];\n /** Menu item icon. */\n icon?: string;\n /** Already-translated placeholder; defaults to a generic hint. */\n placeholder?: string;\n /** Open the typeahead while typing (the `@` trigger remains available but is not required). */\n activateOnTyping?: boolean;\n } & Omit<EditorViewProps, 'initialValue'> &\n Pick<EditorMenuProviderProps, 'numItems'>\n>;\n\n/** The RefEditor's behaviour, without its chrome: the props for an `Editor.Root` around the caller's `Editor.View`. */\nexport type RefEditorOptions = Omit<\n RefEditorProps,\n 'classNames' | 'value' | keyof Omit<EditorViewProps, 'initialValue'>\n>;\n\n/**\n * The typeahead, decorations and keymap of a {@link RefEditor} as `Editor.Root` props, so a Next control can frame the\n * same editor (`ControlFrame`) instead of the current input chrome.\n */\nexport const useRefEditor = (\n {\n db,\n type,\n readonly,\n mode = 'ref',\n match,\n getLabel,\n getValues,\n icon = 'ph--link--regular',\n placeholder: placeholderProp,\n activateOnTyping,\n numItems = 8,\n }: RefEditorOptions,\n forwardedRef: ForwardedRef<EditorController>,\n) => {\n const { t } = Hooks.useTranslation(translationKey);\n const themeMode = Hooks.useThemeMode();\n const getObjectLabel = useCallback(\n (object: Obj.Unknown) => getLabel?.(object) ?? Obj.getLabel(object) ?? object.id,\n [getLabel],\n );\n\n // Reads go through a ref so the decoration extension stays stable: recreating extensions\n // destroys and recreates the editor, which would blur the input on data changes.\n const filter = useMemo(() => Filter.type(type), [type]);\n const objects = useQuery(db, filter);\n const refs = useMemo(\n () =>\n new Map<string, RefInfo>(\n objects.map((object) => [object.id, { label: getObjectLabel(object), hue: getHashHue(object.id) }]),\n ),\n [objects, getObjectLabel],\n );\n const refsRef = useRef(refs);\n refsRef.current = refs;\n\n // Internal controller (merged with the forwarded ref) used to re-resolve reference\n // decorations when object data changes after the document was rendered.\n const controllerRef = useRef<EditorController | null>(null);\n const composedRef = useCallback(\n (controller: EditorController | null) => {\n controllerRef.current = controller;\n if (typeof forwardedRef === 'function') {\n forwardedRef(controller);\n } else if (forwardedRef) {\n forwardedRef.current = controller;\n }\n },\n [forwardedRef],\n );\n useEffect(() => {\n controllerRef.current?.view?.dispatch({ effects: refEditorRedecorate.of(null) });\n }, [refs]);\n\n const getMenu = useCallback<NonNullable<UseEditorMenuProps['getMenu']>>(\n async ({ text }) => {\n // With `activateOnTyping` (no `@` trigger) an empty query would otherwise match every object\n // and anchor the popover at the viewport origin (no range to position against). Show nothing\n // until the user types. An explicit `@` trigger still browses (its `text` is '@', not empty).\n if (!text) {\n return [];\n }\n const query = text.replace(/^@/, '').toLowerCase();\n const matchesQuery = (object: Obj.Unknown) =>\n !query ||\n getObjectLabel(object).toLowerCase().includes(query) ||\n (getValues?.(object) ?? []).some((entry) => entry.toLowerCase().includes(query));\n\n if (mode === 'email') {\n // One item per (object, value) pair; selection captures the value as an RFC 5322 mailbox.\n const mailboxes = objects\n .flatMap((object) => (getValues?.(object) ?? []).map((entry) => ({ object, entry })))\n .filter(\n ({ object, entry }) =>\n !query || getObjectLabel(object).toLowerCase().includes(query) || entry.toLowerCase().includes(query),\n );\n\n return [\n {\n id: 'mailboxes',\n items: mailboxes.slice(0, numItems * 2).map(({ object, entry }) => ({\n id: `${object.id}-${entry}`,\n label: `${getObjectLabel(object)} (${entry})`,\n icon,\n onSelect: ({ view, head }: { view: EditorView; head: number }) =>\n insertMailbox(view, head, formatMailbox(getObjectLabel(object), entry)),\n })),\n },\n ];\n }\n\n // 'ref' mode: only match existing objects.\n return [\n {\n id: 'refs',\n items: objects\n .filter(matchesQuery)\n .slice(0, numItems * 2)\n .map((object) => {\n const label = getObjectLabel(object);\n const detail = getValues?.(object)?.[0];\n return {\n id: object.id,\n label: detail && detail !== label ? `${label} (${detail})` : label,\n icon,\n onSelect: ({ view, head }: { view: EditorView; head: number }) =>\n insertAtCursor(view, head, `@${object.id} `),\n };\n }),\n },\n ];\n },\n [objects, numItems, mode, icon, getObjectLabel, getValues],\n );\n\n // NOTE: The placeholder is supplied via the popover (Editor.Root) so the trigger hint and the\n // empty-state hint are a single message; a second basic-extension placeholder would stack with it.\n // Must be referentially stable: the menu extension is memoized on it, and a new extension\n // identity destroys and recreates the editor on every keystroke.\n const placeholder = useMemo(\n () => ({\n content: placeholderProp ?? t(activateOnTyping ? 'ref-editor-auto.placeholder' : 'ref-editor.placeholder'),\n focusOnly: false,\n }),\n [t, placeholderProp, activateOnTyping],\n );\n\n const extensions = useMemo<Extension[]>(\n () => [\n createBasicExtensions({ readOnly: readonly, lineWrapping: false }),\n createThemeExtensions({\n themeMode,\n slots: {\n editor: {\n className: 'w-full',\n },\n scroller: {\n className: 'scrollbar-none',\n },\n },\n }),\n refEditor({ mode, match, getRef: (id) => refsRef.current.get(id) }),\n Prec.highest(\n keymap.of([\n {\n key: 'Enter',\n // Commit the in-progress token when it matches (insert the mode's separator, the\n // same gesture as typing it); always consume the key (single-line input).\n run: (view) => {\n const { head } = view.state.selection.main;\n const line = view.state.doc.lineAt(head);\n const before = line.text.slice(0, head - line.from);\n if (mode === 'email') {\n const segment = before.slice(before.lastIndexOf(',') + 1).trim();\n if (NAME_ADDR_REGEX.test(segment) || (match ?? EMAIL_REGEX).test(segment)) {\n insertAtCursor(view, head, ', ');\n }\n } else {\n const token = before.slice(before.search(/\\S+$/));\n if (token && match?.test(token)) {\n insertAtCursor(view, head, ' ');\n }\n }\n return true;\n },\n },\n {\n key: 'Space',\n // In email mode, a space after a bare address commits it (a tag only forms once\n // committed). A partial `Name <…` segment still needs spaces, so only commit — and\n // consume the space — when the whole in-progress segment is an address.\n run: (view) => {\n if (mode !== 'email') {\n return false;\n }\n const { head } = view.state.selection.main;\n const line = view.state.doc.lineAt(head);\n const before = line.text.slice(0, head - line.from);\n const segment = before.slice(before.lastIndexOf(',') + 1).trim();\n if ((match ?? EMAIL_REGEX).test(segment)) {\n insertAtCursor(view, head, ', ');\n return true;\n }\n return false;\n },\n },\n ]),\n ),\n ],\n [readonly, themeMode, mode, match],\n );\n\n return {\n extensions,\n numItems,\n trigger: '@',\n activateOnTyping,\n placeholder,\n // The menu owns its own matching (labels AND values); the built-in label filter would\n // drop value-matched objects whose label doesn't start with the query.\n filter: false,\n getMenu,\n ref: composedRef,\n };\n};\n\n/**\n * Insert an RFC 5322 mailbox, replacing the in-progress segment (anything typed after the last\n * comma — multi-word queries can leave words outside the popover's completion range).\n */\nconst insertMailbox = (view: EditorView, head: number, mailbox: string) => {\n const line = view.state.doc.lineAt(head);\n const before = line.text.slice(0, head - line.from);\n const lastComma = before.lastIndexOf(',');\n const from = line.from + (lastComma === -1 ? 0 : lastComma + 1);\n const insert = `${lastComma === -1 ? '' : ' '}${mailbox}, `;\n view.dispatch({\n changes: { from, to: head, insert },\n selection: { anchor: from + insert.length, head: from + insert.length },\n });\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { forwardRef } from 'react';\n\nimport { Editor, type EditorController, type EditorViewProps } from '@dxos/react-ui-editor';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type RefEditorOptions, useRefEditor } from './useRefEditor.ts';\n\nexport type RefEditorProps = RefEditorOptions &\n Pick<EditorViewProps, 'onChange' | 'autoFocus' | 'extensions'> & {\n 'value'?: string;\n /** Leading content inside the frame (e.g. an Icon). */\n 'start'?: Input.FrameProps['start'];\n /** Trailing content inside the frame (e.g. icon-only Buttons). */\n 'end'?: Input.FrameProps['end'];\n 'data-testid'?: string;\n };\n\n/**\n * The single-line reference editor (see the current `RefEditor`) in a `ControlFrame`: the frame draws the control's\n * well, size and focus ring around the editor, which fills it between the optional adornments.\n */\nexport const RefEditor = forwardRef<EditorController, RefEditorProps>(\n ({ value, onChange, autoFocus, extensions, start, end, 'data-testid': testId, ...options }, forwardedRef) => {\n const rootProps = useRefEditor(options, forwardedRef);\n return (\n <Editor.Root {...rootProps}>\n <Input.Frame start={start} end={end} disabled={options.readonly} data-testid={testId}>\n <Editor.View\n initialValue={value}\n extensions={extensions}\n onChange={onChange}\n autoFocus={autoFocus}\n selectionEnd\n />\n </Input.Frame>\n </Editor.Root>\n );\n },\n);\n\nRefEditor.displayName = 'RefEditor';\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Filter, Obj, type Registry, Type, type View } from '@dxos/echo';\nimport { Format, FormatEnums, formatToType } from '@dxos/echo/Format';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { log } from '@dxos/log';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport {\n type ProjectionModel,\n type PropertyType,\n formatToAdditionalPropertyAttributes,\n getFormatSchema,\n} from '@dxos/schema';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldMap } from '#types';\n\nimport { getFormProperties } from '../util/index.ts';\nimport { SelectField, SelectOptionField } from './fields/index.ts';\nimport { Form, type FormRootProps } from './Form.tsx';\n\nexport type FieldEditorProps = Pick<FormRootProps<PropertyType>, 'readonly'> & {\n projection: ProjectionModel;\n field: View.FieldType;\n registry?: Registry.Registry;\n view?: Obj.Unknown;\n onSave: () => void;\n onCancel?: () => void;\n};\n\nconst omitType = (props: SchemaEx.SchemaProperty[]) => props.filter((prop) => prop.name !== 'type');\n\n/**\n * Edits a view field's projection (property, format, options, reference) on `react-ui-form`; the current\n * FieldEditor's logic with Next renderers.\n */\nexport const FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }: FieldEditorProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const [props, setProps] = useState<PropertyType>(projection.getFieldProjection(field.id).props);\n useEffect(() => setProps(projection.getFieldProjection(field.id).props), [field, projection]);\n\n const [schemas, setSchemas] = useState<Type.Type[]>([]);\n Hooks.useAsyncEffect(async () => {\n if (!registry) {\n return;\n }\n const subscription = registry\n .query(Filter.type(Type.Type))\n .subscribe((query) => setSchemas(query.results), { fire: true });\n setSchemas(await registry.query(Filter.type(Type.Type)).run());\n return () => subscription?.();\n }, [registry]);\n\n // A `Type.Type` is a class, which a state setter would call as an updater, so it is stored through a lambda.\n const [referenceSchema, setReferenceSchema] = useState<Type.Type>();\n useEffect(() => {\n setReferenceSchema(() => schemas.find((schema) => Type.getTypename(schema) === props?.referenceSchema));\n }, [schemas, props?.referenceSchema]);\n\n // Wrapped in an object for the same reason: a schema class must not reach a setter directly.\n const [{ fieldSchema }, setFieldSchema] = useState({ fieldSchema: getFormatSchema(props?.format) });\n\n const fieldMap = useMemo<FormFieldMap>(\n () => ({\n ['format' satisfies keyof PropertyType]: (fieldProps) => (\n <Form.Field path={fieldProps.jsonPath}>\n <SelectField\n {...fieldProps}\n options={FormatEnums.filter((value) => value !== Format.TypeFormat.None).map((value) => ({\n value,\n label: t(`format.${value}.label`),\n }))}\n />\n </Form.Field>\n ),\n ['referenceSchema' satisfies keyof PropertyType]: (fieldProps) => (\n <Form.Field path={fieldProps.jsonPath}>\n <SelectField\n {...fieldProps}\n options={schemas\n .map((schema) => Type.getTypename(schema))\n .filter((typename): typename is string => typename != null)\n .map((typename) => ({ value: typename }))}\n />\n </Form.Field>\n ),\n ['referencePath' satisfies keyof PropertyType]: (fieldProps) => (\n <Form.Field path={fieldProps.jsonPath}>\n <SelectField\n {...fieldProps}\n options={\n referenceSchema\n ? getFormProperties(Type.getSchema(referenceSchema).ast)\n .sort((a, b) => a.name.toString().localeCompare(b.name.toString()))\n .map((prop) => ({ value: prop.name.toString() }))\n : []\n }\n />\n </Form.Field>\n ),\n ['options' satisfies keyof PropertyType]: (fieldProps) => (\n <Form.Field path={fieldProps.jsonPath} standalone>\n <SelectOptionField {...fieldProps} />\n </Form.Field>\n ),\n }),\n [t, schemas, referenceSchema],\n );\n\n const handleValuesChanged = useCallback<NonNullable<FormRootProps<PropertyType>['onValuesChanged']>>(\n (next) => {\n setFieldSchema((previous) => {\n const fieldSchema = getFormatSchema(next.format);\n return previous.fieldSchema === fieldSchema ? previous : { fieldSchema };\n });\n setReferenceSchema((previous) => {\n if (next.referenceSchema !== (previous ? Type.getTypename(previous) : undefined)) {\n return schemas.find((schema) => Type.getTypename(schema) === next.referenceSchema) ?? previous;\n }\n return previous;\n });\n setProps((current) => {\n const type = next.format ? formatToType[next.format] : current.type;\n // The format's extra JSON-schema attributes (e.g. a currency's multipleOf), not its JSON-schema `format` string.\n const { format: _format, ...additional } = next.format ? formatToAdditionalPropertyAttributes[next.format] : {};\n return current.type !== type ? { ...current, ...next, ...additional, type } : { ...current, ...next };\n });\n },\n [schemas],\n );\n\n const handleValidate = useCallback<NonNullable<FormRootProps<PropertyType>['onValidate']>>(\n ({ property }) => {\n if (property && projection.getFields().find((other) => other.path === property && other.path !== field.path)) {\n return [{ path: 'property', message: `property is not unique: '${property}'` }];\n }\n },\n [projection, field],\n );\n\n const handleSave = useCallback<NonNullable<FormRootProps<PropertyType>['onSave']>>(\n (next) => {\n if (view) {\n // The projection writes into the view, so the write runs inside the view's update.\n Obj.update(view, (view) => {\n projection.setFieldProjection({ field, props: next });\n });\n } else {\n projection.setFieldProjection({ field, props: next });\n }\n onSave();\n },\n [projection, field, view, onSave],\n );\n\n const handleCancel = useCallback(() => {\n onSave();\n // Deferred so the form can close first.\n requestAnimationFrame(() => onCancel?.());\n }, [onSave, onCancel]);\n\n if (!fieldSchema) {\n log.warn('invalid format', { props });\n return null;\n }\n\n return (\n <Form.Root<PropertyType>\n key={field.id}\n fieldMap={fieldMap}\n autoFocus\n readonly={readonly}\n schema={fieldSchema}\n values={props}\n onValuesChanged={handleValuesChanged}\n onValidate={handleValidate}\n onSave={handleSave}\n onCancel={handleCancel}\n >\n <Form.Content>\n <Form.Fields filter={omitType} sort={['property', 'format']} />\n <Form.Actions />\n </Form.Content>\n </Form.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport * as Match from 'effect/Match';\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as Struct from 'effect/Struct';\nimport React, { forwardRef, useCallback, useContext, useImperativeHandle, useMemo, useState } from 'react';\n\nimport {\n DXN,\n EID,\n Entity,\n Feed,\n Filter,\n Format,\n Obj,\n Query,\n QueryAST,\n Ref,\n type Registry,\n Type,\n View,\n} from '@dxos/echo';\nimport { useObject, useQuery } from '@dxos/echo-react';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { invariant } from '@dxos/invariant';\nimport { OrderedList } from '@dxos/react-ui-list';\nimport { QueryForm, type QueryFormProps } from '@dxos/react-ui-query';\nimport * as Banner from '@dxos/react-ui/Banner';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport {\n ParentLabelAnnotation,\n ProjectionModel,\n VIEW_FIELD_LIMIT,\n createEchoChangeCallback,\n getTypeURIFromQuery,\n} from '@dxos/schema';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldMap, type FormFieldRendererProps } from '#types';\n\nimport { FieldEditor } from './FieldEditor.tsx';\nimport { Form } from './Form.tsx';\nimport { FormField } from './FormField.tsx';\nimport { type FormRootProps } from './FormRoot.tsx';\n\nexport type ViewEditorProps = {\n type?: Type.AnyEntity;\n view: View.View;\n mode?: 'schema' | 'tag';\n registry?: Registry.Registry;\n onQueryChanged?: (query: QueryAST.Query, target?: EID.EID) => void;\n onDelete?: (fieldId: string) => void;\n} & Pick<QueryFormProps, 'types' | 'tags'> &\n Pick<FormRootProps<any>, 'readonly' | 'db'>;\n\nconst isJsonProp = Schema.is(SchemaEx.JsonProp);\n\n/** The view's projection model: edits write through to the ECHO view, and to the type when its schema is mutable. */\nconst useProjectionModel = (type: Type.AnyEntity | undefined, view: View.View) => {\n const atomRegistry = useContext(RegistryContext);\n return useMemo(\n () =>\n type\n ? new ProjectionModel({\n registry: atomRegistry,\n view,\n baseSchema: type.jsonSchema,\n change: createEchoChangeCallback(view, Type.getDatabase(type) != null ? type : undefined),\n })\n : null,\n [atomRegistry, type, view],\n );\n};\n\n/**\n * Edits a view on `react-ui-form`: its query (a record type, or in `tag` mode a query and target feed) and the\n * ordered list of its field projections, each opening to a `FieldEditor`. A system (read-only) schema is announced in\n * a `Banner`.\n */\nexport const ViewEditor = forwardRef<ProjectionModel | null, ViewEditorProps>(\n ({ type, view, mode = 'schema', registry, db, readonly, types, tags, onQueryChanged, onDelete }, forwardedRef) => {\n const { t } = Hooks.useTranslation(translationKey);\n const schemaReadonly = type == null || Type.getDatabase(type) == null;\n const projectionModel = useProjectionModel(type, view);\n useImperativeHandle<ProjectionModel | null, ProjectionModel | null>(forwardedRef, () => projectionModel, [\n projectionModel,\n ]);\n\n const feedTarget = Match.value(view.query.ast).pipe(\n Match.when({ type: 'from' }, ({ from }) =>\n from._tag === 'scope'\n ? Option.fromNullishOr(from.scopes.find((scope) => scope._tag === 'feed')).pipe(\n Option.map((scope) => scope.feedUri),\n Option.getOrUndefined,\n )\n : undefined,\n ),\n Match.orElse(() => undefined),\n );\n\n const feeds = useQuery(db, Filter.type(Feed.Feed));\n const targetRef = useMemo(() => {\n const targetEid = feedTarget ? EID.tryParse(feedTarget) : undefined;\n const feed = targetEid\n ? feeds.find((feed) => {\n const feedEid = Feed.getFeedUri(feed);\n return feedEid != null && EID.equals(feedEid, targetEid);\n })\n : undefined;\n return feed ? Ref.fromURI(Entity.getURI(feed)) : undefined;\n }, [feedTarget, feeds]);\n\n const viewSchema = useMemo(() => {\n const base = Schema.Struct({\n query:\n mode === 'schema'\n ? Format.URL.annotate({ title: 'Record type' })\n : QueryAST.Query.annotate({ title: 'Query' }),\n });\n\n // `Schema.mutable` is arrays-only in v4; a struct's fields are made mutable key by key.\n return mode === 'tag'\n ? Schema.Struct({\n ...base.fields,\n target: Ref.Ref(Feed.Feed).pipe(\n Schema.annotate({ title: 'Target Feed' }),\n ParentLabelAnnotation.set(true),\n Schema.optional,\n ),\n }).mapFields(Struct.map(Schema.mutableKey))\n : base.mapFields(Struct.map(Schema.mutableKey));\n }, [mode]);\n\n const viewValues = useMemo(() => {\n // Schema mode edits a typename: the version-less name of the type DXN.\n const typeUri = getTypeURIFromQuery(view.query.ast);\n const typeDxn = typeUri ? DXN.tryMake(typeUri) : undefined;\n return {\n query: mode === 'schema' ? (typeDxn ? DXN.getName(typeDxn) : (typeUri ?? '')) : view.query.ast,\n target: targetRef,\n };\n }, [mode, view.query.ast, targetRef]);\n\n const fieldMap = useMemo<FormFieldMap | undefined>(\n () => (mode === 'tag' ? { query: (props) => <QueryField {...props} types={types} tags={tags} /> } : undefined),\n [mode, types, tags],\n );\n\n const handleUpdate = useCallback(\n (values: { query?: unknown; target?: unknown }) => {\n const feed = Ref.isRef(values.target)\n ? feeds.find((feed) => Ref.isRef(values.target) && Obj.getURI(feed) === values.target.uri)\n : undefined;\n const feedDxn = feed ? Feed.getFeedUri(feed) : undefined;\n if (mode === 'schema') {\n // A db-backed type has no DXN, so its `echo:` EID is kept verbatim; a bare name is wrapped as a DXN.\n const typename = typeof values.query === 'string' ? values.query : '';\n onQueryChanged?.(Query.select(Filter.type(EID.isEID(typename) ? typename : DXN.make(typename))).ast, feedDxn);\n } else if (Schema.is(QueryAST.Query)(values.query)) {\n // A plain copy: the form's value may hold ECHO proxy arrays, which serialize as objects with numeric keys.\n onQueryChanged?.(Schema.decodeUnknownSync(QueryAST.Query)(JSON.parse(JSON.stringify(values.query))), feedDxn);\n }\n },\n [onQueryChanged, mode, feeds],\n );\n\n return (\n <Form.Root schema={viewSchema} values={viewValues} fieldMap={fieldMap} db={db} onValuesChanged={handleUpdate}>\n <Form.Content>\n {/* A read-only editor needs no notice that the schema is read-only. */}\n {schemaReadonly && !readonly && (\n <Banner.Root valence='info'>\n <Banner.Title>{t('system-schema.description')}</Banner.Title>\n </Banner.Root>\n )}\n <Form.Fields />\n {type && projectionModel && (\n <FieldList\n type={type}\n view={view}\n projectionModel={projectionModel}\n registry={registry}\n readonly={readonly}\n onDelete={(fieldId) => {\n invariant(!readonly);\n onDelete?.(fieldId);\n }}\n />\n )}\n </Form.Content>\n </Form.Root>\n );\n },\n);\n\nViewEditor.displayName = 'ViewEditor';\n\n/** The `tag` mode's query: the query builder in a standalone form row. */\nconst QueryField = ({\n type,\n label,\n getValue,\n onValueChange,\n types,\n tags,\n}: FormFieldRendererProps & Pick<QueryFormProps, 'types' | 'tags'>) => (\n <FormField label={label} standalone>\n <QueryForm\n initialQuery={getValue()}\n types={types}\n tags={tags}\n onChange={(query) => onValueChange(type, query.ast)}\n />\n </FormField>\n);\n\ntype FieldListProps = {\n type: Type.AnyEntity;\n view: View.View;\n projectionModel: ProjectionModel;\n registry?: Registry.Registry;\n readonly?: boolean;\n onDelete: (fieldId: string) => void;\n};\n\n/** The view's field projections: reorderable rows that hide, show or delete a field and open to its editor. */\nconst FieldList = ({ type, view, projectionModel, registry, readonly, onDelete }: FieldListProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const schemaReadonly = Type.getDatabase(type) == null;\n // Subscribe to the view, so edits from elsewhere re-render the list.\n const [snapshot] = useObject(view);\n const [expandedId, setExpandedId] = useState<string>();\n const fields = useMemo(\n () => (snapshot?.projection.fields ?? []).filter(Schema.is(View.FieldSchema)),\n [snapshot?.projection.fields],\n );\n\n const handleAdd = useCallback(() => {\n invariant(!readonly);\n setExpandedId(projectionModel.createFieldProjection().id);\n }, [projectionModel, readonly]);\n\n const handleMove = useCallback(\n (from: number, to: number) => {\n invariant(!readonly);\n Obj.update(view, (view) => {\n // Splice a copy rather than `arrayMove` in place, which races the kanban model.\n const next = [...view.projection.fields];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n view.projection.fields = next;\n });\n },\n [view, readonly],\n );\n\n const handleDelete = useCallback(\n (fieldId: string) => {\n setExpandedId((expanded) => (expanded === fieldId ? undefined : expanded));\n onDelete(fieldId);\n },\n [onDelete],\n );\n\n return (\n <>\n <Field.Header>\n <Typography.Text truncate>{t('fields.label')}</Typography.Text>\n {!readonly && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--plus--regular'\n label={t('add-property-button.label')}\n disabled={fields.length >= VIEW_FIELD_LIMIT}\n onClick={handleAdd}\n />\n )}\n </Field.Header>\n <OrderedList.Root\n items={fields}\n getId={(field) => field.id}\n getLabel={(field) => field.path}\n onMove={handleMove}\n readonly={!!readonly || schemaReadonly}\n >\n {({ items }) => (\n <OrderedList.Content scroll={false} gutter='inherit' aria-label={t('fields.label')}>\n {items.map((field) => {\n const hidden = field.visible === false;\n return (\n <OrderedList.Item\n key={field.id}\n id={field.id}\n canDrag={!readonly && !schemaReadonly}\n collapsible={!readonly}\n open={expandedId === field.id}\n onOpenChange={(open) => setExpandedId(open ? field.id : undefined)}\n >\n <OrderedList.DragHandle />\n <OrderedList.ItemText tone={hidden ? 'muted' : undefined}>{field.path}</OrderedList.ItemText>\n <Button.Toggle\n iconOnly\n variant='ghost'\n pressed={hidden}\n icon='ph--eye--regular'\n activeIcon='ph--eye-closed--regular'\n label={t(hidden ? 'show-field.label' : 'hide-field.label')}\n disabled={readonly || (!hidden && projectionModel.getFields().length <= 1)}\n onPressedChange={() => {\n setExpandedId(undefined);\n if (hidden) {\n // A hidden field is a schema property, so its path is a property name.\n if (isJsonProp(field.path)) {\n projectionModel.showFieldProjection(field.path);\n }\n } else {\n projectionModel.hideFieldProjection(field.id);\n }\n }}\n data-testid={hidden ? 'show-field-button' : 'hide-field-button'}\n />\n {!readonly && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--x--regular'\n label={t('delete-field.label')}\n disabled={schemaReadonly || fields.length <= 1}\n onClick={() => handleDelete(field.id)}\n data-testid='field.delete'\n />\n )}\n {!readonly && (\n <OrderedList.Detail>\n <FieldEditor\n readonly={readonly || schemaReadonly}\n registry={registry}\n projection={projectionModel}\n field={field}\n onSave={() => setExpandedId(undefined)}\n />\n </OrderedList.Detail>\n )}\n </OrderedList.Item>\n );\n })}\n </OrderedList.Content>\n )}\n </OrderedList.Root>\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,IAAa,cAAc,QAAmC,SAAqD;CACjH,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,OAAO,MAChB,OAAO,OAAO,SAAS;CAEzB,OAAO;AACT;;;;;;;;AAsBA,IAAa,uBACX,SACA,KACA,EAAE,aAAa,KAAK,UAAU,SAAqC,CAAC,MACvC;CAC7B,MAAM,aAAa,OAAO,OAAO;CACjC,WAAW,UAAU;CACrB,MAAM,CAAC,OAAO,YAAY,SAAmC;EAAE,SAAS;EAAO,OAAO,KAAA;EAAW,MAAM,KAAA;CAAU,CAAC;CAElH,gBAAgB;EACd,IAAI,CAAC,SAAS;GACZ,SAAS;IAAE,SAAS;IAAO,OAAO,KAAA;IAAW,MAAM,KAAA;GAAU,CAAC;GAC9D;EACF;EAEA,IAAI;EACJ,MAAM,QAAQ,iBAAiB;GAC7B,UAAU,UAAU;IAAE,GAAG;IAAM,SAAS;IAAM,OAAO,KAAA;GAAU,EAAE;GACjE,SAAS,OAAO,YAAY,WAAW,QAAQ,GAAG,EAChD,SAAS,SAAgC;IACvC,KAAK,MAAM,MAAM;KACf,YAAY,SAAS,SAAS;MAAE,SAAS;MAAO,OAAO,KAAA;MAAW;KAAK,CAAC;KACxE,YAAY,UAAU;MAEpB,IAAI,CAAC,MAAM,kBAAkB,KAAK,GAChC,UAAU,UAAU;OAAE,SAAS;OAAO,OAAO,MAAM,OAAO,KAAK;OAAG,MAAM,KAAK;MAAK,EAAE;KAExF;IACF,CAAC;GACH,EACF,CAAC;EACH,GAAG,UAAU;EAEb,aAAa;GACX,aAAa,KAAK;GAClB,SAAS;EACX;CACF,GAAG;EAAC;EAAK;EAAS;CAAU,CAAC;CAE7B,OAAO;AACT;;;ACvCA,IAAa,CAAC,qBAAqB,kBAAkB,cAAgC,MAAM;;;;AAK3F,IAAa,iBAOR,eAAuB,MAA4B,iBAA6B;CACnF,MAAM,aAAa,cAAc,QAAQ,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK,GAAG,IAAI,KAAA,CAAS,CAAC;CAChF,MAAM,WAAW,SAAS,eAAe,UAAU;CACnD,MAAM,EACJ,MAAM,EAAE,QAAQ,oBACd,eAAe,aAAa;CAEhC,MAAM,QAAQ,SAAS,SAAS,QAAQ,QAAQ;CAKhD,MAAM,qBAAqB,OAAsB,IAAI;CACrD,gBAAgB;EACd,IAAI,SAAS,QAAQ,gBAAgB,mBAAmB,YAAY,UAAU;GAC5E,mBAAmB,UAAU;GAC7B,cAAc,YAAY,UAAU,eAAe,aAAa,CAAC;EACnE;CACF,GAAG;EAAC;EAAO;EAAc;EAAe;EAAY;CAAQ,CAAC;CAE7D,OAAO;AACT;;;;AAKA,IAAa,qBAAqB,eAAuB,OAA4B,CAAC,MAA2B;CAC/G,MAAM,aAAa,cAAc,MAAM,CAAC,MAAM,QAAQ,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,IAAI,CAAC;CACpF,MAAM,EACJ,MAAM,EAAE,WAAW,UAAU,QAAQ,oBACnC,eAAe,aAAa;CAEhC,OAAO,eACE;EACL,iBAAiB,UAAU,UAAU;EACrC,gBAAgB,SAAS,UAAU;EACnC,cAAc,OAAO,UAAU;EAC/B,gBAAgB,KAAoB,UAAe,cAAc,YAAY,KAAK,KAAK;CACzF,IACA;EAAC;EAAW;EAAU;EAAQ;EAAe;CAAU,CACzD;AACF;;;AC3EA,IAAa,cAAc,EAAE,MAAM,QAAQ,YAAwB;CACjE,IAAI,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,IACrD;CAGF,MAAM,eAAe,SAAoB;EACvC,QAAQ,MAAR;GACE,KAAK,SAAS;IACZ,IAAI,OAAO,UAAU,UAAU;KAC7B,MAAM,iBAAiB,MAAM,YAAY;KACzC,IAAI,mBAAmB,OAAO,mBAAmB,SAC/C,OAAO;UACF,IAAI,mBAAmB,OAAO,mBAAmB,QACtD,OAAO;IAEX;IACA,OAAO,QAAQ,KAAK;GAGtB,KAAK,SAAS,QAAQ;IACpB,MAAM,UAAU,OAAO,UAAU,WAAW,MAAM,QAAQ,cAAc,EAAE,IAAI;IAC9E,MAAM,MAAM,OAAO,OAAO;IAC1B,OAAO,OAAO,MAAM,GAAG,IAAI,OAAO;GACpC;GAEA,KAAK,SAAS;GACd,KAAK,SAAS,KACZ,OAAO,OAAO,KAAK;GAErB,SACE,OAAO;EAEX;CACF;CAEA,IAAI,CAAC,QACH,OAAO,YAAY,IAAI;CAGzB,QAAQ,QAAR;EACE,KAAK,SAAO,WAAW,SACrB,OAAO,YAAY,SAAS,OAAO;EAErC,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW,UACrB,OAAO,YAAY,SAAS,MAAM;EAEpC,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW,UACrB,OAAO,YAAY,SAAS,MAAM;EAGpC,KAAK,SAAO,WAAW,KACrB,MAAM,IAAI,MAAM,sBAAsB,SAAO,WAAW,KAAK;EAE/D,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW,WAAW;GAChC,MAAM,OAAO,IAAI,KAAK,KAAwB;GAC9C,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,OAAO;EACxC;EAEA,KAAK,SAAO,WAAW;GAErB,IAAI,OAAO,UAAU,UAAU;IAG7B,MAAM,QADU,MAAM,QAAQ,eAAe,EAC/B,CAAA,CAAQ,MAAM,GAAG;IAC/B,IAAI,MAAM,WAAW,GAAG;KACtB,MAAM,MAAM,WAAW,MAAM,EAAE;KAC/B,MAAM,OAAO,WAAW,MAAM,EAAE;KAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,GAC5B,OAAO,YAAY,WAAW;MAAE,UAAU;MAAK,WAAW;KAAK,CAAC;IAEpE;GACF;GAEA,OAAO,CAAC,GAAG,CAAC;EAGd,SACE,OAAO;CAEX;AACF;AAQA,IAAa,2BAA2B,EAAE,MAAM,aAAiE;CAC/G,QAAQ,UAAU,MAAlB;EACE,KAAK,SAAO,WAAW,UACrB;EACF,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW,UACrB,OAAO,CAAC,aAAa,YAAY;EACnC,KAAK,SAAO,WAAW,UACrB,OAAO,CAAC,YAAY;EACtB,KAAK,SAAO,WAAW;EACvB,KAAK,SAAO,WAAW,KACrB,OAAO,CAAC,WAAW;EACrB,KAAK,SAAS;EACd,KAAK,SAAS,SACZ,OAAO,CAAC,cAAc,WAAW;EACnC,KAAK,SAAS,QACZ;EACF,KAAK,SAAS,KACZ;EACF,SACE;CACJ;AACF;AAGA,IAAa,sBAAsB,UAAmC;CACpE,MAAM;CACN,SAAS,IAAI,KAAK;AACpB;;;AC5HA,IAAa,UACX,iBAC6C;CAI7C,OAAO,iBAHoB,KAAK,OAAO,YAAY,IAAI,KAAK,UAAU,YAAY,IAAI,YAGxD;AAChC;;;;;;;AAQA,IAAM,oBAAoB,WAAmC;CAC3D,MAAM,MAAM,OAAO;CACnB,IAAI,UAAU,QAAQ,GAAG,GACvB,OAAO,OAAO,MAAM,IAAI,MAAM,KAAK,SAAS,iBAAiB,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC;CAKlF,OAHc,UAAU,sBAAsB,GAAG,CAAC,CAAC,MAAM,SAAS,KAAK,SAAS,IAGzE,IAAQ,OAAO,KAAiB,UAAU,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI;AACxE;;;;;;;AAQA,IAAa,wBAA0D,WAAiB;CAEtF,MAAM,SADa,UAAU,sBAAsB,OAAO,GAC3C,CAAA,CACZ,QAAQ,SAAS,OAAO,UAAU,WAAW,oBAAoB,WAAW,KAAK,IAAI,SAAS,IAAI,MAAM,KAAK,CAAA,CAC7G,KAAK,SAAS,KAAK,IAAc;CAGpC,OAAO,OAAO,WAAW,IAAI,SAAU,OAAO,KAAiB,UAAU,KAAK,OAAO,KAAK,MAAM,CAAC;AACnG;;;;AChDA,IAAM,kBAAkB,SAAqD;CAC3E,IAAI,CAAC,UAAU,WAAW,KAAK,IAAI,KAAK,CAAC,UAAU,QAAQ,KAAK,IAAI,GAClE,OAAO,KAAK;CAGd,MAAM,UAAU,KAAK,KAAK,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW;CAC1E,IAAI,QAAQ,WAAW,GACrB,OAAO,KAAK;CAEd,OAAO,QAAQ,WAAW,IACtB,QAAQ,KACR,IAAI,UAAU,MAAM,SAAS,KAAK,KAAK,SAAS,KAAK,KAAK,aAAa,KAAK,KAAK,MAAM;AAC7F;;;;;;;;AASA,IAAa,4BAA4B,QAA4D;CACnG,IAAI,CAAC,OAAO,CAAC,SAAS,qBAAqB,GAAG,KAAK,CAAC,UAAU,QAAQ,GAAG,GACvE,OAAO,CAAC;CAGV,MAAM,iBAAiB,IAAI,IAAI,SAAS,uBAAuB,GAAG,KAAK,CAAC,CAAC;CACzE,MAAM,CAAC,SAAS,IAAI;CACpB,IAAI,CAAC,SAAS,eAAe,SAAS,GACpC,OAAO,CAAC;CAGV,OAAO,OAAO,YACZ,UAAU,sBAAsB,KAAK,CAAA,CAClC,QAAQ,SAAS,eAAe,IAAI,KAAK,KAAK,SAAS,CAAC,KAAK,UAAU,UAAU,KAAK,IAAI,CAAC,CAAA,CAC3F,KAAK,SAAS,CAAC,KAAK,KAAK,SAAS,GAAI,KAAK,KAA2B,OAAO,CAAC,CACnF;AACF;;;;;;;;;;AAWA,IAAa,yBACX,KACA,WAC8B;CAC9B,IAAI,CAAC,SAAS,qBAAqB,GAAG,GACpC,OAAO,kBAAkB,GAAG;CAG9B,MAAM,aAAa,SAAS,qBAAqB,KAAK,UAAU,CAAC,CAAC;CAClE,IAAI,CAAC,YACH,OAAO,kBAAkB,GAAG;CAE9B,MAAM,cAAc,kBAAkB,UAAU;CAEhD,MAAM,iBAAiB,IAAI,KAAK,SAAS,uBAAuB,GAAG,KAAK,CAAC,EAAA,CAAG,KAAK,SAAS,KAAK,SAAS,CAAC,CAAC;CAC1G,IAAI,eAAe,SAAS,GAC1B,OAAO;CAIT,MAAM,WAAW,SAAS,qBAAqB,KAAK,CAAC,CAAC;CACtD,MAAM,yBAAyB,WAAW,kBAAkB,QAAQ,IAAI;CACxE,OAAO,YAAY,KAAK,SACtB,eAAe,IAAI,KAAK,KAAK,SAAS,CAAC,IAClC,uBAAuB,MAAM,cAAc,UAAU,SAAS,KAAK,IAAI,KAAK,OAC7E,IACN;AACF;;;;;;;;;;;;;;;;;;;;;AAsBA,IAAa,qBAAqB,QAAkD;CAClF,MAAM,aAAa,UAAU,sBAAsB,GAAG;CACtD,MAAM,YAAY,IAAI,IAAgC,WAAW,KAAK,SAAS,CAAC,KAAK,MAAM,eAAe,IAAI,CAAC,CAAC,CAAC;CACjH,MAAM,SAAS,IAAI,IACjB,WACG,QACE,SACC,WAAW,oBAAoB,WAAW,eAAe,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,gBAAgB,IAAI,CAAC,MAAM,KAC3G,CAAA,CACC,KAAK,SAAS,KAAK,IAAI,CAC5B;CACA,OAAO,SAAS,cAAc,GAAG,CAAA,CAC9B,QAAQ,SAAS,CAAC,OAAO,IAAI,KAAK,IAAI,CAAC,CAAA,CACvC,KAAK,SAAS;EACb,MAAM,MAAM,UAAU,IAAI,KAAK,IAAI;EACnC,OAAO,QAAQ,SAAS,aAAa,GAAG,KAAK,SAAS,YAAY,GAAG,KAAK;GAAE,GAAG;GAAM,MAAM;EAAI,IAAI;CACrG,CAAC;AACL;;;;;;AAOA,IAAa,mBACX,KACA,MACA,WAC8B;CAC9B,IAAI,OAAsB;CAC1B,KAAK,MAAM,WAAW,MAAM;EAC1B,IAAI,OAAO,YAAY,UAAU;GAC/B,MAAM,UAAU,SAAS,oBAAoB,IAAI;GACjD,IAAI,CAAC,SACH;GAEF,OAAO;GACP;EACF;EACA,MAAM,UAAU,SAAS,SAAS,MAAM,UAAU,SAAS;EAC3D,IAAI,CAAC,SACH;EAEF,MAAM,OAAO,UAAU,sBAAsB,OAAO,CAAC,CAAC,MAAM,cAAc,OAAO,UAAU,IAAI,MAAM,OAAO;EAC5G,IAAI,CAAC,MACH;EAEF,OAAO,eAAe,IAAI;CAC5B;CACA,MAAM,QAAQ,SAAS,SAAS,MAAM,SAAS,oBAAoB;CACnE,OAAO,QACH,SAAS,qBAAqB,OAAO,SAAS,SAAS,UAAU,CAAC,GAAG,SAAS,eAAe,IAAI,CAAC,KAAK,CAAC,CAAC,IACzG,SAAS,SAAS,MAAM,UAAU,SAAS;AACjD;;;ACnJA,IAAa,eAAe,QAA6C;CAEvE,IAAI,SAAS,YAAY,GAAG,GAAG;EAC7B,MAAM,cAAc,SAAS,oBAAoB,GAAG;EACpD,IAAI,aACE;OAAA,IAAI,UAAU,WAAW,GAK3B,OAAO;IAAE,KAAK;IAAa,SAAS;IAAM,UAJzB,SAAS,eACxB,aACA,aAAW,qBACb,CAAC,EAAE;GACgD;EAAA;CAGzD;CAGA,IAAI,IAAI,UAAU,GAAG,GAKnB,OAAO;EAAE;EAAK,SAAS;EAAO,UAJb,SAAS,eACxB,KACA,aAAW,qBACb,CAAC,EAAE;CACoC;AAI3C;;;;;;;;ACqFA,IAAa,kBAA2C,EACtD,QACA,UACA,gBACA,QAAQ,YACR,eAAe,mBACf,iBACA,YACA,QACA,UACA,GAAG,YACsC;CACzC,MAAM,CAAC,SAAS,cAAc,SAA6C,CAAC,CAAC;CAC7E,MAAM,CAAC,SAAS,cAAc,SAA6C,CAAC,CAAC;CAC7E,MAAM,CAAC,QAAQ,aAAa,SAA4C,CAAC,CAAC;CAC1E,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,OAAO,MAAM,gBAA4B,0BAA0B,CAAC,EAAE;CAG5E,MAAM,gBAAgB,eACb;EAAE,GAAG,yBAAyB,QAAQ,GAAG;EAAG,GAAG;CAAK,IAC3D,CAAC,QAAQ,IAAI,CACf;CAMA,MAAM,SAAS,cAAc;CAK7B,MAAM,CAAC,WAAW,gBAAgB,SAA6C,CAAC,CAAC;CAIjF,MAAM,SAAS,eAAe,QAAQ,SAAS;CAG/C,MAAM,WAAW,aACd,WAAoC;EACnC,IAAI,CAAC,QACH,OAAO;EAGT,IAAI,SAA4B,eAAe,QAAQ,MAAM,KAAK,CAAC;EACnE,IAAI,YAAY;GAAE;GAAQ;EAAO,GAAA;GAAA,YAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA,KAAA;EAAA,CAAC;EAClC,IAAI,OAAO,WAAW,KAAK,YAEzB,SAAS,WAAW,MAAe,KAAK,CAAC;EAG3C,UAAU,QAAQ,MAAM,CAAC;EAEzB,OADc,OAAO,WAAW;CAElC,GACA,CAAC,QAAQ,UAAU,CACrB;CAGA,MAAM,CAAC,eAAe,oBAAoB,SAAS,KAAK;CACxD,gBAAgB,iBAAiB,IAAI,GAAG,CAAC,MAAM,CAAC;CAChD,gBAAgB;EACd,IAAI,eAAe;GACjB,SAAS,MAAM;GACf,iBAAiB,KAAK;EACxB;CACF,GAAG;EAAC;EAAU;EAAQ;CAAa,CAAC;CAMpC,gBAAgB;EACd,MAAM,aAAc,OAAO,KAAK,SAAS,CAAC,CAAyB,QAAQ,SACzE,YAAY,SAAS,SAAS,QAAQ,IAAI,GAAG,UAAU,KAAK,CAC9D;EACA,IAAI,WAAW,WAAW,GACxB;EAEF,cAAc,SAAS,UAAU,MAAM,UAAU,CAAC;EAClD,YAAY,SAAS,UAAU,MAAM,UAAU,CAAC;EAChD,YAAY,SAAS,UAAU,MAAM,UAAU,CAAC;CAClD,CAAC;CAED,MAAM,UAAU,cAAc;EAC5B,OAAO,OAAO,KAAK,MAAM,CAAC,CAAC,WAAW;CACxC,GAAG,CAAC,MAAM,CAAC;;;;;CAMX,MAAM,UAAU,cAEZ,CAAC,UAED,CAAC,OAAO,QAAQ,OAAO,CAAC,CAAC,MACtB,CAAC,MAAM,eACN,aACA,OAAO,KAAK,MAAM,CAAC,CAAC,MACjB,cAAc,cAAc,QAAQ,UAAU,WAAW,GAAG,KAAK,EAAE,KAAK,UAAU,WAAW,GAAG,KAAK,EAAE,CAC1G,CACJ,GACF;EAAC;EAAS;EAAQ;CAAM,CAC1B;CAEA,MAAM,aAAa,YAAY,YAAY;EACzC,IAAI,SAAS,MAAM,GAAG;GACpB,UAAU,IAAI;GACd,IAAI;IACF,MAAM,SAAS,QAAQ;KAAE;KAAS;IAAQ,CAAC;GAC7C,UAAU;IACR,UAAU,KAAK;GACjB;EACF;CACF,GAAG;EAAC;EAAQ;EAAU;EAAQ;EAAS;CAAO,CAAC;CAE/C,MAAM,eAAe,kBAAkB;EACrC,WAAW;CACb,GAAG,CAAC,QAAQ,CAAC;CAMb,MAAM,YAAY,aACf,SAAS;EACR,MAAM,WAAW,MAAM,QAAQ,IAAI,IAAI,SAAS,eAAe,IAAI,IAAI;EACvE,MAAM,CAAC,GAAG,SACR,OAAO,QAAQ,MAAM,CAAC,CAAC,MACpB,CAAC,eACA,cAAc,YAAY,UAAU,WAAW,GAAG,SAAS,EAAE,KAAK,UAAU,WAAW,GAAG,SAAS,EAAE,CACzG,KAAK,CAAC;EAER,MAAM,gBAAgB,gBAAgB,gBAAgB,WAAW,QAAQ;EAIzE,IAAI,CADc,QAAQ,WAExB,OAAO;GACL,QAAQ,KAAA;GACR,OAAO,KAAA;GACP;EACF;EAGF,OAAO;GACL,QAAQ,QAAQ,UAAU,KAAA;GAC1B,OAAO,QAAS,SAAS,KAAA,IAAa,KAAA;GACtC;EACF;CACF,GACA;EAAC;EAAQ;EAAS;EAAgB;CAAS,CAC7C;CAEA,MAAM,cAAc,aACjB,SAAS,iBAAiB,SAAS,eAAe,IAAI,IACvD,CAAC,cAAc,CACjB;CAEA,MAAM,WAAW,aACd,SAAS;EACR,MAAM,WAAW,SAAS,eAAe,IAAI;EAC7C,IAAI,OAAO,UAAU,eAAe,KAAK,WAAW,QAAQ,GAC1D,OAAO,UAAU;EAGnB,IAAI,iBAAiB,SAAS,EAAE,eAC9B;EAGF,OAAO,SAAS,SAAS,QAAQ,QAAQ;CAC3C,GACA;EAAC;EAAQ;EAAW;CAAc,CACpC;CAEA,MAAM,gBAAgB,aACnB,MAAM,MAAM,UAAU;EACrB,IAAI,iBAAiB;GAAE;GAAM;EAAM,GAAA;GAAA,YAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA,KAAA;EAAA,CAAC;EAEpC,MAAM,WAAW,SAAS,eAAe,IAAI;EAE7C,IAAI,cAAc;EAClB,IAAI;GACF,IAAI,KAAK,SAAS,UAChB,cAAc,WAAW,KAAe,KAAK;EAEjD,SAAS,KAAK;GACZ,IAAI,MAAM,KAAE,KAAA,GAAA;IAAA,YAAA;IAAA,GAAA;IAAA,GAAA;IAAA,GAAA,KAAA;GAAA,CAAC;GACb,cAAc,KAAA;EAChB;EAIA,MAAM,eAAe;GAAE,GAAG;IAAY,WAAW;EAAY;EAC7D,aAAa,YAAY;EAGzB,MAAM,aAAa,GAAG,WAAW,KAAK;EACtC,YAAY,UAAU;GAAE,GAAG;GAAM,GAAG;EAAW,EAAE;EAGjD,MAAM,YAAY,eAAe,QAAQ,YAAY;EAGrD,MAAM,UAAU,SAAS,SAAS;EAGlC,kBAAkB,WAAW;GAAE;GAAS,SAAS;EAAW,CAAC;CAC/D,GACA;EAAC;EAAQ;EAAW;EAAU;CAAe,CAC/C;CAKA,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAClD,MAAM,SAAS,aAAa,SAA8B;EACxD,MAAM,WAAW,SAAS,eAAe,IAAI;EAG7C,YAAY,aAAa;GAAE,GAAG;IAAU,WAAW;EAAK,EAAE;EAC1D,cAAc,IAAI;CACpB,GAAG,CAAC,CAAC;CACL,gBAAgB;EACd,IAAI,CAAC,YACH;EAEF,cAAc,KAAK;EACnB,MAAM,UAAU,SAAS,MAAM;EAC/B,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,KAAK,WAAW,UAChD,SAAc,QAAa;GAAE;GAAS;EAAQ,CAAC;CAEnD,GAAG;EAAC;EAAY;EAAU;EAAQ;EAAS;EAAU;CAAM,CAAC;CAE5D,OAAO,eACE;EAEL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA,QAAQ;EACR,UAAU;EAGV;EACA;EACA;EACA;EACA;EAEA,GAAG;CACL,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;AACF;;;;;AAMA,IAAM,eAAe,KAAU,MAAoC,UAAoB;CACrF,IAAI,KAAK,WAAW,GAClB,OAAO;CAGT,MAAM,CAAC,MAAM,GAAG,QAAQ;CACxB,MAAM,QAAQ,KAAK,WAAW,IAAI,QAAQ,YAAY,MAAM,OAAO,MAAM,KAAK;CAE9E,IAAI,MAAM,QAAQ,GAAG,GAAG;EACtB,MAAM,OAAO,CAAC,GAAG,GAAG;EACpB,KAAK,QAAkB;EACvB,OAAO;CACT;CAEA,OAAO;EAAE,GAAG;GAAM,OAAO;CAAM;AACjC;;AAGA,IAAM,kBAAqB,MAAkB,cAA8D;CACzG,IAAI,SAAqB;CACzB,KAAK,MAAM,QAAQ,OAAO,KAAK,SAAS,GACtC,SAAS,YAAY,QAAQ,SAAS,cAAc,IAAI,GAAG,UAAU,KAAK;CAE5E,OAAO;AACT;AAOA,IAAM,eAAe,MAAe,UAA4B;CAC9D,IAAI,SAAS,OACX,OAAO;CAET,IAAI,SAAS,QAAQ,UAAU,MAC7B,OAAO,SAAS;CAElB,IAAI,OAAO,SAAS,YAAY,OAAO,UAAU,UAC/C,OAAO,MAAM,OAAO,MAAM,KAAK;CAEjC,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,KAAK,GACpC,OAAO,KAAK,QAAQ,MAAM;CAE5B,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,KAAK,GACpC,OAAO;CAET,IAAI,MAAM,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAK,GAAG;EAC/C,IAAI,KAAK,WAAW,MAAM,QACxB,OAAO;EAET,OAAO,KAAK,OAAO,OAAO,UAAU,YAAY,OAAO,MAAM,MAAM,CAAC;CACtE;CACA,IAAI,MAAM,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAK,GAC5C,OAAO;CAET,MAAM,aAAa;CACnB,MAAM,cAAc;CACpB,MAAM,uBAAO,IAAI,IAAI,CACnB,GAAG,OAAO,KAAK,UAAU,CAAC,CAAC,QAAQ,QAAQ,QAAQ,IAAI,GACvD,GAAG,OAAO,KAAK,WAAW,CAAC,CAAC,QAAQ,QAAQ,QAAQ,IAAI,CAC1D,CAAC;CACD,KAAK,MAAM,OAAO,MAChB,IAAI,CAAC,YAAY,WAAW,MAAM,YAAY,IAAI,GAChD,OAAO;CAGX,OAAO;AACT;;AAGA,IAAM,mBACJ,gBACA,WACA,aACY,CAAC,CAAC,iBAAiB,SAAS,EAAE,iBAAiB,CAAC,OAAO,UAAU,eAAe,KAAK,WAAW,QAAQ;;AAGtH,IAAM,aACJ,QACA,UACiC;CACjC,MAAM,OAAO,IAAI,IAAY,KAAK;CAClC,OAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;AACpF;AAEA,IAAM,WAAW,WAA8B;CAC7C,OAAO,OAAO,QACX,QAAQ,EAAE,MAAM,cAAc;EAE7B,MAAM,WAAW,SAAS,yBAAyB,IAAI;EACvD,IAAI,EAAE,YAAY,SAChB,OAAO,YAAY;EAErB,OAAO;CACT,GACA,CAAC,CACH;AACF;;;;;;;AC/eA,IAAM,iBAAiB,UACrB,MAAM,QAAQ,YAAY,MAAM,WAAW,MAAM,YAAY,CAAC,MAAM,YAAY,CAAC,MAAM,UAAU,CAAC,MAAM;;;;AAU1G,IAAa,iBACX,OACA,MACA,EAAE,aAAgC,CAAC,MAChC;CACH,MAAM,gBAAgB,aACnB,UAAyB;EAExB,IAAI,CAAC,cAAc,KAAK,KAAK,YAAY,KAAK,UAC5C;EAKF,KADc,MAAM,kBAAkB,UAAU,MAAM,OAAO,QAAQ,iBAAe,IAAI,UAC1E,MAAM,eAClB;EAKF,MAAM,eAAe;EACrB,MAAM,gBAAgB;EAItB,IAAI,KAAK,WAAW,KAAK,SACvB,KAAK,OAAO;CAEhB,GACA;EAAC;EAAU,KAAK;EAAU,KAAK;EAAS,KAAK;EAAS,KAAK;CAAM,CACnE;CAEA,sBAAsB;EACpB,MAAM,KAAK,MAAM;EACjB,IAAI,CAAC,IACH;EAIF,OAAO,iBAAiB,IAAI,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;CACzE,GAAG,CAAC,OAAO,aAAa,CAAC;AAC3B;;;;ACzDA,IAAM,0CAA0B,IAAI,IAAI;CAAC;CAAI;CAAQ;CAAU;CAAS;CAAO;CAAO;CAAY;AAAQ,CAAC;AAE3G,IAAM,qBAAqB,WACzB,kBAAkB,oBAClB,wBAAwB,IAAI,OAAO,IAAI,KAEvC,CAAC,OAAO,aAAa,mBAAmB,KACxC,OAAO,aAAa,MAAM,MAAM;;;;;AAUlC,IAAa,oBACX,OACA,UACA,EAAE,aAAmC,CAAC,MACnC;CACH,MAAM,cAAc,OAAO,QAAQ;CACnC,YAAY,UAAU;CAEtB,gBAAgB;EACd,MAAM,KAAK,MAAM;EACjB,IAAI,CAAC,MAAM,UACT;EAKF,OAAO,iBAAiB,GAAG,eAAe,YAAY,UAAyB;GAC7E,IACE,MAAM,QAAQ,WACd,MAAM,oBACN,MAAM,eAEN,MAAM,YAAY,OAClB,MAAM,YACN,MAAM,UACN,MAAM,WACN,MAAM,WACN,CAAC,kBAAkB,MAAM,MAAM,KAC/B,CAAC,GAAG,SAAS,MAAM,MAAM,GAEzB;GAGF,MAAM,eAAe;GACrB,YAAY,QAAQ;EACtB,CAAC;CACH,GAAG,CAAC,OAAO,QAAQ,CAAC;AACtB;;;;;;;AC1BA,IAAM,4BAA4B,KAAoB,aAAgE;CACpH,IAAI,OAAsB;CAC1B,KAAK,IAAI,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS;EACpD,MAAM,cAAc,SAAS,SAAS,MAAM,UAAU,SAAS;EAC/D,IAAI,CAAC,aACH;EAEF,MAAM,OAAO,UAAU,sBAAsB,WAAW,CAAC,CAAC,MACvD,MAAM,WAAW,OAAO,EAAE,IAAI,MAAM,SAAS,MAChD;EACA,IAAI,CAAC,MACH;EAEF,IAAI,UAAU,SAAS,SAAS,GAC9B,OAAO;EAET,OAAO,KAAK;CACd;AAGF;;;;;;;;AASA,IAAa,sBAAsB,QAA4B,SAAkD;CAC/G,MAAM,WAAW,KAAK,MAAM,GAAG;CAC/B,MAAM,OAAO,yBAAyB,OAAO,KAAK,QAAQ;CAC1D,IAAI,CAAC,MACH;CAKF,MAAM,EAAE,MAAM,aAAa,SAAS,YAAY,KAAK,IAAI;CAEzD,MAAM,iBAAiB,KAAK,KAAK,SAAS;CAC1C,MAAM,OACJ,kBAAkB,QAAQ,QAAQ,cAAc,CAAC,CAAC,SAAS,IACvD,UAAU,SAAS,UAAU,cAAc,IAC3C;CAEN,MAAM,QAAQ,SAAS,cAAsB,UAAU,iBAAiB,CAAC,CAAC,IAAI;CAK9E,MAAM,YAAY,SAAS,SAAS,KAAK,MAAM,UAAU,SAAS;CAClE,MAAM,WAAW,aAAa,QAAQ,OAAO,OAAO,WAAW,gBAAgB,WAAW,SAAS,CAAC;CAEpG,OAAO;EACL;EACA;EACA,UAAU,SAAS,SAAS,SAAS;EACrC;EACA,WAAW,WAAW,YAAY,KAAA;EAClC,UAAU,CAAC,UAAU,WAAW,KAAK,IAAI;CAC3C;AACF;;;;;;;;AC1EA,IAAa,qBAAqB,OAAgB,aAAuC;CACvF,IAAI,SAAS,MACX,OAAO;CAGT,QAAQ,UAAR;EACE,KAAK,OAAO,WAAW;EACvB,KAAK,OAAO,WAAW;EACvB,KAAK,OAAO,WAAW,MAAM;GAC3B,MAAM,OAAO,IAAI,KAAK,KAAe;GACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAC7B,OAAO,OAAO,KAAK;GAErB,MAAM,UAAU,aAAW,OAAO,WAAW,WAAW,QAAQ,aAAW,OAAO,WAAW,OAAO,OAAO;GAC3G,OAAO,OAAW,MAAM,OAAO;EACjC;EACA,SACE,OAAO,OAAO,KAAK;CACvB;AACF;;AAGA,IAAa,yBAAyB,eAAuB,SAAiB;CAC5E,MAAM,EAAE,SAAS,eAAe,aAAa;CAC7C,OAAO,cAAc;EACnB,IAAI,CAAC,KAAK,QACR;EAEF,MAAM,WAAW,mBAAmB,KAAK,QAAQ,IAAI;EACrD,IAAI,CAAC,UACH;EAEF,MAAM,cAAc,SAAS,cAAsB,UAAU,uBAAuB,CAAC,CAAC,SAAS,IAAI;EACnG,MAAM,SAAS,OAAO,iBAAiB,WAAW,SAAS,IAAI,CAAC,CAAC,KAAK,OAAO,cAAc;EAC3F,OAAO;GACL,MAAM,SAAS;GACf,OAAO,SAAS,SAAS,IAAI,WAAW,SAAS,QAAQ;GACzD;GACA;GACA,UAAU,SAAS;EACrB;CACF,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC;AACxB;;AAKA,IAAa,yBACX,eACA,MACA,UACA,EAAE,UAAU,UAAU,mBACE;CACxB,MAAM,EAAE,UAAU,cAAc,WAAW,eAAe,aAAa;CAEvE,MAAM,EAAE,WAAW,UAAU,QAAQ,kBAAkB,kBAAkB,eADxD,cAAe,SAAS,WAAW,IAAI,IAAI,SAAS,cAAc,IAAI,IAAI,CAAC,GAAI,CAAC,IAAI,CACb,CAAQ;CAChG,MAAM,EAAE,QAAQ,OAAO,kBAAkB,UAAU;CACnD,MAAM,QAAQ,SAAS;CACvB,MAAM,OAAO,UAAU,QAAQ,UAAU;CACzC,OAAO,eACE;EACL;EACA;EACA;EACA,WAAW,SAAwB,cAAc,MAAM,IAAI;EAC3D;EACA;EACA;EACA;EACA,UAAU,YAAY,UAAU;EAChC,UAAU,YAAY;EACtB,cAAc,gBAAgB;CAChC,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;EACA;EACA;EACA;CACF,CACF;AACF;;AAGA,IAAa,gBAAgB,UAC3B,SAAS,QAAQ,UAAU,MAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW;AAc7E,IAAa,yBAAb,cAA4C,UAA4D;CACtG,OAAO,yBAAyB,OAAgC;EAC9D,OAAO,EAAE,MAAM;CACjB;CAEA,QAAiB,EAAE,OAAO,KAAA,EAAU;CAEpC,mBAA4B,WAAwC;EAClE,IAAI,UAAU,SAAS,KAAK,MAAM,MAChC,KAAK,WAAW;CAEpB;CAEA,SAAkB;EAChB,IAAI,KAAK,MAAM,OACb,OACE,oBAAC,OAAO,MAAR;GAAa,SAAQ;GACnB,UAAA,oBAAC,OAAO,MAAR,EAAA,UAAc,SAAS,OAAO,KAAK,MAAM,MAAM,KAAK,GAAG,CAAC,IAAiB,CAAA;EAC9D,CAAA;EAIjB,OAAO,KAAK,MAAM;CACpB;CAEA,aAAqB;EACnB,KAAK,SAAS,EAAE,OAAO,KAAA,EAAU,CAAC;CACpC;AACF;;;AClIA,IAAa,CAAC,0BAA0B,uBAAuB,cAAgC,YAAY;;;ACnB3G,IAAM,oBAAoB,UACvB,MAAM,aAAsE;AAE/E,IAAM,YAAY,SAAyC,QAAoC;CAC7F,MAAM,QAAQ,UAAU;CACxB,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;AAC7C;;;;;;;;;AAUA,IAAa,yBAAyB,QAAyE;CAC7G,IAAI;CACJ,IAAI;CACJ,IAAI,UAAU;CAGd,MAAM,WAAW,OAAgB,UAAmB;EAClD,IAAI,UAAU,KAAA,GACZ,MAAM,QAAQ,KAAA,IAAY,QAAQ,KAAK,IAAI,KAAK,KAAK;EAEvD,IAAI,UAAU,KAAA,GACZ,MAAM,QAAQ,KAAA,IAAY,QAAQ,KAAK,IAAI,KAAK,KAAK;CAEzD;CAEA,KAAK,MAAM,SAAS,UAAU,UAAU,GAAG,GAAG;EAC5C,MAAM,iBAAiB,iBAAiB,KAAK;EAC7C,QAAQ,gBAAgB,IAAxB;GACE,KAAK;IACH,QAAQ,SAAS,eAAe,SAAS,SAAS,GAAG,SAAS,eAAe,SAAS,SAAS,CAAC;IAChG;GACF,KAAK;IACH,QAAQ,SAAS,eAAe,SAAS,SAAS,GAAG,KAAA,CAAS;IAC9D;GACF,KAAK;IACH,QAAQ,KAAA,GAAW,SAAS,eAAe,SAAS,SAAS,CAAC;IAC9D;GACF,KAAK;IACH,UAAU;IACV;GACF,KAAK,8BACH,YAAY,SAAS,eAAe,SAAS,SAAS,MAAM;EAEhE;CACF;CAEA,OAAO;EAAE;EAAK;EAAK;CAAQ;AAC7B;;;;;;;AChDA,IAAa,mBAAmB,QAA6B;CAC3D,QAAQ,KAAK,MAAb;EACE,KAAK,UACH,OAAO;EAET,KAAK,UAIH,OAAO,sBAAsB,GAAG,CAAC,CAAC,OAAO;EAE3C,KAAK,WACH,OAAO;EAET,KAAK,WACH,OAAO,gBAAgB,IAAI,MAAM,CAAC;EAEpC,SACE,IAAI,OAAO,SAAS,aAAa,GAAG,GAClC,OAAO,CAAC;OAER,MAAM,IAAI,MAAM,qBAAqB,KAAK,MAAM;CAGtD;AACF;;;;;;;;ACHA,IAAa,cAAc,EAAE,MAAM,MAAM,OAAO,UAAU,QAAQ,YAAY,GAAG,YAA6B;CAC5G,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,cAAc,SAAS,oBAAoB,IAAI;CACrD,MAAM,EAAE,kBAAkB;CAC1B,MAAM,SAAS,cAAyB,mBAAmB,YAAY,CAAC,CAAC;CACzE,MAAM,UAAU,WAAW,sBAAsB,WAAW,IAAI,CAAC,CAAC,KAAK,OAAO,gBAAgB,KAAK,CAAC;CACpG,MAAM,WAAW,CAAC,YAAY,WAAW;CAGzC,MAAM,SAAS,OAAiB,CAAC,CAAC;CAClC,MAAM,aAAa,OAAO,CAAC;CAC3B,MAAM,MAAM,OAAO;CACnB,MAAM,QAAQ,QAAQ,UAAU;CAChC,OAAO,IAAI,SAAS,OAClB,IAAI,KAAK,QAAQ,WAAW,WAAW;CAEzC,IAAI,SAAS;CACb,MAAM,QAAgB,IAAI,KAAK,IAAI,WAAW;EAAE;EAAI;CAAM,EAAE;CAE5D,MAAM,YAAY,kBAAkB;EAClC,IAAI;EACJ,IAAI;GACF,QACE,eAAe,SAAS,aAAa,WAAW,IAAI,cAAc,WAAW,IAAI,gBAAgB,WAAW;EAChH,SAAS,KAAK;GACZ,IAAI,MAAM,KAAE,KAAA,GAAA;IAAA,YAAA;IAAA,GAAA;IAAA,GAAA;IAAA,GAAA,KAAA;GAAA,CAAC;GACb;EACF;EACA,cAAc,MAAM,CAAC,GAAI,UAAU,CAAC,GAAI,KAAK,CAAC;CAChD,GAAG;EAAC;EAAa;EAAe;EAAM;CAAM,CAAC;CAE7C,MAAM,eAAe,aAClB,UAAkB;EACjB,OAAO,QAAQ,OAAO,OAAO,CAAC;EAC9B,cACE,OACC,UAAU,CAAC,EAAA,CAAG,QAAQ,GAAG,cAAc,cAAc,KAAK,CAC7D;CACF,GACA;EAAC;EAAe;EAAM;CAAM,CAC9B;CAEA,MAAM,aAAa,aAChB,MAAc,OAAe;EAC5B,MAAM,OAAO,CAAC,GAAI,UAAU,CAAC,CAAE;EAC/B,UAAU,MAAM,MAAM,EAAE;EACxB,UAAU,OAAO,SAAS,MAAM,EAAE;EAClC,cAAc,MAAM,IAAI;CAC1B,GACA;EAAC;EAAe;EAAM;CAAM,CAC9B;CAEA,IAAI,CAAC,eAAgB,CAAC,YAAY,UAAU,GAC1C,OAAO;CAGT,MAAM,WAAW,SAAS,aAAa,WAAW,KAAK,CAAC,IAAI,UAAU,WAAW;CACjF,MAAM,UAAU;EAAC,WAAW,YAAY;EAAwB;EAAkB,YAAY;CAAsB,CAAA,CACjH,OAAO,OAAO,CAAA,CACd,KAAK,GAAG;CAEX,OACE,qBAAA,YAAA,EAAA,UAAA,CACE,qBAAC,MAAM,QAAP,EAAA,UAAA,CACE,oBAAC,WAAW,MAAZ;EAAiB,UAAA;EAAU,UAAA;CAAuB,CAAA,GACjD,YACC,oBAAC,OAAO,MAAR;EACE,UAAA;EACA,SAAQ;EACR,MAAK;EACL,OAAO,EAAE,iBAAiB;EAC1B,SAAS;EACT,eAAa,GAAG,SAAS,eAAe,QAAQ,CAAC,CAAC,EAAE;CACrD,CAAA,CAES,EAAA,CAAA,GACd,oBAAC,YAAY,MAAb;EACS;EACP,QAAQ,SAAS,KAAK;EACtB,WAAW,SAAS,GAAG,MAAM,GAAG,KAAK,QAAQ;EACpC;EACT,QAAQ;EACR,UAAU,CAAC;EAET,WAAA,EAAE,YACF,oBAAC,YAAY,SAAb;GAAqB,QAAQ;GAAO,QAAO;GAAU,KAAI;GAAK,cAAY;GACvE,UAAA,MAAM,KAAK,SACV,qBAAC,YAAY,MAAb;IAAgC,IAAI,KAAK;IAAI,SAAS,WAAW;IAAjE,UAAA;KACG,WAAW,YAAY,oBAAC,YAAY,YAAb,CAAyB,CAAA;KAEjD,oBAAC,OAAO,WAAR;MAAkB,QAAO;MACvB,UAAA,oBAAC,mBAAD;OACE,GAAI;OACJ,MAAM;OACN,MAAM;OACN,OAAO,WAAW,KAAA,IAAY;OAC9B,MAAM,CAAC,GAAI,QAAQ,CAAC,GAAI,KAAK,KAAK;OAClC,UAAU,CAAC;OACX,QAAQ,WAAW,SAAS;MAC7B,CAAA;KACe,CAAA;KACjB,YACC,oBAAC,OAAO,MAAR;MACE,UAAA;MACA,SAAQ;MACR,MAAK;MACL,OAAO,EAAE,oBAAoB;MAC7B,eAAe,aAAa,KAAK,KAAK;KACvC,CAAA;IAEa;GAvBK,GAAA,KAAK,EAuBV,CACnB;EACkB,CAAA;CAEP,CAAA,CAClB,EAAA,CAAA;AAEN;AAEA,IAAM,iBAAiB,aAAqD;CAC1E,MAAM,WAAW,SAAS,SAAS,UAAU,SAAS,oBAAoB;CAC1E,MAAM,cAAc,WAChB,SAAS,qBAAqB,UAAU,CAAC,CAAC,IAC1C,SAAS,SAAS,UAAU,UAAU,SAAS;CACnD,OAAO,cACH,OAAO,YACL,kBAAkB,WAAW,CAAC,CAAC,KAAK,SAAS,CAAC,KAAK,MAAM,UAAU,qBAAqB,KAAK,IAAI,CAAC,CAAC,CACrG,IACA,CAAC;AACP;;;;;;;;;AC9IA,IAAa,mBAAmB,YAAsD;CACpF;CACA,UAAU,WAAW;CACrB,WAAW,WAAW;CACtB,WAAW,WAAW;AACxB;;;;;;;ACNA,IAAa,eAAe,EAC1B,MACA,UACA,aACA,UAAU,CAAC,GACX,cACA,UACA,eACA,aACsB;CACtB,MAAM,QAAQ,cACN,QAAQ,KAAK,EAAE,OAAO,OAAO,YAAY;EAAE,OAAO,OAAO,KAAK;EAAG,OAAO,SAAS,OAAO,KAAK;EAAG;CAAK,EAAE,GAC7G,CAAC,OAAO,CACV;CACA,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,QAAQ,SAAS;CACvB,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OACE,oBAAC,WAAW,MAAZ;EAAiB,UAAA;EACd,UAAA,QAAQ,MAAM,WAAW,OAAO,UAAU,KAAK,CAAC,EAAE,SAAS,OAAO,SAAS,EAAE;CAC/D,CAAA;CAIrB,OACE,oBAAC,eAAD;EACS;EACP,OAAO,SAAS,OAAO,KAAA,IAAY,OAAO,KAAK;EAC/C,aAAa,eAAe,EAAE,oBAAoB;EACxC;EACV,gBAAgB,SAAS;GAEvB,cAAc,MAAM,QAAQ,MAAM,WAAW,OAAO,OAAO,KAAK,MAAM,IAAI,CAAC,EAAE,KAAK;GAClF,OAAO;EACT;CACD,CAAA;AAEL;;AAaA,IAAa,iBAAiB,EAAE,OAAO,OAAO,aAAa,UAAU,SAAS,oBAC5E,qBAAC,OAAO,MAAR;CACS;CACP,OAAO,UAAU,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK;CACxC,UAAU,CAAC,CAAC;CACZ,gBAAgB,EAAE,OAAO,CAAC,YAAY,cAAc,IAAI;CAJ1D,UAAA,CAME,oBAAC,OAAO,SAAR;EAA6B;EAAsB;CAAU,CAAA,GAC7D,oBAAC,OAAO,SAAR,EAAA,UACG,MAAM,KAAK,SACV,oBAAC,OAAO,MAAR,EAAoC,KAAO,GAAzB,KAAK,KAAoB,CAC5C,EACa,CAAA,CACL;;;;;;;;AC9Df,IAAa,oBAAoB,EAC/B,QACA,MACA,QACA,UACA,aACA,cACA,UACA,eACA,aAC2B;CAC3B,MAAM,SAAS,cAA6B,uBAAuB;CACnE,MAAM,SAAS,cAAc,WAAW,QAAQ,OAAO,IAAI,GAAG,CAAC,QAAQ,OAAO,IAAI,CAAC;CAEnF,MAAM,EAAE,SAAS,SAAS,0BAAyD,OAAO,KAAK,MAAM,GADzF,cAAc,KAAK,UAAU,MAAM,GAAG,CAAC,MAAM,CAC+C,CAAG;CAC3G,MAAM,QAAQ,eACL,QAAQ,CAAC,EAAA,CAAG,KAAK,EAAE,OAAO,OAAO,YAAY;EAAE;EAAO,OAAO,SAAS;EAAO;CAAK,EAAE,GAC3F,CAAC,IAAI,CACP;CAGA,MAAM,UAAU,SAAS;CACzB,MAAM,mBAAmB,OAAO,aAAa;CAC7C,iBAAiB,UAAU;CAC3B,MAAM,kBAAkB,OAAoB,KAAA,CAAS;CACrD,gBAAgB;EACd,KAAK,WAAW,QAAQ,YAAY,OAAO,MAAM,WAAW,KAAK,SAAS,gBAAgB,SAAS;GACjG,gBAAgB,UAAU;GAC1B,iBAAiB,QAAQ,MAAM,KAAK,EAAE,CAAC,KAAK;EAC9C;CACF,GAAG;EAAC;EAAS;EAAM;CAAI,CAAC;CAExB,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAiB,OAAO,MAAM,MAAM,SAAS,KAAK,UAAU,OAAO,CAAC,EAAE,SAAS;EAAiB;CAAS,CAAA;CAGlH,OACE,oBAAC,eAAD;EACS;EACP,OAAO,WAAW,KAAA;EACL;EACH;EACD;EACT,gBAAgB,SAAS;GACvB,cAAc,MAAM,IAAI;GACxB,OAAO;EACT;CACD,CAAA;AAEL;;;AC7DA,IAAa,aAAa,EACxB,MACA,QACA,UACA,aACA,cACA,WACA,UACA,UACA,QACA,oBACoC;CACpC,MAAM,QAAQ,SAAS,KAAK;CAC5B,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAwB;EAAe;CAAS,CAAA;CAIzD,MAAM,MAAM,WAAW,OAAO,WAAW;CACzC,OACE,oBAAC,MAAM,MAAP;EACE,YAAA;EACW;EACX,UAAU,CAAC,CAAC;EACC;EACN;EACC;EACR,WAAW,UAAU,cAAc,MAAM,MAAM,OAAO,KAAK;EAE3D,YAAY,UAAU;GACpB,IAAI,MAAM,QAAQ,WAAW,CAAC,MAAM,YAAY,aAC9C,OAAO;EAEX;EACA,eAAa;EACb,GAAK,OAAO;GAAE,SAAS;GAAQ,YAAY;GAAO,aAAa;GAAO,gBAAgB;EAAO;CAC9F,CAAA;AAEL;;;;;;;AC7BA,IAAa,iBAAiB,EAAE,UAAU,GAAG,iBAAqC;CAChF,MAAM,SAAS,cAA6B,oBAAoB;CAChE,MAAM,SAAS,cAAc,WAAW,QAAQ,SAAS,IAAI,GAAG,CAAC,QAAQ,SAAS,IAAI,CAAC;CAEvF,MAAM,EAAE,SAAS,0BAA8C,SAAS,OAAO,MAAM,GADzE,cAAc,KAAK,UAAU,MAAM,GAAG,CAAC,MAAM,CAC+B,CAAG;CAI3F,MAAM,EAAE,SAAS;CACjB,MAAM,cAAc,OAAO,WAAW,QAAQ;CAC9C,YAAY,UAAU,WAAW;CACjC,MAAM,mBAAmB,OAAO,WAAW,aAAa;CACxD,iBAAiB,UAAU,WAAW;CACtC,MAAM,gBAAgB,OAA2B,KAAA,CAAS;CAC1D,gBAAgB;EACd,MAAM,UAAU,YAAY,QAAQ;EACpC,IAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAAG;GAEjD,IAAI,cAAc,WAAW,QAAQ,YAAY,cAAc,SAAS;IACtE,cAAc,UAAU,KAAA;IACxB,iBAAiB,QAAQ,MAAM,EAAE;GACnC;GACA;EACF;EACA,IAAI,YAAY,MAAM;GACpB,cAAc,UAAU;GACxB;EACF;EACA,IAAI,WAAW,QAAQ,YAAY,MAAM,YAAY,cAAc,SAAS;GAC1E,cAAc,UAAU;GACxB,iBAAiB,QAAQ,MAAM,IAAI;EACrC;CACF,GAAG,CAAC,MAAM,IAAI,CAAC;CAEf,OAAO,oBAAC,WAAD,EAAW,GAAI,WAAa,CAAA;AACrC;;;;ACzCA,IAAa,gBAAgB,EAC3B,MACA,QACA,OACA,UACA,cACA,eACA,UACA,eACA,aACqC;CACrC,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,EAAE,YAAY,eAAe,mBAAmB;CACtD,MAAM,QAAQ,SAAS;CACvB,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAwB;EAAe;CAAS,CAAA;CAGzD,OACE,oBAAC,MAAM,QAAP;EAEiB;EACf,OACE,YAAY,aAAa,KAAA,IAAY,gBAAgB,GAAG,MAAM,IAAI,EAAE,2BAA2B,EAAE,KAAK;EAExG,UAAU,CAAC,CAAC;EACZ,SAAS,CAAC,CAAC;EAEX,kBAAkB,EAAE,cAAc;GAChC,cAAc,MAAM,OAAO;GAC3B,OAAO;EACT;CACD,CAAA;AAEL;AAEA,aAAa,iBAAiB;;;AC/B9B,IAAM,gBAAgB;;;;;;AAOtB,IAAa,iBAAiB,EAC5B,QACA,MACA,QACA,UACA,aACA,cACA,UACA,UACA,eACA,aACwB;CACxB,MAAM,SAAS,cAA6B,oBAAoB;CAChE,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,eAAe,cAAc;EACjC,MAAM,SAAS,WAAW,QAAQ,OAAO,IAAI;EAC7C,IAAI,YAAY,OAAO,KAAK,SAAS,QAAQ,GAC3C,OAAO,YAAY;EAErB,OAAO;CACT,GAAG;EAAC;EAAQ,OAAO;EAAM;EAAU;CAAK,CAAC;CAEzC,MAAM,EAAE,SAAS,0BAAyD,OAAO,KAAK,YAAY,GADtF,cAAc,KAAK,UAAU,YAAY,GAAG,CAAC,YAAY,CACgC,CAAG;CAExG,MAAM,QAAQ,SAAS,KAAK;CAC5B,MAAM,UAAU,MAAM,KAAK;CAC3B,MAAM,QAAQ,cAAiC;EAC7C,MAAM,UAAU,QAAQ,CAAC,EAAA,CAAG,KAAK,YAAY;GAAE,OAAO,OAAO;GAAO,OAAO,OAAO,SAAS,OAAO;EAAM,EAAE;EAC1G,MAAM,UACJ,QAAQ,WAAW,IACf,OAAO,QACL,SACA,CAAC,IACH,OAAO,QAAQ,WAAW,OAAO,MAAM,YAAY,CAAC,CAAC,SAAS,QAAQ,YAAY,CAAC,CAAC;EAC1F,MAAM,OAAO,QAAQ,SAAS,KAAK,CAAC,QAAQ,MAAM,WAAW,OAAO,UAAU,OAAO;EAGrF,OAAO;GACL,GAFc,SAAS,CAAC,QAAQ,MAAM,WAAW,OAAO,UAAU,KAAK,IAEzD,CAAC,OAAO,MAAM,WAAW,OAAO,UAAU,KAAK,KAAK;IAAE;IAAO,OAAO;GAAM,CAAC,IAAI,CAAC;GAC9F,GAAG;GACH,GAAI,OAAO,CAAC;IAAE,OAAO;IAAS,OAAO;GAAQ,CAAC,IAAI,CAAC;EACrD;CACF,GAAG;EAAC;EAAM;EAAS,OAAO;EAAO;CAAK,CAAC;CAEvC,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAiB,OAAO,MAAM,MAAM,SAAS,KAAK,UAAU,KAAK,CAAC,EAAE,SAAS;EAAe;CAAS,CAAA;CAG9G,OACE,qBAAC,SAAS,MAAV;EACS;EACP,QAAQ;EACR,UAAU,CAAC,CAAC;EACZ,OAAO,QAAQ,CAAC,KAAK,IAAI,CAAC;EAC1B,qBAAqB,EAAE,YAAY,aAAa,WAAW,kBAAkB,SAAS,UAAU;EAChG,eAAe,EAAE,WAAW,CAAC,QAAQ,SAAS,EAAE;EAChD,gBAAgB,EAAE,OAAO,CAAC,YAAY;GACpC,cAAc,MAAM,IAAI;GACxB,OAAO;EACT;EAVF,UAAA,CAYE,qBAAC,SAAS,SAAV,EAAA,UAAA,CACE,oBAAC,SAAS,OAAV,EAA6B,YAAc,CAAA,GAC3C,oBAAC,SAAS,SAAV,CAAmB,CAAA,CACH,EAAA,CAAA,GAClB,oBAAC,SAAS,SAAV,CAAmB,CAAA,CACN;;AAEnB;;;;ACzEA,IAAM,WAAW;;AAGjB,IAAa,qBAAqB,EAChC,SACA,eAAe,gBACkC;CACjD,MAAM,aAAa,QAAQ,KAAK,WAAY,OAAO,WAAW,WAAW;EAAE,OAAO;EAAQ,OAAO;CAAO,IAAI,MAAO;CACnH,UACE,CAAC,WAAW,MAAM,WAAW,OAAO,UAAU,QAAQ,GACtD,oCAAoC,SAAS,iBAChD;EAAA,YAAA;EAAA,GAAA;EAAA,GAAA;EAAA,GAAA,KAAA;EAAA,GAAA,CAAA,2DAAA,8DAAA;CAAA,CAAC;CACA,MAAM,aAAa,iBAAiB;CACpC,MAAM,QAAyB,CAC7B,GAAI,aAAa,CAAC;EAAE,OAAO;EAAU,OAAO;CAAa,CAAC,IAAI,CAAC,GAC/D,GAAG,WAAW,KAAK,YAAY;EAAE,OAAO,OAAO;EAAO,OAAO,OAAO,SAAS,OAAO;CAAM,EAAE,CAC9F;CAEA,MAAM,uBAAuB,EAC3B,MACA,OACA,UACA,UACA,cACA,UACA,eACA,aACgD;EAChD,MAAM,QAAQ,SAAS;EACvB,OACE,oBAAC,WAAD;GAAW,MAAM;GAAiB;GAAiB;GAAwB;GACxE,UAAA,gBAAgB,YAAY,CAAC,CAAC,WAC7B,oBAAC,WAAW,MAAZ;IAAiB,UAAA;IACd,UAAA,WAAW,MAAM,WAAW,OAAO,UAAU,KAAK,CAAC,EAAE,SAAS,OAAO,SAAS,EAAE;GAClE,CAAA,IAEjB,oBAAC,eAAD;IACS;IACP,OAAO,UAAU,aAAa,WAAW,KAAA;IAC/B;IACV,gBAAgB,SAAS;KACvB,cAAc,MAAM,cAAc,SAAS,WAAW,KAAA,IAAY,IAAI;KACtE,OAAO;IACT;GACD,CAAA;EAEM,CAAA;CAEf;CACA,OAAO;AACT;;;;ACnEA,IAAa,sBAAsB,UAAsC;CACvE,IAAI,CAAC,OACH,OAAO;CAET,MAAM,OAAO,IAAI,KAAK,KAAK;CAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAC7B,OAAO;CAET,OAAO,OAAW,MAAM,oBAAoB;AAC9C;;AAGA,IAAa,sBAAsB,UAAsC;CACvE,IAAI,CAAC,OACH;CAGF,MAAM,OAAO,IAAI,KAAK,KAAK;CAC3B,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,KAAA,IAAY,KAAK,YAAY;AACrE;;;;;;;ACPA,IAAa,aAAa,EACxB,MACA,QACA,UACA,cACA,UACA,oBACgD;CAChD,MAAM,QAAQ,SAAS;CACvB,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAwB;EAAe;CAAS,CAAA;CAGzD,QAAQ,QAAR;EACE,KAAK,OAAO,WAAW,MACrB,OACE,oBAAC,MAAM,MAAP;GACE,MAAK;GACL,UAAU,CAAC,CAAC;GACZ,OAAO,SAAS;GAChB,gBAAgB,SAAS,cAAc,MAAM,QAAQ,KAAA,CAAS;EAC/D,CAAA;EAEL,KAAK,OAAO,WAAW,MACrB,OACE,oBAAC,MAAM,MAAP;GACE,MAAK;GACL,aAAY;GACZ,UAAU,CAAC,CAAC;GACZ,OAAO,SAAS;GAChB,gBAAgB,SAAS,cAAc,MAAM,QAAQ,KAAA,CAAS;EAC/D,CAAA;EAEL,SACE,OACE,oBAAC,MAAM,MAAP;GACE,MAAK;GACL,UAAU,CAAC,CAAC;GACZ,OAAO,mBAAmB,KAAK;GAC/B,gBAAgB,SAAS,cAAc,MAAM,mBAAmB,IAAI,CAAC;EACtE,CAAA;CAEP;AACF;;;;ACxCA,IAAa,iBAAiB,EAC5B,MACA,UACA,cACA,UACA,oBACsC;CACtC,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,WAAW,SAAS;CAC1B,MAAM,WAAW,cAAc,YAAY,aAAa,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;CACvF,MAAM,CAAC,MAAM,WAAW,SAAS;EAC/B,UAAU,SAAS,UAAU,SAAS,KAAK;EAC3C,WAAW,SAAS,WAAW,SAAS,KAAK;CAC/C,CAAC;CACD,gBAAgB;EACd,QAAQ;GAAE,UAAU,SAAS,UAAU,SAAS,KAAK;GAAI,WAAW,SAAS,WAAW,SAAS,KAAK;EAAG,CAAC;CAC5G,GAAG,CAAC,QAAQ,CAAC;CAEb,MAAM,WAAW,gBAAgB,YAAY;CAC7C,IAAI,SAAS,UACX,OAAO,CAAC,SAAS,YAAY,CAAC,SAAS,YAAY,OACjD,qBAAC,WAAW,MAAZ;EAAiB,UAAA;EAAjB,UAAA;GACG,KAAK,IAAI,SAAS,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;GAAE;IAAG,SAAS,YAAY,MAAM,IAAI,MAAM;GAAK;GACzF,KAAK,IAAI,SAAS,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;GAAE;IAAG,SAAS,aAAa,MAAM,IAAI,MAAM;EACxE;;CAIrB,MAAM,gBAAgB,YAAwB,UAAkB;EAC9D,SAAS,cAAc;GAAE,GAAG;IAAW,aAAa;EAAM,EAAE;EAC5D,MAAM,SAAS,eAAe,KAAK;EACnC,IAAI,UAAU,OAAO,WAAW,KAAA,KAAa,CAAC,OAAO,MAAM,MAAM,GAC/D,cAAc,MAAM,YAAY,WAAW;GAAE,GAAG;IAAW,aAAa;EAAO,CAAC,CAAC;CAErF;CAEA,MAAM,cAAc,MAAkB,UACpC,qBAAC,MAAM,MAAP,EAAA,UAAA,CACG,SAAS,aACR,oBAAC,MAAM,QAAP,EAAA,UACE,oBAAC,MAAM,OAAP,EAAA,UAAc,EAAE,GAAG,KAAK,OAAO,EAAe,CAAA,EAClC,CAAA,GAEhB,oBAAC,MAAM,MAAP;EACE,MAAK;EACL,MAAK;EACL,KAAK,CAAC;EACN,KAAK;EACL,UAAU,CAAC,CAAC;EACZ,aAAa,EAAE,GAAG,KAAK,aAAa;EACpC,OAAO,KAAK;EACZ,WAAW,UAAU,aAAa,MAAM,MAAM,OAAO,KAAK;CAC3D,CAAA,CACS,EAAA,CAAA;CAGd,OACE,qBAAC,OAAO,WAAR;EAAkB,QAAO;EAAM,QAAO;EAAU,SAAQ;EAAgC,KAAI;EAA5F,UAAA,CACG,WAAW,YAAY,EAAE,GACzB,WAAW,aAAa,GAAG,CACZ;;AAEtB;AAEA,cAAc,aAAa;;;ACvE3B,IAAM,cAAc,QAAgB,IAAI,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,MAAM,CAAC;;AAG7E,IAAa,cAA+B,KAAK,KAAK,SAAS;CAC7D,OAAO;CACP,OAAO,WAAW,GAAG;CACrB,MAAM;CACN,SAAS;AACX,EAAE;;AAUF,IAAa,aAAa,EAAE,OAAO,aAAa,UAAU,oBACxD,oBAAC,eAAD;CACE,OAAO;CACA;CACM;CACH;CACK;AAChB,CAAA;;AAIH,IAAa,YAAY,EACvB,MACA,QACA,aACA,UACA,cACA,UACA,eACA,aACgD;CAChD,MAAM,QAAQ,SAAS;CACvB,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAiB,OAAO,SAAS,WAAW,KAAK;EAAW;CAAS,CAAA;CAG9E,OACE,oBAAC,WAAD;EACS;EACM;EACH;EACV,gBAAgB,QAAQ;GAEtB,cAAc,MAAM,GAAG;GACvB,OAAO;EACT;CACD,CAAA;AAEL;;;AC3DA,IAAM,qBAAqB;;;;;;;AAsB3B,IAAa,gBAAgB,EAC3B,UACA,OACA,aACA,aACA,cAAc,MACd,SACA,QACA,eAAe,aACQ;CACvB,MAAM,EAAE,WAAW,eAAe,kBAAkB;CACpD,MAAM,CAAC,MAAM,WAAW,SAAS,WAAW;CAC5C,MAAM,YAAY,WAAW,YAAY,CAAC,CAAC;CAC3C,MAAM,cAAc,CAAC,CAAC,eAAe,aAAa,SAAS,QAAQ,QAAQ,CAAC,CAAC,SAAS;CACtF,MAAM,SAAS,eAAe,oBAAC,SAAS,YAAV,EAAA,UAAsB,YAAiC,CAAA;CACrF,MAAM,SAAS,aACb,qBAAC,SAAS,QAAV;EAAiB,MAAM,SAAS,KAAA,IAAY;EAAM,SAAS,SAAS,KAAA,IAAY;EAAhF,UAAA;GACG;GACA;GACA,eACC,oBAAC,aAAa,YAAd;IAAyB,SAAQ;IAAe;IAAO,UAAU;IAAM,kBAAkB;GAAU,CAAA;EAEtF;;CAKnB,MAAM,SAAS,SACb,oBAAC,SAAS,MAAV;EAAe,QAAO;EAAU,OAAA;EAC7B;CACY,CAAA,IAEf;CAGF,IAAI,aACF,OACE,oBAAC,YAAY,MAAb;EAAkB,SAAA;EAAc;EAAM,eAAe,EAAE,WAAW,QAAQ,IAAI;EAC5E,UAAA,qBAAC,SAAS,MAAV;GAAe,QAAO;GAAU,eAAa;GAA7C,UAAA;IACG;IACA;IACD,oBAAC,YAAY,SAAb;KAAqB,QAAO;KAAW,UAAA;IAA4B,CAAA;GACtD;;CACC,CAAA;CAItB,OACE,qBAAC,SAAS,MAAV;EAAe,QAAO;EAAU,eAAa;EAA7C,UAAA;GACG;GACA;GACA;EACY;;AAEnB;AAEA,aAAa,cAAc;;;AChD3B,IAAa,YAAqD,EAChE,UACA,QACA,QACA,QACA,UACA,GAAG,YACmB;CACtB,MAAM,OAAO,eAAe;EAAE;EAAQ;EAAQ;EAAQ;EAAU,GAAG;CAAM,CAAC;CAE1E,OACE,oBAAC,qBAAD;EAA2B;EAAM,GAAI;EAClC;CACkB,CAAA;AAEzB;AAEA,SAAS,cAAc;;;;;;;ACxBvB,IAAa,kBAAkB,EAC7B,MACA,UACA,OACA,IACA,UACA,eACA,UACA,SAAA,YAAU,cACe;CACzB,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,YAAY,SAAS;CAC3B,MAAM,WAAW,cAEb,SAAS,eAAoD,MAAM,aAAW,qBAAqB,CAAC,EAAE,UACxG,CAAC,IAAI,CACP;CACA,MAAM,aAAa,UAAQ,IAAI,WAAW,MAAI,KAAK,QAAQ,IAAI,KAAA,CAAS;CACxE,MAAM,eAAe,YAAY,YAAY;EAC3C,IAAI,CAAC,cAAc,CAAC,UAClB;EAEF,MAAM,UAAU,MAAM,SAAS,YAAY,CAAC,CAAC;EAC7C,IAAI,SACF,cAAc,MAAM,IAAI,KAAK,OAAO,CAAC;CAEzC,GAAG;EAAC;EAAY;EAAU;EAAe;CAAI,CAAC;CAE9C,IAAI,YAAY,CAAC,IAAI,MAAM,SAAS,GAClC,OAAO;CAGT,OACE,oBAAC,cAAD;EAAqB;EAAO,aAAA;EAAY,QAAA;EACrC,UAAA,IAAI,MAAM,SAAS,IAClB,oBAAC,YAAD;GAAuB;GAAe;GAAc;GAAmB,SAAA;EAAU,CAAA,IAEjF,CAAC,YACD,YACE,oBAAC,OAAO,OAAR;GAAc,MAAA;GACZ,UAAA,oBAAC,OAAO,MAAR;IACE,MAAK;IACL,OAAO,SAAS,EAAE,uBAAuB;IACzC,UAAU,CAAC;IACX,eAAe,KAAK,aAAa;GAClC,CAAA;EACW,CAAA;CAGN,CAAA;AAElB;;AAUA,IAAM,cAAc,EAAE,WAAW,IAAI,UAAU,SAAA,YAAU,cAAsC;CAC7F,MAAM,SAAS,aAAa,cAAc,UAAU,MAAM,CAAC,SAAS,CAAC,CAAC;CACtE,MAAM,mBAAmB,UAAQ,IAAI,SAAS,IAAI,WAAW,MAAM,IAAI,KAAA,CAAS;CAChF,MAAM,aAAc,UAAU,IAAI,QAAQ,MAAM,KAAM;CACtD,MAAM,SAAS,cAAe,aAAa,OAAO,KAAK,UAAU,UAAU,CAAC,IAAI,KAAA,GAAY,CAAC,UAAU,CAAC;CACxG,MAAM,gBAAgB,cAAe,SAAS,EAAE,GAAG,OAAO,IAAI,CAAC,GAAI,CAAC,MAAM,CAAC;CAC3E,MAAM,eAAe,aAEjB,QACA,EAAE,SAAS,cACR;EACH,IAAI,CAAC,WAAW,CAAC,QACf;EAEF,MAAM,QAAS,OAAO,KAAK,OAAO,CAAC,CAAyB,QAAQ,SAAS,QAAQ,KAAK;EAC1F,IAAI,MAAM,SAAS,GACjB,IAAI,OAAO,SAAS,WAAW;GAC7B,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,QAAQ,SAAS,cAAc,IAAI;IACzC,IAAI,SAAS,QAAQ,OAAO,SAAS,SAAS,QAAQ,IAAI,CAAC;GAC7D;EACF,CAAC;CAEL,GACA,CAAC,MAAM,CACT;CAEA,IAAI,CAAC,UAAU,CAAC,QACd,OAAO;CAGT,OACE,oBAAC,UAAD;EAAc;EAAY;EAAuB;EAAe,iBAAiB;EAC/E,UAAA,oBAAC,YAAD,EAAsB,SAAW,CAAA;CACzB,CAAA;AAEd;;;;AC3GA,IAAM,OAAO;;;;;AAMb,IAAM,aAAa,WAAW,MAAM;CAClC,KAAK,EAAE,WAAW,OAAO;CACzB,eAAe,EAAE,cAAc,WAAW;CAE1C,iCAAiC;EAAE,YAAY;EAAgB,QAAQ;EAAQ,UAAU;CAAU;AACrG,CAAC;;;;;;AAOD,IAAa,iBAAiB,EAC5B,MACA,UACA,aACA,cACA,IACA,UACA,oBAC4B;CAC5B,MAAM,QAAiB,SAAS;CAChC,MAAM,WAAW,gBAAgB,YAAY,CAAC,CAAC;CAC/C,IAAI,IAAI,UAAU,IAAI,GAAG;EACvB,MAAM,YAAY,IAAI,MAAM,KAAK,IAAI,QAAQ,KAAA;EAC7C,IAAI,WACF,OAAO,WACL,oBAAC,eAAD,EAA0B,UAAY,CAAA,IAEtC,oBAAC,mBAAD;GAA8B;GAAwB;GAAa,UAAU,CAAC,CAAC;EAAW,CAAA;EAI9F,OAAO,YAAY,WAAW,OAC5B,oBAAC,kBAAD;GAAsB;GAAI,WAAW,YAAY,cAAc,MAAM,OAAO;EAAI,CAAA;CAEpF;CAEA,MAAM,OAAO,OAAO,UAAU,WAAW,QAAQ;CACjD,OAAO,WACL,oBAAC,WAAW,MAAZ,EAAA,UAAkB,KAAsB,CAAA,IAExC,oBAAC,sBAAD;EACE,OAAO;EACM;EACb,UAAU,CAAC,CAAC;EACZ,WAAW,SAAS,cAAc,MAAM,IAAI;CAC7C,CAAA;AAEL;AASA,IAAM,wBAAwB,EAAE,OAAO,aAAa,UAAU,eAA0C;CACtG,MAAM,EAAE,uBAAuB,eAAe,eAAe;CAE7D,MAAM,kBAAkB,cAAc,CAAC,YAAY,GAAI,sBAAsB,CAAC,CAAE,GAAG,CAAC,kBAAkB,CAAC;CACvG,MAAM,aAAa,2BAA2B;EAAE;EAAa;EAAU,YAAY;CAAgB,CAAC;CACpG,OACE,oBAAC,MAAM,OAAP;EAAa,MAAM;EAAM,UAAU;EACjC,UAAA,oBAAC,OAAO,MAAR,EAAA,UACE,oBAAC,OAAO,MAAR;GAAyB;GAAmB;GAAO,UAAU,WAAW,KAAA,IAAY;EAAW,CAAA,EACpF,CAAA;CACF,CAAA;AAEjB;;AAGA,IAAM,iBAAiB,EAAE,gBAA4C;CACnE,MAAM,SAAS,aAAa,cAAc,UAAU,MAAM,CAAC,SAAS,CAAC,CAAC;CACtE,MAAM,UAAU,IAAI,WAAW,KAAK,MAAM,MAAM,IAAI,OAAO,UAAU,KAAA;CACrE,OAAO,UAAU,oBAAC,WAAW,MAAZ,EAAA,UAAkB,QAAyB,CAAA,IAAI;AAClE;AAQA,IAAM,qBAAqB,EAAE,WAAW,aAAa,eAAuC;CAC1F,MAAM,SAAS,aAAa,cAAc,UAAU,MAAM,CAAC,SAAS,CAAC,CAAC;CACtE,MAAM,OAAO,IAAI,WAAW,KAAK,MAAM,MAAM,IAAI,SAAS,KAAA;CAC1D,MAAM,iBAAiB,cACd,OAAO,CAAC,qBAAqB;EAAE,IAAI,UAAU;EAAK,MAAM,IAAI,eAAe,MAAM,CAAC,SAAS,CAAC;CAAE,CAAC,CAAC,IAAI,CAAC,GAC5G,CAAC,MAAM,SAAS,CAClB;CACA,MAAM,EAAE,uBAAuB,eAAe,eAAe;CAC7D,MAAM,kBAAkB,cAChB;EAAC;EAAY,GAAG;EAAgB,GAAI,sBAAsB,CAAC;CAAE,GACnE,CAAC,gBAAgB,kBAAkB,CACrC;CACA,MAAM,aAAa,2BAA2B;EAAE;EAAa;EAAU,YAAY;CAAgB,CAAC;CACpG,IAAI,CAAC,MACH,OAAO;CAGT,OACE,oBAAC,MAAM,OAAP;EAAa,MAAM;EAAM,UAAU;EACjC,UAAA,oBAAC,OAAO,MAAR,EAAA,UACE,oBAAC,OAAO,MAAR,EAAyB,WAAa,CAAA,EAC3B,CAAA;CACF,CAAA;AAEjB;AAOA,IAAM,oBAAoB,EAAE,IAAI,eAAsC;CACpE,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,OACE,oBAAC,OAAO,MAAR;EAAa,MAAK;EAAoB,UAAU,CAAC;EAAI,eAAe,MAAM,SAAS,IAAI,KAAK,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7G,UAAA,EAAE,mBAAmB;CACX,CAAA;AAEjB;;;;ACzIA,IAAM,eAAe,OAA2B,YAC9C,UAAU,IAAI,UAAU,KAAA,KAAa,KAAK,IAAI,KAAK,IAAI,IAAI,MAAO;;AAGpE,IAAa,eAAe,EAC1B,MACA,QACA,UACA,aACA,cACA,KAAK,SACL,KAAK,SACL,MAAM,UACN,UACA,eACA,aACoC;CACpC,MAAM,cAAc,sBAAsB,IAAI;CAE9C,MAAM,MAAM,WAAW,YAAY;CACnC,MAAM,MAAM,WAAW,YAAY;CACnC,MAAM,UAAU,YAAY,WAAY,aAAa,KAAA,KAAa,OAAO,UAAU,QAAQ;CAC3F,MAAM,YAAY,SAAS;CAE3B,MAAM,CAAC,MAAM,WAAW,SAAS,cAAc,KAAA,IAAY,KAAK,OAAO,SAAS,CAAC;CACjF,gBAAgB;EACd,IAAI,cAAc,KAAA,KAAa,OAAO,IAAI,MAAM,WAC9C,QAAQ,OAAO,SAAS,CAAC;CAE7B,GAAG,CAAC,SAAS,CAAC;CAEd,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAiB,OAAO;EAAmB;CAAS,CAAA;CAG7D,OACE,oBAAC,MAAM,QAAP;EACE,UAAU,CAAC,CAAC;EACC;EACR;EACA;EACL,MAAM,YAAY,OAAO,UAAU,eAAe,WAAW,IAAI,SAAS,YAAY,WAAW,OAAO,CAAC;EACzG,eAAe,UAAU,EAAE,uBAAuB,EAAE,IAAI,EAAE,aAAa,MAAM;EAC7E,OAAO;EACP,gBAAgB,MAAM,kBAAkB;GACtC,QAAQ,IAAI;GACZ,IAAI,CAAC,OAAO,MAAM,aAAa,GAAG;IAChC,cAAc,MAAM,aAAa;IAEjC,OAAO;GACT;EACF;CACD,CAAA;AAEL;;;AC1DA,IAAa,iBAAiB,EAC5B,MACA,QACA,UACA,aACA,cACA,UACA,oBACoC;CACpC,MAAM,QAAQ,SAAS,KAAK;CAC5B,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAiB,OAAO,IAAI,OAAO,MAAM,MAAM;EAAW;CAAS,CAAA;CAG5E,OACE,oBAAC,MAAM,UAAP;EACE,wBAAA;EACA,UAAU,CAAC,CAAC;EACC;EACN;EACP,gBAAgB,SAAS,cAAc,MAAM,IAAI;CAClD,CAAA;AAEL;;;;;;;ACeA,IAAM,kBAAkB,EAAE,SAAS,cAAc,eAAgC;CAC/E,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,UAAU,eAAe,SAAiB;CAkBjD,OAAO;EAAE;EAAM;EAAS;EAAU;EAAa,OAjBjC,cACN,QAAQ,KAAK,EAAE,IAAI,OAAO,mBAAmB;GAAE,OAAO;GAAI;GAAO;EAAY,EAAE,GACrF,CAAC,OAAO,CAeqC;EAAO,kBAb7B,aAAa,EAAE,WAA8B;GACpE,QAAQ,IAAI;GACZ,IAAI,CAAC,MACH,YAAY,KAAA,CAAS;EAEzB,GAAG,CAAC,CAQkD;EAAkB,aANtE,iBAAiB,KAAA,KAAa,aAAa,KAAA,KACtC,UAAkB;GACjB,YAAY,KAAK;GACjB,QAAQ,IAAI;EACd,IACA,KAAA;CAC8E;AACtF;;AAUA,IAAM,cAAc,EAAE,QAAQ,OAAO,wBAAwB,gBAAgB,QAAQ,eACnF,oBAAC,UAAD;CACE,QAAO;CACC;CACR,eAAe,yBAAyB,GAAG,yBAAyB,MAAM,IAAI,CAAC;CAC/E,UAAU;CACF;CACE;CAEV,UAAA,oBAAC,OAAO,WAAR;EAAkB,QAAO;EACvB,UAAA,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,YAAD,CAAa,CAAA,GACb,oBAAC,aAAD,CAAc,CAAA,CACH,EAAA,CAAA;CACG,CAAA;AACV,CAAA;;;;;AAiBZ,IAAa,gBAAgB,EAC3B,OACA,aACA,SACA,SACA,cACA,wBACA,gBACA,aACA,YACA,UACA,UACA,cACuB;CACvB,MAAM,EAAE,SAAS,UAAU,aAAa,OAAO,MAAM,kBAAkB,gBAAgB,eAAe;EACpG;EACA;EACA;CACF,CAAC;CACD,MAAM,aAAa,YACjB,OAAO,WAAgB;EACrB,MAAM,WAAW,MAAM;EACvB,YAAY,KAAA,CAAS;EACrB,QAAQ,KAAK;CACf,GACA,CAAC,QAAQ,CACX;CAEA,OACE,qBAAC,SAAS,MAAV;EACS;EACE;EACH;EACN,cAAc;EACd,OAAO,QAAQ,CAAC,KAAK,IAAI,CAAC;EAC1B,WAAW,EAAE,gBAAgB;GAC3B,IAAI,QAAQ,MAAM,WAAW,OAAO,OAAO,SAAS,GAClD,SAAS,cAAc,QAAQ,KAAA,IAAY,SAAS;EAExD;EACA,UAAU;EACG;EACD;EAbd,UAAA,CAeG,UACC,oBAAC,SAAS,SAAV;GAAkB,SAAA;GAAS,UAAA;EAA0B,CAAA,IAErD,oBAAC,SAAS,SAAV,EAA+B,YAAc,CAAA,GAE/C,oBAAC,SAAS,SAAV,EAAA,UACG,aAAa,KAAA,KAAa,eACzB,oBAAC,YAAD;GACE,QAAQ;GACR,OAAO;GACiB;GACR;GAChB,QAAQ;GACR,gBAAgB,YAAY,KAAA,CAAS;EACtC,CAAA,IACC,KAAA,EACY,CAAA,CACL;;AAEnB;;;;;;AAoBA,IAAa,qBAAqB,EAChC,OACA,aACA,SACA,cACA,wBACA,gBACA,aACA,YACA,UACA,eACA,SACA,SACA,eAAe,aACa;CAC5B,MAAM,EAAE,UAAU,aAAa,OAAO,MAAM,kBAAkB,gBAAgB,eAAe;EAC3F;EACA;EACA;CACF,CAAC;CACD,MAAM,aAAa,YACjB,OAAO,WAAgB;EACrB,MAAM,KAAK,MAAM,WAAW,MAAM;EAClC,IAAI,IACF,cAAc,CAAC,GAAG,OAAO,EAAE,CAAC;EAE9B,YAAY,KAAA,CAAS;CACvB,GACA;EAAC;EAAU;EAAe;CAAK,CACjC;CAEA,MAAM,WAAW,MAAM,KAAK,OAAO,QAAQ,MAAM,WAAW,OAAO,OAAO,EAAE,KAAK;EAAE;EAAI,OAAO;CAAG,CAAC;CAClG,MAAM,EAAE,cAAc,aAAa;EAAE;EAAO;CAAc,CAAC;CAC3D,OACE,qBAAC,SAAS,MAAV;EACS;EACE;EACT,UAAA;EACA,eAAe;EACT;EACN,cAAc;EACP;EACP,gBAAgB,EAAE,YAAY,cAAc,KAAK;EACjD,UAAU;EACG;EACD;EAXd,UAAA,CAaE,qBAAC,SAAS,SAAV;GAAkB,MAAA;GAAK,eAAa;GAApC,UAAA;IACG,SAAS,WAAW,KAAK,eAAe,oBAAC,WAAW,MAAZ;KAAiB,MAAK;KAAS,UAAA;IAA6B,CAAA;IACpG,SAAS,KAAK,WACb,oBAAC,MAAI,KAAL;KAEE,KAAK,KAAK,MAAM,QAAQ,QAAQ,OAAO,GAAG;KAC1C,gBAAgB,cAAc,MAAM,QAAQ,OAAO,OAAO,OAAO,EAAE,CAAC;KACpE,GAAK,WAAW,UAAU,OAAO,EAAE;KAElC,UAAA,OAAO;IACD,GANF,OAAO,EAML,CACV;IACD,oBAAC,SAAS,SAAV,CAAmB,CAAA;GACH;EAClB,CAAA,GAAA,oBAAC,SAAS,SAAV,EAAA,UACG,aAAa,KAAA,KAAa,eACzB,oBAAC,YAAD;GACE,QAAQ;GACR,OAAO;GACiB;GACR;GAChB,QAAQ;GACR,gBAAgB,YAAY,KAAA,CAAS;EACtC,CAAA,IAED,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,SAAS,OAAV,CAAiB,CAAA,GACjB,oBAAC,SAAS,MAAV,CAAgB,CAAA,CAChB,EAAA,CAAA,EAEY,CAAA,CACL;;AAEnB;;AAKA,IAAM,UAAU;;;;;AAMhB,IAAM,gBAAgB,EAAE,OAAO,oBAAsC;CACnE,MAAM,CAAC,SAAS,cAAc,SAAiB;CAC/C,MAAM,SAAS,OAA2B,IAAI;CAC9C,gBAAgB;EACd,IAAI,SAAS;GACX,OAAO,SAAS,cAA2B,IAAI,QAAQ,IAAI,IAAI,OAAO,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM;GAC3F,WAAW,KAAA,CAAS;EACtB;CACF,GAAG,CAAC,SAAS,KAAK,CAAC;CAEnB,MAAM,QAAQ,IAAY,OAAe;EACvC,MAAM,OAAO,MAAM,QAAQ,EAAE;EAC7B,IAAI,OAAO,KAAK,KAAK,KAAK,MAAM,MAAM,UAAU,SAAS,IACvD;EAEF,MAAM,OAAO,CAAC,GAAG,KAAK;EACtB,UAAU,MAAM,MAAM,EAAE;EACxB,cAAc,IAAI;CACpB;CAEA,MAAM,aAAa,QAAgB;GAChC,UAAU;EACX,aAAa;EACb,YAAY;EACZ,qBAAqB;EACrB,cAAc,UAAsC;GAClD,MAAM,OAAO,MAAM,QAAQ,cAAc,KAAK,MAAM,QAAQ,eAAe,IAAI;GAC/E,IAAI,MAAM,UAAU,SAAS,KAAK,MAAM,WAAW,MAAM,eAAe;IACtE,MAAM,eAAe;IACrB,OAAO,UAAU,MAAM,cAAc;IACrC,KAAK,IAAI,MAAM,QAAQ,EAAE,IAAI,IAAI;IACjC,WAAW,EAAE;GACf;EACF;EACA,gBAAgB,UAAkC;GAChD,MAAM,aAAa,QAAQ,WAAW,EAAE;GACxC,MAAM,aAAa,gBAAgB;EACrC;EACA,eAAe,UAAkC;GAC/C,IAAI,MAAM,aAAa,MAAM,SAAS,SAAS,GAC7C,MAAM,eAAe;EAEzB;EACA,WAAW,UAAkC;GAC3C,MAAM,UAAU,MAAM,aAAa,QAAQ,SAAS;GACpD,IAAI,SAAS;IACX,MAAM,eAAe;IACrB,KAAK,SAAS,MAAM,QAAQ,EAAE,CAAC;GACjC;EACF;CACF;CAEA,OAAO,EAAE,UAAU;AACrB;;AAGA,IAAM,YAAY;;;AC3UlB,IAAM,iBAAiB,QAAqC;CAC1D,OAAO,OAAO,QAAQ,YAAY,OAAQ,MAAc,SAAS;AACnE;;;;;;;;;;AAWA,IAAa,iBAAiB,OAAgB,YAAgD;CAC5F,MAAM,QAAQ,IAAI,MAAM,KAAK;CAC7B,IAAI,CAAC,SAAS,CAAC,cAAc,KAAK,GAChC;CAEF,MAAM,WAAW,QAAQ,MAAM,MAAM,MAAM;CAG3C,MAAM,cAAc,QAAQ,MAAM,WAAW,OAAO,OAAO,QAAQ;CACnE,IAAI,aACF,OAAO;CAET,MAAM,WAAW,MAAI,SAAS,QAAQ;CACtC,IAAI,CAAC,UACH;CAEF,MAAM,eAAe,MAAI,WAAW,QAAQ;CAC5C,MAAM,aAAa,MAAI,QAAQ,QAAQ;CACvC,OAAO,QAAQ,MAAM,WAAW;EAC9B,MAAM,YAAY,MAAI,SAAS,OAAO,EAAE;EACxC,IAAI,CAAC,WACH,OAAO;EAET,MAAM,gBAAgB,MAAI,WAAW,SAAS;EAC9C,IAAI,gBAAgB,QAAQ,iBAAiB,QAAQ,iBAAiB,eACpE,OAAO;EAET,OAAO,MAAI,OAAO,MAAI,QAAQ,SAAS,GAAG,UAAU;CACtD,CAAC;AACH;;;;;;;;;;;;;ACjCA,IAAa,gBAAgB;;;;;;AAO7B,IAAa,gBAAgB,WAC3B,OAGE,OAAO,KACL,UAAU,aACR,OAAO,OAAO,GACX,gBAAgB,OAAO,MAAM,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,SAAS,EAAE,OAAO,OAAO,CAAC,GAAG,OAAO,QAAQ,EAC1G,CAAC,CAAC,CAAC,KACH,OAAO,GACT,CACF,CACF;AAEF,IAAM,QAAQ,IAAI,WAAW,IAAI,GAAG;;;;;;;;;;;;;;AAepC,IAAa,uBAA0B,YACrC,QAAQ,QAAQ,WAAW,CAAC,MAAM,MAAM,KAAK,IAAI,UAAU,MAAM,CAAC;;;;;;AAOpE,IAAM,cAAc,QAAoC;CACtD,MAAM,SAAS,MAAI,SAAS,GAAG;CAC/B,OAAO,SAAS,MAAI,YAAY,MAAM,IAAI,KAAA;AAC5C;;;;;;;;;;;;;;;;AAiBA,IAAa,qBACX,MACA,eACoE;CACpE,MAAM,8BAAc,IAAI,IAAY;CACpC,KAAK,MAAM,aAAa,YACtB,IAAI,MAAM,SAAS,KAAK,IAAI,cAAc,SAAS,GAAG;EACpD,MAAM,KAAK,WAAW,IAAI,OAAO,SAAS,CAAC,CAAC,SAAS,CAAC;EACtD,IAAI,OAAO,KAAA,GACT,YAAY,IAAI,EAAE;CAEtB;CAGF,MAAM,WAA+B,CAAC;CACtC,MAAM,YAAgC,CAAC;CACvC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,KAAK,WAAW,IAAI,GAAG;EAC7B,CAAC,OAAO,KAAA,KAAa,YAAY,IAAI,EAAE,IAAI,YAAY,SAAA,CAAU,KAAK,GAAG;CAC3E;CAEA,OAAO;EAAE;EAAU;CAAU;AAC/B;;;;ACxFA,IAAa,eAAe,KAAK,YAAY,IAAI,GAAG;;;;;AAMpD,IAAa,qBAAmE,IAAI,aAAa;CAC/F,MAAM,UAAU,SACd,IACA,CAAC,WACG,MAAM,OAAO,OAAO,QAAQ,CAAC,IAC7B,aAAa,sBACX,MAAM,OAAO,OAAO,WAAW,CAAC,IAChC,MAAM,OAAO,OAAO,KAAK,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,CAC1F;CACA,MAAM,aAAa,aAAa;CAChC,OAAO,cAAe,aAAa,oBAAoB,OAAO,IAAI,SAAU,CAAC,YAAY,OAAO,CAAC;AACnG;;AAGA,IAAa,qBAAmE,YAC9E,QAAQ,KAAK,WAAW;CACtB,MAAM,KAAK,OAAO,OAAO,QAAQ,EAAE,QAAQ,QAAQ,CAAC;CACpD,MAAM,MAAM,IAAI,WAAW,IAAI,KAAK,MAAM,IAAI,KAAK,MAAM,QAAQ,QAAQ,OAAO,GAAG,IAAI,KAAA;CACvF,OAAO;EAAE;EAAI,OAAO,OAAO,SAAS,MAAM,KAAK;EAAI,GAAI,OAAO,EAAE,IAAI;CAAG;AACzE,CAAC;;;;;AAaH,IAAa,oBAAoB,YAAkC;CACjE,MAAM,EACJ,SACA,IACA,SAAA,YAAU,SACV,aAAa,mBACb,aAAa,mBACb,mBACA,UACA,uBACE;CACJ,MAAM,EAAE,MAAM,MAAM,eAAe;CACnC,MAAM,WAAW,cACT,SAAS,eAAyC,SAAS,qBAAqB,CAAC,EAAE,UACzF,CAAC,OAAO,CACV;CACA,MAAM,UAAU,WAAW,IAAI,QAAQ;CACvC,MAAM,aAAa,cAAc,WAAW,OAAO,GAAG,CAAC,SAAS,UAAU,CAAC;CAC3E,MAAM,SAAS,UAAQ,IAAI,YAAY,aAAa,sBAAsB,IAAI,KAAK,QAAQ,IAAI,KAAA,CAAS;CAExG,MAAM,cAAc,WAAW,qBAAqB,QAAQ,IAAI,KAAA;CAChE,MAAM,eAAe,cACb,aAAa,gBAAgB,UAAU,qBAAqB,OAAO,KAAK,UAAU,MAAM,CAAC,CAAC,IAChG,CAAC,aAAa,MAAM,CACtB;CAEA,MAAM,UAAU,YACd,OAAO,WACL,aAAa,gBAAgB,KACzB,MAAM,YAAY,aAAa,QAAQ,EAAE,IACzC,UAAU,WACR,MAAM,SAAS,QAAQ,MAAM,IAC7B,KAAA,GACR;EAAC;EAAa;EAAI;EAAQ;CAAQ,CACpC;CAUA,OAAO;EACL;EACA;EACA;EACA,SAAS;EACT;EACA,aAdkB,cAAc;GAChC,IAAI,CAAC,mBACH;GAEF,MAAM,CAAC,KAAK,EAAE,QAAQ;GACtB,QAAQ,UAAkB,EAAE,KAAK;IAAE;IAAI,MAAM;IAAO,eAAe,EAAE,aAAa,MAAM;GAAE,CAAC;EAC7F,GAAG,CAAC,mBAAmB,CAAC,CAQtB;EAEA,QAAQ,YAAY,aAAa,eAAe,UAAU,KAAA;CAC5D;AACF;;;;;;;AChFA,IAAa,wBAAwB,MAAqB,aAAiC;CACzF,MAAM,eAAe,OAAO,eAAe,WAAW,4BAA4B,WAAW,IAAI,CAAC;CAClG,OAAO;EACL,SAAS,cAAc,YAAY,aAAa,eAAe,QAAQ;EACvE,SACE,cAAc,WAAW,WAAW,sBAAsB,WAAW,IAAI,CAAC,CAAC,KAAK,OAAO,gBAAgB,KAAK,CAAC;EAC/G,aAAa,cAAc;CAC7B;AACF;;;;;;;AAeA,IAAa,iBAAiB,EAC5B,MACA,aACA,UACA,OACA,aACA,cACA,UACA,UACA,eACA,wBACA,gBACA,kBACA,GAAG,YACqB;CACxB,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,EAAE,UAAU,QAAQ,SAAS,cAAc,aAAa,WAAW,iBAAiB;EACxF,GAAG;EACH,SAAS;CACX,CAAC;CACD,MAAM,EAAE,SAAS,SAAS,gBAAgB,qBAAqB,MAAM,QAAQ;CAC7E,MAAM,QAAQ,SAAS,KAAK,CAAC,EAAA,CAAG,OAAO,IAAI,KAAK,CAAC,CAAC,SAAS,QAAQ;EACjE,MAAM,KAAK,cAAc,KAAK,OAAO,CAAC,EAAE;EACxC,OAAO,KAAK,CAAC;GAAE;GAAI;EAAI,CAAC,IAAI,CAAC;CAC/B,CAAC;CACD,MAAM,MAAM,KAAK,KAAK,EAAE,SAAS,EAAE;CACnC,MAAM,UAAU,SACd,cACE,MACA,KAAK,KAAK,OAAO,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC,CAC5C;CACF,MAAM,UACJ,WACC,OAAO,WAAgB;EACtB,MAAM,UAAU,MAAM,OAAO,MAAM;EACnC,OAAO,UAAU,OAAO,OAAO,SAAS,EAAE,QAAQ,QAAQ,CAAC,IAAI,KAAA;CACjE;CACF,MAAM,cAAc;EAClB;EACA;EACA;EACA;EACA;EACA,YAAY;CACd;CACA,MAAM,WAAW,YAAY,gBAAgB,YAAY,CAAC,CAAC;CAC3D,IAAI,CAAC,UACH,OAAO;CAGT,IAAI,YAAY,SACd,OACE,oBAAC,WAAD;EACS;EACF;EACI;EACT,SAAS,IAAI,IAAI,KAAK,KAAK,EAAE,IAAI,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;EAC5D,MAAM,UAAU,OAAO,eAAe,WAAW,eAAe,IAAI,KAAK,UAAU,MAAM,CAAC,CAAC;EAC9E;EACJ;EACT,UAAU;EACV,QAAQ;EACR,UAAU;EAET,UAAA,CAAC,YACA,oBAAC,cAAD;GACE,GAAI;GACJ,SAAS,QAAQ,QAAQ,WAAW,CAAC,IAAI,SAAS,OAAO,EAAE,CAAC;GAC5D,aAAa,eAAe,EAAE,uBAAuB;GACrD,WAAW,OAAO,MAAM,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC;GAC3C,UACE,YACC,OAAO,WAAW;IACjB,MAAM,KAAK,MAAM,QAAQ,MAAM;IAC/B,IAAI,IACF,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC;GAEvB;EAEH,CAAA;CAEM,CAAA;CAIf,IAAI,UAAU;EACZ,MAAM,WAAW,IAAI,SAAS,OAAO,QAAQ,MAAM,WAAW,OAAO,OAAO,EAAE,KAAK,CAAC,CAAC;EACrF,OAAO,SAAS,WAAW,IACzB,oBAAC,WAAW,MAAZ;GAAiB,MAAK;GAAS,UAAA,EAAE,gCAAgC;EAAmB,CAAA,IAEpF,oBAAC,OAAO,OAAR,EAAA,UACG,SAAS,KAAK,WACb,oBAAC,MAAI,KAAL;GAAyB,KAAK,KAAK,MAAM,QAAQ,QAAQ,OAAO,GAAG;GAChE,UAAA,OAAO;EACD,GAFK,OAAO,EAEZ,CACV,EACW,CAAA;CAElB;CAEA,OACE,oBAAC,mBAAD;EACE,GAAI;EACJ,OAAO;EACE;EACT,aAAa,eAAe;EAC5B,eAAa;EACb,UAAU;EACV,eAAe;CAChB,CAAA;AAEL;;AAmBA,IAAM,YAAY,QAAmB,QACnC,IAAI,cAAc,IAAI,iBAAiB;CAAE,KAAK,OAAO;CAAI,OAAO,OAAO;CAAO,SAAS;AAAI,CAAC,CAAC;;AAG/F,IAAM,aAAa,EACjB,OACA,KACA,SACA,SACA,MACA,aACA,SACA,UACA,QACA,UACA,eACoB;CACpB,MAAM,OAAO,cAET,IAAI,SAAS,OAAO;EAClB,MAAM,SAAS,QAAQ,MAAM,WAAW,OAAO,OAAO,EAAE;EACxD,IAAI,CAAC,QACH,OAAO,CAAC;EAGV,MAAM,SAAS,QAAQ,IAAI,EAAE;EAC7B,MAAM,QAAQ,eAAe,IAAI,SAAS,MAAM,IAAI,IAAI,SAAS,QAAQ,CAAC,WAAW,CAAC,IAAI,KAAA;EAC1F,OAAO,CAAC;GAAE,GAAG;GAAQ,aAAa,OAAO,UAAU,WAAW,QAAQ,OAAO;EAAY,CAAC;CAC5F,CAAC,GACH;EAAC;EAAK;EAAS;EAAS;CAAW,CACrC;CACA,MAAM,UAAU,KAAK,MAAM,QAAQ,QAAQ,MAAM,GAAG;CAEpD,MAAM,cAAc,MAAc,OAAe;EAC/C,MAAM,OAAO,CAAC,GAAG,GAAG;EACpB,UAAU,MAAM,MAAM,EAAE;EACxB,SAAS,IAAI;CACf;CAGA,MAAM,eAAe,YAAuB,UAAmC;EAC7E,IAAI,EAAE,MAAM,kBAAkB,WAAW,MAAM,OAAO,QAAQ,QAAQ,IACpE,SAAS,QAAQ,MAAM,aAAa;CAExC;CAGA,MAAM,iBAAiB,UAAsC;EAC3D,IAAI,MAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,eAClD;EAEF,MAAM,MAAM,MAAM,cAAc,cAA2B,wCAAsC;EACjG,MAAM,SAAS,KAAK,MAAM,WAAW,OAAO,OAAO,KAAK,QAAQ,KAAK;EACrE,IAAI,OAAO,QAAQ;GACjB,MAAM,eAAe;GACrB,SAAS,QAAQ,GAAG;EACtB;CACF;CAEA,OACE,qBAAA,YAAA,EAAA,UAAA;EACE,oBAAC,MAAM,QAAP,EAAA,UACE,oBAAC,WAAW,MAAZ;GAAiB,UAAA;GAAU,UAAA;EAAuB,CAAA,EACtC,CAAA;EACb,KAAK,SAAS,KACb,oBAAC,YAAY,MAAb;GACE,OAAO;GACP,QAAQ,WAAW,OAAO;GAC1B,WAAW,WAAW,OAAO;GAC7B,QAAQ;GACR,UAAU,YAAY,CAAC;GAErB,WAAA,EAAE,YACF,oBAAC,YAAY,SAAb;IACE,QAAQ;IACR,QAAO;IACP,cAAY;IACZ,eAAa;IACb,WAAW;IAEV,UAAA,MAAM,KAAK,WACV,qBAAC,YAAY,MAAb;KAEE,IAAI,OAAO;KACX,SAAS,WAAW,CAAC;KACrB,SAAS,YAAY,MAAM;KAJ7B,UAAA;MAMG,WAAW,CAAC,YAAY,oBAAC,YAAY,YAAb,CAAyB,CAAA;MACjD,QAAQ,oBAAC,YAAY,UAAb;OAAsB,MAAM,KAAK;OAAM,KAAK;MAAU,CAAA;MAC/D,oBAAC,YAAY,UAAb,EAAA,UAAuB,OAAO,MAA4B,CAAA;MACzD,OAAO,eACN,oBAAC,YAAY,iBAAb,EAAA,UAA8B,OAAO,YAAyC,CAAA;MAE/E,CAAC,YACA,oBAAC,aAAa,QAAd;OACE,SAAQ;OACR,eAAe,SAAS,IAAI,QAAQ,OAAO,OAAO,OAAO,EAAE,CAAC;MAC7D,CAAA;KAEa;IAjBX,GAAA,OAAO,EAiBI,CACnB;GACkB,CAAA;EAEP,CAAA;EAEnB;CACD,EAAA,CAAA;AAEN;;;;;;;;AC3QA,IAAa,YAAY,EACvB,MACA,UACA,OACA,aACA,cACA,UACA,eACA,wBACA,gBACA,kBACA,GAAG,YACgB;CACnB,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,EAAE,UAAU,SAAS,cAAc,aAAa,WAAW,iBAAiB;EAAE,GAAG;EAAO,SAAS;CAAK,CAAC;CAC7G,MAAM,WAAW,cAAc,SAAS,GAAG,OAAO;CAClD,IAAI,CAAC,UACH,OAAO;CAET,IAAI,YAAY,gBAAgB,YAAY,CAAC,CAAC,UAC5C,OACE,oBAAC,WAAW,MAAZ;EAAiB,UAAA;EAAS,MAAM,WAAW,YAAY;EACpD,UAAA,UAAU,SAAS,EAAE,gCAAgC;CACvC,CAAA;CAIrB,OACE,oBAAC,cAAD;EACW;EACT,OAAO,UAAU;EACjB,aAAa,eAAe,SAAS,EAAE,uBAAuB;EAChD;EACU;EACR;EACH;EACb,YAAY;EACZ,UACE,WACC,OAAO,WAAW;GACjB,MAAM,UAAU,MAAM,OAAO,MAAM;GACnC,IAAI,SACF,cAAc,MAAM,IAAI,KAAK,OAAO,CAAC;EAEzC;EAEF,WAAW,OAAO,cAAc,MAAM,KAAK,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC,IAAI,KAAA,CAAS;CACjF,CAAA;AAEL;;;;ACnDA,IAAM,WAAW,YAAqC;CACpD,MAAM,OAAO,IAAI,IAAI,QAAQ,KAAK,WAAW,OAAO,KAAK,CAAC;CAC1D,MAAM,SAAS,KAAK,QAAQ,QAAQ,CAAC,KAAK,IAAI,GAAG,CAAC;CAClD,IAAI,OAAO,SAAS,GAClB,OAAO,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,MAAM;CAExD,MAAM,SAAS,IAAI,IAAI,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK,WAAW,OAAO,KAAK,CAAC;CACtE,MAAM,YAAY,KAAK,QAAQ,QAAQ,CAAC,OAAO,IAAI,GAAG,CAAC;CACvD,OAAO,UAAU,KAAK,MAAM,KAAK,OAAO,IAAI,UAAU,MAAM,MAAM,KAAK;AACzE;;;;;;AAOA,IAAa,qBAAqB,EAChC,MACA,OACA,UACA,UACA,oBACwD;CACxD,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,UAAU,SAAS;CACzB,MAAM,CAAC,YAAY,iBAAiB,SAAiB;CAErD,gBAAgB;EACd,IAAI,YAAY,KAAA,GACd,cAAc,MAAM,CAAC,CAAC;CAE1B,GAAG;EAAC;EAAS;EAAM;CAAa,CAAC;CAEjC,MAAM,SAAS,aACZ,IAAY,WACX,cACE,OACC,WAAW,CAAC,EAAA,CAAG,KAAK,WAAY,OAAO,OAAO,KAAK;EAAE,GAAG;EAAQ,GAAG;CAAO,IAAI,MAAO,CACxF,GACF;EAAC;EAAS;EAAM;CAAa,CAC/B;CAEA,MAAM,YAAY,kBAAkB;EAClC,MAAM,KAAK,UAAU,OAAO,CAAC,CAAC,SAAS;EACvC,cAAc,MAAM,CAAC,GAAI,WAAW,CAAC,GAAI;GAAE;GAAI,OAAO;GAAI,OAAO,QAAQ,WAAW,CAAC,CAAC;EAAE,CAAC,CAAC;EAC1F,cAAc,EAAE;CAClB,GAAG;EAAC;EAAS;EAAM;CAAa,CAAC;CAEjC,MAAM,aAAa,aAChB,MAAc,OAAe;EAC5B,MAAM,OAAO,CAAC,GAAI,WAAW,CAAC,CAAE;EAChC,UAAU,MAAM,MAAM,EAAE;EACxB,cAAc,MAAM,IAAI;CAC1B,GACA;EAAC;EAAS;EAAM;CAAa,CAC/B;CAEA,OACE,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,YAAY,MAAb;EACE,OAAO,WAAW,CAAC;EACnB,QAAQ,WAAW,OAAO;EAC1B,WAAW,WAAW,OAAO;EAC7B,QAAQ;EACR,UAAU,CAAC,CAAC;EAEV,WAAA,EAAE,YACF,oBAAC,YAAY,SAAb;GAAqB,QAAQ;GAAO,QAAO;GAAU,cAAY;GAC9D,UAAA,MAAM,KAAK,WACV,qBAAC,YAAY,MAAb;IAEE,IAAI,OAAO;IACX,SAAS,CAAC;IACV,MAAM,eAAe,OAAO;IAC5B,eAAe,SAAS,cAAc,OAAO,OAAO,KAAK,KAAA,CAAS;IAClE,eAAa,UAAU,OAAO;IANhC,UAAA;KAQE,oBAAC,YAAY,YAAb,CAAyB,CAAA;KACzB,oBAAC,YAAY,UAAb,EAAA,UACE,oBAAC,MAAI,KAAL;MAAS,KAAK,KAAK,MAAM,QAAQ,QAAQ,OAAO,KAAK;MAAI,UAAA,OAAO,SAAS;KAAkB,CAAA,EACvE,CAAA;KACrB,CAAC,YACA,oBAAC,OAAO,MAAR;MACE,UAAA;MACA,SAAQ;MACR,MAAK;MACL,OAAO,EAAE,6BAA6B;MACtC,eACE,cACE,OACC,WAAW,CAAC,EAAA,CAAG,QAAQ,SAAS,KAAK,OAAO,OAAO,EAAE,CACxD;KAEH,CAAA;KAEH,oBAAC,YAAY,QAAb,EAAA,UACE,qBAAC,OAAO,WAAR;MAAkB,QAAO;MAAM,QAAO;MAAO,SAAQ;MAAgC,KAAI;MAAzF,UAAA,CACE,qBAAC,MAAM,MAAP,EAAA,UAAA,CACE,oBAAC,MAAM,OAAP,EAAA,UAAc,EAAE,qBAAqB,EAAe,CAAA,GACpD,oBAAC,MAAM,MAAP;OACE,WAAW,eAAe,OAAO,MAAM,OAAO,UAAU;OACxD,UAAU,CAAC,CAAC;OACZ,aAAa,EAAE,iCAAiC;OAChD,OAAO,OAAO;OACd,WAAW,UAAU,OAAO,OAAO,IAAI,EAAE,OAAO,MAAM,OAAO,MAAM,CAAC;OACpE,YAAY,UAAU,MAAM,QAAQ,WAAW,cAAc,KAAA,CAAS;MACvE,CAAA,CACS,EAAA,CAAA,GACZ,qBAAC,MAAM,MAAP,EAAA,UAAA,CACE,oBAAC,MAAM,OAAP,EAAA,UAAc,EAAE,2BAA2B,EAAe,CAAA,GAC1D,oBAAC,WAAD;OACE,OAAO,OAAO;OACJ;OACV,gBAAgB,UAAU,SAAS,OAAO,OAAO,IAAI,EAAE,MAAM,CAAC;MAC/D,CAAA,CACS,EAAA,CAAA,CACI;KACA,CAAA,EAAA,CAAA;IACJ;GAhDX,GAAA,OAAO,EAgDI,CACnB;EACkB,CAAA;CAEP,CAAA,GACjB,CAAC,YACA,oBAAC,OAAO,OAAR,EAAA,UACE,oBAAC,OAAO,MAAR;EAAa,MAAK;EAAoB,OAAO,EAAE,0BAA0B;EAAG,SAAS;CAAY,CAAA,EACrF,CAAA,CAEhB,EAAA,CAAA;AAEN;;;AC7IA,IAAa,iBAAiB,EAC5B,MACA,QACA,UACA,aACA,cACA,UACA,eACA,aACoC;CACpC,MAAM,QAAQ,SAAS,KAAK;CAC5B,IAAI,gBAAgB,YAAY,CAAC,CAAC,UAChC,OAAO,oBAAC,iBAAD;EAAwB;EAAe;CAAS,CAAA;CAGzD,OACE,oBAAC,MAAM,UAAP;EACE,YAAA;EACA,UAAU,CAAC,CAAC;EACC;EACN;EACP,WAAW,UAAU,cAAc,MAAM,MAAM,OAAO,KAAK;EACnD;CACT,CAAA;AAEL;;;ACTA,IAAa,mBAAb,cAAsC,MAAM;CAI/B;CAHX,OAAgB;CAChB,YACE,SACA,UACA;EACA,MAAM,aAAa,KAAA,IAAY,GAAG,QAAQ,gBAAgB,SAAS,KAAK,OAAO;EAFtE,KAAA,WAAA;CAGX;AACF;AAEA,IAAM,SAAS;AACf,IAAM,UAAU;AAMhB,IAAM,cAAc,QAAwC;CAC1D,MAAM,QAAgC,CAAC;CACvC,QAAQ,YAAY;CACpB,IAAI;CACJ,QAAQ,QAAQ,QAAQ,KAAK,GAAG,OAAO,MAAM;EAC3C,MAAM,GAAG,KAAK,cAAc,cAAc,QAAQ;EAClD,MAAM,OAAO,gBAAgB,gBAAgB;CAC/C;CACA,OAAO;AACT;AAEA,IAAM,YAAY,UAA2B;CAC3C,MAAM,SAAkB,CAAC;CACzB,OAAO,YAAY;CACnB,IAAI;CACJ,IAAI,SAAS;CACb,QAAQ,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM;EAE5C,MAAM,UAAU,MAAM,MAAM,QAAQ,MAAM,KAAK;EAC/C,IAAI,QAAQ,KAAK,CAAC,CAAC,SAAS,GAC1B,MAAM,IAAI,iBAAiB,4BAA4B,KAAK,UAAU,QAAQ,KAAK,CAAC,KAAK,MAAM;EAEjG,MAAM,GAAG,OAAO,MAAM,UAAU,aAAa;EAC7C,IAAI,OACF,OAAO,KAAK;GAAE,MAAM;GAAS;GAAM,UAAU,MAAM;EAAM,CAAC;OAE1D,OAAO,KAAK;GACV,MAAM;GACN;GACA,OAAO,WAAW,QAAQ;GAC1B,aAAa,cAAc;GAC3B,UAAU,MAAM;EAClB,CAAC;EAEH,SAAS,MAAM,QAAQ,MAAM,EAAE,CAAC;CAClC;CAEA,MAAM,WAAW,MAAM,MAAM,MAAM;CACnC,IAAI,SAAS,KAAK,CAAC,CAAC,SAAS,GAC3B,MAAM,IAAI,iBAAiB,4BAA4B,KAAK,UAAU,SAAS,KAAK,CAAC,KAAK,MAAM;CAElG,OAAO;AACT;AAEA,IAAM,eAAe,OAA+B,KAAa,KAAa,aAA6B;CACzG,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,iBAAiB,IAAI,IAAI,gCAAgC,IAAI,IAAI,QAAQ;CAErF,OAAO;AACT;AAEA,IAAM,gBAAgB,OAAe,MAAc,KAAa,aAA6B;CAC3F,IAAI,CAAC,QAAQ,KAAK,KAAK,GACrB,MAAM,IAAI,iBACR,IAAI,IAAI,eAAe,KAAK,4BAA4B,KAAK,UAAU,KAAK,KAC5E,QACF;CAEF,OAAO,OAAO,SAAS,OAAO,EAAE;AAClC;;AAGA,IAAa,eAAe,aAAiC;CAC3D,MAAM,SAAS,SAAS,QAAQ;CAChC,IAAI,OAAO,WAAW,GACpB,MAAM,IAAI,iBAAiB,gBAAgB;CAG7C,IAAI,QAAQ;CAEZ,MAAM,kBAA8B;EAClC,MAAM,QAAQ,OAAO;EACrB,IAAI,CAAC,SAAS,MAAM,SAAS,QAC3B,MAAM,IAAI,iBAAiB,gCAAgC,KAAK,UAAU,KAAK,KAAK,OAAO,QAAQ;EAGrG,IAAI,MAAM,SAAS,SAAS;GAC1B,IAAI,CAAC,MAAM,aACT,MAAM,IAAI,iBAAiB,2DAAyD,MAAM,QAAQ;GAEpG,MAAM,OAAO,YAAY,MAAM,OAAO,QAAQ,SAAS,MAAM,QAAQ;GACrE,MAAM,UAAU,MAAM,MAAM;GAC5B,MAAM,OAAO,YAAY,KAAA,IAAY,aAAa,SAAS,QAAQ,SAAS,MAAM,QAAQ,IAAI,KAAA;GAC9F,SAAS;GACT,OAAO;IAAE,MAAM;IAAS;IAAM;GAAK;EACrC;EAEA,IAAI,MAAM,SAAS,QAAQ;GACzB,IAAI,MAAM,aACR,MAAM,IAAI,iBAAiB,iDAAiD,MAAM,QAAQ;GAE5F,MAAM,OAAO,aACX,YAAY,MAAM,OAAO,QAAQ,QAAQ,MAAM,QAAQ,GACvD,QACA,QACA,MAAM,QACR;GACA,SAAS;GACT,MAAM,WAAyB,CAAC;GAChC,OAAO,QAAQ,OAAO,UAAU,EAAE,OAAO,MAAM,CAAC,SAAS,WAAW,OAAO,MAAM,CAAC,SAAS,SACzF,SAAS,KAAK,UAAU,CAAC;GAE3B,MAAM,UAAU,OAAO;GACvB,IAAI,CAAC,WAAW,QAAQ,SAAS,WAAW,QAAQ,SAAS,QAC3D,MAAM,IAAI,iBAAiB,qBAAqB,MAAM,QAAQ;GAEhE,SAAS;GACT,MAAM,QAAQ,MAAM,MAAM,UAAU;GACpC,OAAO;IAAE,MAAM;IAAQ;IAAM,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;IAAI;GAAS;EACrE;EAEA,MAAM,IAAI,iBAAiB,oBAAoB,MAAM,KAAK,IAAI,MAAM,QAAQ;CAC9E;CAEA,MAAM,OAAO,UAAU;CACvB,IAAI,UAAU,OAAO,QAAQ;EAC3B,MAAM,WAAW,OAAO;EACxB,MAAM,IAAI,iBACR,4BAA4B,SAAS,SAAS,SAAS,KAAK,MAAM,SAAS,KAAK,IAChF,SAAS,QACX;CACF;CACA,IAAI,KAAK,SAAS,QAChB,MAAM,IAAI,iBAAiB,6BAA6B;CAE1D,OAAO;AACT;;;ACrJA,IAAM,mBAAmB;;;;;;AAezB,IAAa,cAAc,EACzB,QACA,UACA,OAAO,WAAW,qBAClB,MACA,GAAG,YACkB;CACrB,MAAM,YAAY,OAAO,eAAe,WAAW,qBAAqB,IAAI,MAAM,CAAC;CACnF,MAAM,SAAS,YAAY,YAAY;CACvC,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,iBACR,YACI,oBAAoB,KAAK,0BAA0B,OAAO,KAAK,SAAS,CAAC,CAAC,KAAK,IAAI,KAAK,IAAI,KAC5F,6DACN;CAGF,MAAM,OAAO,cAAc,YAAY,MAAM,GAAG,CAAC,MAAM,CAAC;CACxD,OAAO,oBAAC,gBAAD;EAAgB,MAAM;EAAc;EAAQ,UAAU,QAAQ,CAAC;EAAG,GAAI;CAAQ,CAAA;AACvF;AAEA,WAAW,cAAc;AAOzB,IAAM,kBAAkB,EAAE,MAAM,QAAQ,UAAU,GAAG,YAAiC;CACpF,IAAI,KAAK,SAAS,QAChB,OACE,oBAAC,OAAO,WAAR;EACE,QAAO;EACP,QAAO;EACP,OAAM;EACN,KAAI;EACJ,SAAS,UAAU,KAAK,KAAK;EAC7B,OAAO,KAAK;EAEX,UAAA,KAAK,SAAS,KAAK,OAAO,UACzB,oBAAC,UAAD,EAAA,UACE,oBAAC,gBAAD;GAAgB,MAAM;GAAe;GAAkB;GAAU,GAAI;EAAQ,CAAA,EACrE,GAFK,KAEL,CACX;CACe,CAAA;CAItB,MAAM,WAAW,mBAAmB,QAAQ,KAAK,IAAI;CACrD,IAAI,CAAC,UACH,MAAM,IAAI,iBAAiB,UAAU,KAAK,KAAK,sBAAsB;CAGvE,MAAM,EAAE,MAAM,UAAU,UAAU,OAAO,WAAW,aAAa;CACjE,MAAM,OAAO,CAAC,GAAG,UAAU,GAAG,QAAQ;CACtC,OAEE,oBAAC,OAAO,WAAR;EAAkB,QAAO;EAAO,MAAM,KAAK;EACzC,UAAA,oBAAC,wBAAD;GAA8B;GAC3B,UAAA,YACC,oBAAC,YAAD;IACE,QAAQ,OAAO,KAAK,SAAS;IAC7B,OAAO,SAAS,IAAO,WAAW,QAAQ;IACpC;IACN,QAAQ,MAAM;GACf,CAAA,IAED,oBAAC,mBAAD;IAAyB;IAAM,MAAM;IAAgB;IAAgB;IAAU,GAAI;GAAQ,CAAA;EAEvE,CAAA;CACR,CAAA;AAEtB;;AAUA,IAAM,cAAc,EAAE,QAAQ,OAAO,MAAM,aAA8B;CACvE,MAAM,EAAE,aAAa,kBAAkB,kBAAkB,IAAI;CAC7D,MAAM,QAAQ,SAAS;CACvB,MAAM,OAAO,SAAS,OAAO,KAAA,IAAY,WAAW,mBAAmB,QAAQ,KAAK;CACpF,IAAI,QAAQ,QAAQ,KAAK,KAAK,CAAC,CAAC,WAAW,GACzC,OAAO;CAGT,OACE,oBAAC,cAAD;EAAqB;EAAO,UAAA;EAAS,YAAA;EAAW,cAAc;EAC5D,UAAA,oBAAC,WAAW,MAAZ;GAAiB,UAAA;GAAU,UAAA;EAAsB,CAAA;CACrC,CAAA;AAElB;;AAGA,IAAa,wBAAwB,EACnC,QACA,GAAG,YAC6E;CAChF,MAAM,EAAE,MAAM,SAAS,UAAU,QAAQ,SAAS,GAAG,YAAY,eAAe,gBAAgB;CAChG,MAAM,WAAW,UAAU,KAAK;CAChC,OAAO,WAAW,oBAAC,YAAD;EAAY,QAAQ;EAAU,GAAI;EAAS,GAAI;CAAQ,CAAA,IAAI;AAC/E;AAEA,qBAAqB,cAAc;;;AC/HnC,IAAa,kBAAkB,SAC7B,SAAS,KAAA,IACL,CAAC,IACD,OAAO,SAAS,WACd,SAAS,WAAW,IAAI,IACtB,SAAS,cAAc,IAAI,IAC3B,CAAC,IACH;;;;AAkCR,IAAa,2BAA2B,EACtC,QACA,SACA,SACA,QACA,YACA,QACA,WAC8D;CAG9D,OAAO,cAAc;EACnB,IAAI,CAAC,QACH,OAAO,CAAC;EAIV,MAAM,cAAc,sBAAsB,OAAO,KAAK,MAAM;EAC5D,MAAM,WAAW,UAAU,YAAY,QAAQ,SAAS,QAAQ,SAAS,KAAK,KAAK,SAAS,CAAC,CAAC,IAAI;EAClG,MAAM,WAAW,UAAU,SAAS,QAAQ,SAAS,CAAC,QAAQ,SAAS,KAAK,KAAK,SAAS,CAAC,CAAC,IAAI;EAChG,MAAM,gBAAgB,SAAS,OAAO,QAAQ,IAAI;EAGlD,IAAI,YAAY;GACd,MAAM,mBAAmB,WAAW,oBAAoB;GACxD,MAAM,mBAAmB,IAAI,IAAI,WAAW,oBAAoB,CAAC;GAGjE,MAAM,eAAe,cAAc,QAAQ,SAAS,CAAC,iBAAiB,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC;GAC/F,MAAM,eAA0C,CAAC;GAGjD,KAAK,MAAM,mBAAmB,kBAAkB;IAC9C,MAAM,YAAY,OAAO,gBAAgB,MAAM,IAAI;IACnD,MAAM,OAAO,aAAa,MAAM,SAAS,KAAK,SAAS,SAAS;IAChE,IAAI,MACF,aAAa,KAAK,IAAI;GAE1B;GAGA,MAAM,kBAAkB,IAAI,IAAI,iBAAiB,KAAK,eAAe,OAAO,WAAW,MAAM,IAAI,CAAC,CAAC;GACnG,MAAM,iBAAiB,aAAa,QAAQ,SAAS,CAAC,gBAAgB,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC;GAC/F,aAAa,KAAK,GAAG,cAAc;GACnC,OAAO;EACT;EAGA,OAAO,OACH,CAAC,GAAG,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE,MAAM,QAAQ,KAAK,QAAQ,EAAE,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,SAAS,CAAC,CAAC,IAC7G;CACN,GAAG;EAAC;EAAQ;EAAQ;EAAS;EAAS;EAAQ;EAAM;CAAU,CAAC;AACjE;;;;;;;;;ACzCA,IAAa,wBAAwB,EACnC,MACA,MACA,UACA,OACA,UACA,eACA,YACA,gBACsE;CACtE,MAAM,SAAS,WAAW;CAC1B,IAAI,QACF,OAAO;EAAE,MAAM;EAAU,WAAW;CAAO;CAG7C,IAAI,eAAe;EACjB,MAAM,UAAU,cAAc;GAAE,QAAQ,OAAO,KAA6B,IAAI;GAAG,MAAM,QAAQ;GAAI;EAAW,CAAC;EACjH,IAAI,SACF,OAAO;GAAE,MAAM;GAAY;EAAQ;CAEvC;CAEA,MAAM,SAAS,OAAO,eAAe,wBAAwB,WAAW,IAAI,CAAC;CAC7E,IAAI,QACF,OAAO;EAAE,MAAM;EAAU;EAAQ,UAAU,CAAC,CAAC,OAAO;CAAS;CAG/D,MAAM,WAAW,OAAO,eAAe,mBAAmB,WAAW,IAAI,CAAC;CAC1E,IAAI,UACF,OAAO;EAAE,MAAM;EAAY;CAAS;CAGtC,IAAI,OAAO,eAAe,cAAc,WAAW,IAAI,CAAC,GACtD,OAAO,EAAE,MAAM,MAAM;CAGvB,IAAI,SAAS,YAAY,IAAI,GAC3B,OAAO,EAAE,MAAM,QAAQ;CAGzB,MAAM,SAAS,cAAc;EAAE;EAAM,QAAQ,WAAW;CAAO,CAAC;CAChE,IAAI,QACF,OAAO;EAAE,MAAM;EAAU;CAAO;CAGlC,MAAM,UAAU,iBAAiB,IAAI;CACrC,IAAI,SACF,OAAO;EAAE,MAAM;EAAU;CAAQ;CAGnC,MAAM,WAAW,YAAY,IAAI;CACjC,IAAI,UAGF,OAAO;EAAE,MAAM;EAAO;EAAU,SAD9B,aAAa,WAAW,qBAAqB,WAAW,SAAS,GAAG,CAAC,CAAC,KAAK,OAAO,gBAAgB,KAAK,CAAC,MACxD,CAAC,SAAS;CAAQ;CAGtE,IAAI,SAAS,aAAa,IAAI,GAAG;EAC/B,MAAM,WAAW,SAAS,SAAS,MAAM,SAAS,oBAAoB;EACtE,MAAM,cAAc,WAChB,SAAS,qBAAqB,UAAU,KAAY,IACpD,SAAS,SAAS,MAAM,UAAU,SAAS;EAC/C,IAAI,aACF,OAAO;GAAE,MAAM;GAAU,QAAQ,OAAO,KAA6B,WAAW;EAAE;CAEtF;AAGF;;AA2BA,IAAM,iBAAiB,EAAE,MAAM,aAAsF;CAQnH,MAAM,cAAc,MAAM,MAAM,MAAM,CAAC,CAAC,KACtC,MAAM,eAAuC,GAC7C,MAAM,KAAK,OAAO,WAAW,YAAY,MAAM,GAC/C,MAAM,KAAK,OAAO,WAAW,gBAAgB,MAAM,GACnD,MAAM,KAAK,OAAO,WAAW,gBAAgB,WAAW,GACxD,MAAM,KAAK,OAAO,WAAW,gBAAgB,UAAU,GACvD,MAAM,KAAK,OAAO,WAAW,gBAAgB,UAAU,GACvD,MAAM,KAAK,OAAO,WAAW,YAAY,WAAW,GACpD,MAAM,KAAK,OAAO,WAAW,YAAY,MAAM,GAC/C,MAAM,aAAa,KAAA,CAAS,CAC9B;CACA,IAAI,aACF,OAAO;CAOT,QAAQ,KAAK,MAAb;EAEE,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,WACH,OAAO;CACX;AAGF;AAEA,IAAM,oBAAoB,QAAqD;CAC7E,IAAI,SAAS,eAAe,GAAG,GAC7B,OAAO,IAAI,MAAM,KAAK,SAAS,KAAK,OAAO,CAAC,CAAC,QAAQ,MAA4B,MAAM,IAAI;CAG7F,OAAO,OAAO,kBAAkB,WAAW,GAAG,CAAC,CAAC,MAAM,eAAe,OAAO,eAAe,UAAU,CAAC;AACxG;;;;;;;AC5JA,IAAM,eAAe,SAAwC;CAC3D,QAAQ,MAAR;EACE,KAAK,QACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,aACH,OAAO;EACT,KAAK,YACH,OAAO;EACT,KAAK,aACH,OAAO;EACT,KAAK,YACH,OAAO;CACX;AACF;;AAKA,IAAa,qBAAqB,UAAkC;CAClE,MAAM,EACJ,MACA,MACA,OAAO,WACP,MACA,UACA,YACA,UACA,eACA,UAAU,cACV,YAAY,MACZ,QACA,gBACA,mBACA,kBACA,wBACA,gBACA,IACA,SACA,YACA,UACA,oBACA,cACE;CACJ,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,EAAE,SAAS,SAAS,eAAe,kBAAkB,WAAW;CAEtE,MAAM,WAAW,KAAK,YAAY,QAAQ,CAAC,CAAC;CAC5C,MAAM,QAAQ,SAAS,cAAsB,UAAU,iBAAiB,CAAC,CAAC,IAAI;CAC9E,MAAM,cAAc,UAAU,eAAe,SAAS,cAAsB,UAAU,uBAAuB,CAAC,CAAC,IAAI;CACnH,MAAM,WAAW,SAAS,cAAwB,UAAU,oBAAoB,CAAC,CAAC,IAAI;CACtF,MAAM,QAAQ,cACN,UAAU,SAAS,aAAa,UAAU,QAAQ,OAAO,KAAK,IAAO,WAAW,IAAI,IAC1F;EAAC,UAAU;EAAO;EAAW;EAAO;CAAI,CAC1C;CACA,MAAM,WAAW,UAAU,YAAY;CAEvC,MAAM,cAAc,cAEhB,UAAU,SACN,GAAG,EAAE,qBAAqB,EAAE,IAAI,SAAS,OACzC,YAAY,aACV,KAAA,IACC,eAAe,OACxB;EAAC;EAAU;EAAa;EAAO;EAAS;CAAC,CAC3C;CAEA,MAAM,aAAa,kBAAkB,kBAAkB,aAAa,IAAI;CACxE,MAAM,WAAW,SAAS,eAAe,QAAQ,CAAC,CAAC;CACnD,MAAM,gBAAgB,WAAW,UAAU,CAAC,CAAC;CAC7C,MAAM,aAAqC;EACzC;EACA,QAAQ,OAAO,iBAAiB,WAAW,IAAI,CAAC,CAAC,MAAM,eAAe,OAAO,eAAe,UAAU,CAAC;EACvG;EACA;EACA;EACA;EAEA,aAAa,gBACR,UAAU,eAAe,EAAE,2BAA2B,IACtD,UAAU,eAAe;EAC9B,cAAc;EACd;EACA;EACA,KAAK,UAAU;EACf,KAAK,UAAU;EACf,MAAM,UAAU;EAChB;EACA,GAAG;CACL;CAEA,IAAI,UAAU,WAAY,YAAY,WAAW,aAAa,aAAa,WAAW,SAAS,KAAK,MAClG,OAAO;CAGT,MAAM,aAAa,qBAAqB;EACtC;EACA;EACA;EACA,OAAO,WAAW,SAAS;EAC3B;EACA;EACA;EACA;CACF,CAAC;CACD,IAAI,CAAC,YACH,OAAO;CAGT,IAAI,WAAW,SAAS,UAAU;EAChC,MAAM,cAAc,WAAW;EAC/B,OAAO,oBAAC,aAAD,EAAa,GAAI,WAAa,CAAA;CACvC;CACA,IAAI,WAAW,SAAS,YACtB,OAAO,WAAW;CAIpB,MAAM,WAAW,WAAW,SAAS,UAAU,YAAY,IAAI,IAAI,KAAA;CACnE,MAAM,WACJ,UAAU,WAAW,OAAO,OAAO,WAAW,qBAAqB,WAAW,IAAI,CAAC,IAAI,WAAW,KAAA;CACpG,IAAI,WAAW,SAAS,WAAW,CAAC,UAClC,OAAO,oBAAC,YAAD;EAAY,YAAY;EAAmB;EAAO,GAAI;CAAQ,CAAA;CAEvE,MAAM,gBAAgB,YACpB,oBAAC,eAAD;EACE,GAAI;EACJ,GAAI,iBAAiB,SAAS,QAAQ;EACtC,aAAa,SAAS;EAClB;EACK;EACG;EACF;EACU;CACrB,CAAA;CAEH,IAAI,YAAY,qBAAqB,MAAM,SAAS,QAAQ,CAAC,CAAC,YAAY,SACxE,OAAO;CAET,IAAI,WAAW,SAAS,UACtB,OACE,oBAAC,cAAD;EAAqB;EAAO,aAAA;EAAY,QAAA;EAAO,eAAa,SAAS;EACnE,UAAA,oBAAC,YAAD;GACE,QAAQ,WAAW;GACb;GACI;GACF;GACI;GACF;GACK;GACX;GACK;GACG;GACF;GACU;EACrB,CAAA;CACW,CAAA;CAIlB,IAAI,WAAW,SAAS,SAAS,WAAW,QAC1C,OAAO,oBAAC,gBAAD;EAAgB,GAAI;EAAgB;EAAa;EAAmB;CAAW,CAAA;CAGxF,MAAM,UAAU,cAAc,UAAU;CACxC,IAAI,YAAY,KAAA,GACd,OAAO;CAGT,MAAM,EAAE,QAAQ,UAAU,WAAW,UAAU;CAC/C,MAAM,UAA4B;EAChC,MAAM;EACN;EACA,OAAO,WAAW,SAAS;EAC3B,WAAW,SAAS,WAAW,cAAc,MAAM,IAAI;EACvD,QAAQ,WAAW;EACnB;EACA;EACA;EACA,UAAU,WAAW;EACrB;EACA,cAAc;CAChB;CACA,MAAM,SAAS,WAAW,SAAS,WAAW,YAAY,WAAW,MAAM,IAAI,KAAA;CAC/E,OACE,oBAAC,cAAD;EACS;EACM;EACb,QAAQ,WAAW;EACV;EACT,YAAY,WAAW,OAAO,QAAQ;EACtC,gBAAgB,QAAQ;EACxB,cAAc,WAAW,SAAS,WAAW,mBAAmB,WAAW,SAAS,YAAY,IAAI,IAAI,KAAA;EAEvG,UAAA;CACW,CAAA;;CAIhB,SAAS,iBAAiB,UAA6C;EACrE,OAAO,CAAC,kBAAkB,aAAa,iBACnC;GAAE;GAAmB;GAAkB;GAAwB;EAAe,IAC9E,CAAC;CACP;CAEA,SAAS,cAAc,YAA4D;EACjF,QAAQ,WAAW,MAAnB;GACE,KAAK,UAAU;IACb,MAAM,cAAc,YAAY,WAAW,MAAM;IACjD,OAAO,cAAc,oBAAC,aAAD,EAAa,GAAI,WAAa,CAAA,IAAI,KAAA;GACzD;GACA,KAAK,UACH,OAAO,oBAAC,aAAD;IAAa,GAAI;IAAY,SAAS,cAAc,WAAW,SAAS,YAAY,IAAI;GAAI,CAAA;GACrG,KAAK,UACH,OAAO,WAAW,WAChB,oBAAC,eAAD;IAAe,GAAI;IAAY,QAAQ,WAAW;GAAS,CAAA,IAE3D,oBAAC,kBAAD;IAAkB,GAAI;IAAY,QAAQ,WAAW;GAAS,CAAA;GAElE,KAAK,YACH,OAAO,oBAAC,eAAD;IAAe,GAAI;IAAY,UAAU,WAAW;GAAW,CAAA;GACxE,KAAK,OACH,OAAO,oBAAC,UAAD,EAAU,GAAI,WAAa,CAAA;GACpC,KAAK,SACH,OAAO;GACT,KAAK,OACH,OACE,oBAAC,UAAD;IACE,GAAI;IACJ,GAAI,WAAW;IACf,GAAI,iBAAiB,WAAW,SAAS,QAAQ;IAC7C;IACK;IACG;IACF;IACU;GACrB,CAAA;GAGL,SACE;EACJ;CACF;AACF;AAEA,kBAAkB,cAAc;;AAGhC,IAAM,iBACJ,SACA,YACA,SACG;CACH,MAAM,SAAS,YAAY,oBAAoB,CAAC,CAAC,MAAM,cAAc,UAAU,MAAM,SAAS,IAAI,CAAC,EAAE,MAAM;CAC3G,OAAO,QAAQ,KAAK,YAAY;EAC9B,OAAO;EACP,OAAO,QAAQ,MAAM,cAAc,UAAU,OAAO,WAAW,OAAO,MAAM,CAAC,CAAC,EAAE,SAAS,OAAO,SAAS;CAC3G,EAAE;AACJ;AAEA,IAAM,sBACH,SAA2B,YAAkD,UAC7E,UACC,cAAc,SAAS,YAAY,IAAI,CAAC,CAAC,MAAM,cAAc,UAAU,UAAU,KAAK,CAAC,EAAE,SACzF,WAAW,OAAO,SAAS,EAAE;AAMjC,IAAM,mBAAmB;;;;;AAMzB,IAAa,cAAc,EACzB,MAAM,UACN,SACA,SACA,MACA,QACA,QAAQ,YACR,aAAa,WAAW,qBACxB,GAAG,YACuB;CAC1B,MAAM,EAAE,MAAM,SAAS,UAAU,QAAQ,SAAS,GAAG,iBAAiB,eAAe,gBAAgB;CACrG,MAAM,OAAO,cAAc,eAAe,QAAQ,GAAG,CAAC,OAAO,aAAa,WAAW,WAAW,UAAU,KAAK,GAAG,CAAC,CAAC;CACpH,MAAM,SAAS,cAA6B,kBAAkB,IAAI;CAClE,MAAM,EAAE,UAAU,QAAQ,YAAY,GAAG,iBAAiB;EAAE,GAAG;EAAc,GAAG;CAAM;CACtF,MAAM,SAAS,cAAc;EAC3B,IAAI,YACF,OAAO;EAET,IAAI,CAAC,KAAK,QACR;EAEF,MAAM,MAAM,KAAK,SAAS,gBAAgB,KAAK,OAAO,KAAK,MAAM,KAAK,MAAM,IAAI,KAAK,OAAO;EAC5F,OAAO,MAAM,OAAO,KAA6B,GAAG,IAAI,KAAA;CAG1D,GAAG;EAAC;EAAY,KAAK;EAAQ;EAAM;CAAM,CAAC;CAC1C,MAAM,aAAa,wBAAwB;EAAE;EAAQ;EAAQ;EAAS;EAAS;EAAQ;EAAM;CAAW,CAAC;CACzG,KAAK,YAAY,WAAW,aAAa,UAAU,MACjD,OAAO;CAIT,MAAM,UAAU,SAAS,OAAO,eAAe,WAAW,qBAAqB,IAAI,MAAM,CAAC,IAAI,KAAA;CAC9F,IAAI,UAAU,UAAU,gBAAgB,KAAA,GACtC,OACE,oBAAC,YAAD;EACU;EACR,MAAM;EACA;EACI;EACF;EACI;EACZ,GAAI;CACL,CAAA;CAIL,OACE,oBAAA,YAAA,EAAA,UACG,WAAW,KAAK,aAAa;EAC5B,MAAM,OAAO,SAAS,KAAK,SAAS;EACpC,OACE,oBAAC,wBAAD;GAAmC,MAAM,CAAC,GAAG,MAAM,IAAI;GACrD,UAAA,oBAAC,mBAAD;IACE,MAAM,SAAS;IACT;IACN,MAAM,CAAC,GAAG,MAAM,IAAI;IACpB,UAAU,CAAC,SAAS;IACV;IACF;IACI;IACZ,GAAI;GACL,CAAA;EACqB,GAXK,IAWL;CAE5B,CAAC,EACD,CAAA;AAEN;AAEA,WAAW,cAAc;;;ACnYzB,IAAM,kBAAkB;;AAGxB,IAAa,mBAAmB,EAAE,OAAO,aACvC,oBAAC,WAAW,MAAZ;CAAiB,UAAA;CAAU,UAAA,kBAAkB,OAAO,MAAM;AAAmB,CAAA;;AAsB/E,IAAa,aAAiB,EAAE,MAAM,UAAU,GAAG,YAA+B;CAChF,IAAI,SAAS,KAAA,GACX,OAAO,aAAa,KAAA,IAClB,oBAAC,wBAAD;EAA8B;EAAM,GAAI;CAAQ,CAAA,IAEhD,oBAAC,gBAAD;EAAyB;EAAM,GAAI;EAChC;CACa,CAAA;CAGpB,OAAO,oBAAC,cAAD;EAAiB,GAAI;EAAQ;CAAuB,CAAA;AAC7D;AAEA,UAAU,cAAc;AAIxB,IAAM,kBAAsB,EAAE,MAAM,UAAU,GAAG,YAAoC;CACnF,MAAM,WAAW,sBAAsB,iBAAiB,IAAI;CAC5D,MAAM,UAAU,sBAAyB,iBAAiB,MAAM,UAAU,KAAK;CAC/E,OACE,oBAAC,cAAD;EACE,OAAO,MAAM,SAAS,UAAU,SAAS;EACzC,aAAa,MAAM,eAAe,UAAU;EAC5C,QAAQ,UAAU;EAClB,GAAI;EACK;EAER;CACW,CAAA;AAElB;AAEA,IAAM,0BAA8B,EAAE,MAAM,GAAG,YAAoC;CACjF,MAAM,EAAE,MAAM,OAAO,SAAS,UAAU,QAAQ,SAAS,GAAG,YAAY,eAAe,eAAe;CACtG,MAAM,WAAW,sBAAsB,iBAAiB,IAAI;CAC5D,IAAI,CAAC,UACH,OAAO;CAET,MAAM,WAAW,SAAS,WAAW,IAAI,IAAI,SAAS,cAAc,IAAI,IAAI,CAAC;CAC7E,OACE,oBAAC,mBAAD;EACE,GAAI;EACJ,MAAM,SAAS;EACf,MAAM,OAAO,SAAS,SAAS,SAAS,EAAE;EAC1C,OAAO,MAAM;EACb,MAAM;EACN,UAAU,MAAM,YAAY,SAAS;EACrC,UAAU,MAAM,YAAY,QAAQ;EACpC,QAAQ,MAAM,gBAAgB,QAAQ;CACvC,CAAA;AAEL;;;;;AAWA,IAAa,gBAAoB,EAC/B,UACA,OACA,aACA,OAAO,WACP,UAAU,cACV,UAAU,cACV,YACA,UACA,iBAAiB,SACjB,cAAc,kBACd,cACA,QACA,cAC0B;CAC1B,MAAM,EAAE,UAAU,WAAW,WAAW,eAAe,eAAe;CACtE,MAAM,WAAW,YAAY;CAC7B,MAAM,WAAW,gBAAgB,oBAAoB,SAAS,gBAAgB,MAAM;CACpF,MAAM,QAAQ,SAAS,SAAS;CAChC,MAAM,WAAW,SAAS,YAAY;CAEtC,MAAM,WAAW,UAAU,QAAQ,YAAY,CAAC,QAAQ,iBAAiB,aAAa,QAAQ,KAAK,IAAI;CAEvG,IAAI,UAAqB;CACzB,IAAI,WAAW,SAAS,UAAU;EAChC,IAAI,QAAQ,SAAS,MACnB,OAAO;EAET,UAAU,eAAe,QAAQ,KAAK,KAAK,oBAAC,iBAAD;GAAiB,OAAO,QAAQ;GAAe;EAAS,CAAA;CACrG;CAGA,MAAM,aAAa,SAAS,aAAa,CAAC,CAAC,UAAU,mBAAmB,YAAY;CACpF,MAAM,MACJ,qBAAC,MAAM,MAAP;EACE,QAAQ,WAAW,QAAQ;EAC3B,OAAO,WAAW,OAAO,KAAA;EACzB,SAAS,CAAC,CAAC;EACX,UAAU,CAAC,CAAC;EACZ,UAAU;EAGV,QACE,WACK,UAAU;GACT,IAAI,EAAE,MAAM,yBAAyB,QAAQ,MAAM,cAAc,SAAS,MAAM,aAAa,IAC3F,QAAQ,OAAO,KAAK;EAExB,IACA,KAAA;EAfR,UAAA;GAkBG,cACC,qBAAC,MAAM,QAAP,EAAA,UAAA;IACG,cAAc,WACb,oBAAC,WAAW,MAAZ;KAAiB,UAAA;KAAU,UAAA;IAAuB,CAAA,IAElD,oBAAC,MAAM,OAAP,EAAA,UAAc,MAAmB,CAAA;IAElC;IACA,SACC,oBAAC,OAAO,OAAR,EAAA,UACE,oBAAC,KAAK,MAAN;KAAW,MAAK;KAAuB,SAAQ;KAAQ,OAAO;IAAQ,CAAA,EAC1D,CAAA;GAEJ,EAAA,CAAA;GAEf,YAAY,eAAe,oBAAC,MAAM,YAAP,EAAA,UAAmB,YAA8B,CAAA;GAC5E;GACA,SAAS,aAAa,SAAS,oBAAC,MAAM,WAAP,EAAA,UAAkB,MAAuB,CAAA;EAC/D;;CAGd,OAAO,UAAU,oBAAC,0BAAD;EAA0B,GAAI;EAAU,UAAA;CAA8B,CAAA,IAAI;AAC7F;AAEA,aAAa,cAAc;;;;AC/J3B,IAAa,mBAAmB;;;;;;AAyBhC,IAAa,eAAe,KAAK,YAC9B,EAAE,UAAU,QAAQ,MAAM,QAAQ,YAAY,QAAQ,GAAG,SAAS,iBAAiB;CAClF,MAAM,gBAAgB,OAAO,iBAAiB;CAC9C,MAAM,gBAAgB,UAAU,aAAa,QAAQ,KAAA;CACrD,OAAO,SACL,oBAAC,MAAM,MAAP;EACE,GAAI;EACE;EACN,OAAO;EACP,QAAQ,WAAW,YAAY,KAAA,IAAY;EAC3C,KAAK;EAEL,UAAA,oBAAC,MAAM,MAAP;GAAY,SAAA;GACV,UAAA,oBAAC,WAAW,MAAZ,EAAA,UACE,oBAAC,WAAW,UAAZ;IAAqB,SAAA;IAEnB,UAAA,oBAAC,OAAO,WAAR;KAAkB,UAAA;KAAU;IAA2B,CAAA;GACpC,CAAA,EACN,CAAA;EACP,CAAA;CACF,CAAA,IAEZ,oBAAC,OAAO,WAAR;EAAkB,GAAI;EAAO,QAAQ,UAAU,iBAAiB;EAAM,OAAO;EAAe,KAAK;EAC9F;CACe,CAAA;AAEtB,CACF;AAEA,aAAa,cAAc;;;;;AAY3B,IAAa,cAAc,YAA8C,EAAE,YAAY,iBAAiB;CACtG,MAAM,EAAE,MAAM,UAAU,QAAQ,YAAY,eAAe,cAAc;CACzE,MAAM,WAAW,OAAuB,IAAI;CAC5C,MAAM,MAAM,gBAAgB,cAAc,QAAQ;CAClD,cAAc,UAAU,MAAM,EAAE,SAAS,CAAC;CAC1C,MAAM,WAAW,YAAY;CAE7B,OACE,oBAAC,OAAO,WAAR;EACE,MAAK;EACL,QAAQ,WAAW,SAAS;EAC5B,OAAO,WAAW,aAAa,KAAA;EAC/B,KAAK,WAAW,OAAO;EACvB,SAAS,WAAW,mBAAmB,KAAA;EACvC,eAAa;EACR;EAEJ;CACe,CAAA;AAEtB,CAAC;AAED,YAAY,cAAc;AAY1B,IAAa,eAAe,EAAE,aAAa,qBAAuC;CAChF,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,EACJ,MAAM,EAAE,SAAS,QAAQ,YACzB,UACA,WACE,eAAe,cAAc;CACjC,IAAI,YAAY,WAAW,UACzB,OAAO;CAGT,OACE,qBAAC,OAAO,OAAR;EAAc,SAAQ;EAAtB,UAAA,CACG,YACC,oBAAC,aAAa,QAAd;GACE,UAAU;GACV,OAAO,EAAE,qBAAqB;GAC9B,SAAS;GACT,eAAY;IAEL,OAAO,6BAA6B;EAC5C,CAAA,GAEF,UACC,oBAAC,aAAa,MAAd;GACE,UAAU;GACV,MAAK;GACL,OAAO,eAAe,EAAE,mBAAmB;GAC3C,UAAU,CAAC,WAAW;GACtB,eAAe,OAAO;GACtB,eAAY;EACb,CAAA,CAES;;AAElB;AAEA,YAAY,cAAc;AAe1B,IAAa,cAAc,EAAE,OAAO,UAAU,MAAM,WAA4B;CAC9E,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,EACJ,MAAM,EAAE,SAAS,UACjB,UACA,WACE,eAAe,aAAa;CAChC,IAAI,YAAY,WAAW,UACzB,OAAO;CAGT,MAAM,cAAc;EAClB,QAAQ;EACR,SAAS,SAAS,EAAE,mBAAmB;EACvC,YAAY,YAAY,CAAC;EACzB,iBAAiB,OAAO;EACxB,eAAe;CACjB;CAEA,OACE,oBAAC,OAAO,OAAR;EAAc,MAAA;EACX,UAAA,QAAQ,OACP,oBAAC,OAAO,MAAR;GAAa,GAAI;GAAa,SAAQ;GAAU,MAAM,QAAQ;GAAsB,MAAM;EAAO,CAAA,IAEjG,oBAAC,aAAa,MAAd;GAAmB,GAAI;GAAa,UAAU;EAAQ,CAAA;CAE5C,CAAA;AAElB;AAEA,WAAW,cAAc;AAMzB,IAAa,iBAAiB,EAAE,eAC9B,WACE,oBAAC,MAAM,MAAP;CAAY,SAAA;CACV,UAAA,oBAAC,MAAM,WAAP;EAAiB,eAAY;EAAc;CAA0B,CAAA;AAC3D,CAAA,IACV;AAEN,cAAc,cAAc;;AAG5B,IAAa,OAAO;CAClB,MAAM;CACN,UAAU;CACV,SAAS;CACT,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,OAAO;CACP,SAAS;CACT,QAAQ;CACR,WAAW;AACb;;;;;ACnNA,IAAM,mBAAuD,CAAC,uBAAuB,EAAE,IAAI,eAAe,CAAC;;AAG3G,IAAM,iBAA+B,EACnC,MAAM,UACJ,oBAAC,WAAD;CAAW,MAAM,MAAM;CAAU,OAAO,MAAM;CAAO,cAAc,MAAM;CACvE,UAAA,oBAAC,UAAD,EAAU,GAAI,MAAQ,CAAA;AACb,CAAA,EAEf;;;;;;AAiBA,IAAM,sBAAsB,EAAE,QAAQ,UAAU,SAAiC;CAC/E,MAAM,OAAO,IAAI,QAAQ,MAAM;CAE/B,MAAM,YAAY,SAAS,IAAI,OAAO,KAAK,IAAI,GAAG,CAAC;CACnD,MAAM,EAAE,UAAU,MAAM,WAAW,kBAAkB,cAC7C,kBAAkB,CAAC,GAAG,KAAK,IAAI,GAAG,SAAS,GACjD,CAAC,KAAK,MAAM,SAAS,CACvB;CAkDA,OAAO;EAAE,QAjDM,eAAe;IAAG,gBAAgB;GAAM,GAAG;EAAS,IAAI,CAAC,UAAU,IAAI,CAiD7E;EAAQ,cA9CI,aAClB,MAAsB,WAA6B;GAClD,UAAU,IAAC,KAAA,GAAA;IAAA,YAAA;IAAA,GAAA;IAAA,GAAA;IAAA,GAAA,KAAA;IAAA,GAAA,CAAA,MAAA,EAAA;GAAA,CAAC;GACZ,UAAU,KAAK,SAAS,IAAI,GAAA,KAAA,GAAA;IAAA,YAAA;IAAA,GAAA;IAAA,GAAA;IAAA,GAAA,KAAA;IAAA,GAAA,CAAA,uBAAA,EAAA;GAAA,CAAC;GAC7B,MAAM,UAAU,OAAO,eAAe,kBAAkB,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC;GACjF,MAAM,OAAO,UAAU,QAAQ,MAAM,IAAI,IAAI,KAAK,MAAM,MAAM;GAC9D,UAAU,IAAI,SAAS,IAAI,GAAA,KAAA,GAAA;IAAA,YAAA;IAAA,GAAA;IAAA,GAAA;IAAA,GAAA,KAAA;IAAA,GAAA,CAAA,sBAAA,EAAA;GAAA,CAAC;GAC5B,MAAM,QAAQ,GAAG,IAAI,IAAI;GACzB,UAAU,IAAI,SAAS,KAAK,GAAA,KAAA,GAAA;IAAA,YAAA;IAAA,GAAA;IAAA,GAAA;IAAA,GAAA,KAAA;IAAA,GAAA,CAAA,uBAAA,EAAA;GAAA,CAAC;GAC7B,OAAO;EACT,GACA,CAAC,EAAE,CAmCY;EAAc,cAhCV,aAEjB,GAAG,gBAAgB,UAAU,GAAG,UAChC,EAAE,SAAS,cACR;GACH,IAAI,CAAC,SACH;GAGF,MAAM,eAAe,OAAO,KAAK,OAAO,CAAA,CACrC,OAAO,SAAS,UAAU,CAAA,CAC1B,QAAQ,SAAS,QAAQ,KAAK;GACjC,MAAM,aAAa,SAA4B,SAAS,cAAc,IAAI,CAAC,CAAC,OAAO;GACnF,IAAI,aAAa,KAAK,SAAS,GAC7B,IAAI,OAAO,SAAS,WAAW;IAE7B,IAAI,QAAQ,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,eAAe,GAAI,YAAY,CAAC,CAAE;GACnE,CAAC;GAGH,MAAM,gBAAgB,aAAa,QAAQ,SAAS,CAAC,UAAU,IAAI,CAAC;GACpE,IAAI,cAAc,SAAS,GACzB,IAAI,OAAO,SAAS,WAAW;IAC7B,KAAK,MAAM,QAAQ,eACjB,IAAI,SAAS,QAAQ,SAAS,cAAc,IAAI,GAAG,SAAS,SAAS,QAAQ,IAAI,CAAC;GAEtF,CAAC;EAEL,GACA,CAAC,QAAQ,aAAa,CAGO;CAAa;AAC9C;;AAeA,IAAa,cAAc,EAAE,QAAQ,MAAM,QAAQ,WAAW,WAA4B;CACxF,MAAM,KAAK,IAAI,YAAY,MAAM;CAEjC,MAAM,CAAC,YAAY,UAAU,MAAM;CACnC,MAAM,EAAE,QAAQ,cAAc,iBAAiB,mBAAmB;EAAE;EAAQ;EAAU;CAAG,CAAC;CAC1F,MAAM,aAAa,cAAc;EAC/B,MAAM,OAAO,UAAU,KAAK,UAAU,IAAI;EAC1C,OAAO,WAAW,aAAa,IAAI,IAAI,OAAO,IAAI;CACpD,GAAG;EAAC;EAAQ;EAAM;CAAQ,CAAC;CAE3B,OACE,oBAAC,KAAK,MAAN;EACE,QAAQ;EACA;EACJ;EACJ,gBAAgB,KAAK,YAAY,IAAI,GAAG;EACxC,mBAAmB;EACnB,kBAAiB;EACjB,wBAAuB;EACP;EAChB,iBAAiB;EACjB,UAAU;EAEV,UAAA,oBAAC,KAAK,SAAN,EAAA,UACE,oBAAC,KAAK,QAAN,CAAc,CAAA,EACF,CAAA;CACL,CAAA;AAEf;;;;;;AAWA,IAAa,mBAAmB,KAAK,YAClC,EAAE,UAAU,QAAQ,mBAAmB,oBAAoB,GAAG,SAAS,iBAAiB;CACvF,MAAM,KAAK,IAAI,YAAY,MAAM;CACjC,MAAM,CAAC,YAAY,UAAU,MAAM;CACnC,MAAM,EAAE,QAAQ,cAAc,iBAAiB,mBAAmB;EAAE;EAAQ;EAAU;CAAG,CAAC;CAE1F,MAAM,aAAa,QAAQ,IAAI,IAAI,WAAW,MAAM,CAAC;CACrD,MAAM,OAAO,IAAI,QAAQ,MAAM,KAAK;CACpC,MAAM,aAAa,cAAe,OAAO,aAAa,KAAK,UAAU,IAAI,CAAC,IAAI,KAAA,GAAY,CAAC,IAAI,CAAC;CAChG,IAAI,CAAC,YACH,OAAO;CAGT,OACE,oBAAC,KAAK,MAAN;EACE,QAAQ;EACA;EACJ;EACJ,gBAAgB,KAAK,YAAY,IAAI,GAAG;EACxC,mBAAmB;EACnB,kBAAiB;EACjB,wBAAuB;EACP;EAChB,iBAAiB;EACjB,UAAU;EACS;EACC;EAEpB,UAAA,oBAAC,KAAK,UAAN;GAAe,GAAI;GAAO,QAAA;GAAO,KAAK;GACpC,UAAA,qBAAC,KAAK,SAAN,EAAA,UAAA,CACE,oBAAC,KAAK,QAAN,CAAc,CAAA,GACb,YAAY,oBAAC,KAAK,UAAN,EAAgB,SAAwB,CAAA,CACzC,EAAA,CAAA;EACD,CAAA;CACN,CAAA;AAEf,CACF;;;;ACrKA,IAAa,YAAY;;AAGzB,IAAa,cAAc;;AAG3B,IAAa,kBAAkB;;AAG/B,IAAa,iBAAiB,MAA0B,UAA2B,OAAO,GAAG,KAAK,IAAI,MAAM,KAAK;;;;;AAMjH,IAAa,sBAAsB,YAAY,OAAa;;;;;;;;;;AAoB5D,IAAa,aAAa,EAAE,OAAO,OAAO,QAAQ,OAAO,aAAwC,CAAC,MAAiB;CAGjH,IAAI;;CAGJ,MAAM,eAAe,MAAkB,SAAsB;EAG3D,MAAM,QAAQ,CAAC,GAAG,KAAK,WAAW,iBAAiB,+BAA6B,CAAC,CAAC,CAAC,QAAQ,IAAI;EAC/F,IAAI,QAAQ,GACV;EAEF,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,CAAC,KAAK;EAChD,IAAI;EACJ,KAAK,IAAI,UAAU,GAAG,OAAO,OAAO,WAAW,OAAO,KAAK,GACzD,IAAI,YAAY,OAAO;GACrB,QAAQ;IAAE,MAAM,OAAO;IAAM,IAAI,OAAO;GAAG;GAC3C;EACF;EAEF,IAAI,CAAC,OACH;EAGF,MAAM,MAAM,KAAK,MAAM,IAAI,SAAS;EACpC,IAAI,EAAE,SAAS;EACf,MAAM,EAAE,OAAO;EACf,IAAI,SAAS,WAAW,CAAC,QAAQ,KAAK,IAAI,MAAM,MAAM,EAAE,CAAC,GAAG;GAE1D,MAAM,WAAW,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC,MAAM,OAAO;GACjD,IAAI,UACF,QAAQ,SAAS,EAAE,CAAC;EAExB;EACA,KAAK,SAAS;GAAE,SAAS;IAAE;IAAM;GAAG;GAAG,WAAW,EAAE,QAAQ,KAAK;EAAE,CAAC;CACtE;CAEA,MAAM,uBAAuB,UAAuB;EAClD,MAAM,OAAO,IAAI,gBAA4B;EAC7C,MAAM,OAAO,MAAM,IAAI,SAAS;EAChC,MAAM,aAAa;EACnB,IAAI;EACJ,OAAQ,aAAa,WAAW,KAAK,IAAI,GAAI;GAC3C,MAAM,QAAQ,WAAW;GACzB,MAAM,OAAO,WAAW;GACxB,MAAM,KAAK,OAAO,MAAM;GAExB,MAAM,WAAW,MAAM,MAAM,SAAS;GACtC,IAAI,UAAU;IACZ,MAAM,MAAM,SAAS,SAAS,EAAE;IAChC,IAAI,KACF,KAAK,IACH,MACA,IACA,WAAW,QAAQ,EACjB,QAAQ,IAAI,UACV,IAAI,OACJ,IAAI,QAAQ,WAAW,WAAW,SAAS,EAAE,IAAI,KAAA,IACjD,WACF,EACF,CAAC,CACH;IAEF;GACF;GAEA,IAAI,OAAO,KAAK,KAAK,GACnB,KAAK,IACH,MACA,IACA,WAAW,QAAQ,EACjB,QAAQ,IAAI,UAAU,OAAO,KAAA,GAAW,WAAW,EACrD,CAAC,CACH;EAEJ;EAEA,OAAO,KAAK,OAAO;CACrB;CAEA,MAAM,yBAAyB,UAAuB;EACpD,MAAM,YAAY,SAAS;EAC3B,MAAM,OAAO,IAAI,gBAA4B;EAC7C,MAAM,OAAO,MAAM,IAAI,SAAS;EAGhC,MAAM,eAAe;EACrB,IAAI;EACJ,OAAQ,eAAe,aAAa,KAAK,IAAI,GAAI;GAC/C,MAAM,UAAU,aAAa;GAC7B,MAAM,aAAa,QAAQ,QAAQ,GAAG;GACtC,MAAM,WAAW,eAAe,KAAK,UAAU,QAAQ,MAAM,GAAG,UAAU,EAAA,CAAG,KAAK;GAClF,IAAI,CAAC,SACH;GAKF,IAAI,eAAe,IACjB;GAEF,MAAM,UAAU,QAAQ,SAAS,QAAQ,UAAU,CAAC,CAAC;GACrD,MAAM,OAAO,aAAa,QAAQ;GAClC,MAAM,KAAK,aAAa,QAAQ,QAAQ;GAExC,MAAM,WAAW,QAAQ,MAAM,eAAe;GAC9C,IAAI,UACF,KAAK,IACH,MACA,IACA,WAAW,QAAQ,EACjB,QAAQ,IAAI,UACV,SAAS,MAAM,SAAS,IACxB,WAAW,WAAW,SAAS,EAAE,IAAI,KAAA,GACrC,WACF,EACF,CAAC,CACH;QACK,IAAI,UAAU,KAAK,OAAO,GAC/B,KAAK,IACH,MACA,IACA,WAAW,QAAQ,EACjB,QAAQ,IAAI,UAAU,SAAS,KAAA,GAAW,WAAW,EACvD,CAAC,CACH;EAEJ;EAEA,OAAO,KAAK,OAAO;CACrB;CAEA,MAAM,mBAAmB,SAAS,UAAU,wBAAwB;CAEpE,YAAY,WAAW,OAAsB;EAC3C,SAAS,UAAU,iBAAiB,KAAK;EACzC,SAAS,MAAM,OAAO;GACpB,IAAI,GAAG,cAAc,GAAG,QAAQ,MAAM,WAAW,OAAO,GAAG,mBAAmB,CAAC,GAC7E,OAAO,iBAAiB,GAAG,KAAK;GAGlC,OAAO;EACT;EACA,UAAU,UAAU,CAClB,WAAW,YAAY,KAAK,KAAK,GAEjC,WAAW,aAAa,IAAI,SAAS,KAAK,MAAM,MAAM,KAAK,CAAC,CAC9D;CACF,CAAC;CAED,MAAM,YAAY,SAAS,UAAU,OAAO;CAK5C,MAAM,kBAAkB,YAAY,kBAAkB,IAAI,OAAO;EAC/D,IAAI,CAAC,GAAG,cAAc,CAAC,GAAG,YAAY,OAAO,GAC3C,OAAO;EAET,MAAM,OAAO,GAAG,WAAW,MAAM,WAAW,KAAK;EACjD,IAAI,CAAC,MACH,OAAO;EAGT,IAAI;EACJ,GAAG,QAAQ,aAAa,OAAO,KAAK,QAAQ,KAAK,aAAa;GAC5D,IAAI,SAAS,UAAU,KACrB;GAEF,MAAM,OAAO,SAAS,SAAS;GAC/B,IAAI,CAAC,QAAQ,SAAS,KAAK,IAAI,GAC7B;GAGF,IAAI,WAAW;GACf,KAAK,MAAM,SAAS,KAAK,KAAK,GAAG,OAAO,OAAO,OAAO,KAAK,GAAG;IAC5D,IAAI,OAAO,SAAS,OAAO;KACzB,WAAW;KACX;IACF;IACA,IAAI,OAAO,OAAO,OAChB;GAEJ;GACA,IAAI,UACF,QAAQ;IAAE,SAAS;KAAE,MAAM;KAAK,QAAQ;IAAU;IAAG,YAAY;IAAM,WAAW,EAAE,QAAQ,IAAI;GAAE;EAEtG,CAAC;EAED,OAAO,QAAQ,CAAC,IAAI,KAAK,IAAI;CAC/B,CAAC;CAED,OAAO;EAAC;EAAQ;EAAW;CAAe;AAC5C;;;;;;AAUA,IAAM,aAAa,YAAoB,GAAG,aAAoC;CAC5E,MAAM,QAAQ,OAAO,GAAG,MAAM,CAAA,CAC3B,WAAW,GAAG,+DAA+D,UAAU,CAAC,CAAA,CACxF,OAAO,GAAG,QAAQ;CACrB,OAAO,OAAO,GAAG,MAAM,CAAC,CAAC,WAAW,+BAA+B,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC;AACrF;;AAGA,IAAM,gBAAgB,MAAkB,WAAwB;CAC9D,MAAM,SAAS,OAAO,GAAG,QAAQ,CAAA,CAC9B,WAAW,sEAAsE,CAAA,CACjF,WAAW;EAAE,QAAQ;EAAU,cAAc;CAAS,CAAC,CAAA,CACvD,OAAO,OAAO,IAAI,aAAa,CAAC,CAAC,WAAW,sBAAsB,CAAC,CAAA,CAEnE,GAAG,cAAc,UAAU;EAC1B,MAAM,eAAe;EACrB,OAAO,MAAM,OAAO,IAAI;CAC1B,CAAC;CACH,OAAO;AACT;;;;;AAMA,IAAM,YAAN,cAAwB,WAAW;CAEd;CACA;CACA;CAHnB,YACE,QACA,MACA,SACA;EACA,MAAM;EAJW,KAAA,SAAA;EACA,KAAA,OAAA;EACA,KAAA,UAAA;CAGnB;CAEA,GAAY,OAAa;EACvB,OAAO,KAAK,WAAW,MAAM,UAAU,KAAK,SAAS,MAAM;CAC7D;CAEA,MAAe,MAAkB;EAC/B,MAAM,SAAS,KAAK,OAAO,UAAU,KAAK,IAAI,IAAI,KAAA;EAClD,OAAO,UACL,GAAG,+BAA+B,QAAQ,MAAM,GAChD,OAAO,GAAG,MAAM,CAAC,CAAC,WAAW,6BAA6B,CAAC,CAAC,KAAK,KAAK,MAAM,GAC5E,aAAa,MAAM,KAAK,OAAO,CACjC;CACF;AACF;AAEA,IAAM,SAAS,WAAW,MAAM,EAG9B,YAAY;CACV,SAAS;CACT,SAAS;CACT,YAAY;AACd,EACF,CAAC;;;;;;;AC9PD,IAAa,gBACX,EACE,IACA,MACA,UACA,OAAO,OACP,OACA,UACA,WACA,OAAO,qBACP,aAAa,iBACb,kBACA,WAAW,KAEb,iBACG;CACH,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,YAAY,MAAM,aAAa;CACrC,MAAM,iBAAiB,aACpB,WAAwB,WAAW,MAAM,KAAK,IAAI,SAAS,MAAM,KAAK,OAAO,IAC9E,CAAC,QAAQ,CACX;CAIA,MAAM,SAAS,cAAc,OAAO,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC;CACtD,MAAM,UAAU,SAAS,IAAI,MAAM;CACnC,MAAM,OAAO,cAET,IAAI,IACF,QAAQ,KAAK,WAAW,CAAC,OAAO,IAAI;EAAE,OAAO,eAAe,MAAM;EAAG,KAAK,WAAW,OAAO,EAAE;CAAE,CAAC,CAAC,CACpG,GACF,CAAC,SAAS,cAAc,CAC1B;CACA,MAAM,UAAU,OAAO,IAAI;CAC3B,QAAQ,UAAU;CAIlB,MAAM,gBAAgB,OAAgC,IAAI;CAC1D,MAAM,cAAc,aACjB,eAAwC;EACvC,cAAc,UAAU;EACxB,IAAI,OAAO,iBAAiB,YAC1B,aAAa,UAAU;OAClB,IAAI,cACT,aAAa,UAAU;CAE3B,GACA,CAAC,YAAY,CACf;CACA,gBAAgB;EACd,cAAc,SAAS,MAAM,SAAS,EAAE,SAAS,oBAAoB,GAAG,IAAI,EAAE,CAAC;CACjF,GAAG,CAAC,IAAI,CAAC;CAET,MAAM,UAAU,YACd,OAAO,EAAE,WAAW;EAIlB,IAAI,CAAC,MACH,OAAO,CAAC;EAEV,MAAM,QAAQ,KAAK,QAAQ,MAAM,EAAE,CAAC,CAAC,YAAY;EACjD,MAAM,gBAAgB,WACpB,CAAC,SACD,eAAe,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,KAAK,MAClD,YAAY,MAAM,KAAK,CAAC,EAAA,CAAG,MAAM,UAAU,MAAM,YAAY,CAAC,CAAC,SAAS,KAAK,CAAC;EAEjF,IAAI,SAAS,SASX,OAAO,CACL;GACE,IAAI;GACJ,OAVc,QACf,SAAS,YAAY,YAAY,MAAM,KAAK,CAAC,EAAA,CAAG,KAAK,WAAW;IAAE;IAAQ;GAAM,EAAE,CAAC,CAAA,CACnF,QACE,EAAE,QAAQ,YACT,CAAC,SAAS,eAAe,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,KAAK,KAAK,MAAM,YAAY,CAAC,CAAC,SAAS,KAAK,CAM/F,CAAA,CAAU,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,aAAa;IAClE,IAAI,GAAG,OAAO,GAAG,GAAG;IACpB,OAAO,GAAG,eAAe,MAAM,EAAE,IAAI,MAAM;IAC3C;IACA,WAAW,EAAE,MAAM,WACjB,cAAc,MAAM,MAAM,cAAc,eAAe,MAAM,GAAG,KAAK,CAAC;GAC1E,EAAE;EACJ,CACF;EAIF,OAAO,CACL;GACE,IAAI;GACJ,OAAO,QACJ,OAAO,YAAY,CAAA,CACnB,MAAM,GAAG,WAAW,CAAC,CAAA,CACrB,KAAK,WAAW;IACf,MAAM,QAAQ,eAAe,MAAM;IACnC,MAAM,SAAS,YAAY,MAAM,CAAC,GAAG;IACrC,OAAO;KACL,IAAI,OAAO;KACX,OAAO,UAAU,WAAW,QAAQ,GAAG,MAAM,IAAI,OAAO,KAAK;KAC7D;KACA,WAAW,EAAE,MAAM,WACjB,eAAe,MAAM,MAAM,IAAI,OAAO,GAAG,EAAE;IAC/C;GACF,CAAC;EACL,CACF;CACF,GACA;EAAC;EAAS;EAAU;EAAM;EAAM;EAAgB;CAAS,CAC3D;CAMA,MAAM,cAAc,eACX;EACL,SAAS,mBAAmB,EAAE,mBAAmB,gCAAgC,wBAAwB;EACzG,WAAW;CACb,IACA;EAAC;EAAG;EAAiB;CAAgB,CACvC;CAmEA,OAAO;EACL,YAlEiB,cACX;GACJ,sBAAsB;IAAE,UAAU;IAAU,cAAc;GAAM,CAAC;GACjE,sBAAsB;IACpB;IACA,OAAO;KACL,QAAQ,EACN,WAAW,SACb;KACA,UAAU,EACR,WAAW,iBACb;IACF;GACF,CAAC;GACD,UAAU;IAAE;IAAM;IAAO,SAAS,OAAO,QAAQ,QAAQ,IAAI,EAAE;GAAE,CAAC;GAClE,KAAK,QACH,OAAO,GAAG,CACR;IACE,KAAK;IAGL,MAAM,SAAS;KACb,MAAM,EAAE,SAAS,KAAK,MAAM,UAAU;KACtC,MAAM,OAAO,KAAK,MAAM,IAAI,OAAO,IAAI;KACvC,MAAM,SAAS,KAAK,KAAK,MAAM,GAAG,OAAO,KAAK,IAAI;KAClD,IAAI,SAAS,SAAS;MACpB,MAAM,UAAU,OAAO,MAAM,OAAO,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK;MAC/D,IAAI,gBAAgB,KAAK,OAAO,MAAM,SAAS,YAAA,CAAa,KAAK,OAAO,GACtE,eAAe,MAAM,MAAM,IAAI;KAEnC,OAAO;MACL,MAAM,QAAQ,OAAO,MAAM,OAAO,OAAO,MAAM,CAAC;MAChD,IAAI,SAAS,OAAO,KAAK,KAAK,GAC5B,eAAe,MAAM,MAAM,GAAG;KAElC;KACA,OAAO;IACT;GACF,GACA;IACE,KAAK;IAIL,MAAM,SAAS;KACb,IAAI,SAAS,SACX,OAAO;KAET,MAAM,EAAE,SAAS,KAAK,MAAM,UAAU;KACtC,MAAM,OAAO,KAAK,MAAM,IAAI,OAAO,IAAI;KACvC,MAAM,SAAS,KAAK,KAAK,MAAM,GAAG,OAAO,KAAK,IAAI;KAClD,MAAM,UAAU,OAAO,MAAM,OAAO,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK;KAC/D,KAAK,SAAS,YAAA,CAAa,KAAK,OAAO,GAAG;MACxC,eAAe,MAAM,MAAM,IAAI;MAC/B,OAAO;KACT;KACA,OAAO;IACT;GACF,CACF,CAAC,CACH;EACF,GACA;GAAC;GAAU;GAAW;GAAM;EAAK,CAIjC;EACA;EACA,SAAS;EACT;EACA;EAGA,QAAQ;EACR;EACA,KAAK;CACP;AACF;;;;;AAMA,IAAM,iBAAiB,MAAkB,MAAc,YAAoB;CACzE,MAAM,OAAO,KAAK,MAAM,IAAI,OAAO,IAAI;CAEvC,MAAM,YADS,KAAK,KAAK,MAAM,GAAG,OAAO,KAAK,IAC5B,CAAA,CAAO,YAAY,GAAG;CACxC,MAAM,OAAO,KAAK,QAAQ,cAAc,KAAK,IAAI,YAAY;CAC7D,MAAM,SAAS,GAAG,cAAc,KAAK,KAAK,MAAM,QAAQ;CACxD,KAAK,SAAS;EACZ,SAAS;GAAE;GAAM,IAAI;GAAM;EAAO;EAClC,WAAW;GAAE,QAAQ,OAAO,OAAO;GAAQ,MAAM,OAAO,OAAO;EAAO;CACxE,CAAC;AACH;;;;;;;AChRA,IAAa,YAAY,YACtB,EAAE,OAAO,UAAU,WAAW,YAAY,OAAO,KAAK,eAAe,QAAQ,GAAG,WAAW,iBAAiB;CAC3G,MAAM,YAAY,aAAa,SAAS,YAAY;CACpD,OACE,oBAAC,OAAO,MAAR;EAAa,GAAI;EACf,UAAA,oBAAC,MAAM,OAAP;GAAoB;GAAY;GAAK,UAAU,QAAQ;GAAU,eAAa;GAC5E,UAAA,oBAAC,OAAO,MAAR;IACE,cAAc;IACF;IACF;IACC;IACX,cAAA;GACD,CAAA;EACU,CAAA;CACF,CAAA;AAEjB,CACF;AAEA,UAAU,cAAc;;;;ACVxB,IAAM,YAAY,UAAqC,MAAM,QAAQ,SAAS,KAAK,SAAS,MAAM;;;;;AAMlG,IAAa,eAAe,EAAE,UAAU,YAAY,OAAO,UAAU,MAAM,QAAQ,eAAiC;CAClH,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,CAAC,OAAO,YAAY,SAAuB,WAAW,mBAAmB,MAAM,EAAE,CAAC,CAAC,KAAK;CAC9F,gBAAgB,SAAS,WAAW,mBAAmB,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,UAAU,CAAC;CAE5F,MAAM,CAAC,SAAS,cAAc,SAAsB,CAAC,CAAC;CACtD,MAAM,eAAe,YAAY;EAC/B,IAAI,CAAC,UACH;EAEF,MAAM,eAAe,SAClB,MAAM,OAAO,KAAK,KAAK,IAAI,CAAC,CAAA,CAC5B,WAAW,UAAU,WAAW,MAAM,OAAO,GAAG,EAAE,MAAM,KAAK,CAAC;EACjE,WAAW,MAAM,SAAS,MAAM,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;EAC7D,aAAa,eAAe;CAC9B,GAAG,CAAC,QAAQ,CAAC;CAGb,MAAM,CAAC,iBAAiB,sBAAsB,SAAoB;CAClE,gBAAgB;EACd,yBAAyB,QAAQ,MAAM,WAAW,KAAK,YAAY,MAAM,MAAM,OAAO,eAAe,CAAC;CACxG,GAAG,CAAC,SAAS,OAAO,eAAe,CAAC;CAGpC,MAAM,CAAC,EAAE,eAAe,kBAAkB,SAAS,EAAE,aAAa,gBAAgB,OAAO,MAAM,EAAE,CAAC;CAElG,MAAM,WAAW,eACR;GACJ,YAAyC,eACxC,oBAAC,KAAK,OAAN;GAAY,MAAM,WAAW;GAC3B,UAAA,oBAAC,aAAD;IACE,GAAI;IACJ,SAAS,YAAY,QAAQ,UAAU,UAAU,SAAO,WAAW,IAAI,CAAC,CAAC,KAAK,WAAW;KACvF;KACA,OAAO,EAAE,UAAU,MAAM,OAAO;IAClC,EAAE;GACH,CAAA;EACS,CAAA;GAEb,qBAAkD,eACjD,oBAAC,KAAK,OAAN;GAAY,MAAM,WAAW;GAC3B,UAAA,oBAAC,aAAD;IACE,GAAI;IACJ,SAAS,QACN,KAAK,WAAW,KAAK,YAAY,MAAM,CAAC,CAAA,CACxC,QAAQ,aAAiC,YAAY,IAAI,CAAA,CACzD,KAAK,cAAc,EAAE,OAAO,SAAS,EAAE;GAC3C,CAAA;EACS,CAAA;GAEb,mBAAgD,eAC/C,oBAAC,KAAK,OAAN;GAAY,MAAM,WAAW;GAC3B,UAAA,oBAAC,aAAD;IACE,GAAI;IACJ,SACE,kBACI,kBAAkB,KAAK,UAAU,eAAe,CAAC,CAAC,GAAG,CAAA,CAClD,MAAM,GAAG,MAAM,EAAE,KAAK,SAAS,CAAC,CAAC,cAAc,EAAE,KAAK,SAAS,CAAC,CAAC,CAAA,CACjE,KAAK,UAAU,EAAE,OAAO,KAAK,KAAK,SAAS,EAAE,EAAE,IAClD,CAAC;GAER,CAAA;EACS,CAAA;GAEb,aAA0C,eACzC,oBAAC,KAAK,OAAN;GAAY,MAAM,WAAW;GAAU,YAAA;GACrC,UAAA,oBAAC,mBAAD,EAAmB,GAAI,WAAa,CAAA;EAC1B,CAAA;CAEhB,IACA;EAAC;EAAG;EAAS;CAAe,CAC9B;CAEA,MAAM,sBAAsB,aACzB,SAAS;EACR,gBAAgB,aAAa;GAC3B,MAAM,cAAc,gBAAgB,KAAK,MAAM;GAC/C,OAAO,SAAS,gBAAgB,cAAc,WAAW,EAAE,YAAY;EACzE,CAAC;EACD,oBAAoB,aAAa;GAC/B,IAAI,KAAK,qBAAqB,WAAW,KAAK,YAAY,QAAQ,IAAI,KAAA,IACpE,OAAO,QAAQ,MAAM,WAAW,KAAK,YAAY,MAAM,MAAM,KAAK,eAAe,KAAK;GAExF,OAAO;EACT,CAAC;EACD,UAAU,YAAY;GACpB,MAAM,OAAO,KAAK,SAAS,aAAa,KAAK,UAAU,QAAQ;GAE/D,MAAM,EAAE,QAAQ,SAAS,GAAG,eAAe,KAAK,SAAS,qCAAqC,KAAK,UAAU,CAAC;GAC9G,OAAO,QAAQ,SAAS,OAAO;IAAE,GAAG;IAAS,GAAG;IAAM,GAAG;IAAY;GAAK,IAAI;IAAE,GAAG;IAAS,GAAG;GAAK;EACtG,CAAC;CACH,GACA,CAAC,OAAO,CACV;CAEA,MAAM,iBAAiB,aACpB,EAAE,eAAe;EAChB,IAAI,YAAY,WAAW,UAAU,CAAC,CAAC,MAAM,UAAU,MAAM,SAAS,YAAY,MAAM,SAAS,MAAM,IAAI,GACzG,OAAO,CAAC;GAAE,MAAM;GAAY,SAAS,4BAA4B,SAAS;EAAG,CAAC;CAElF,GACA,CAAC,YAAY,KAAK,CACpB;CAEA,MAAM,aAAa,aAChB,SAAS;EACR,IAAI,MAEF,IAAI,OAAO,OAAO,SAAS;GACzB,WAAW,mBAAmB;IAAE;IAAO,OAAO;GAAK,CAAC;EACtD,CAAC;OAED,WAAW,mBAAmB;GAAE;GAAO,OAAO;EAAK,CAAC;EAEtD,OAAO;CACT,GACA;EAAC;EAAY;EAAO;EAAM;CAAM,CAClC;CAEA,MAAM,eAAe,kBAAkB;EACrC,OAAO;EAEP,4BAA4B,WAAW,CAAC;CAC1C,GAAG,CAAC,QAAQ,QAAQ,CAAC;CAErB,IAAI,CAAC,aAAa;EAChB,IAAI,KAAK,kBAAkB,EAAE,MAAM,GAAA;GAAA,YAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA,KAAA;EAAA,CAAC;EACpC,OAAO;CACT;CAEA,OACE,oBAAC,KAAK,MAAN;EAEY;EACV,WAAA;EACU;EACV,QAAQ;EACR,QAAQ;EACR,iBAAiB;EACjB,YAAY;EACZ,QAAQ;EACR,UAAU;EAEV,UAAA,qBAAC,KAAK,SAAN,EAAA,UAAA,CACE,oBAAC,KAAK,QAAN;GAAa,QAAQ;GAAU,MAAM,CAAC,YAAY,QAAQ;EAAI,CAAA,GAC9D,oBAAC,KAAK,SAAN,CAAe,CAAA,CACH,EAAA,CAAA;CACL,GAfJ,MAAM,EAeF;AAEf;;;;AC/HA,IAAM,aAAa,OAAO,GAAG,SAAS,QAAQ;;AAG9C,IAAM,sBAAsB,MAAkC,SAAoB;CAChF,MAAM,eAAe,WAAW,eAAe;CAC/C,OAAO,cAEH,OACI,IAAI,gBAAgB;EAClB,UAAU;EACV;EACA,YAAY,KAAK;EACjB,QAAQ,yBAAyB,MAAM,KAAK,YAAY,IAAI,KAAK,OAAO,OAAO,KAAA,CAAS;CAC1F,CAAC,IACD,MACN;EAAC;EAAc;EAAM;CAAI,CAC3B;AACF;;;;;;AAOA,IAAa,aAAa,YACvB,EAAE,MAAM,MAAM,OAAO,UAAU,UAAU,IAAI,UAAU,OAAO,MAAM,gBAAgB,YAAY,iBAAiB;CAChH,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,iBAAiB,QAAQ,QAAQ,KAAK,YAAY,IAAI,KAAK;CACjE,MAAM,kBAAkB,mBAAmB,MAAM,IAAI;CACrD,oBAAoE,oBAAoB,iBAAiB,CACvG,eACF,CAAC;CAED,MAAM,aAAa,MAAM,MAAM,KAAK,MAAM,GAAG,CAAC,CAAC,KAC7C,MAAM,KAAK,EAAE,MAAM,OAAO,IAAI,EAAE,WAC9B,KAAK,SAAS,UACV,OAAO,cAAc,KAAK,OAAO,MAAM,UAAU,MAAM,SAAS,MAAM,CAAC,CAAC,CAAC,KACvE,OAAO,KAAK,UAAU,MAAM,OAAO,GACnC,OAAO,cACT,IACA,KAAA,CACN,GACA,MAAM,aAAa,KAAA,CAAS,CAC9B;CAEA,MAAM,QAAQ,SAAS,IAAI,OAAO,KAAK,KAAK,IAAI,CAAC;CACjD,MAAM,YAAY,cAAc;EAC9B,MAAM,YAAY,aAAa,IAAI,SAAS,UAAU,IAAI,KAAA;EAC1D,MAAM,OAAO,YACT,MAAM,MAAM,SAAS;GACnB,MAAM,UAAU,KAAK,WAAW,IAAI;GACpC,OAAO,WAAW,QAAQ,IAAI,OAAO,SAAS,SAAS;EACzD,CAAC,IACD,KAAA;EACJ,OAAO,OAAO,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC,IAAI,KAAA;CACnD,GAAG,CAAC,YAAY,KAAK,CAAC;CAEtB,MAAM,aAAa,cAAc;EAC/B,MAAM,OAAO,OAAO,OAAO,EACzB,OACE,SAAS,WACL,OAAO,IAAI,SAAS,EAAE,OAAO,cAAc,CAAC,IAC5C,SAAS,MAAM,SAAS,EAAE,OAAO,QAAQ,CAAC,EAClD,CAAC;EAGD,OAAO,SAAS,QACZ,OAAO,OAAO;GACZ,GAAG,KAAK;GACR,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,KACzB,OAAO,SAAS,EAAE,OAAO,cAAc,CAAC,GACxC,sBAAsB,IAAI,IAAI,GAC9B,OAAO,QACT;EACF,CAAC,CAAC,CAAC,UAAU,OAAO,IAAI,OAAO,UAAU,CAAC,IAC1C,KAAK,UAAU,OAAO,IAAI,OAAO,UAAU,CAAC;CAClD,GAAG,CAAC,IAAI,CAAC;CAET,MAAM,aAAa,cAAc;EAE/B,MAAM,UAAU,oBAAoB,KAAK,MAAM,GAAG;EAClD,MAAM,UAAU,UAAU,IAAI,QAAQ,OAAO,IAAI,KAAA;EACjD,OAAO;GACL,OAAO,SAAS,WAAY,UAAU,IAAI,QAAQ,OAAO,IAAK,WAAW,KAAO,KAAK,MAAM;GAC3F,QAAQ;EACV;CACF,GAAG;EAAC;EAAM,KAAK,MAAM;EAAK;CAAS,CAAC;CAEpC,MAAM,WAAW,cACR,SAAS,QAAQ,EAAE,QAAQ,UAAU,oBAAC,YAAD;EAAY,GAAI;EAAc;EAAa;CAAO,CAAA,EAAE,IAAI,KAAA,GACpG;EAAC;EAAM;EAAO;CAAI,CACpB;CAEA,MAAM,eAAe,aAClB,WAAkD;EACjD,MAAM,OAAO,IAAI,MAAM,OAAO,MAAM,IAChC,MAAM,MAAM,SAAS,IAAI,MAAM,OAAO,MAAM,KAAK,IAAI,OAAO,IAAI,MAAM,OAAO,OAAO,GAAG,IACvF,KAAA;EACJ,MAAM,UAAU,OAAO,KAAK,WAAW,IAAI,IAAI,KAAA;EAC/C,IAAI,SAAS,UAAU;GAErB,MAAM,WAAW,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;GACnE,iBAAiB,MAAM,OAAO,OAAO,KAAK,IAAI,MAAM,QAAQ,IAAI,WAAW,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO;EAC9G,OAAO,IAAI,OAAO,GAAG,SAAS,KAAK,CAAC,CAAC,OAAO,KAAK,GAE/C,iBAAiB,OAAO,kBAAkB,SAAS,KAAK,CAAC,CAAC,KAAK,MAAM,KAAK,UAAU,OAAO,KAAK,CAAC,CAAC,GAAG,OAAO;CAEhH,GACA;EAAC;EAAgB;EAAM;CAAK,CAC9B;CAEA,OACE,oBAAC,KAAK,MAAN;EAAW,QAAQ;EAAY,QAAQ;EAAsB;EAAc;EAAI,iBAAiB;EAC9F,UAAA,qBAAC,KAAK,SAAN,EAAA,UAAA;GAEG,kBAAkB,CAAC,YAClB,oBAAC,OAAO,MAAR;IAAa,SAAQ;IACnB,UAAA,oBAAC,OAAO,OAAR,EAAA,UAAe,EAAE,2BAA2B,EAAgB,CAAA;GACjD,CAAA;GAEf,oBAAC,KAAK,QAAN,CAAc,CAAA;GACb,QAAQ,mBACP,oBAAC,WAAD;IACQ;IACA;IACW;IACP;IACA;IACV,WAAW,YAAY;KACrB,UAAU,CAAC,UAAO,KAAA,GAAA;MAAA,YAAA;MAAA,GAAA;MAAA,GAAA;MAAA,GAAA,KAAA;MAAA,GAAA,CAAA,aAAA,EAAA;KAAA,CAAC;KACnB,WAAW,OAAO;IACpB;GACD,CAAA;EAES,EAAA,CAAA;CACL,CAAA;AAEf,CACF;AAEA,WAAW,cAAc;;AAGzB,IAAM,cAAc,EAClB,MACA,OACA,UACA,eACA,OACA,WAEA,oBAAC,WAAD;CAAkB;CAAO,YAAA;CACvB,UAAA,oBAAC,WAAD;EACE,cAAc,SAAS;EAChB;EACD;EACN,WAAW,UAAU,cAAc,MAAM,MAAM,GAAG;CACnD,CAAA;AACQ,CAAA;;AAab,IAAM,aAAa,EAAE,MAAM,MAAM,iBAAiB,UAAU,UAAU,eAA+B;CACnG,MAAM,EAAE,MAAM,MAAM,eAAe,cAAc;CACjD,MAAM,iBAAiB,KAAK,YAAY,IAAI,KAAK;CAEjD,MAAM,CAAC,YAAY,UAAU,IAAI;CACjC,MAAM,CAAC,YAAY,iBAAiB,SAAiB;CACrD,MAAM,SAAS,eACN,UAAU,WAAW,UAAU,CAAC,EAAA,CAAG,OAAO,OAAO,GAAG,KAAK,WAAW,CAAC,GAC5E,CAAC,UAAU,WAAW,MAAM,CAC9B;CAEA,MAAM,YAAY,kBAAkB;EAClC,UAAU,CAAC,UAAO,KAAA,GAAA;GAAA,YAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA,KAAA;GAAA,GAAA,CAAA,aAAA,EAAA;EAAA,CAAC;EACnB,cAAc,gBAAgB,sBAAsB,CAAC,CAAC,EAAE;CAC1D,GAAG,CAAC,iBAAiB,QAAQ,CAAC;CAE9B,MAAM,aAAa,aAChB,MAAc,OAAe;EAC5B,UAAU,CAAC,UAAO,KAAA,GAAA;GAAA,YAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA,KAAA;GAAA,GAAA,CAAA,aAAA,EAAA;EAAA,CAAC;EACnB,IAAI,OAAO,OAAO,SAAS;GAEzB,MAAM,OAAO,CAAC,GAAG,KAAK,WAAW,MAAM;GACvC,MAAM,CAAC,SAAS,KAAK,OAAO,MAAM,CAAC;GACnC,KAAK,OAAO,IAAI,GAAG,KAAK;GACxB,KAAK,WAAW,SAAS;EAC3B,CAAC;CACH,GACA,CAAC,MAAM,QAAQ,CACjB;CAEA,MAAM,eAAe,aAClB,YAAoB;EACnB,eAAe,aAAc,aAAa,UAAU,KAAA,IAAY,QAAS;EACzE,SAAS,OAAO;CAClB,GACA,CAAC,QAAQ,CACX;CAEA,OACE,qBAAA,YAAA,EAAA,UAAA,CACE,qBAAC,MAAM,QAAP,EAAA,UAAA,CACE,oBAAC,WAAW,MAAZ;EAAiB,UAAA;EAAU,UAAA,EAAE,cAAc;CAAmB,CAAA,GAC7D,CAAC,YACA,oBAAC,OAAO,MAAR;EACE,UAAA;EACA,SAAQ;EACR,MAAK;EACL,OAAO,EAAE,2BAA2B;EACpC,UAAU,OAAO,UAAU;EAC3B,SAAS;CACV,CAAA,CAES,EAAA,CAAA,GACd,oBAAC,YAAY,MAAb;EACE,OAAO;EACP,QAAQ,UAAU,MAAM;EACxB,WAAW,UAAU,MAAM;EAC3B,QAAQ;EACR,UAAU,CAAC,CAAC,YAAY;EAEtB,WAAA,EAAE,YACF,oBAAC,YAAY,SAAb;GAAqB,QAAQ;GAAO,QAAO;GAAU,cAAY,EAAE,cAAc;GAC9E,UAAA,MAAM,KAAK,UAAU;IACpB,MAAM,SAAS,MAAM,YAAY;IACjC,OACE,qBAAC,YAAY,MAAb;KAEE,IAAI,MAAM;KACV,SAAS,CAAC,YAAY,CAAC;KACvB,aAAa,CAAC;KACd,MAAM,eAAe,MAAM;KAC3B,eAAe,SAAS,cAAc,OAAO,MAAM,KAAK,KAAA,CAAS;KANnE,UAAA;MAQE,oBAAC,YAAY,YAAb,CAAyB,CAAA;MACzB,oBAAC,YAAY,UAAb;OAAsB,MAAM,SAAS,UAAU,KAAA;OAAY,UAAA,MAAM;MAA2B,CAAA;MAC5F,oBAAC,OAAO,QAAR;OACE,UAAA;OACA,SAAQ;OACR,SAAS;OACT,MAAK;OACL,YAAW;OACX,OAAO,EAAE,SAAS,qBAAqB,kBAAkB;OACzD,UAAU,YAAa,CAAC,UAAU,gBAAgB,UAAU,CAAC,CAAC,UAAU;OACxE,uBAAuB;QACrB,cAAc,KAAA,CAAS;QACvB,IAAI,QAEE;aAAA,WAAW,MAAM,IAAI,GACvB,gBAAgB,oBAAoB,MAAM,IAAI;QAAA,OAGhD,gBAAgB,oBAAoB,MAAM,EAAE;OAEhD;OACA,eAAa,SAAS,sBAAsB;MAC7C,CAAA;MACA,CAAC,YACA,oBAAC,OAAO,MAAR;OACE,UAAA;OACA,SAAQ;OACR,MAAK;OACL,OAAO,EAAE,oBAAoB;OAC7B,UAAU,kBAAkB,OAAO,UAAU;OAC7C,eAAe,aAAa,MAAM,EAAE;OACpC,eAAY;MACb,CAAA;MAEF,CAAC,YACA,oBAAC,YAAY,QAAb,EAAA,UACE,oBAAC,aAAD;OACE,UAAU,YAAY;OACZ;OACV,YAAY;OACL;OACP,cAAc,cAAc,KAAA,CAAS;MACtC,CAAA,EACiB,CAAA;KAEN;IApDX,GAAA,MAAM,EAoDK;GAEtB,CAAC;EACkB,CAAA;CAEP,CAAA,CAClB,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/hooks/useAsyncFieldEffect.ts","../../src/hooks/useFormContext.ts","../../src/util/field.ts","../../src/util/omit.ts","../../src/util/properties.ts","../../src/util/refs.ts","../../src/hooks/useFormHandler.ts","../../src/hooks/useKeyHandler.tsx","../../src/hooks/useSubmitOnEnter.ts","../../src/components/layout/resolve-layout-field.ts","../../src/components/field-binding.tsx","../../src/components/FormFieldContext.ts","../../src/components/fields/numeric-constraints.ts","../../src/components/fields/default-value.ts","../../src/components/fields/ArrayField.tsx","../../src/components/presentation.tsx","../../src/components/fields/SelectField.tsx","../../src/components/fields/AsyncSelectField.tsx","../../src/components/fields/TextField.tsx","../../src/components/fields/AutofillField.tsx","../../src/components/fields/BooleanField.tsx","../../src/components/fields/ComboboxField.tsx","../../src/components/fields/createSelectField.tsx","../../src/components/fields/date-value.ts","../../src/components/fields/DateField.tsx","../../src/components/fields/GeoPointField.tsx","../../src/components/fields/HueField.tsx","../../src/components/FormFieldSet.tsx","../../src/components/FormRoot.tsx","../../src/components/fields/InlineRefField.tsx","../../src/components/fields/MarkdownField.tsx","../../src/components/fields/NumberField.tsx","../../src/components/fields/PasswordField.tsx","../../src/components/ObjectPicker.tsx","../../src/components/fields/find-ref-option.ts","../../src/components/meta-tags.ts","../../src/components/fields/ref-options.ts","../../src/components/fields/RefArrayField.tsx","../../src/components/fields/RefField.tsx","../../src/components/fields/SelectOptionField.tsx","../../src/components/fields/TextAreaField.tsx","../../src/components/layout/parser.ts","../../src/components/FormLayout.tsx","../../src/components/property-walk.ts","../../src/components/resolve-field.ts","../../src/components/FormFieldDispatch.tsx","../../src/components/FormField.tsx","../../src/components/Form.tsx","../../src/components/ObjectForm.tsx","../../src/components/ref-editor-extension.ts","../../src/components/useRefEditor.ts","../../src/components/RefEditor.tsx","../../src/components/FieldEditor.tsx","../../src/components/ViewEditor.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Cause from 'effect/Cause';\nimport * as Effect from 'effect/Effect';\nimport * as Exit from 'effect/Exit';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\n\n/** Picks the declared dependency fields from the form values — the subset a dynamic field subscribes to. */\nexport const pickValues = (values: AnyProperties | undefined, deps: readonly string[]): Record<string, unknown> => {\n const subset: Record<string, unknown> = {};\n for (const dep of deps) {\n subset[dep] = values?.[dep];\n }\n return subset;\n};\n\nexport type AsyncFieldEffectState<A> = {\n loading: boolean;\n error: unknown;\n data: A | undefined;\n};\n\nexport type UseAsyncFieldEffectOptions = {\n /** Debounce applied before running, so per-keystroke value changes coalesce into one run. */\n debounceMs?: number;\n /** When false, the effect is not run and prior data/error is cleared. */\n enabled?: boolean;\n};\n\n/**\n * Runs a self-contained Effect (`R = never`) whenever `key` changes, debounced and abortable. Used by\n * dynamic form fields to load select options, derive values, or validate against an external source from\n * the current form values. The latest `factory` is always used, but a run is only (re)triggered when\n * `key` changes — derive `key` from the inputs the factory actually reads. Re-running interrupts the\n * prior run (cancelling any in-flight request).\n */\nexport const useAsyncFieldEffect = <A>(\n factory: () => Effect.Effect<A, unknown>,\n key: string,\n { debounceMs = 400, enabled = true }: UseAsyncFieldEffectOptions = {},\n): AsyncFieldEffectState<A> => {\n const factoryRef = useRef(factory);\n factoryRef.current = factory;\n const [state, setState] = useState<AsyncFieldEffectState<A>>({ loading: false, error: undefined, data: undefined });\n\n useEffect(() => {\n if (!enabled) {\n setState({ loading: false, error: undefined, data: undefined });\n return;\n }\n\n let cancel: (() => void) | undefined;\n const timer = setTimeout(() => {\n setState((prev) => ({ ...prev, loading: true, error: undefined }));\n cancel = Effect.runCallback(factoryRef.current(), {\n onExit: (exit: Exit.Exit<A, unknown>) => {\n Exit.match(exit, {\n onSuccess: (data) => setState({ loading: false, error: undefined, data }),\n onFailure: (cause) => {\n // A superseding run interrupts this one; ignore the resulting interruption.\n if (!Cause.hasInterruptsOnly(cause)) {\n setState((prev) => ({ loading: false, error: Cause.squash(cause), data: prev.data }));\n }\n },\n });\n },\n });\n }, debounceMs);\n\n return () => {\n clearTimeout(timer);\n cancel?.();\n };\n }, [key, enabled, debounceMs]);\n\n return state;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { useEffect, useMemo, useRef } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { createContext } from '@dxos/react-hooks';\n\nimport { type FieldContext, type FormFieldStateProps } from '#types';\n\nimport { type FormHandler } from './useFormHandler.ts';\n\n/** Visual variants of a form: `settings` is the two-column settings-panel layout. */\nexport type FormVariant = 'default' | 'settings';\n\n//\n// Context\n//\n\nexport type FormContextValue<T extends AnyProperties = any> = {\n /**\n * Form handler.\n */\n form: FormHandler<T>;\n\n /**\n * Testing.\n */\n testId?: string;\n\n /** Visual variant applied across the form's parts (see Form.theme). */\n variant?: FormVariant;\n\n /** Editor extensions for the form's markdown fields, beyond their own (what a host's plugins contribute). */\n markdownExtensions?: Extension[];\n} & FieldContext;\n\nexport const [FormContextProvider, useFormContext] = createContext<FormContextValue>('Form');\n\n/**\n * Get the current form values.\n */\nexport const useFormValues: {\n <T extends AnyProperties>(componentName: string, path?: (string | number)[]): T;\n <T extends AnyProperties>(\n componentName: string,\n path: (string | number)[] | undefined,\n defaultValue: () => T,\n ): T | undefined;\n} = (componentName: string, path?: (string | number)[], defaultValue?: () => any) => {\n const stablePath = useMemo(() => path ?? [], [path ? path.join('.') : undefined]);\n const jsonPath = SchemaEx.createJsonPath(stablePath);\n const {\n form: { values, onValueChange },\n } = useFormContext(componentName);\n\n const value = SchemaEx.getValue(values, jsonPath);\n\n // Apply default value once when the field has no value. lastAppliedPathRef prevents\n // re-applying on every render (e.g. when defaultValue() returns null) and ensures\n // we apply per path when the hook is used for different fields.\n const lastAppliedPathRef = useRef<string | null>(null);\n useEffect(() => {\n if (value == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {\n lastAppliedPathRef.current = jsonPath;\n onValueChange(stablePath, SchemaAST.stringKeyword, defaultValue());\n }\n }, [value, defaultValue, onValueChange, stablePath, jsonPath]);\n\n return value;\n};\n\n/**\n * Get the state props for the given field.\n */\nexport const useFormFieldState = (componentName: string, path: (string | number)[] = []): FormFieldStateProps => {\n const stablePath = useMemo(() => path, [Array.isArray(path) ? path.join('.') : path]);\n const {\n form: { getStatus, getValue, onBlur, onValueChange },\n } = useFormContext(componentName);\n\n return useMemo(\n () => ({\n getStatus: () => getStatus(stablePath),\n getValue: () => getValue(stablePath),\n onBlur: () => onBlur(stablePath),\n onValueChange: (ast: SchemaAST.AST, value: any) => onValueChange(stablePath, ast, value),\n }),\n [getStatus, getValue, onBlur, onValueChange, stablePath],\n );\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { Format, GeoLocation, TypeEnum } from '@dxos/echo/Format';\nimport { type ValidationError } from '@dxos/schema';\n\n/**\n * Parse value by field value type.\n * Used by Table, Sheet, etc.\n * Handles various data types including booleans, numbers, dates, and strings.\n * Returns undefined for empty or null inputs.\n */\nexport type ParseProps = {\n type?: TypeEnum;\n format?: Format.TypeFormat;\n value: any;\n};\n\nexport const parseValue = ({ type, format, value }: ParseProps) => {\n if (value === undefined || value === null || value === '') {\n return undefined;\n }\n\n const parseScalar = (type?: TypeEnum) => {\n switch (type) {\n case TypeEnum.Boolean: {\n if (typeof value === 'string') {\n const lowercaseValue = value.toLowerCase();\n if (lowercaseValue === '0' || lowercaseValue === 'false') {\n return false;\n } else if (lowercaseValue === '1' || lowercaseValue === 'true') {\n return true;\n }\n }\n return Boolean(value);\n }\n\n case TypeEnum.Number: {\n const cleaned = typeof value === 'string' ? value.replace(/[^0-9.-]+/g, '') : value;\n const num = Number(cleaned);\n return Number.isNaN(num) ? null : num;\n }\n\n case TypeEnum.String:\n case TypeEnum.Ref:\n return String(value);\n\n default: {\n return value;\n }\n }\n };\n\n if (!format) {\n return parseScalar(type);\n }\n\n switch (format) {\n case Format.TypeFormat.Boolean:\n return parseScalar(TypeEnum.Boolean);\n\n case Format.TypeFormat.Number:\n case Format.TypeFormat.Percent:\n case Format.TypeFormat.Currency:\n return parseScalar(TypeEnum.Number);\n\n case Format.TypeFormat.String:\n case Format.TypeFormat.Markdown: {\n return parseScalar(TypeEnum.String);\n }\n\n case Format.TypeFormat.Ref:\n throw new Error(`unexpected format: ${Format.TypeFormat.Ref}`);\n\n case Format.TypeFormat.DateTime:\n case Format.TypeFormat.Date:\n case Format.TypeFormat.Time:\n case Format.TypeFormat.Timestamp: {\n const date = new Date(value as string | number);\n return isNaN(date.getTime()) ? null : date;\n }\n\n case Format.TypeFormat.GeoPoint: {\n // Parse string in format \"lat,long\" to GeoPoint [longitude, latitude].\n if (typeof value === 'string') {\n // Only keep digits, decimal points, minus signs, and commas.\n const cleaned = value.replace(/[^0-9.,-]+/g, '');\n const parts = cleaned.split(',');\n if (parts.length === 2) {\n const lat = parseFloat(parts[0]);\n const long = parseFloat(parts[1]);\n if (!isNaN(lat) && !isNaN(long)) {\n return GeoLocation.toGeoPoint({ latitude: lat, longitude: long });\n }\n }\n }\n\n return [0, 0];\n }\n\n default: {\n return value;\n }\n }\n};\n\n// TODO(burdon): Type and format.\nexport type CellClassesForFieldTypeProps = {\n type?: TypeEnum;\n format?: Format.TypeFormat;\n};\n\nexport const cellClassesForFieldType = ({ type, format }: CellClassesForFieldTypeProps): string[] | undefined => {\n switch (format || type) {\n case Format.TypeFormat.Markdown:\n return undefined;\n case Format.TypeFormat.Time:\n case Format.TypeFormat.Timestamp:\n case Format.TypeFormat.DateTime:\n case Format.TypeFormat.Date:\n case Format.TypeFormat.Duration:\n return ['font-mono', 'text-right'];\n case Format.TypeFormat.Currency:\n return ['text-right'];\n case Format.TypeFormat.JSON:\n case Format.TypeFormat.DID:\n return ['font-mono'];\n case TypeEnum.Number:\n case TypeEnum.Boolean:\n return ['text-right', 'font-mono'];\n case TypeEnum.String:\n return undefined;\n case TypeEnum.Ref:\n return undefined;\n default:\n return undefined;\n }\n};\n\n// TODO(ZaymonFC): How to do this with translations?\nexport const pathNotUniqueError = (path: string): ValidationError => ({\n path: 'path',\n message: `'${path}' is already present`,\n});\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, Type } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\n\n// TODO(burdon): Reconcile with @dxos/echo.\n// Distributive: applied per union member so `ExcludeId<A | B>` → `ExcludeId<A> | ExcludeId<B>` rather\n// than `Omit<InstanceType<A> | InstanceType<B>, 'id'>` (which would intersect away per-member narrowing).\nexport type ExcludeId<S extends Schema.Codec<any, any> | Type.AnyEntity> = S extends Type.AnyEntity\n ? Omit<Type.InstanceType<S>, 'id'>\n : S extends Schema.Codec<any, any>\n ? Omit<Schema.Schema.Type<S>, 'id'>\n : never;\n\n// TODO(burdon): Move to @dxos/schema (re-export here).\nexport const omitId = <S extends Schema.Codec<any, any> | Type.AnyEntity>(\n schemaOrType: S,\n): Schema.Codec<ExcludeId<S>, ExcludeId<S>> => {\n const schema: Schema.Top = Type.isType(schemaOrType) ? Type.getSchema(schemaOrType) : schemaOrType;\n // Cast: dropping a key cannot statically express the `ExcludeId<S>` result type, so the result is\n // a widened schema; the runtime shape matches the declared return type.\n return omitIdFromSchema(schema) as any;\n};\n\n/**\n * Removes the `id` field where present, preserving the schema's shape. Recurses into unions so a\n * discriminated (create) schema keeps its discriminant — `Schema.omit('id')` is a struct operation and\n * would otherwise flatten the union, breaking variant rendering. A no-op when there is no `id` (plain\n * create structs that never carried one).\n */\nconst omitIdFromSchema = (schema: Schema.Top): Schema.Top => {\n const ast = schema.ast;\n if (SchemaAST.isUnion(ast)) {\n return Schema.Union(ast.types.map((type) => omitIdFromSchema(Schema.make(type))));\n }\n const hasId = SchemaAST.getPropertySignatures(ast).some((prop) => prop.name === 'id');\n // `SchemaAST.omit`, not `mapFields(Struct.omit)`: the latter needs the key literals at the type\n // level, which a schema known only as a `Top` cannot supply.\n return hasId ? Schema.make<Schema.Top>(SchemaAST.omit(ast, ['id'])) : schema;\n};\n\n/**\n * Drop fields annotated with `FormInputAnnotation.set(false)` from a schema so\n * the form's validator doesn't trip on required-but-hidden fields. Used by\n * the picker's inline create form, where a `FactoryAnnotation` typically\n * supplies the hidden values (e.g. a backing-object Ref) outside the form.\n */\nexport const omitHiddenFormFields = <S extends Schema.Codec<any, any>>(schema: S): S => {\n const properties = SchemaAST.getPropertySignatures(schema.ast);\n const hidden = properties\n .filter((prop) => Option.getOrElse(Annotation.FormInputAnnotation.getFromAst(prop.type), () => true) === false)\n .map((prop) => prop.name as string);\n // Cast: omitting a dynamically-computed set of keys can't be expressed as the original `S`, but\n // the result is structurally a subset of `S` and callers treat it as `S`.\n return hidden.length === 0 ? schema : (Schema.make<Schema.Top>(SchemaAST.omit(schema.ast, hidden)) as any);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\n\nimport { Annotation } from '@dxos/echo';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\n/** The property's type with an optional `T | undefined` union unwrapped to its inner `T`. */\nconst unwrapOptional = (prop: SchemaAST.PropertySignature): SchemaAST.AST => {\n if (!SchemaAST.isOptional(prop.type) || !SchemaAST.isUnion(prop.type)) {\n return prop.type;\n }\n // Drop the `undefined` member, preserving the remaining union (don't collapse `A | B | undefined` to `A`).\n const defined = prop.type.types.filter((type) => type._tag !== 'Undefined');\n if (defined.length === 0) {\n return prop.type;\n }\n return defined.length === 1\n ? defined[0]\n : new SchemaAST.Union(defined, prop.type.options, prop.type.annotations, prop.type.checks);\n};\n\n/**\n * Discriminator values that open a root discriminated union on its first member.\n *\n * A union root with no discriminator value renders as a lone select and nothing else — no member's\n * fields, and no way to submit — so the form seeds the first member rather than presenting a dead\n * form. Member order is therefore the declaration order of `Schema.Union`: put the common case first.\n */\nexport const getDiscriminatorDefaults = (ast: SchemaAST.AST | undefined): Record<string, unknown> => {\n if (!ast || !SchemaEx.isDiscriminatedUnion(ast) || !SchemaAST.isUnion(ast)) {\n return {};\n }\n\n const discriminators = new Set(SchemaEx.getDiscriminatingProps(ast) ?? []);\n const [first] = ast.types;\n if (!first || discriminators.size === 0) {\n return {};\n }\n\n return Object.fromEntries(\n SchemaAST.getPropertySignatures(first)\n .filter((prop) => discriminators.has(prop.name.toString()) && SchemaAST.isLiteral(prop.type))\n .map((prop) => [prop.name.toString(), (prop.type as SchemaAST.Literal).literal]),\n );\n};\n\n/**\n * Resolve the properties to render for a field set's *root* schema, given the current form values.\n *\n * A top-level discriminated union is rendered flat: the fields of the member selected by the current\n * discriminator value, with the discriminator field keeping the union-wide set of literals so it stays\n * switchable. (`SchemaAST.getPropertySignatures` on a union returns only the common discriminator, so a\n * union root would otherwise render just that one field.) Non-union roots are unchanged. Nested unions are\n * unaffected — those are expanded per-field by `FormFieldDispatch`, which passes a single-member type literal here.\n */\nexport const getRootFormProperties = (\n ast: SchemaAST.AST,\n values: AnyProperties | undefined,\n): SchemaEx.SchemaProperty[] => {\n if (!SchemaEx.isDiscriminatedUnion(ast)) {\n return getFormProperties(ast);\n }\n\n const activeType = SchemaEx.getDiscriminatedType(ast, values ?? {});\n if (!activeType) {\n return getFormProperties(ast);\n }\n const activeProps = getFormProperties(activeType);\n\n const discriminators = new Set((SchemaEx.getDiscriminatingProps(ast) ?? []).map((name) => name.toString()));\n if (discriminators.size === 0) {\n return activeProps;\n }\n // The matched member types its discriminator as a single literal; swap in the union-wide literal so the\n // field renders as a full select rather than a fixed value.\n const fullType = SchemaEx.getDiscriminatedType(ast, {});\n const fullDiscriminatorProps = fullType ? getFormProperties(fullType) : activeProps;\n return activeProps.map((prop) =>\n discriminators.has(prop.name.toString())\n ? (fullDiscriminatorProps.find((candidate) => candidate.name === prop.name) ?? prop)\n : prop,\n );\n};\n\n/**\n * Get the property types of an AST and filter out properties that are not form inputs.\n *\n * The `FormInputAnnotation` is read from the raw property signature's AST (before\n * `encodedBoundAST` is applied by `SchemaEx.getProperties`), because `encodedBoundAST` strips\n * annotations from non-keyword inner types (e.g., `Schema.Struct`, `Schema.Array`).\n * Without this, fields like `Routine.input` (a JsonSchema struct) annotated\n * `FormInputAnnotation.set(false)` would still render in the form.\n *\n * For optional fields, `prop.type` is the union `T | undefined` — the annotation\n * lives on the inner `T`. Unwrap before reading so that the conventional pattern\n * `Schema.String.pipe(FormInputAnnotation.set(false), Schema.optional)` works.\n *\n * Container properties (nested structs, unions, arrays) keep their *raw* AST rather than\n * the `encodedBoundAST` produced by `SchemaEx.getProperties`. `encodedBoundAST` strips annotations\n * from non-keyword inner types, so a `FormInputAnnotation` nested beneath an encoded container\n * (e.g. `RouteLeg.geometry`, reached via `Segment → details → routes → Route → legs`) would\n * otherwise be lost by the time recursion reaches it. Leaf/transformation fields stay encoded\n * (e.g. a `DateTime` still renders as its encoded string input).\n */\nexport const getFormProperties = (ast: SchemaAST.AST): SchemaEx.SchemaProperty[] => {\n const signatures = SchemaAST.getPropertySignatures(ast);\n const rawByName = new Map<PropertyKey, SchemaAST.AST>(signatures.map((prop) => [prop.name, unwrapOptional(prop)]));\n const hidden = new Set(\n signatures\n .filter(\n (prop) =>\n Annotation.FormInputAnnotation.getFromAst(unwrapOptional(prop)).pipe(Option.getOrElse(() => true)) === false,\n )\n .map((prop) => prop.name),\n );\n return SchemaEx.getProperties(ast)\n .filter((prop) => !hidden.has(prop.name))\n .map((prop) => {\n const raw = rawByName.get(prop.name);\n return raw && (SchemaEx.isNestedType(raw) || SchemaEx.isArrayType(raw)) ? { ...prop, type: raw } : prop;\n });\n};\n\n/**\n * The object type at a path of the schema, for walking a nested object's properties: each segment\n * is a property name (an array index selects the element type), and a discriminated union is\n * resolved by the value at that path. `undefined` when the path leads to no object.\n */\nexport const getSchemaAtPath = (\n ast: SchemaAST.AST,\n path: (string | number)[],\n values: AnyProperties | undefined,\n): SchemaAST.AST | undefined => {\n let node: SchemaAST.AST = ast;\n for (const segment of path) {\n if (typeof segment === 'number') {\n const element = SchemaEx.getArrayElementType(node);\n if (!element) {\n return undefined;\n }\n node = element;\n continue;\n }\n const literal = SchemaEx.findNode(node, SchemaAST.isObjects);\n if (!literal) {\n return undefined;\n }\n const prop = SchemaAST.getPropertySignatures(literal).find((candidate) => String(candidate.name) === segment);\n if (!prop) {\n return undefined;\n }\n node = unwrapOptional(prop);\n }\n const union = SchemaEx.findNode(node, SchemaEx.isDiscriminatedUnion);\n return union\n ? SchemaEx.getDiscriminatedType(union, SchemaEx.getValue(values ?? {}, SchemaEx.createJsonPath(path)) ?? {})\n : SchemaEx.findNode(node, SchemaAST.isObjects);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { Ref } from '@dxos/echo';\nimport * as Annotation from '@dxos/echo/Annotation';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\ntype RefProps = {\n ast: SchemaAST.AST;\n isArray: boolean;\n typename?: string;\n};\n\nexport const getRefProps = (ast: SchemaAST.AST): RefProps | undefined => {\n // Array of references.\n if (SchemaEx.isArrayType(ast)) {\n const elementType = SchemaEx.getArrayElementType(ast);\n if (elementType) {\n if (Ref.isRefType(elementType)) {\n const typename = SchemaEx.findAnnotation<Annotation.ReferenceAnnotationValue>(\n elementType,\n Annotation.ReferenceAnnotationId,\n )?.typename;\n return { ast: elementType, isArray: true, typename };\n }\n }\n }\n\n // Direct reference.\n if (Ref.isRefType(ast)) {\n const typename = SchemaEx.findAnnotation<Annotation.ReferenceAnnotationValue>(\n ast,\n Annotation.ReferenceAnnotationId,\n )?.typename;\n return { ast, isArray: false, typename };\n }\n\n return undefined;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Equal from 'effect/Equal';\nimport type * as Schema from 'effect/Schema';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Ref } from '@dxos/echo';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { log } from '@dxos/log';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport { type ValidationError, validateSchema } from '@dxos/schema';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { type FormFieldOverride, type FormFieldStatus } from '#types';\n\nimport { getDiscriminatorDefaults } from '../util/index.ts';\n\n/**\n * Form properties.\n */\nexport interface FormHandlerProps<T extends AnyProperties> {\n /**\n * Effect schema (Type literal).\n */\n schema?: Schema.Codec<T, any>;\n\n /**\n * Source values. Fields the user is not editing reflect this value; in-progress edits (including intermediate\n * invalid values) are held locally and never snap back until they are committed and the source catches up. Persist\n * committed values from `onValuesChanged`/`onSave`. The form re-renders when a new value is passed, so to reflect\n * external/remote mutations pass a reactive source (e.g. a `useObject` snapshot that changes on mutation) rather\n * than a raw live object — a render-time read of an ECHO object does not itself subscribe to it.\n */\n values?: Partial<T>;\n\n /**\n * Seeds an uncontrolled form once at mount when `values` is not provided; not reconciled thereafter.\n */\n defaultValues?: Partial<T>;\n\n /** Per-field overrides by json-path (`style.hue`); see {@link FormFieldOverride}. */\n fieldOverrides?: Readonly<Record<string, FormFieldOverride>>;\n\n /**\n * Auto-save the form when the values change.\n */\n autoSave?: boolean;\n\n /**\n * Callback for value changes. Note: This is called even when values are invalid.\n * Sometimes the parent component may want to know about changes even if the form is\n * in an invalid state.\n */\n onValuesChanged?: (values: Partial<T>, meta: FormUpdateMeta<T>) => void;\n\n /**\n * Custom validation function that runs only after schema validation passes.\n * Use this for complex validation logic that can't be expressed in the schema.\n * @returns Array of validation errors, or undefined if validation passes\n */\n onValidate?: (values: T) => ValidationError[] | undefined;\n\n /**\n * Called when the form is submitted and passes validation.\n */\n onSave?: (values: T, meta: FormUpdateMeta<T>) => MaybePromise<void>;\n\n /**\n * Called when the form is canceled.\n */\n onCancel?: () => void;\n}\n\nexport type FormUpdateMeta<T extends AnyProperties> = {\n changed: FormHandler<T>['changed'];\n isValid: boolean;\n};\n\n/**\n * Form handler properties and methods.\n */\nexport type FormHandler<T extends AnyProperties> = Pick<FormHandlerProps<T>, 'schema' | 'autoSave'> & {\n /** Initial values (which may not pass validation). */\n values: Partial<T>;\n\n /** Fields whose value has been edited (set by `onValueChange`). Gates autosave-on-blur. */\n changed: Record<SchemaEx.JsonPath, boolean>;\n /** Fields the user has interacted with (set by `onBlur`). Gates error *visibility* — errors only surface once touched. */\n touched: Record<SchemaEx.JsonPath, boolean>;\n\n /** Map of error strings. */\n errors: Record<SchemaEx.JsonPath, string>;\n\n /** Whether the values pass validation (no errors at all). */\n isValid: boolean;\n /**\n * Whether the submit affordance should be enabled. Stricter than `isValid`: it also requires no save\n * in flight (`saving`) and only blocks on errors for *touched* fields, so a pristine form with\n * not-yet-touched required fields can still show an enabled control.\n */\n canSave: boolean;\n\n onSave: () => void;\n onCancel: () => void;\n\n //\n // Form field state management\n //\n\n getStatus: (path: string | (string | number)[]) => FormFieldStatus;\n /** The caller's override for the field at `path`, if any. */\n getOverride: (path: (string | number)[]) => FormFieldOverride | undefined;\n getValue: <V>(path: (string | number)[]) => V | undefined;\n onBlur: (path: (string | number)[]) => void;\n onValueChange: <V>(path: (string | number)[], type: SchemaAST.AST, value: V) => void;\n};\n\n/**\n * Creates a hook for managing form state, including values, validation, and submission.\n * Deeply integrated with `@dxos/schema` for schema-based validation.\n */\nexport const useFormHandler = <T extends AnyProperties>({\n schema,\n autoSave,\n fieldOverrides,\n values: valuesProp,\n defaultValues: defaultValuesProp,\n onValuesChanged,\n onValidate,\n onSave,\n onCancel,\n ...props\n}: FormHandlerProps<T>): FormHandler<T> => {\n const [changed, setChanged] = useState<Record<SchemaEx.JsonPath, boolean>>({});\n const [touched, setTouched] = useState<Record<SchemaEx.JsonPath, boolean>>({});\n const [errors, setErrors] = useState<Record<SchemaEx.JsonPath, string>>({});\n const [saving, setSaving] = useState(false);\n const seed = Hooks.useDefaultValue<Partial<T>>(defaultValuesProp, () => ({}));\n // A root discriminated union renders nothing but its select until the discriminator has a value, so\n // the form opens on the first member unless the caller seeded one of its own.\n const defaultValues = useMemo(\n () => ({ ...getDiscriminatorDefaults(schema?.ast), ...seed }) as Partial<T>,\n [schema, seed],\n );\n\n // The source the form reads from for every field the user is not actively editing. The form is a pure function of\n // this value and re-renders when the parent passes a new one; to reflect external/remote mutations the parent must\n // supply a reactive source (e.g. a `useObject` snapshot that changes on mutation). `defaultValues` seeds an\n // uncontrolled form once when no `values` are provided.\n const source = valuesProp ?? defaultValues;\n\n // Sparse local edits keyed by json-path. A path stays here — holding even an intermediate invalid value, so it\n // never snaps back — until the source catches up to it (typically once a valid edit has been persisted and echoed\n // back through `values`). Un-edited paths are never buffered, so they always reflect the current source.\n const [overrides, setOverrides] = useState<Record<SchemaEx.JsonPath, unknown>>({});\n\n // Merged view (source overlaid with local edits) for whole-form consumers: validation, save, and context/debug.\n // Computed each render (not memoized) so it stays fresh when the source value changes.\n const values = applyOverrides(source, overrides);\n\n // Validate.\n const validate = useCallback(\n (values: Partial<T>): values is T => {\n if (!schema) {\n return false;\n }\n\n let errors: ValidationError[] = validateSchema(schema, values) ?? [];\n if (errors.length === 0 && onValidate) {\n const validatedValues = values as T;\n errors = onValidate(validatedValues) ?? [];\n }\n\n setErrors(flatMap(errors));\n const valid = errors.length === 0;\n // Never log values or error messages: fields may hold secrets (passwords, API keys) and messages can echo them.\n log('validate', { valid, errorPaths: errors.map((error) => error.path) });\n return valid;\n },\n [schema, onValidate],\n );\n\n // Validate on schema change.\n const [schemaChanged, setSchemaChanged] = useState(false);\n useEffect(() => setSchemaChanged(true), [schema]);\n useEffect(() => {\n if (schemaChanged) {\n validate(values);\n setSchemaChanged(false);\n }\n }, [validate, values, schemaChanged]);\n\n // Drop an override once the source has caught up to it (the committed value has been echoed back), so the field\n // returns to reflecting the source. Edits the source has not yet reflected — including intermediate invalid values,\n // and in-progress edits to a field that changed remotely — are kept, so the form never snaps back. Runs on every\n // render (a new source value re-renders the form), reconciling against whatever the source currently holds.\n useEffect(() => {\n const reconciled = (Object.keys(overrides) as SchemaEx.JsonPath[]).filter((path) =>\n valuesEqual(SchemaEx.getValue(source, path), overrides[path]),\n );\n if (reconciled.length === 0) {\n return;\n }\n setOverrides((prev) => omitPaths(prev, reconciled));\n setChanged((prev) => omitPaths(prev, reconciled));\n setTouched((prev) => omitPaths(prev, reconciled));\n });\n\n const isValid = useMemo(() => {\n return Object.keys(errors).length === 0;\n }, [errors]);\n\n /**\n * NOTE: We can submit if there is no touched field that has an error.\n * If there's a validation message visible in the form, submit should be disabled.\n */\n const canSave = useMemo(\n () =>\n !saving &&\n // Check if any error paths that are touched have errors.\n !Object.entries(touched).some(\n ([path, isTouched]) =>\n isTouched &&\n Object.keys(errors).some(\n (errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`),\n ),\n ),\n [touched, errors, saving],\n );\n\n const handleSave = useCallback(async () => {\n if (validate(values)) {\n setSaving(true);\n try {\n await onSave?.(values, { changed, isValid });\n } finally {\n setSaving(false);\n }\n }\n }, [values, validate, onSave, changed, isValid]);\n\n const handleCancel = useCallback(() => {\n onCancel?.();\n }, [onCancel]);\n\n //\n // Fields.\n //\n\n const getStatus = useCallback<FormHandler<T>['getStatus']>(\n (path) => {\n const jsonPath = Array.isArray(path) ? SchemaEx.createJsonPath(path) : path;\n const [_, error] =\n Object.entries(errors).find(\n ([errorPath]) =>\n errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`),\n ) ?? [];\n\n const indeterminate = isIndeterminate(fieldOverrides, overrides, jsonPath);\n\n // Only show errors for touched fields.\n const isTouched = touched[jsonPath as SchemaEx.JsonPath];\n if (!isTouched) {\n return {\n status: undefined,\n error: undefined,\n indeterminate,\n };\n }\n\n return {\n status: error ? 'error' : undefined,\n error: error ? (error ?? undefined) : undefined,\n indeterminate,\n };\n },\n [errors, touched, fieldOverrides, overrides],\n );\n\n const getOverride = useCallback<FormHandler<T>['getOverride']>(\n (path) => fieldOverrides?.[SchemaEx.createJsonPath(path)],\n [fieldOverrides],\n );\n\n const getValue = useCallback<FormHandler<T>['getValue']>(\n (path) => {\n const jsonPath = SchemaEx.createJsonPath(path);\n if (Object.prototype.hasOwnProperty.call(overrides, jsonPath)) {\n return overrides[jsonPath] as any;\n }\n // An indeterminate value has none to show until it is edited.\n if (fieldOverrides?.[jsonPath]?.indeterminate) {\n return undefined;\n }\n // Un-edited fields reflect the current source value.\n return SchemaEx.getValue(source, jsonPath);\n },\n [source, overrides, fieldOverrides],\n );\n\n const onValueChange = useCallback<FormHandler<T>['onValueChange']>(\n (path, type, value) => {\n log('onValueChange', { path });\n\n const jsonPath = SchemaEx.createJsonPath(path);\n const pathArray = path;\n let parsedValue = value as any;\n try {\n if (type._tag === 'Number') {\n parsedValue = parseFloat(value as string) || 0;\n }\n } catch (err) {\n log.catch(err);\n parsedValue = undefined;\n }\n\n // Hold the edit locally as an override (including invalid values, so it never snaps back); un-edited paths keep\n // tracking the live source. The prune effect drops the override once the source catches up.\n const newOverrides = { ...overrides, [jsonPath]: parsedValue };\n setOverrides(newOverrides);\n\n // TODO(burdon): Check value has changed from original.\n const newChanged = { [jsonPath]: true };\n setChanged((prev) => ({ ...prev, ...newChanged }));\n\n // Merged values for validation and the callback. Form never mutates the source; the parent persists.\n const newValues = applyOverrides(source, newOverrides);\n\n // Validate.\n const isValid = validate(newValues);\n\n // Notify parent; parent is responsible for persisting the change (typically once valid).\n onValuesChanged?.(newValues, { isValid, changed: newChanged });\n },\n [source, overrides, validate, onValuesChanged],\n );\n\n // A blur commits the field. The validation and auto-save run in an effect, after the render that carries the\n // change, so a control that changes and blurs in one handler (a switch, a select, a picker) commits the value it\n // just set rather than the one rendered before it.\n const [committing, setCommitting] = useState(false);\n const onBlur = useCallback((path: (string | number)[]) => {\n const jsonPath = SchemaEx.createJsonPath(path);\n\n // TODO(burdon): Check value has changed from original.\n setTouched((touched) => ({ ...touched, [jsonPath]: true }));\n setCommitting(true);\n }, []);\n useEffect(() => {\n if (!committing) {\n return;\n }\n setCommitting(false);\n const isValid = validate(values);\n if (Object.keys(changed).length > 0 && isValid && autoSave) {\n void onSave?.(values as T, { changed, isValid });\n }\n }, [committing, validate, values, changed, autoSave, onSave]);\n\n return useMemo<FormHandler<T>>(\n () => ({\n // State.\n schema,\n values,\n errors,\n touched,\n changed,\n isValid,\n canSave,\n autoSave,\n\n // Actions.\n onSave: handleSave,\n onCancel: handleCancel,\n\n // Field utils.\n getStatus,\n getOverride,\n getValue,\n onBlur,\n onValueChange,\n\n ...props,\n }),\n [\n schema,\n autoSave,\n values,\n errors,\n touched,\n changed,\n canSave,\n isValid,\n getStatus,\n getOverride,\n getValue,\n onBlur,\n onValueChange,\n handleSave,\n handleCancel,\n ],\n );\n};\n\n/**\n * Creates a new object with value at path. Does not mutate source.\n * Preserves arrays when path segments are numeric indices.\n */\nconst mergeAtPath = (obj: any, path: readonly (string | number)[], value: any): any => {\n if (path.length === 0) {\n return value;\n }\n\n const [head, ...rest] = path;\n const child = rest.length === 0 ? value : mergeAtPath(obj?.[head], rest, value);\n\n if (Array.isArray(obj)) {\n const copy = [...obj];\n copy[head as number] = child;\n return copy;\n }\n\n return { ...obj, [head]: child };\n};\n\n/** Overlays sparse json-path edits onto a base value without mutating it; un-edited paths keep the base reference. */\nconst applyOverrides = <T>(base: Partial<T>, overrides: Record<SchemaEx.JsonPath, unknown>): Partial<T> => {\n let result: Partial<T> = base;\n for (const path of Object.keys(overrides) as SchemaEx.JsonPath[]) {\n result = mergeAtPath(result, SchemaEx.splitJsonPath(path), overrides[path]) as Partial<T>;\n }\n return result;\n};\n\n// Copied from `@dxos/echo` (internal `Obj.valuesEqual`): references compare by target URI, arrays and plain\n// object-shaped property bags (excluding `id`) compare recursively, and leaves fall back to Effect `Equal.equals`,\n// which is structural by default in Effect 4. Effect's `Schema.toEquivalence` is not a safe substitute — it returns false-positive\n// equality for dynamic/union/ref-array schemas, which would silently prune edits.\n// TODO(wittjosiah): Factor out into a shared util rather than duplicating echo's internal implementation.\nconst valuesEqual = (left: unknown, right: unknown): boolean => {\n if (left === right) {\n return true;\n }\n if (left === null || right === null) {\n return left === right;\n }\n if (typeof left !== 'object' || typeof right !== 'object') {\n return Equal.equals(left, right);\n }\n if (Ref.isRef(left) && Ref.isRef(right)) {\n return left.uri === right.uri;\n }\n if (Ref.isRef(left) || Ref.isRef(right)) {\n return false;\n }\n if (Array.isArray(left) && Array.isArray(right)) {\n if (left.length !== right.length) {\n return false;\n }\n return left.every((value, index) => valuesEqual(value, right[index]));\n }\n if (Array.isArray(left) || Array.isArray(right)) {\n return false;\n }\n const leftRecord = left as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n const keys = new Set([\n ...Object.keys(leftRecord).filter((key) => key !== 'id'),\n ...Object.keys(rightRecord).filter((key) => key !== 'id'),\n ]);\n for (const key of keys) {\n if (!valuesEqual(leftRecord[key], rightRecord[key])) {\n return false;\n }\n }\n return true;\n};\n\n/** Whether a path is indeterminate and still unedited: an edit is the user's own value, so it shows. */\nconst isIndeterminate = (\n fieldOverrides: FormHandlerProps<any>['fieldOverrides'],\n overrides: Record<SchemaEx.JsonPath, unknown>,\n jsonPath: string,\n): boolean => !!fieldOverrides?.[jsonPath]?.indeterminate && !Object.prototype.hasOwnProperty.call(overrides, jsonPath);\n\n/** Returns a copy of `record` without the given json-path keys. */\nconst omitPaths = <V>(\n record: Record<SchemaEx.JsonPath, V>,\n paths: SchemaEx.JsonPath[],\n): Record<SchemaEx.JsonPath, V> => {\n const omit = new Set<string>(paths);\n return Object.fromEntries(Object.entries(record).filter(([key]) => !omit.has(key))) as Record<SchemaEx.JsonPath, V>;\n};\n\nconst flatMap = (errors: ValidationError[]) => {\n return errors.reduce(\n (result, { path, message }) => {\n // Convert the validation error path format to our SchemaEx.JsonPath format.\n const jsonPath = SchemaEx.fromEffectValidationPath(path);\n if (!(jsonPath in result)) {\n result[jsonPath] = message;\n }\n return result;\n },\n {} as Record<SchemaEx.JsonPath, string>,\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type RefObject, useCallback, useLayoutEffect } from 'react';\n\nimport { addEventListener } from '@dxos/async';\n\nimport { type FormHandler } from './useFormHandler.ts';\n\n/**\n * Cmd+Enter on macOS, Ctrl+Enter elsewhere; both are accepted everywhere, as GitHub's forms do.\n * Not while an IME is composing, where the chord confirms the text being composed.\n */\nconst isSubmitChord = (event: KeyboardEvent) =>\n event.key === 'Enter' && (event.metaKey || event.ctrlKey) && !event.shiftKey && !event.altKey && !event.isComposing;\n\nexport type KeyHandlerOptions = {\n /** A readonly form has nothing to submit, so the chord passes through to whatever holds focus. */\n readonly?: boolean;\n};\n\n/**\n * Submits the form on Cmd/Ctrl+Enter from any field, including multi-line ones.\n */\nexport const useKeyHandler = (\n elRef: RefObject<HTMLDivElement | null>,\n form: FormHandler<any>,\n { readonly }: KeyHandlerOptions = {},\n) => {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n // An auto-saving form has no submit for the chord to mean.\n if (!isSubmitChord(event) || readonly || form.autoSave) {\n return;\n }\n\n // Capture runs outermost first, so a nested form's chord must be left to that form.\n const owner = event.target instanceof Element ? event.target.closest('[role=\"form\"]') : null;\n if (owner !== event.currentTarget) {\n return;\n }\n\n // Consumed even when nothing is saved, so a field's own binding (CodeMirror's Mod-Enter inserts\n // a blank line) never runs in its place.\n event.preventDefault();\n event.stopPropagation();\n\n // `isValid` as well as `canSave`: a required field the reader never touched carries no visible\n // error, so `canSave` alone would submit an empty form.\n if (form.canSave && form.isValid) {\n form.onSave();\n }\n },\n [readonly, form.autoSave, form.isValid, form.canSave, form.onSave],\n );\n\n useLayoutEffect(() => {\n const el = elRef.current;\n if (!el) {\n return;\n }\n\n // Capture phase, so the form sees the chord before the focused field's own key handling.\n return addEventListener(el, 'keydown', handleKeyDown, { capture: true });\n }, [elRef, handleKeyDown]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type RefObject, useEffect, useRef } from 'react';\n\nimport { addEventListener } from '@dxos/async';\n\n/** Input types whose Enter carries no meaning of its own, as in a native `<form>`'s implicit submission. */\nconst SINGLE_LINE_INPUT_TYPES = new Set(['', 'text', 'search', 'email', 'url', 'tel', 'password', 'number']);\n\nconst isSingleLineInput = (target: EventTarget | null): target is HTMLInputElement =>\n target instanceof HTMLInputElement &&\n SINGLE_LINE_INPUT_TYPES.has(target.type) &&\n // An autocompleting input (combobox, ref picker) spends Enter on choosing an option.\n !target.hasAttribute('aria-autocomplete') &&\n target.getAttribute('role') !== 'combobox';\n\nexport type SubmitOnEnterOptions = {\n disabled?: boolean;\n};\n\n/**\n * Calls `onSubmit` on a plain Enter in a single-line input inside `elRef`, the implicit submission a\n * native `<form>` gives; multi-line fields (textarea, markdown editors) and modified Enter keep their own meaning.\n */\nexport const useSubmitOnEnter = (\n elRef: RefObject<HTMLElement | null>,\n onSubmit: () => void,\n { disabled }: SubmitOnEnterOptions = {},\n) => {\n const onSubmitRef = useRef(onSubmit);\n onSubmitRef.current = onSubmit;\n\n useEffect(() => {\n const el = elRef.current;\n if (!el || disabled) {\n return;\n }\n\n // On the document, in the bubble phase, so a field that handles Enter itself (and says so with\n // `preventDefault`) has already run; content portaled out of `el` (popovers) is never a target.\n return addEventListener(el.ownerDocument, 'keydown', (event: KeyboardEvent) => {\n if (\n event.key !== 'Enter' ||\n event.defaultPrevented ||\n event.isComposing ||\n // Safari ends an IME composition with an Enter whose `isComposing` is false but `keyCode` is 229.\n event.keyCode === 229 ||\n event.shiftKey ||\n event.altKey ||\n event.metaKey ||\n event.ctrlKey ||\n !isSingleLineInput(event.target) ||\n !el.contains(event.target)\n ) {\n return;\n }\n\n event.preventDefault();\n onSubmitRef.current();\n });\n }, [elRef, disabled]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\n// Kept out of `FormLayout.tsx`: react-refresh only fast-refreshes a module whose\n// exports are all components, so values exported beside them force a full page reload on every edit.\n\nexport type ResolvedLayoutField = {\n /** Resolved leaf AST node for the field. */\n type: SchemaAST.AST;\n /** Path segments (dotted names split on `.`). */\n segments: string[];\n /** Last path segment; used to derive the field label when there is no `title` annotation. */\n leafName: string;\n /** Resolved `title` annotation for the field, if any. */\n title?: string;\n /**\n * Set when the field resolves to a nested struct carrying a `LabelAnnotation` —\n * the type literal whose computed label should render in place of the struct's\n * sub-fields. Undefined for ordinary (non-auto-labelled) fields.\n */\n labelType?: SchemaAST.AST;\n /** Whether the resolved property is required (non-optional). */\n required: boolean;\n};\n\n/**\n * Walks a dotted path of property names through nested struct ASTs, returning the\n * leaf `PropertySignature` (or `undefined` if any segment is missing).\n */\nconst resolvePropertySignature = (ast: SchemaAST.AST, segments: string[]): SchemaAST.PropertySignature | undefined => {\n let node: SchemaAST.AST = ast;\n for (let index = 0; index < segments.length; index++) {\n const typeLiteral = SchemaEx.findNode(node, SchemaAST.isObjects);\n if (!typeLiteral) {\n return undefined;\n }\n const prop = SchemaAST.getPropertySignatures(typeLiteral).find(\n (p) => globalThis.String(p.name) === segments[index],\n );\n if (!prop) {\n return undefined;\n }\n if (index === segments.length - 1) {\n return prop;\n }\n node = prop.type;\n }\n\n return undefined;\n};\n\n/**\n * Resolves a (possibly dotted) layout field name against a schema.\n * - `origin.code` drills through nested structs to the leaf field.\n * - A name resolving to a nested struct with a `LabelAnnotation` is flagged via\n * `labelType` so the layout can auto-convert it to a single read-only label.\n * Returns `undefined` when the name does not resolve to a property.\n */\nexport const resolveLayoutField = (schema: Schema.Schema<any>, name: string): ResolvedLayoutField | undefined => {\n const segments = name.split('.');\n const prop = resolvePropertySignature(schema.ast, segments);\n if (!prop) {\n return undefined;\n }\n\n // Normalized leaf type (optional unwrapped, refinements stripped, signature-level\n // annotations merged) — matches how `getProperties` feeds `FormFieldDispatch`.\n const { type: baseType } = SchemaEx.getBaseType(prop.type);\n // Key annotations (v3's `PropertySignature.annotations`) hang off the type's context in v4.\n const keyAnnotations = prop.type.context?.annotations;\n const type =\n keyAnnotations && Reflect.ownKeys(keyAnnotations).length > 0\n ? SchemaAST.annotate(baseType, keyAnnotations)\n : baseType;\n\n const title = SchemaEx.getAnnotation<string>(SchemaAST.TitleAnnotationId)(type);\n\n // Label detection reads the *raw* property type: `SchemaEx.getBaseType`'s `encodedBoundAST`\n // strips annotations from non-keyword inner types (e.g. nested structs), which would\n // drop the `LabelAnnotation` we rely on here.\n const labelType = SchemaEx.findNode(prop.type, SchemaAST.isObjects);\n const labelled = labelType != null && Option.isSome(Annotation.LabelAnnotation.getFromAst(labelType));\n\n return {\n type,\n segments,\n leafName: segments[segments.length - 1],\n title,\n labelType: labelled ? labelType : undefined,\n required: !SchemaAST.isOptional(prop.type),\n };\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { format as formatDate } from 'date-fns';\nimport * as Option from 'effect/Option';\nimport * as Str from 'effect/String';\nimport React, { Component, type PropsWithChildren, useMemo } from 'react';\n\nimport { Format } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport * as Banner from '@dxos/react-ui/Banner';\n\nimport { type FormPresentation } from '#types';\n\nimport { useFormContext, useFormFieldState } from '../hooks/index.ts';\nimport { type FormFieldBinding } from './FormFieldContext.ts';\nimport { resolveLayoutField } from './layout/resolve-layout-field.ts';\n\n/**\n * Formats a value for `static` (read-only, plain-DOM) presentation based on its\n * type `format`. Dates/times are rendered human-readable; everything else falls\n * back to `String(value)`.\n */\nexport const formatStaticValue = (value: unknown, format?: Format.TypeFormat): string => {\n if (value == null) {\n return '';\n }\n\n switch (format) {\n case Format.TypeFormat.DateTime:\n case Format.TypeFormat.Date:\n case Format.TypeFormat.Time: {\n const date = new Date(value as string);\n if (Number.isNaN(date.getTime())) {\n return String(value);\n }\n const pattern = format === Format.TypeFormat.DateTime ? 'PPp' : format === Format.TypeFormat.Date ? 'PP' : 'p';\n return formatDate(date, pattern);\n }\n default:\n return String(value);\n }\n};\n\n/** The schema property at a path of the form's schema: its type, and what the row derives from it. */\nexport const useFormSchemaProperty = (componentName: string, path: string) => {\n const { form } = useFormContext(componentName);\n return useMemo(() => {\n if (!form.schema) {\n return undefined;\n }\n const resolved = resolveLayoutField(form.schema, path);\n if (!resolved) {\n return undefined;\n }\n const description = SchemaEx.getAnnotation<string>(SchemaAST.DescriptionAnnotationId)(resolved.type);\n const format = Format.FormatAnnotation.getFromAst(resolved.type).pipe(Option.getOrUndefined);\n return {\n type: resolved.type,\n label: resolved.title ?? Str.capitalize(resolved.leafName),\n description,\n format,\n required: resolved.required,\n };\n }, [form.schema, path]);\n};\n\ntype SchemaProperty = ReturnType<typeof useFormSchemaProperty>;\n\n/** The binding for a row at a path, from the form handler. */\nexport const useFormFieldBindingAt = <T,>(\n componentName: string,\n path: string,\n property: SchemaProperty,\n { required, readonly, presentation }: { required?: boolean; readonly?: boolean; presentation?: FormPresentation },\n): FormFieldBinding<T> => {\n const { readonly: formReadonly, layout } = useFormContext(componentName);\n const segments = useMemo(() => (SchemaEx.isJsonPath(path) ? SchemaEx.splitJsonPath(path) : []), [path]);\n const { getStatus, getValue, onBlur, onValueChange } = useFormFieldState(componentName, segments);\n const { status, error, indeterminate } = getStatus();\n const value = getValue() as T | undefined;\n const type = property?.type ?? SchemaAST.unknownKeyword;\n return useMemo(\n () => ({\n path,\n type,\n value,\n setValue: (next: T | undefined) => onValueChange(type, next),\n onBlur,\n status,\n error,\n indeterminate,\n required: required ?? property?.required,\n readonly: readonly ?? formReadonly,\n presentation: presentation ?? layout,\n }),\n [\n path,\n type,\n value,\n onValueChange,\n onBlur,\n status,\n error,\n indeterminate,\n required,\n property?.required,\n readonly,\n formReadonly,\n presentation,\n layout,\n ],\n );\n};\n\n/** Whether a value counts as unfilled for the required marker. `false` and `0` are values. */\nexport const isEmptyValue = (value: unknown): boolean =>\n value == null || value === '' || (Array.isArray(value) && value.length === 0);\n\n//\n// FormFieldErrorBoundary\n//\n\ntype FormFieldErrorState = {\n error: Error | undefined;\n};\n\ntype FormFieldErrorBoundaryProps = PropsWithChildren<{\n path?: (string | number)[];\n}>;\n\nexport class FormFieldErrorBoundary extends Component<FormFieldErrorBoundaryProps, FormFieldErrorState> {\n static getDerivedStateFromError(error: Error): { error: Error } {\n return { error };\n }\n\n override state = { error: undefined };\n\n override componentDidUpdate(prevProps: FormFieldErrorBoundaryProps) {\n if (prevProps.path !== this.props.path) {\n this.resetError();\n }\n }\n\n override render() {\n if (this.state.error) {\n return (\n <Banner.Root valence='error'>\n <Banner.Body>{`ERROR ${String(this.props.path?.join('.'))}`}</Banner.Body>\n </Banner.Root>\n );\n }\n\n return this.props.children;\n }\n\n private resetError() {\n this.setState({ error: undefined });\n }\n}\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type FocusEvent } from 'react';\n\nimport type * as SchemaAST from '@dxos/effect/SchemaAST';\nimport { createContext } from '@dxos/react-hooks';\n\nimport { type FormFieldStatus, type FormPresentation } from '#types';\n\n// Kept out of `FormField.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a context and its hook exported beside them force a full page reload on every edit.\n\n/** What a bound row provides to the control inside it. */\nexport type FormFieldBinding<T = any> = {\n /** Dotted from the form's root. */\n path: string;\n type: SchemaAST.AST;\n value: T | undefined;\n setValue: (value: T | undefined) => void;\n onBlur: (event?: FocusEvent<HTMLElement>) => void;\n status: FormFieldStatus['status'];\n error?: string;\n /** The field shows no value until it is edited (see `FormFieldOverride.indeterminate`). */\n indeterminate?: boolean;\n required?: boolean;\n readonly?: boolean;\n presentation?: FormPresentation;\n};\n\nexport const [FormFieldBindingProvider, useFormFieldBinding] = createContext<FormFieldBinding>('Form.Field');\n\n/**\n * The binding of the enclosing `Form.Field path`, for a control written by hand inside a bound row:\n * the value to show, `setValue` to commit an edit, `onBlur` to mark it touched, and the row's status.\n */\nexport const useFormField = <T = any>(): FormFieldBinding<T> => useFormFieldBinding('useFormField');\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\n\n// Kept out of `NumberField.tsx`: react-refresh only fast-refreshes a module whose\n// exports are all components, so values exported beside them force a full page reload on every edit.\n\n/** The `representation` annotation a v4 check carries, naming the filter and its payload. */\ntype CheckRepresentation = { readonly id?: string; readonly payload?: Record<string, unknown> | null };\n\nconst representationOf = (check: SchemaAST.Check<any>): CheckRepresentation | undefined =>\n (check.annotations as { representation?: CheckRepresentation } | undefined)?.representation;\n\nconst numberAt = (payload: CheckRepresentation['payload'], key: string): number | undefined => {\n const value = payload?.[key];\n return typeof value === 'number' ? value : undefined;\n};\n\n/**\n * Extracts numeric constraints (`minimum`/`maximum` bounds and whether the value must be an integer)\n * from the checks attached to the node (e.g. produced by `Schema.isBetween` / `Schema.isInt`).\n * Returns empty constraints when none are declared.\n *\n * Effect 4 has no `Refinement` node: refinements are checks on the node itself, each carrying a\n * `representation` annotation naming the filter and its payload.\n */\nexport const getNumericConstraints = (ast: SchemaAST.AST): { min?: number; max?: number; integer: boolean } => {\n let min: number | undefined;\n let max: number | undefined;\n let integer = false;\n\n // Stacked checks intersect: keep the strictest bound (largest min, smallest max).\n const tighten = (lower?: number, upper?: number) => {\n if (lower !== undefined) {\n min = min === undefined ? lower : Math.max(min, lower);\n }\n if (upper !== undefined) {\n max = max === undefined ? upper : Math.min(max, upper);\n }\n };\n\n for (const check of SchemaAST.getChecks(ast)) {\n const representation = representationOf(check);\n switch (representation?.id) {\n case 'effect/schema/isBetween':\n tighten(numberAt(representation.payload, 'minimum'), numberAt(representation.payload, 'maximum'));\n break;\n case 'effect/schema/isGreaterThanOrEqualTo':\n tighten(numberAt(representation.payload, 'minimum'), undefined);\n break;\n case 'effect/schema/isLessThanOrEqualTo':\n tighten(undefined, numberAt(representation.payload, 'maximum'));\n break;\n case 'effect/schema/isInt':\n integer = true;\n break;\n case 'effect/schema/isMultipleOf':\n integer ||= numberAt(representation.payload, 'divisor') === 1;\n break;\n }\n }\n\n return { min, max, integer };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\nimport { getNumericConstraints } from './numeric-constraints.ts';\n\n// Kept out of `ArrayField.tsx`: react-refresh only fast-refreshes a module whose\n// exports are all components, so values exported beside them force a full page reload on every edit.\n\n/**\n * Returns the default empty value for a given AST.\n * Used for initializing new array values etc.\n */\n// TODO(wittjosiah): Factor out?\nexport const getDefaultValue = (ast?: SchemaAST.AST): any => {\n switch (ast?._tag) {\n case 'String': {\n return '';\n }\n case 'Number': {\n // v4 has no `Refinement` node: a refined number IS a `Number` node carrying checks, so the\n // declared minimum (e.g. `Schema.isBetween(1, 31)`) is read from them and used as the default\n // so new array items start within the valid range.\n return getNumericConstraints(ast).min ?? 0;\n }\n case 'Boolean': {\n return false;\n }\n case 'Suspend': {\n return getDefaultValue(ast.thunk());\n }\n default: {\n if (ast && SchemaEx.isNestedType(ast)) {\n return {};\n } else {\n throw new Error(`Unsupported type: ${ast?._tag}`);\n }\n }\n }\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport React, { useCallback, useRef } from 'react';\n\nimport { Annotation, Ref } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { log } from '@dxos/log';\nimport { OrderedList } from '@dxos/react-ui-list';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { arrayMove } from '@dxos/util';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldStateProps } from '#types';\n\nimport { useFormValues } from '../../hooks/index.ts';\nimport { getFormProperties } from '../../util/index.ts';\nimport { FormFieldDispatch } from '../FormFieldDispatch.tsx';\nimport { type FormFieldDispatchProps } from '../resolve-field.ts';\nimport { getDefaultValue } from './default-value.ts';\n\ntype Item = { id: string; index: number };\n\nexport type ArrayFieldProps = {\n label: string;\n fieldProps: FormFieldStateProps;\n} & FormFieldDispatchProps;\n\n/**\n * An array as a header row (label and an add Button) over a `react-ui-list` OrderedList whose rows hold the item's\n * control and a remove Button; a `FormOrderedAnnotation` array adds a DragHandle (pointer drag and keyboard moves).\n */\nexport const ArrayField = ({ type, path, label, readonly, layout, fieldProps, ...props }: ArrayFieldProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const elementType = SchemaEx.getArrayElementType(type);\n const { onValueChange } = fieldProps;\n const values = useFormValues<unknown[]>('Form.ArrayField', path, () => []);\n const ordered = Annotation.FormOrderedAnnotation.getFromAst(type).pipe(Option.getOrElse(() => false));\n const editable = !readonly && layout !== 'static';\n\n // Rows need identities that survive a reorder; values have none, so the field keeps a parallel id list.\n const idsRef = useRef<string[]>([]);\n const counterRef = useRef(0);\n const ids = idsRef.current;\n const count = values?.length ?? 0;\n while (ids.length < count) {\n ids.push(`item-${counterRef.current++}`);\n }\n ids.length = count;\n const items: Item[] = ids.map((id, index) => ({ id, index }));\n\n const handleAdd = useCallback(() => {\n let value: unknown;\n try {\n value =\n elementType && SchemaEx.isNestedType(elementType) ? defaultObject(elementType) : getDefaultValue(elementType);\n } catch (err) {\n log.catch(err);\n return;\n }\n onValueChange(type, [...(values ?? []), value]);\n }, [elementType, onValueChange, type, values]);\n\n const handleRemove = useCallback(\n (index: number) => {\n idsRef.current.splice(index, 1);\n onValueChange(\n type,\n (values ?? []).filter((_, candidate) => candidate !== index),\n );\n },\n [onValueChange, type, values],\n );\n\n const handleMove = useCallback(\n (from: number, to: number) => {\n const next = [...(values ?? [])];\n arrayMove(next, from, to);\n arrayMove(idsRef.current, from, to);\n onValueChange(type, next);\n },\n [onValueChange, type, values],\n );\n\n if (!elementType || (!editable && count === 0)) {\n return null;\n }\n\n const asObject = SchemaEx.isNestedType(elementType) && !Ref.isRefType(elementType);\n const columns = [ordered && editable && 'var(--dx-block-size)', 'minmax(0, 1fr)', editable && 'var(--dx-block-size)']\n .filter(Boolean)\n .join(' ');\n\n return (\n <>\n <Field.Header>\n <Typography.Text truncate>{label}</Typography.Text>\n {editable && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--plus--regular'\n label={t('add-item.button')}\n onClick={handleAdd}\n data-testid={`${SchemaEx.createJsonPath(path ?? [])}.add`}\n />\n )}\n </Field.Header>\n <OrderedList.Root\n items={items}\n getId={(item) => item.id}\n getLabel={(item) => `${label} ${item.index + 1}`}\n columns={columns}\n onMove={handleMove}\n readonly={!editable}\n >\n {({ items }) => (\n <OrderedList.Content scroll={false} gutter='inherit' gap='sm' aria-label={label}>\n {items.map((item) => (\n <OrderedList.Item key={item.id} id={item.id} canDrag={ordered && editable}>\n {ordered && editable && <OrderedList.DragHandle />}\n {/* A cell holding a nested group must be a template root, so the group's subgrid finds `content`. */}\n <Layout.Container gutter='none'>\n <FormFieldDispatch\n {...props}\n type={elementType}\n name={null}\n label={asObject ? undefined : label}\n path={[...(path ?? []), item.index]}\n readonly={!editable}\n layout={asObject ? layout : 'inline'}\n />\n </Layout.Container>\n {editable && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--x--regular'\n label={t('remove-item.button')}\n onClick={() => handleRemove(item.index)}\n />\n )}\n </OrderedList.Item>\n ))}\n </OrderedList.Content>\n )}\n </OrderedList.Root>\n </>\n );\n};\n\nconst defaultObject = (typeNode: SchemaAST.AST): Record<string, unknown> => {\n const baseNode = SchemaEx.findNode(typeNode, SchemaEx.isDiscriminatedUnion);\n const typeLiteral = baseNode\n ? SchemaEx.getDiscriminatedType(baseNode, {})\n : SchemaEx.findNode(typeNode, SchemaAST.isObjects);\n return typeLiteral\n ? Object.fromEntries(\n getFormProperties(typeLiteral).map((prop) => [prop.name, SchemaAST.getDefaultAnnotation(prop.type)]),\n )\n : {};\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type FormPresentation } from '#types';\n\n/**\n * Resolved presentation strategy for a field — which parts render, derived from {@link FormPresentation}.\n * Visual chrome (borders, grid, spacing) is owned by the Form theme recipe, not here.\n */\nexport type FormFieldPresentation = {\n layout?: FormPresentation;\n /** Render the value as read-only plain DOM rather than an editable control. */\n isStatic: boolean;\n /** Render the field's label row. */\n showLabel: boolean;\n /** Render the inline validation/error block beneath the control. */\n showError: boolean;\n};\n\n/**\n * Derive the {@link FormFieldPresentation} for a layout.\n * - `static` renders read-only plain DOM.\n * - `inline` drops the label (the control stands alone, e.g. an array row).\n * - `full` adds the inline error block.\n */\nexport const presentationFor = (layout?: FormPresentation): FormFieldPresentation => ({\n layout,\n isStatic: layout === 'static',\n showLabel: layout !== 'inline',\n showError: layout === 'full',\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Select from '@dxos/react-ui/Select';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { presentationFor } from '../presentation.tsx';\n\nexport type SelectFieldOption = { value: string | number; label?: string; icon?: string };\n\nexport type SelectFieldProps = FormFieldRendererProps & {\n options?: SelectFieldOption[];\n};\n\n/**\n * `Select` over literal options. Next options are strings (AUDIT 2.14), so the field keeps the map back to each\n * literal; the popup inherits the row's size (Phase 4 decision 2).\n */\nexport const SelectField = ({\n type,\n readonly,\n placeholder,\n options = [],\n presentation,\n getValue,\n onValueChange,\n onBlur,\n}: SelectFieldProps) => {\n const items = useMemo<Select.Option[]>(\n () => options.map(({ value, label, icon }) => ({ value: String(value), label: label ?? String(value), icon })),\n [options],\n );\n const { t } = Hooks.useTranslation(translationKey);\n const value = getValue();\n if (presentationFor(presentation).isStatic) {\n return (\n <Typography.Text truncate>\n {options.find((option) => option.value === value)?.label ?? String(value ?? '')}\n </Typography.Text>\n );\n }\n\n return (\n <SelectControl\n items={items}\n value={value == null ? undefined : String(value)}\n placeholder={placeholder ?? t('select.placeholder')}\n readonly={readonly}\n onValueChange={(next) => {\n // A choice is a commit: the select never blurs, so it commits itself.\n onValueChange(type, options.find((option) => String(option.value) === next)?.value);\n onBlur();\n }}\n />\n );\n};\n\ntype SelectControlProps = {\n items: Select.Option[];\n value?: string;\n placeholder?: string;\n readonly?: boolean;\n /** Options are still loading: the trigger shows a spinner and is `aria-busy`. */\n loading?: boolean;\n onValueChange: (value: string | undefined) => void;\n};\n\n/** The Select a field row holds: Ark reads the enclosing `Field.Root` for the label and state ids. */\nexport const SelectControl = ({ items, value, placeholder, readonly, loading, onValueChange }: SelectControlProps) => (\n <Select.Root\n items={items}\n value={value === undefined ? [] : [value]}\n disabled={!!readonly}\n onValueChange={({ value: [next] }) => onValueChange(next)}\n >\n <Select.Trigger placeholder={placeholder} loading={loading} />\n <Select.Content>\n {items.map((item) => (\n <Select.Item key={item.value} item={item} />\n ))}\n </Select.Content>\n </Select.Root>\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useEffect, useMemo, useRef } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport type * as Select from '@dxos/react-ui/Select';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { type OptionsLookup, type OptionsLookupEntry } from '../../annotations.ts';\nimport { pickValues, useAsyncFieldEffect, useFormValues } from '../../hooks/index.ts';\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { SelectControl } from './SelectField.tsx';\n\nexport type AsyncSelectFieldProps = FormFieldRendererProps<string | undefined> & {\n /** Loads the options from the lookup's declared dependency fields. */\n lookup: OptionsLookup;\n};\n\n/**\n * A Select whose options load (debounced) from the fields the lookup declares in `deps`; the trigger shows a spinner\n * while they load, and the sole option is chosen when exactly one resolves and nothing is chosen yet.\n */\nexport const AsyncSelectField = ({\n lookup,\n type,\n format,\n readonly,\n placeholder,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n}: AsyncSelectFieldProps) => {\n const values = useFormValues<AnyProperties>('Form.AsyncSelectField');\n const subset = useMemo(() => pickValues(values, lookup.deps), [values, lookup.deps]);\n const key = useMemo(() => JSON.stringify(subset), [subset]);\n const { loading, data } = useAsyncFieldEffect<readonly OptionsLookupEntry[]>(() => lookup.load(subset), key);\n const items = useMemo<Select.Option[]>(\n () => (data ?? []).map(({ value, label, icon }) => ({ value, label: label ?? value, icon })),\n [data],\n );\n\n // Held in refs so the auto-select depends only on the resolved options, not on accessors that change every edit.\n const current = getValue();\n const onValueChangeRef = useRef(onValueChange);\n onValueChangeRef.current = onValueChange;\n const autoSelectedRef = useRef<typeof data>(undefined);\n useEffect(() => {\n if ((current == null || current === '') && data?.length === 1 && data !== autoSelectedRef.current) {\n autoSelectedRef.current = data;\n onValueChangeRef.current(type, data[0].value);\n }\n }, [current, data, type]);\n\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={items.find((item) => item.value === current)?.label ?? current} format={format} />;\n }\n\n return (\n <SelectControl\n items={items}\n value={current || undefined}\n placeholder={placeholder}\n readonly={readonly}\n loading={loading}\n onValueChange={(next) => {\n onValueChange(type, next);\n onBlur();\n }}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Format } from '@dxos/echo';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\nexport const TextField = ({\n type,\n format,\n readonly,\n placeholder,\n presentation,\n autoFocus,\n jsonPath,\n getValue,\n onBlur,\n onValueChange,\n}: FormFieldRendererProps<string>) => {\n const value = getValue() ?? '';\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value} format={format} />;\n }\n\n // An opaque identifier is not prose: no spellcheck squiggles, no autocorrect, no capitalisation.\n const key = format === Format.TypeFormat.Key;\n return (\n <Input.Root\n noAutoFill\n autoFocus={autoFocus}\n disabled={!!readonly}\n placeholder={placeholder}\n value={value}\n onBlur={onBlur}\n onChange={(event) => onValueChange(type, event.target.value)}\n // Enter commits the field as leaving it does, so an auto-saving form saves without the user tabbing away.\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.nativeEvent.isComposing) {\n onBlur();\n }\n }}\n data-testid={jsonPath}\n {...(key && { variant: 'mono', spellCheck: false, autoCorrect: 'off', autoCapitalize: 'none' })}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useEffect, useMemo, useRef } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { type Autofill } from '../../annotations.ts';\nimport { pickValues, useAsyncFieldEffect, useFormValues } from '../../hooks/index.ts';\nimport { TextField } from './TextField.tsx';\n\nexport type AutofillFieldProps = FormFieldRendererProps<string> & {\n /** Derives this field's value from the autofill's declared dependency fields (e.g. a sibling URL). */\n autofill: Autofill;\n};\n\n/**\n * A text field that pre-fills (debounced) from the fields its {@link Autofill} declares in `deps`, writing only while\n * the user has not typed their own value (empty, or still the last fill), so a manual edit is never clobbered.\n */\nexport const AutofillField = ({ autofill, ...fieldProps }: AutofillFieldProps) => {\n const values = useFormValues<AnyProperties>('Form.AutofillField');\n const subset = useMemo(() => pickValues(values, autofill.deps), [values, autofill.deps]);\n const key = useMemo(() => JSON.stringify(subset), [subset]);\n const { data } = useAsyncFieldEffect<string | undefined>(() => autofill.derive(subset), key);\n\n // Read through refs so the write depends only on the derived value; the accessors change on every edit and would\n // re-fire the effect after its own write.\n const { type } = fieldProps;\n const getValueRef = useRef(fieldProps.getValue);\n getValueRef.current = fieldProps.getValue;\n const onValueChangeRef = useRef(fieldProps.onValueChange);\n onValueChangeRef.current = fieldProps.onValueChange;\n const lastFilledRef = useRef<string | undefined>(undefined);\n useEffect(() => {\n const current = getValueRef.current();\n if (typeof data !== 'string' || data.length === 0) {\n // A derivation that stops returning a value clears a fill the user has not edited.\n if (lastFilledRef.current != null && current === lastFilledRef.current) {\n lastFilledRef.current = undefined;\n onValueChangeRef.current(type, '');\n }\n return;\n }\n if (current === data) {\n lastFilledRef.current = data;\n return;\n }\n if (current == null || current === '' || current === lastFilledRef.current) {\n lastFilledRef.current = data;\n onValueChangeRef.current(type, data);\n }\n }, [data, type]);\n\n return <TextField {...fieldProps} />;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { useFormContext } from '../../hooks/index.ts';\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\n/** A Switch that labels itself, except in a settings row, whose header column holds the label. */\nexport const BooleanField = ({\n type,\n format,\n label,\n readonly,\n presentation,\n indeterminate,\n getValue,\n onValueChange,\n onBlur,\n}: FormFieldRendererProps<boolean>) => {\n const { t } = Hooks.useTranslation(translationKey);\n const { variant } = useFormContext('Form.BooleanField');\n const value = getValue();\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value} format={format} />;\n }\n\n return (\n <Input.Switch\n // A switch has no third state: an indeterminate one is dimmed and says so, and the first press sets it.\n indeterminate={indeterminate}\n label={\n variant === 'settings' ? undefined : indeterminate ? `${label} (${t('indeterminate.placeholder')})` : label\n }\n disabled={!!readonly}\n checked={!!value}\n // A toggle is a commit: the switch never blurs, so it commits itself.\n onCheckedChange={({ checked }) => {\n onValueChange(type, checked);\n onBlur();\n }}\n />\n );\n};\n\nBooleanField.labelPlacement = 'beside' as const;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useMemo, useState } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as Combobox from '@dxos/react-ui/Combobox';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { type OptionsLookup, type OptionsLookupEntry } from '../../annotations.ts';\nimport { pickValues, useAsyncFieldEffect, useFormValues } from '../../hooks/index.ts';\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\nexport type ComboboxFieldProps = FormFieldRendererProps<string | undefined> & {\n /** Loads suggestions from the lookup's declared dependency fields (typically the field's own value). */\n lookup: OptionsLookup;\n};\n\n// The lookup's suggestions are already narrowed by the query, so the Combobox keeps every item it is given.\nconst keepAll = () => true;\n\n/**\n * An editable `Combobox` (input mode) whose suggestions load (debounced) from an {@link OptionsLookup}; when the\n * field's own path is among the lookup's `deps`, the typed text drives the lookup. The typed text is offered last as a\n * free value unless a suggestion already is it; nothing is listed before typing unless the lookup is `eager`.\n */\nexport const ComboboxField = ({\n lookup,\n type,\n format,\n readonly,\n placeholder,\n presentation,\n jsonPath,\n getValue,\n onValueChange,\n onBlur,\n}: ComboboxFieldProps) => {\n const values = useFormValues<AnyProperties>('Form.ComboboxField');\n const [query, setQuery] = useState('');\n const lookupValues = useMemo(() => {\n const subset = pickValues(values, lookup.deps);\n if (jsonPath && lookup.deps.includes(jsonPath)) {\n subset[jsonPath] = query;\n }\n return subset;\n }, [values, lookup.deps, jsonPath, query]);\n const key = useMemo(() => JSON.stringify(lookupValues), [lookupValues]);\n const { data } = useAsyncFieldEffect<readonly OptionsLookupEntry[]>(() => lookup.load(lookupValues), key);\n\n const value = getValue() ?? '';\n const trimmed = query.trim();\n const items = useMemo<Combobox.Option[]>(() => {\n const loaded = (data ?? []).map((option) => ({ value: option.value, label: option.label ?? option.value }));\n const results =\n trimmed.length === 0\n ? lookup.eager\n ? loaded\n : []\n : loaded.filter((option) => option.label.toLowerCase().includes(trimmed.toLowerCase()));\n const free = trimmed.length > 0 && !results.some((option) => option.value === trimmed);\n // The current value stays an item, so the input can show its label before anything is typed.\n const current = value && !results.some((option) => option.value === value);\n return [\n ...(current ? [loaded.find((option) => option.value === value) ?? { value, label: value }] : []),\n ...results,\n ...(free ? [{ value: trimmed, label: trimmed }] : []),\n ];\n }, [data, trimmed, lookup.eager, value]);\n\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={items.find((item) => item.value === value)?.label ?? value} format={format} />;\n }\n\n return (\n <Combobox.Root\n items={items}\n filter={keepAll}\n disabled={!!readonly}\n value={value ? [value] : []}\n onInputValueChange={({ inputValue, reason }) => reason === 'input-change' && setQuery(inputValue)}\n onOpenChange={({ open }) => !open && setQuery('')}\n onValueChange={({ value: [next] }) => {\n onValueChange(type, next);\n onBlur();\n }}\n >\n <Combobox.Control>\n <Combobox.Input placeholder={placeholder} />\n <Combobox.Trigger />\n </Combobox.Control>\n <Combobox.Content />\n </Combobox.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { invariant } from '@dxos/invariant';\nimport type * as Select from '@dxos/react-ui/Select';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { type FormFieldRenderer, type FormFieldRendererProps } from '#types';\n\nimport { FormField } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { SelectControl } from './SelectField.tsx';\n\nexport type CreateSelectFieldOptions = {\n /** Options to display. Strings are used as both value and label. */\n options: ReadonlyArray<string | { value: string; label?: string }>;\n /** Label for the sentinel option that maps to `undefined`. Defaults to `'Default'`. Pass `null` to omit. */\n defaultLabel?: string | null;\n};\n\n// A value outside every option, since Ark reads an empty value as no selection.\nconst SENTINEL = '__default__';\n\n/** The current `createSelectField`, same signature, on `Select`; the renderer owns its row as before. */\nexport const createSelectField = ({\n options,\n defaultLabel = 'Default',\n}: CreateSelectFieldOptions): FormFieldRenderer => {\n const normalized = options.map((option) => (typeof option === 'string' ? { value: option, label: option } : option));\n invariant(\n !normalized.some((option) => option.value === SENTINEL),\n `createSelectField: option value '${SENTINEL}' is reserved.`,\n );\n const hasDefault = defaultLabel !== null;\n const items: Select.Option[] = [\n ...(hasDefault ? [{ value: SENTINEL, label: defaultLabel }] : []),\n ...normalized.map((option) => ({ value: option.value, label: option.label ?? option.value })),\n ];\n\n const SelectFieldRenderer = ({\n type,\n label,\n jsonPath,\n readonly,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n }: FormFieldRendererProps<string | undefined>) => {\n const value = getValue();\n return (\n <FormField path={jsonPath} label={label} readonly={readonly} presentation={presentation}>\n {presentationFor(presentation).isStatic ? (\n <Typography.Text truncate>\n {normalized.find((option) => option.value === value)?.label ?? String(value ?? '')}\n </Typography.Text>\n ) : (\n <SelectControl\n items={items}\n value={value ?? (hasDefault ? SENTINEL : undefined)}\n readonly={readonly}\n onValueChange={(next) => {\n onValueChange(type, hasDefault && next === SENTINEL ? undefined : next);\n onBlur();\n }}\n />\n )}\n </FormField>\n );\n };\n return SelectFieldRenderer;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { format as formatDate } from 'date-fns';\n\n/** ISO 8601 → `YYYY-MM-DDTHH:mm` in the user's local timezone. */\nexport const isoToLocalDateTime = (value: string | undefined): string => {\n if (!value) {\n return '';\n }\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n return formatDate(date, \"yyyy-MM-dd'T'HH:mm\");\n};\n\n/** `YYYY-MM-DDTHH:mm` (local) → ISO 8601 with timezone. */\nexport const localDateTimeToIso = (value: string): string | undefined => {\n if (!value) {\n return undefined;\n }\n // Treat the input as local time. `new Date('YYYY-MM-DDTHH:mm')` parses as local.\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : date.toISOString();\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Format } from '@dxos/echo';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { isoToLocalDateTime, localDateTimeToIso } from './date-value.ts';\n\n/**\n * Stored shapes: `Format.DateTime` is ISO 8601, `Format.Date` `YYYY-MM-DD`, `Format.Time` `HH:mm:ss`; DateInput takes\n * the native strings, so a date-time converts through local time and a time keeps its seconds.\n */\nexport const DateField = ({\n type,\n format,\n readonly,\n presentation,\n getValue,\n onValueChange,\n}: FormFieldRendererProps<string | undefined>) => {\n const value = getValue();\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value} format={format} />;\n }\n\n switch (format) {\n case Format.TypeFormat.Date:\n return (\n <Input.Date\n type='date'\n disabled={!!readonly}\n value={value ?? ''}\n onValueChange={(next) => onValueChange(type, next || undefined)}\n />\n );\n case Format.TypeFormat.Time:\n return (\n <Input.Date\n type='time'\n granularity='second'\n disabled={!!readonly}\n value={value ?? ''}\n onValueChange={(next) => onValueChange(type, next || undefined)}\n />\n );\n default:\n return (\n <Input.Date\n type='datetime-local'\n disabled={!!readonly}\n value={isoToLocalDateTime(value)}\n onValueChange={(next) => onValueChange(type, localDateTimeToIso(next))}\n />\n );\n }\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useEffect, useMemo, useState } from 'react';\n\nimport { GeoLocation, type GeoPoint } from '@dxos/echo/Format';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { safeParseFloat } from '@dxos/util';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { presentationFor } from '../presentation.tsx';\n\ntype Coordinate = keyof Pick<GeoLocation, 'latitude' | 'longitude'>;\n\n/** Two labelled coordinates in a row Container of two equal tracks, each its own `Field.Root`. */\nexport const GeoPointField = ({\n type,\n readonly,\n presentation,\n getValue,\n onValueChange,\n}: FormFieldRendererProps<GeoPoint>) => {\n const { t } = Hooks.useTranslation(translationKey);\n const geoPoint = getValue();\n const location = useMemo(() => GeoLocation.fromGeoPoint(geoPoint ?? [0, 0]), [geoPoint]);\n const [text, setText] = useState({\n latitude: location.latitude?.toString() ?? '',\n longitude: location.longitude?.toString() ?? '',\n });\n useEffect(() => {\n setText({ latitude: location.latitude?.toString() ?? '', longitude: location.longitude?.toString() ?? '' });\n }, [location]);\n\n const resolved = presentationFor(presentation);\n if (resolved.isStatic) {\n return !location.latitude && !location.longitude ? null : (\n <Typography.Text truncate>\n {Math.abs(location.latitude ?? 0).toFixed(5)}°{(location.latitude ?? 0) >= 0 ? 'N' : 'S'}{' '}\n {Math.abs(location.longitude ?? 0).toFixed(5)}°{(location.longitude ?? 0) >= 0 ? 'E' : 'W'}\n </Typography.Text>\n );\n }\n\n const handleChange = (coordinate: Coordinate, input: string) => {\n setText((previous) => ({ ...previous, [coordinate]: input }));\n const parsed = safeParseFloat(input);\n if (input !== '-' && parsed !== undefined && !Number.isNaN(parsed)) {\n onValueChange(type, GeoLocation.toGeoPoint({ ...location, [coordinate]: parsed }));\n }\n };\n\n const coordinate = (name: Coordinate, bound: number) => (\n <Field.Root>\n {resolved.showLabel && (\n <Field.Header>\n <Field.Label>{t(`${name}.label`)}</Field.Label>\n </Field.Header>\n )}\n <Input.Root\n type='number'\n step='0.00001'\n min={-bound}\n max={bound}\n disabled={!!readonly}\n placeholder={t(`${name}.placeholder`)}\n value={text[name]}\n onChange={(event) => handleChange(name, event.target.value)}\n />\n </Field.Root>\n );\n\n return (\n <Layout.Container layout='row' gutter='inherit' columns='minmax(0, 1fr) minmax(0, 1fr)' gap='sm'>\n {coordinate('latitude', 90)}\n {coordinate('longitude', 180)}\n </Layout.Container>\n );\n};\n\nGeoPointField.standalone = true;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport type * as Select from '@dxos/react-ui/Select';\nimport { hues } from '@dxos/ui-types';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { SelectControl } from './SelectField.tsx';\n\nconst capitalize = (hue: string) => hue.charAt(0).toUpperCase() + hue.slice(1);\n\n/** Every theme hue as a Select option: a filled swatch in the hue, named by the hue. */\nexport const HUE_OPTIONS: Select.Option[] = hues.map((hue) => ({\n value: hue,\n label: capitalize(hue),\n icon: 'ph--circle--fill',\n iconHue: hue,\n}));\n\nexport type HueSelectProps = {\n value?: string;\n placeholder?: string;\n readonly?: boolean;\n onValueChange: (hue: string | undefined) => void;\n};\n\n/** A Select over the theme hues; the current `HuePicker` (react-ui-pickers) has no Next counterpart yet. */\nexport const HueSelect = ({ value, placeholder, readonly, onValueChange }: HueSelectProps) => (\n <SelectControl\n items={HUE_OPTIONS}\n value={value}\n placeholder={placeholder}\n readonly={readonly}\n onValueChange={onValueChange}\n />\n);\n\n/** A field whose value is one of the theme's hues. */\nexport const HueField = ({\n type,\n format,\n placeholder,\n readonly,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n}: FormFieldRendererProps<string | undefined>) => {\n const value = getValue();\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value && capitalize(value)} format={format} />;\n }\n\n return (\n <HueSelect\n value={value}\n placeholder={placeholder}\n readonly={readonly}\n onValueChange={(hue) => {\n // A pick is a commit: the select never blurs, so it commits itself.\n onValueChange(type, hue);\n onBlur();\n }}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { Children, type PropsWithChildren, type ReactNode, useState } from 'react';\n\nimport * as Collapsible from '@dxos/react-ui/Collapsible';\nimport * as Fieldset from '@dxos/react-ui/Fieldset';\nimport * as SystemButton from '@dxos/react-ui/SystemButton';\n\nimport { useFormContext } from '../hooks/index.ts';\n\nconst FORM_FIELDSET_NAME = 'Form.FieldSet';\n\nexport type FormFieldSetProps = PropsWithChildren<{\n 'label'?: string;\n /** Plain text under the legend (the current FieldSet renders markdown; see SPIKE.md). */\n 'description'?: string;\n /** The legend ends with a disclosure button that folds the body. */\n 'collapsible'?: boolean;\n 'defaultOpen'?: boolean;\n /** Controls acting on the group, at the end of its legend row. */\n 'actions'?: ReactNode;\n /** A nested object's group: its fields bordered and indented under the legend. Set by the dispatcher, never read from context. */\n 'nested'?: boolean;\n 'data-testid'?: string;\n}>;\n\n/**\n * A grid `Fieldset` (`gutter='inherit'`): a `group` named by its legend that is a subgrid of the enclosing grid, so\n * fields keep the form's columns at any depth. A nested object's fields are an `inset` set under its legend (bordered and\n * indented on its host's surface, never a surface step); a collapsible set ends its legend with a disclosure button and folds a Collapsible\n * Content that is itself a subgrid.\n */\nexport const FormFieldSet = ({\n children,\n label,\n description,\n collapsible,\n defaultOpen = true,\n actions,\n nested,\n 'data-testid': testId,\n}: FormFieldSetProps) => {\n const { layout } = useFormContext(FORM_FIELDSET_NAME);\n const [open, setOpen] = useState(defaultOpen);\n const showLabel = layout !== 'inline' && !!label;\n const canCollapse = !!collapsible && showLabel && Children.toArray(children).length > 0;\n const helper = description && <Fieldset.HelperText>{description}</Fieldset.HelperText>;\n const legend = showLabel && (\n <Fieldset.Legend size={nested ? undefined : 'md'} variant={nested ? undefined : 'section'}>\n {label}\n {actions}\n {canCollapse && (\n <SystemButton.Disclosure variant='ghost' label={label} expanded={open} onExpandedChange={setOpen} />\n )}\n </Fieldset.Legend>\n );\n\n // A nested object's legend (and its disclosure) heads the border rather than sitting inside it: only the fields are\n // bordered, so the label lines up with the host's other labels.\n const fields = nested ? (\n <Fieldset.Root gutter='inherit' inset>\n {children}\n </Fieldset.Root>\n ) : (\n children\n );\n\n if (canCollapse) {\n return (\n <Collapsible.Root asChild open={open} onOpenChange={({ open }) => setOpen(open)}>\n <Fieldset.Root gutter='inherit' data-testid={testId}>\n {legend}\n {helper}\n <Collapsible.Content gutter='inherit'>{fields}</Collapsible.Content>\n </Fieldset.Root>\n </Collapsible.Root>\n );\n }\n\n return (\n <Fieldset.Root gutter='inherit' data-testid={testId}>\n {legend}\n {helper}\n {fields}\n </Fieldset.Root>\n );\n};\n\nFormFieldSet.displayName = FORM_FIELDSET_NAME;\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { type PropsWithChildren } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport { type Merge } from '@dxos/util';\n\nimport {\n FormContextProvider,\n type FormContextValue,\n type FormHandlerProps,\n type FormUpdateMeta,\n useFormHandler,\n} from '../hooks/index.ts';\nimport { type FormFieldsProps } from './property-walk.ts';\n\n//\n// Root\n//\n\nexport type FormRootProps<T extends AnyProperties = AnyProperties> = Merge<\n Omit<FormContextValue<T>, 'form'>,\n Pick<\n FormHandlerProps<T>,\n 'schema' | 'autoSave' | 'fieldOverrides' | 'values' | 'defaultValues' | 'onValidate' | 'onValuesChanged'\n >,\n Omit<FormFieldsProps<T>, 'path' | 'schema'>,\n PropsWithChildren<{\n /**\n * Called when the form is submitted and passes validation.\n */\n onSave?: (values: T, meta: FormUpdateMeta<T>) => void;\n\n /**\n * Called when the form is canceled to abandon/undo any pending changes.\n */\n onCancel?: () => void;\n }>\n>;\n\nexport const FormRoot = <T extends AnyProperties = AnyProperties>({\n children,\n schema,\n values,\n onSave,\n onCancel,\n ...props\n}: FormRootProps<T>) => {\n const form = useFormHandler({ schema, values, onSave, onCancel, ...props });\n\n return (\n <FormContextProvider form={form} {...props}>\n {children}\n </FormContextProvider>\n );\n};\n\nFormRoot.displayName = 'Form.Root';\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport React, { useCallback, useMemo } from 'react';\n\nimport { type Database, Obj, Ref, Type } from '@dxos/echo';\nimport { useType as defaultUseType } from '@dxos/echo-react';\nimport * as Annotation from '@dxos/echo/Annotation';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { DXN, type URI } from '@dxos/keys';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps, type RefFieldDataProps } from '#types';\n\nimport { omitId } from '../../util/index.ts';\nimport { FormFields } from '../FormFieldDispatch.tsx';\nimport { FormFieldSet } from '../FormFieldSet.tsx';\nimport { FormRoot } from '../FormRoot.tsx';\n\ntype UseType = (db?: Database.Database, typeUri?: URI.URI) => Type.AnyEntity | undefined;\n\nexport type InlineRefFieldProps = FormFieldRendererProps &\n Pick<RefFieldDataProps, 'onCreate'> & {\n useType?: UseType;\n };\n\n/**\n * A referenced object's own fields inline (`FormInlineAnnotation`), as a nested group bound to the target: each\n * changed path is written back to it with `Obj.setValue` in one `Obj.update`. An empty ref offers to create the target.\n */\nexport const InlineRefField = ({\n type,\n readonly,\n label,\n db,\n getValue,\n onValueChange,\n onCreate,\n useType = defaultUseType,\n}: InlineRefFieldProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const reference = getValue();\n const typename = useMemo(\n () =>\n SchemaEx.findAnnotation<Annotation.ReferenceAnnotationValue>(type, Annotation.ReferenceAnnotationId)?.typename,\n [type],\n );\n const createType = useType(db, typename ? DXN.make(typename) : undefined);\n const handleCreate = useCallback(async () => {\n if (!createType || !onCreate) {\n return;\n }\n const created = await onCreate(createType, {});\n if (created) {\n onValueChange(type, Ref.make(created));\n }\n }, [createType, onCreate, onValueChange, type]);\n\n if (readonly && !Ref.isRef(reference)) {\n return null;\n }\n\n return (\n <FormFieldSet label={label} collapsible nested>\n {Ref.isRef(reference) ? (\n <InlineForm reference={reference} db={db} readonly={readonly} useType={useType} />\n ) : (\n !readonly &&\n onCreate && (\n <Button.Group fill>\n <Button.Root\n icon='ph--plus--regular'\n label={label || t('ref-field.placeholder')}\n disabled={!createType}\n onClick={() => void handleCreate()}\n />\n </Button.Group>\n )\n )}\n </FormFieldSet>\n );\n};\n\ntype InlineFormProps = {\n reference: Ref.Ref<any>;\n db?: Database.Database;\n readonly?: boolean;\n useType?: UseType;\n};\n\n/** The target's form: its fields render straight into the enclosing group, sharing its tracks. */\nconst InlineForm = ({ reference, db, readonly, useType = defaultUseType }: InlineFormProps) => {\n const target = useAtomValue(useMemo(() => reference.atom, [reference]));\n const typeFromRegistry = useType(db, target ? Obj.getTypeURI(target) : undefined);\n const targetType = (target && Obj.getType(target)) || typeFromRegistry;\n const schema = useMemo(() => (targetType ? omitId(Type.getSchema(targetType)) : undefined), [targetType]);\n const defaultValues = useMemo(() => (target ? { ...target } : {}), [target]);\n const handleChange = useCallback(\n (\n values: AnyProperties,\n { isValid, changed }: { isValid: boolean; changed: Record<SchemaEx.JsonPath, boolean> },\n ) => {\n if (!isValid || !target) {\n return;\n }\n const paths = (Object.keys(changed) as SchemaEx.JsonPath[]).filter((path) => changed[path]);\n if (paths.length > 0) {\n Obj.update(target, (target) => {\n for (const path of paths) {\n const parts = SchemaEx.splitJsonPath(path);\n Obj.setValue(target, parts, SchemaEx.getValue(values, path));\n }\n });\n }\n },\n [target],\n );\n\n if (!target || !schema) {\n return null;\n }\n\n return (\n <FormRoot db={db} schema={schema} defaultValues={defaultValues} onValuesChanged={handleChange}>\n <FormFields readonly={readonly} />\n </FormRoot>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { EditorView } from '@codemirror/view';\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport React, { useMemo } from 'react';\n\nimport { type Database, Obj, Ref } from '@dxos/echo';\nimport { Doc } from '@dxos/echo-doc';\nimport { Editor, useBasicMarkdownExtensions } from '@dxos/react-ui-editor';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { Text } from '@dxos/schema';\nimport { createDataExtensions } from '@dxos/ui-editor';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { useFormContext } from '../../hooks/index.ts';\nimport { presentationFor } from '../presentation.tsx';\n\n/** The editor's minimum height in lines, as the current field's `min-h-[6lh]`. */\nconst ROWS = 6;\n\n/**\n * Fits the editor to the field: a long unbroken token (an inline-code URL) breaks anywhere rather than widening the\n * content, and the editor fills the frame's height, so its scroller ends at the frame's foot instead of mid-field.\n */\nconst fieldTheme = EditorView.theme({\n '&': { minHeight: '100%' },\n '.cm-content': { overflowWrap: 'anywhere' },\n // Elsewhere inline code is one clipped line (fixed height, no wrapping), which in a field widens the content instead.\n '& .cm-content .cm-code-inline': { whiteSpace: 'break-spaces', height: 'auto', overflow: 'visible' },\n});\n\n/**\n * A markdown value in a CodeMirror editor framed by a multi-line `ControlFrame`. The value is either a string\n * (`Format.TypeFormat.Markdown`), edited as plain text, or a `Ref<Text>`, edited in place through its document; an empty\n * ref offers a button that creates the Text.\n */\nexport const MarkdownField = ({\n type,\n readonly,\n placeholder,\n presentation,\n db,\n getValue,\n onValueChange,\n}: FormFieldRendererProps) => {\n const value: unknown = getValue();\n const isStatic = presentationFor(presentation).isStatic;\n if (Ref.isRefType(type)) {\n const reference = Ref.isRef(value) ? value : undefined;\n if (reference) {\n return isStatic ? (\n <RefStaticText reference={reference} />\n ) : (\n <RefMarkdownEditor reference={reference} placeholder={placeholder} readonly={!!readonly} />\n );\n }\n\n return isStatic || readonly ? null : (\n <CreateTextButton db={db} onCreate={(created) => onValueChange(type, created)} />\n );\n }\n\n const text = typeof value === 'string' ? value : '';\n return isStatic ? (\n <Typography.Text>{text}</Typography.Text>\n ) : (\n <StringMarkdownEditor\n value={text}\n placeholder={placeholder}\n readonly={!!readonly}\n onChange={(next) => onValueChange(type, next)}\n />\n );\n};\n\ntype StringMarkdownEditorProps = {\n value: string;\n placeholder?: string;\n readonly?: boolean;\n onChange: (value: string) => void;\n};\n\nconst StringMarkdownEditor = ({ value, placeholder, readonly, onChange }: StringMarkdownEditorProps) => {\n const { markdownExtensions } = useFormContext('MarkdownField');\n // Memoised: a new list each render would reconfigure the editor on every keystroke and drop its focus.\n const fieldExtensions = useMemo(() => [fieldTheme, ...(markdownExtensions ?? [])], [markdownExtensions]);\n const extensions = useBasicMarkdownExtensions({ placeholder, readonly, extensions: fieldExtensions });\n return (\n <Input.Frame rows={ROWS} disabled={readonly}>\n <Editor.Root>\n <Editor.View extensions={extensions} value={value} onChange={readonly ? undefined : onChange} />\n </Editor.Root>\n </Input.Frame>\n );\n};\n\n/** A `Ref<Text>`'s content, resolved, as read-only text. */\nconst RefStaticText = ({ reference }: { reference: Ref.Unknown }) => {\n const target = useAtomValue(useMemo(() => reference.atom, [reference]));\n const content = Obj.instanceOf(Text.Text, target) ? target.content : undefined;\n return content ? <Typography.Text>{content}</Typography.Text> : null;\n};\n\ntype RefMarkdownEditorProps = {\n reference: Ref.Unknown;\n placeholder?: string;\n readonly?: boolean;\n};\n\nconst RefMarkdownEditor = ({ reference, placeholder, readonly }: RefMarkdownEditorProps) => {\n const target = useAtomValue(useMemo(() => reference.atom, [reference]));\n const text = Obj.instanceOf(Text.Text, target) ? target : undefined;\n const dataExtensions = useMemo(\n () => (text ? [createDataExtensions({ id: reference.uri, text: Doc.createAccessor(text, ['content']) })] : []),\n [text, reference],\n );\n const { markdownExtensions } = useFormContext('MarkdownField');\n const fieldExtensions = useMemo(\n () => [fieldTheme, ...dataExtensions, ...(markdownExtensions ?? [])],\n [dataExtensions, markdownExtensions],\n );\n const extensions = useBasicMarkdownExtensions({ placeholder, readonly, extensions: fieldExtensions });\n if (!text) {\n return null;\n }\n\n return (\n <Input.Frame rows={ROWS} disabled={readonly}>\n <Editor.Root>\n <Editor.View extensions={extensions} />\n </Editor.Root>\n </Input.Frame>\n );\n};\n\ntype CreateTextButtonProps = {\n db?: Database.Database;\n onCreate: (ref: Ref.Ref<Text.Text>) => void;\n};\n\nconst CreateTextButton = ({ db, onCreate }: CreateTextButtonProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n return (\n <Button.Root icon='ph--plus--regular' disabled={!db} onClick={() => db && onCreate(Ref.make(db.add(Text.make())))}>\n {t('create-text.label')}\n </Button.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport React, { useEffect, useState } from 'react';\n\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { StepAnnotation } from '../../annotations.ts';\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { getNumericConstraints } from './numeric-constraints.ts';\n\n/** A fractional field without a declared step moves by 0.01 below magnitude 1, else by 0.1. */\nconst defaultStep = (value: number | undefined, integer: boolean): number =>\n integer ? 1 : value !== undefined && Math.abs(value) < 1 ? 0.01 : 0.1;\n\n/** Ark's number input parses, steps and clamps on blur; the field commits every value that parses. */\nexport const NumberField = ({\n type,\n format,\n readonly,\n placeholder,\n presentation,\n min: minProp,\n max: maxProp,\n step: stepProp,\n getValue,\n onValueChange,\n onBlur,\n}: FormFieldRendererProps<number>) => {\n const constraints = getNumericConstraints(type);\n // A caller's override narrows the schema's bounds for this form; a whole-number step reads as an integer.\n const min = minProp ?? constraints.min;\n const max = maxProp ?? constraints.max;\n const integer = constraints.integer || (stepProp !== undefined && Number.isInteger(stepProp));\n const committed = getValue();\n // The text is kept locally so a partial edit (\"1.\", \"-\") survives until it parses.\n const [text, setText] = useState(committed === undefined ? '' : String(committed));\n useEffect(() => {\n if (committed !== undefined && Number(text) !== committed) {\n setText(String(committed));\n }\n }, [committed]); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={committed} format={format} />;\n }\n\n return (\n <Input.Number\n disabled={!!readonly}\n placeholder={placeholder}\n min={min}\n max={max}\n step={stepProp ?? Option.getOrElse(StepAnnotation.getFromAst(type), () => defaultStep(committed, integer))}\n formatOptions={integer ? { maximumFractionDigits: 0 } : { useGrouping: false }}\n value={text}\n onValueChange={(next, valueAsNumber) => {\n setText(next);\n if (!Number.isNaN(valueAsNumber)) {\n onValueChange(type, valueAsNumber);\n // A stepper press never blurs, so every value that parses commits itself, as a pick does.\n onBlur();\n }\n }}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\nexport const PasswordField = ({\n type,\n format,\n readonly,\n placeholder,\n presentation,\n getValue,\n onValueChange,\n}: FormFieldRendererProps<string>) => {\n const value = getValue() ?? '';\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={'•'.repeat(value.length)} format={format} />;\n }\n\n return (\n <Input.Password\n ignorePasswordManagers\n disabled={!!readonly}\n placeholder={placeholder}\n value={value}\n onValueChange={(next) => onValueChange(type, next)}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport type * as Schema from 'effect/Schema';\nimport React, {\n type DragEvent,\n type KeyboardEvent,\n type ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport * as Combobox from '@dxos/react-ui/Combobox';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Tag from '@dxos/react-ui/Tag';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { hues } from '@dxos/ui-types';\nimport { arrayMove } from '@dxos/util';\n\nimport { type CreateOptions, type RefOption } from '#types';\n\nimport { FormActions, FormContent } from './Form.tsx';\nimport { FormFields } from './FormFieldDispatch.tsx';\n// The parts, not the `Form` namespace: RefField renders this picker inside the Form's module cycle, and the namespace\n// object reads every part when its module is evaluated.\nimport { FormRoot } from './FormRoot.tsx';\n\ntype PickerCreateProps = Pick<CreateOptions, 'createInitialValuePath' | 'createFieldMap'> & {\n /** The inline create form's schema; with `onCreate`, the popup offers a create row for an unmatched query. */\n createSchema?: Schema.Codec<any, any>;\n /** The create row's text for the query (the translated `createOptionLabel`); `Create “{query}”` by default. */\n createLabel?: (query: string) => string;\n /** The create row's icon (`createOptionIcon`); a plus by default. */\n createIcon?: string;\n /** Persists the create form's values; awaited before the form closes. */\n onCreate?: (values: any) => unknown | Promise<unknown>;\n};\n\ntype PickerBaseProps = PickerCreateProps & {\n options: RefOption[];\n loading?: boolean;\n};\n\n/**\n * The popup state shared by the pickers: open, and the query a chosen create row turned into a create form. Choosing\n * the create row also asks the popup to close, so `startCreate` reopens it in the same batch.\n */\nconst usePickerState = ({ options, createSchema, onCreate }: PickerBaseProps) => {\n const [open, setOpen] = useState(false);\n const [creating, setCreating] = useState<string>();\n const items = useMemo<Combobox.Option[]>(\n () => options.map(({ id, label, description }) => ({ value: id, label, description })),\n [options],\n );\n const handleOpenChange = useCallback(({ open }: { open: boolean }) => {\n setOpen(open);\n if (!open) {\n setCreating(undefined);\n }\n }, []);\n const startCreate =\n createSchema !== undefined && onCreate !== undefined\n ? (query: string) => {\n setCreating(query);\n setOpen(true);\n }\n : undefined;\n return { open, setOpen, creating, setCreating, items, handleOpenChange, startCreate };\n};\n\ntype CreateFormProps = Pick<PickerCreateProps, 'createInitialValuePath' | 'createFieldMap'> & {\n schema: Schema.Codec<any, any>;\n query: string;\n onSave: (values: any) => Promise<void>;\n onCancel: () => void;\n};\n\n/** The create form a picker's popup swaps its list for, seeded with the query at `createInitialValuePath`. */\nconst CreateForm = ({ schema, query, createInitialValuePath, createFieldMap, onSave, onCancel }: CreateFormProps) => (\n <FormRoot\n testId='create-referenced-object-form'\n schema={schema}\n defaultValues={createInitialValuePath ? { [createInitialValuePath]: query } : {}}\n fieldMap={createFieldMap}\n onSave={onSave}\n onCancel={onCancel}\n >\n <Layout.Container gutter='inset'>\n <FormContent>\n <FormFields />\n <FormActions />\n </FormContent>\n </Layout.Container>\n </FormRoot>\n);\n\nexport type ObjectPickerProps = PickerBaseProps & {\n /** The selected option's id. */\n value?: string;\n placeholder?: string;\n /** Replaces the selection button, e.g. a toolbar's add button that picks an object to insert. */\n trigger?: ReactElement;\n /** Called with the picked id, or `undefined` when the selected option is picked again. */\n onSelect: (id: string | undefined) => void;\n};\n\n/**\n * Picks one object with `Combobox` in trigger mode: a button showing the selection opens a popup whose search\n * field narrows the options (each with its description). Choosing the create row swaps the list for a create form.\n */\nexport const ObjectPicker = ({\n value,\n placeholder,\n trigger,\n loading,\n createSchema,\n createInitialValuePath,\n createFieldMap,\n createLabel,\n createIcon,\n onCreate,\n onSelect,\n options,\n}: ObjectPickerProps) => {\n const { setOpen, creating, setCreating, items, open, handleOpenChange, startCreate } = usePickerState({\n options,\n createSchema,\n onCreate,\n });\n const handleSave = useCallback(\n async (values: any) => {\n await onCreate?.(values);\n setCreating(undefined);\n setOpen(false);\n },\n [onCreate],\n );\n\n return (\n <Combobox.Root\n items={items}\n loading={loading}\n // Pinned to the field's width: object labels (or URIs) can be long enough to widen the popup past the form.\n positioning={{ sameWidth: true }}\n open={open}\n onOpenChange={handleOpenChange}\n value={value ? [value] : []}\n onSelect={({ itemValue }) => {\n if (options.some((option) => option.id === itemValue)) {\n onSelect(itemValue === value ? undefined : itemValue);\n }\n }}\n onCreate={startCreate}\n createLabel={createLabel}\n createIcon={createIcon}\n >\n {trigger ? (\n <Combobox.Trigger asChild>{trigger}</Combobox.Trigger>\n ) : (\n <Combobox.Trigger placeholder={placeholder} />\n )}\n <Combobox.Content>\n {creating !== undefined && createSchema ? (\n <CreateForm\n schema={createSchema}\n query={creating}\n createInitialValuePath={createInitialValuePath}\n createFieldMap={createFieldMap}\n onSave={handleSave}\n onCancel={() => setCreating(undefined)}\n />\n ) : undefined}\n </Combobox.Content>\n </Combobox.Root>\n );\n};\n\nexport type ObjectMultiPickerProps = Omit<PickerBaseProps, 'onCreate'> & {\n /** The selected options' ids, in order. */\n 'value': string[];\n /** Shown in place of chips while nothing is selected. */\n 'placeholder'?: string;\n /** Chips reorder by drag, or Alt+ArrowLeft/Right on a focused chip. */\n 'ordered'?: boolean;\n 'data-testid'?: string;\n 'onValueChange': (ids: string[]) => void;\n /** Persists the create form's values and returns the new option's id, which is then selected. */\n 'onCreate'?: (values: any) => Promise<string | undefined>;\n};\n\n/**\n * Picks several objects with `Combobox` in `multiple` mode: the selection is a wrapping row of removable\n * `Tag` chips (in each option's hue) whose caret opens a search popup; picking toggles an option and keeps the\n * popup open, and the create row swaps the list for a create form whose new object joins the selection.\n */\nexport const ObjectMultiPicker = ({\n value,\n placeholder,\n loading,\n createSchema,\n createInitialValuePath,\n createFieldMap,\n createLabel,\n createIcon,\n onCreate,\n onValueChange,\n options,\n ordered,\n 'data-testid': testId,\n}: ObjectMultiPickerProps) => {\n const { creating, setCreating, items, open, handleOpenChange, startCreate } = usePickerState({\n options,\n createSchema,\n onCreate,\n });\n const handleSave = useCallback(\n async (values: any) => {\n const id = await onCreate?.(values);\n if (id) {\n onValueChange([...value, id]);\n }\n setCreating(undefined);\n },\n [onCreate, onValueChange, value],\n );\n\n const selected = value.map((id) => options.find((option) => option.id === id) ?? { id, label: id });\n const { chipProps } = useChipOrder({ value, onValueChange });\n return (\n <Combobox.Root\n items={items}\n loading={loading}\n multiple\n closeOnSelect={false}\n open={open}\n onOpenChange={handleOpenChange}\n value={value}\n onValueChange={({ value }) => onValueChange(value)}\n onCreate={startCreate}\n createLabel={createLabel}\n createIcon={createIcon}\n >\n <Combobox.Control wrap data-testid={testId}>\n {selected.length === 0 && placeholder && <Typography.Text tone='muted'>{placeholder}</Typography.Text>}\n {selected.map((option) => (\n <Tag.Tag\n key={option.id}\n hue={hues.find((hue) => hue === option.hue)}\n onDelete={() => onValueChange(value.filter((id) => id !== option.id))}\n {...(ordered && chipProps(option.id))}\n >\n {option.label}\n </Tag.Tag>\n ))}\n <Combobox.Trigger />\n </Combobox.Control>\n <Combobox.Content>\n {creating !== undefined && createSchema ? (\n <CreateForm\n schema={createSchema}\n query={creating}\n createInitialValuePath={createInitialValuePath}\n createFieldMap={createFieldMap}\n onSave={handleSave}\n onCancel={() => setCreating(undefined)}\n />\n ) : (\n <>\n <Combobox.Input />\n <Combobox.List />\n </>\n )}\n </Combobox.Content>\n </Combobox.Root>\n );\n};\n\ntype ChipOrderOptions = Pick<ObjectMultiPickerProps, 'value' | 'onValueChange'>;\n\n/** The data attribute naming a chip's id, so focus can follow a moved chip. */\nconst CHIP_ID = 'data-chip-id';\n\n/**\n * Reordering for a wrapping row of chips: each chip is a native drag source and drop target (dropping moves the dragged\n * chip to its place) and, focused, moves by Alt+ArrowLeft/Right, keeping focus as React moves its element.\n */\nconst useChipOrder = ({ value, onValueChange }: ChipOrderOptions) => {\n const [focusId, setFocusId] = useState<string>();\n const rowRef = useRef<HTMLElement | null>(null);\n useEffect(() => {\n if (focusId) {\n rowRef.current?.querySelector<HTMLElement>(`[${CHIP_ID}=\"${CSS.escape(focusId)}\"]`)?.focus();\n setFocusId(undefined);\n }\n }, [focusId, value]);\n\n const move = (id: string, to: number) => {\n const from = value.indexOf(id);\n if (from < 0 || to < 0 || to >= value.length || from === to) {\n return;\n }\n const next = [...value];\n arrayMove(next, from, to);\n onValueChange(next);\n };\n\n const chipProps = (id: string) => ({\n [CHIP_ID]: id,\n 'draggable': true,\n 'tabIndex': 0,\n 'aria-keyshortcuts': 'Alt+ArrowLeft Alt+ArrowRight',\n 'onKeyDown': (event: KeyboardEvent<HTMLElement>) => {\n const step = event.key === 'ArrowLeft' ? -1 : event.key === 'ArrowRight' ? 1 : 0;\n if (event.altKey && step !== 0 && event.target === event.currentTarget) {\n event.preventDefault();\n rowRef.current = event.currentTarget.parentElement;\n move(id, value.indexOf(id) + step);\n setFocusId(id);\n }\n },\n 'onDragStart': (event: DragEvent<HTMLElement>) => {\n event.dataTransfer.setData(CHIP_MIME, id);\n event.dataTransfer.effectAllowed = 'move';\n },\n 'onDragOver': (event: DragEvent<HTMLElement>) => {\n if (event.dataTransfer.types.includes(CHIP_MIME)) {\n event.preventDefault();\n }\n },\n 'onDrop': (event: DragEvent<HTMLElement>) => {\n const dragged = event.dataTransfer.getData(CHIP_MIME);\n if (dragged) {\n event.preventDefault();\n move(dragged, value.indexOf(id));\n }\n },\n });\n\n return { chipProps };\n};\n\n/** The drag payload type of a chip, so a row only accepts its own chips. */\nconst CHIP_MIME = 'application/x-dxos-chip';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport '@dxos/lit-ui/dx-tag-picker.pcss';\nimport { Ref } from '@dxos/echo';\nimport { EID } from '@dxos/keys';\n\nimport { type RefOption } from '#types';\n\n// Kept out of `RefField.tsx`: react-refresh only fast-refreshes a module whose\n// exports are all components, so values exported beside them force a full page reload on every edit.\n\nconst isRefSnapshot = (val: any): val is { '/': string } => {\n return typeof val === 'object' && typeof (val as any)?.['/'] === 'string';\n};\n\n/**\n * Find the option a ref-like form value points at. Matches on the local (entity-id) form so a bare local EID\n * (`echo:///<id>`, produced by `Ref.make`) still resolves against an option keyed by the entity's qualified\n * self URI (`echo://<space>/<id>`). Returns `undefined` when the value is not a ref or no option matches.\n *\n * Comparing by entity id is only sound within one space (ids are unique there, not globally). Two EIDs that\n * both carry a space authority must therefore agree on it: a qualified value and a qualified option from\n * different spaces never match, even when their entity ids coincide.\n */\nexport const findRefOption = (value: unknown, options: RefOption[]): RefOption | undefined => {\n const isRef = Ref.isRef(value);\n if (!isRef && !isRefSnapshot(value)) {\n return undefined;\n }\n const valueUri = isRef ? value.uri : value['/'];\n // Keyed/registry entities (skills, operations) are referenced by a named DXN rather than an\n // entity-id, so they carry no parseable EID; match those by direct URI equality against the option id.\n const directMatch = options.find((option) => option.id === valueUri);\n if (directMatch) {\n return directMatch;\n }\n const valueEid = EID.tryParse(valueUri);\n if (!valueEid) {\n return undefined;\n }\n const valueSpaceId = EID.getSpaceId(valueEid);\n const valueLocal = EID.toLocal(valueEid);\n return options.find((option) => {\n const optionEid = EID.tryParse(option.id);\n if (!optionEid) {\n return false;\n }\n const optionSpaceId = EID.getSpaceId(optionEid);\n if (valueSpaceId != null && optionSpaceId != null && valueSpaceId !== optionSpaceId) {\n return false;\n }\n return EID.equals(EID.toLocal(optionEid), valueLocal);\n });\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Obj, Ref, Tag } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport { EID } from '@dxos/keys';\n\nimport { omitId } from '../util/index.ts';\n\n/**\n * Form-field key for the synthetic meta-tags array spliced into property/create forms.\n *\n * An object's tags live in `Obj.getMeta(obj).tags` (off-schema), so the form surfaces them as an\n * extra field rather than reading the schema. The key is underscore-prefixed so it never collides\n * with a `tags` field an object schema declares itself — e.g. a `TagIndex` record on a feed host,\n * whose `tags` is `Record<tagId, objectId[]>`, not an array. Extending such a schema with a `tags`\n * array threw \"overlapping types at path: [\\\"tags\\\"]\"; the disjoint `_tags` key avoids it. The\n * human-facing label is restored via the `title` annotation on {@link withMetaTags}.\n */\nexport const META_TAGS_KEY = '_tags';\n\n/**\n * Splices the synthetic meta-tags array (an object's `meta.tags`, surfaced as {@link Tag} refs) onto\n * a schema for editing and drops `id`. Keyed by {@link META_TAGS_KEY} so it never collides with a\n * `tags` field the schema declares itself.\n */\nexport const withMetaTags = (schema: Schema.Codec<any, any>) =>\n omitId(\n // `SchemaAST.assignFields`, not v4's `Schema.fieldsAssign`: the latter needs both sides' fields\n // at the type level, which a schema known only as a `Codec` cannot supply.\n Schema.make<Schema.Codec<any, any>>(\n SchemaAST.assignFields(\n Schema.Struct({\n [META_TAGS_KEY]: Schema.Array(Ref.Ref(Tag.Tag)).pipe(Schema.annotate({ title: 'Tags' }), Schema.optional),\n }).ast,\n schema.ast,\n ),\n ),\n );\n\nconst isTag = Obj.instanceOf(Tag.Tag);\n\n/**\n * Narrows a tag picker's candidates to the tags a user may apply by hand: those with no origin.\n *\n * A tag that carries an origin is owned by whoever put it there — a Gmail label or a JMAP folder is\n * sync's to apply, and a canonical DXOS tag (`starred`, `sent`, `draft`) is applied by a purpose-built\n * affordance such as the star button or the draft lifecycle. Offering either in a generic picker\n * invites an attribution that nothing maintains: on a synced object the next delta silently strips it,\n * and on an unsynced one it never gets corrected at all. See `Tag.md` §\"Tag origin\".\n *\n * Non-tag candidates pass through untouched, so this is safe to apply to any ref field's results —\n * hence generic in the element type rather than narrowed to `Entity.Any`, which concrete instances are\n * deliberately not assignable to.\n */\nexport const filterTagCandidates = <T>(results: readonly T[]): T[] =>\n results.filter((result) => !isTag(result) || Tag.isUserTag(result));\n\n/**\n * A ref's target entity id, ignoring whether the uri is local (`echo:///<id>`) or qualified\n * (`echo://<space>/<id>`) — `Ref.make` produces the former while `Obj.getURI` produces the latter, so\n * the two forms must compare equal. Same reason as `findRefOption`.\n */\nconst entityIdOf = (uri: string): string | undefined => {\n const parsed = EID.tryParse(uri);\n return parsed ? EID.getEntityId(parsed) : undefined;\n};\n\n/**\n * Splits an object's meta tags into the ones a form may edit and the ones a provider owns.\n *\n * Provider-owned tags are held back rather than shown read-only: the tags field is a generic array of\n * refs whose delete affordance knows nothing about tags, so the only way to make one non-removable\n * would be to thread tag-specific policy through a type-agnostic renderer. Holding them out of the\n * form value instead keeps them off the picker *and* out of reach of the delete button, and matches\n * where they are already surfaced — as chips on the object's own views.\n *\n * The caller must write `preserved` back alongside whatever the form returns: `meta.tags` is replaced\n * wholesale on save, so omitting them would delete the object's provider tags on the first edit.\n *\n * `candidates` is the space's tag set (each tag's origin lives on the tag, not on the ref); non-tag\n * entries are ignored, so a caller may pass a broader query result.\n */\nexport const partitionMetaTags = (\n refs: readonly Ref.Ref<Tag.Tag>[],\n candidates: readonly unknown[],\n): { editable: Ref.Ref<Tag.Tag>[]; preserved: Ref.Ref<Tag.Tag>[] } => {\n const providerIds = new Set<string>();\n for (const candidate of candidates) {\n if (isTag(candidate) && Tag.isProviderTag(candidate)) {\n const id = entityIdOf(Obj.getURI(candidate).toString());\n if (id !== undefined) {\n providerIds.add(id);\n }\n }\n }\n\n const editable: Ref.Ref<Tag.Tag>[] = [];\n const preserved: Ref.Ref<Tag.Tag>[] = [];\n for (const ref of refs) {\n const id = entityIdOf(ref.uri);\n (id !== undefined && providerIds.has(id) ? preserved : editable).push(ref);\n }\n\n return { editable, preserved };\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useCallback, useMemo } from 'react';\n\nimport { type Database, DXN, Entity, Filter, Obj, Query, Scope, Tag, Type } from '@dxos/echo';\nimport { useType as defaultUseType, useQuery } from '@dxos/echo-react';\nimport { ANY_OBJECT_TYPENAME, ReferenceAnnotationId, type ReferenceAnnotationValue } from '@dxos/echo/internal';\nimport type * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport { hues } from '@dxos/ui-types';\n\nimport { type CreateOptions, type RefFieldDataProps } from '#types';\n\nimport { omitHiddenFormFields, omitId } from '../../util/index.ts';\nimport { filterTagCandidates } from '../meta-tags.ts';\n\n/** The typename of the meta-tags field's targets, whose rows are a multiple selection of chips. */\nexport const TAG_TYPENAME = Type.getTypename(Tag.Tag);\n\n/**\n * The candidates for a ref field: objects of its type in the space and the registry (space objects only for an untyped\n * ref); tag candidates are the user tags only (`filterTagCandidates`).\n */\nexport const defaultUseResults: NonNullable<RefFieldDataProps['useResults']> = (db, typename) => {\n const results = useQuery(\n db,\n !typename\n ? Query.select(Filter.nothing())\n : typename === ANY_OBJECT_TYPENAME\n ? Query.select(Filter.everything())\n : Query.select(Filter.type(DXN.make(typename))).from(Scope.space(), Scope.registry()),\n );\n const isTagField = typename === TAG_TYPENAME;\n return useMemo(() => (isTagField ? filterTagCandidates(results) : results), [isTagField, results]);\n};\n\n/** Each candidate as an option labelled by its label (else its URI), with a tag's hue. */\nexport const defaultGetOptions: NonNullable<RefFieldDataProps['getOptions']> = (results) =>\n results.map((result) => {\n const id = Entity.getURI(result, { prefer: 'named' });\n const hue = Obj.instanceOf(Tag.Tag, result) ? hues.find((hue) => hue === result.hue) : undefined;\n return { id, label: Entity.getLabel(result) ?? id, ...(hue && { hue }) };\n });\n\nexport type RefCandidatesOptions = RefFieldDataProps &\n Pick<CreateOptions, 'createOptionLabel'> & {\n /** The ref type (a single ref's, or an array's element). */\n refType: SchemaAST.AST;\n db?: Database.Database;\n };\n\n/**\n * The data path a ref picker shares: the ref's typename, its candidates as options, and, when the caller can persist\n * one, the inline create form's schema, a `create` that persists its values, and the create row's translated label.\n */\nexport const useRefCandidates = (options: RefCandidatesOptions) => {\n const {\n refType,\n db,\n useType = defaultUseType,\n useResults = defaultUseResults,\n getOptions = defaultGetOptions,\n createOptionLabel,\n onCreate,\n resolveCreateEntry,\n } = options;\n const { t } = Hooks.useTranslation();\n const typename = useMemo(\n () => SchemaEx.findAnnotation<ReferenceAnnotationValue>(refType, ReferenceAnnotationId)?.typename,\n [refType],\n );\n const results = useResults(db, typename);\n const candidates = useMemo(() => getOptions(results), [results, getOptions]);\n const entity = useType(db, typename && typename !== ANY_OBJECT_TYPENAME ? DXN.make(typename) : undefined);\n // A plugin-registered entry (e.g. `SpaceCapabilities.CreateObjectEntry`) replaces the raw type's schema and create.\n const createEntry = typename ? resolveCreateEntry?.(typename) : undefined;\n const createSchema = useMemo(\n () => createEntry?.inputSchema ?? (entity && omitHiddenFormFields(omitId(Type.getSchema(entity)))),\n [createEntry, entity],\n );\n\n const persist = useCallback(\n async (values: any) =>\n createEntry?.createObject && db\n ? await createEntry.createObject(values, db)\n : entity && onCreate\n ? await onCreate(entity, values)\n : undefined,\n [createEntry, db, entity, onCreate],\n );\n\n const createLabel = useMemo(() => {\n if (!createOptionLabel) {\n return undefined;\n }\n const [key, { ns }] = createOptionLabel;\n return (query: string) => t(key, { ns, text: query, interpolation: { escapeValue: false } });\n }, [createOptionLabel, t]);\n\n return {\n typename,\n entity,\n results,\n options: candidates,\n createSchema,\n createLabel,\n // A resolvable type alone is not enough (operation refs cannot be created ad hoc): the caller must persist it.\n create: onCreate || createEntry?.createObject ? persist : undefined,\n };\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport React, { type KeyboardEvent, type MouseEvent, useMemo } from 'react';\n\nimport { Annotation, Entity, Obj, Ref, Type } from '@dxos/echo';\nimport type * as SchemaAST from '@dxos/effect/SchemaAST';\nimport { URI } from '@dxos/keys';\nimport { OrderedList } from '@dxos/react-ui-list';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as SystemButton from '@dxos/react-ui/SystemButton';\nimport * as Tag from '@dxos/react-ui/Tag';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport { DxAnchorActivate, hues } from '@dxos/ui-types';\nimport { arrayMove } from '@dxos/util';\n\nimport { translationKey } from '#translations';\nimport { type CreateOptions, type FormFieldRendererProps, type RefFieldDataProps, type RefOption } from '#types';\n\nimport { ObjectMultiPicker, ObjectPicker } from '../ObjectPicker.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { findRefOption } from './find-ref-option.ts';\nimport { TAG_TYPENAME, useRefCandidates } from './ref-options.ts';\n\n/**\n * How an array of refs is presented: its `ArrayPresentationAnnotation`, else (and per option) chips for Tag refs and\n * title rows for any other type, unordered unless annotated (`ordered`, or the older `FormOrderedAnnotation`).\n */\nexport const getArrayPresentation = (type: SchemaAST.AST, typename: string | undefined) => {\n const presentation = Option.getOrUndefined(Annotation.ArrayPresentationAnnotation.getFromAst(type));\n return {\n display: presentation?.display ?? (typename === TAG_TYPENAME ? 'tag' : 'title'),\n ordered:\n presentation?.ordered ?? Annotation.FormOrderedAnnotation.getFromAst(type).pipe(Option.getOrElse(() => false)),\n description: presentation?.description,\n } as const;\n};\n\nexport type RefArrayFieldProps = FormFieldRendererProps<readonly unknown[] | undefined> &\n RefFieldDataProps &\n CreateOptions & {\n /** The array's element: the ref type. */\n elementType: SchemaAST.AST;\n };\n\n/**\n * An array of references, presented per {@link getArrayPresentation}:\n * - `tag`: one multiple selection of removable chips in the targets' hues (draggable within the row when ordered);\n * - `title`: a row per target (its type's icon, its label, an optional description, a Remove) that opens the object\n * when activated, with a DragHandle when ordered, and below them a picker that adds one, with inline create.\n */\nexport const RefArrayField = ({\n type,\n elementType,\n readonly,\n label,\n placeholder,\n presentation,\n jsonPath,\n getValue,\n onValueChange,\n createInitialValuePath,\n createFieldMap,\n createOptionIcon,\n ...props\n}: RefArrayFieldProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const { typename, entity, options, createSchema, createLabel, create } = useRefCandidates({\n ...props,\n refType: elementType,\n });\n const { display, ordered, description } = getArrayPresentation(type, typename);\n const refs = (getValue() ?? []).filter(Ref.isRef).flatMap((ref) => {\n const id = findRefOption(ref, options)?.id;\n return id ? [{ id, ref }] : [];\n });\n const ids = refs.map(({ id }) => id);\n const setIds = (next: readonly string[]) =>\n onValueChange(\n type,\n next.map((id) => Ref.fromURI(URI.make(id))),\n );\n const persist =\n create &&\n (async (values: any) => {\n const created = await create(values);\n return created ? Entity.getURI(created, { prefer: 'named' }) : undefined;\n });\n const pickerProps = {\n options,\n createSchema,\n createInitialValuePath,\n createFieldMap,\n createLabel,\n createIcon: createOptionIcon,\n };\n const isStatic = readonly || presentationFor(presentation).isStatic;\n if (!typename) {\n return null;\n }\n\n if (display === 'title') {\n return (\n <TitleRows\n label={label}\n ids={ids}\n options={options}\n targets={new Map(refs.map(({ id, ref }) => [id, ref.peek()]))}\n icon={entity && Option.getOrUndefined(Annotation.IconAnnotation.get(Type.getSchema(entity)))}\n description={description}\n ordered={ordered}\n readonly={isStatic}\n testId={jsonPath}\n onChange={setIds}\n >\n {!isStatic && (\n <ObjectPicker\n {...pickerProps}\n options={options.filter((option) => !ids.includes(option.id))}\n placeholder={placeholder || t('ref-field.placeholder')}\n onSelect={(id) => id && setIds([...ids, id])}\n onCreate={\n persist &&\n (async (values) => {\n const id = await persist(values);\n if (id) {\n setIds([...ids, id]);\n }\n })\n }\n />\n )}\n </TitleRows>\n );\n }\n\n if (isStatic) {\n const selected = ids.flatMap((id) => options.find((option) => option.id === id) ?? []);\n return selected.length === 0 ? (\n <Typography.Text tone='muted'>{t('empty-readonly-ref-field.label')}</Typography.Text>\n ) : (\n <Button.Group>\n {selected.map((option) => (\n <Tag.Tag key={option.id} hue={hues.find((hue) => hue === option.hue)}>\n {option.label}\n </Tag.Tag>\n ))}\n </Button.Group>\n );\n }\n\n return (\n <ObjectMultiPicker\n {...pickerProps}\n value={ids}\n ordered={ordered}\n placeholder={placeholder || label}\n data-testid={jsonPath}\n onCreate={persist}\n onValueChange={setIds}\n />\n );\n};\n\ntype TitleRowsProps = {\n label?: string;\n ids: readonly string[];\n options: RefOption[];\n /** The loaded target of each id, for the configured description field. */\n targets: ReadonlyMap<string, unknown>;\n icon?: { icon: string; hue?: string };\n description?: string;\n ordered: boolean;\n readonly: boolean;\n testId?: string;\n onChange: (ids: readonly string[]) => void;\n /** The add picker, in a row below the rows. */\n children?: React.ReactNode;\n};\n\n/** Opens a target as its anchor would (the app's preview), from the row standing in for it. */\nconst activate = (option: RefOption, row: HTMLElement) =>\n row.dispatchEvent(new DxAnchorActivate({ eid: option.id, label: option.label, trigger: row }));\n\n/** The `title` rows: a header with the label, an OrderedList of the targets, then the add picker. */\nconst TitleRows = ({\n label,\n ids,\n options,\n targets,\n icon,\n description,\n ordered,\n readonly,\n testId,\n onChange,\n children,\n}: TitleRowsProps) => {\n const rows = useMemo(\n () =>\n ids.flatMap((id) => {\n const option = options.find((option) => option.id === id);\n if (!option) {\n return [];\n }\n // The configured description field of the target, else the option's own description.\n const target = targets.get(id);\n const field = description && Obj.isObject(target) ? Obj.getValue(target, [description]) : undefined;\n return [{ ...option, description: typeof field === 'string' ? field : option.description }];\n }),\n [ids, options, targets, description],\n );\n const iconHue = hues.find((hue) => hue === icon?.hue);\n\n const handleMove = (from: number, to: number) => {\n const next = [...ids];\n arrayMove(next, from, to);\n onChange(next);\n };\n\n // A click on the row (not on one of its buttons) opens the target.\n const handleClick = (option: RefOption) => (event: MouseEvent<HTMLElement>) => {\n if (!(event.target instanceof Element && event.target.closest('button'))) {\n activate(option, event.currentTarget);\n }\n };\n\n // Enter on the highlighted row (focus is on the list, the row is its active descendant) opens its target.\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key !== 'Enter' || event.target !== event.currentTarget) {\n return;\n }\n const row = event.currentTarget.querySelector<HTMLElement>('[data-part=\"item\"][data-highlighted]');\n const option = rows.find((option) => option.id === row?.dataset.value);\n if (row && option) {\n event.preventDefault();\n activate(option, row);\n }\n };\n\n return (\n <>\n <Field.Header>\n <Typography.Text truncate>{label}</Typography.Text>\n </Field.Header>\n {rows.length > 0 && (\n <OrderedList.Root\n items={rows}\n getId={(option) => option.id}\n getLabel={(option) => option.label}\n onMove={handleMove}\n readonly={readonly || !ordered}\n >\n {({ items }) => (\n <OrderedList.Content\n scroll={false}\n gutter='inherit'\n aria-label={label}\n data-testid={testId}\n onKeyDown={handleKeyDown}\n >\n {items.map((option) => (\n <OrderedList.Item\n key={option.id}\n id={option.id}\n canDrag={ordered && !readonly}\n onClick={handleClick(option)}\n >\n {ordered && !readonly && <OrderedList.DragHandle />}\n {icon && <OrderedList.ItemIcon icon={icon.icon} hue={iconHue} />}\n <OrderedList.ItemText>{option.label}</OrderedList.ItemText>\n {option.description && (\n <OrderedList.ItemDescription>{option.description}</OrderedList.ItemDescription>\n )}\n {!readonly && (\n <SystemButton.Remove\n variant='ghost'\n onClick={() => onChange(ids.filter((id) => id !== option.id))}\n />\n )}\n </OrderedList.Item>\n ))}\n </OrderedList.Content>\n )}\n </OrderedList.Root>\n )}\n {children}\n </>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Ref } from '@dxos/echo';\nimport { URI } from '@dxos/keys';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { translationKey } from '#translations';\nimport { type CreateOptions, type FormFieldRendererProps, type RefFieldDataProps } from '#types';\n\nimport { ObjectPicker } from '../ObjectPicker.tsx';\nimport { presentationFor } from '../presentation.tsx';\nimport { findRefOption } from './find-ref-option.ts';\nimport { useRefCandidates } from './ref-options.ts';\n\nexport type RefFieldProps = FormFieldRendererProps & RefFieldDataProps & CreateOptions;\n\n/**\n * A single reference picked with the next `ObjectPicker` (Combobox trigger mode): a button showing the target opens a\n * searchable list of candidates with their descriptions and, when the caller can persist one, an inline create form\n * whose row takes `createOptionLabel` and `createOptionIcon`.\n */\nexport const RefField = ({\n type,\n readonly,\n label,\n placeholder,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n createInitialValuePath,\n createFieldMap,\n createOptionIcon,\n ...props\n}: RefFieldProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const { typename, options, createSchema, createLabel, create } = useRefCandidates({ ...props, refType: type });\n const selected = findRefOption(getValue(), options);\n if (!typename) {\n return null;\n }\n if (readonly || presentationFor(presentation).isStatic) {\n return (\n <Typography.Text truncate tone={selected ? 'default' : 'muted'}>\n {selected?.label ?? t('empty-readonly-ref-field.label')}\n </Typography.Text>\n );\n }\n\n return (\n <ObjectPicker\n options={options}\n value={selected?.id}\n placeholder={placeholder || label || t('ref-field.placeholder')}\n createSchema={createSchema}\n createInitialValuePath={createInitialValuePath}\n createFieldMap={createFieldMap}\n createLabel={createLabel}\n createIcon={createOptionIcon}\n onCreate={\n create &&\n (async (values) => {\n const created = await create(values);\n if (created) {\n onValueChange(type, Ref.make(created));\n onBlur();\n }\n })\n }\n // A pick is the whole edit, so it commits as a select does; without the blur an auto-saving form never saves it.\n onSelect={(id) => {\n onValueChange(type, id ? Ref.fromURI(URI.make(id)) : undefined);\n onBlur();\n }}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { type SelectOption } from '@dxos/echo/Format';\nimport { PublicKey } from '@dxos/keys';\nimport { OrderedList } from '@dxos/react-ui-list';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Tag from '@dxos/react-ui/Tag';\nimport { hues } from '@dxos/ui-types';\nimport { arrayMove } from '@dxos/util';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldRendererProps } from '#types';\n\nimport { HueSelect } from './HueField.tsx';\n\n/** A hue no option uses yet, else one the last three options do not use. */\nconst nextHue = (options: readonly SelectOption[]) => {\n const used = new Set(options.map((option) => option.color));\n const unused = hues.filter((hue) => !used.has(hue));\n if (unused.length > 0) {\n return unused[Math.floor(Math.random() * unused.length)];\n }\n const recent = new Set(options.slice(-3).map((option) => option.color));\n const available = hues.filter((hue) => !recent.has(hue));\n return available[Math.floor(Math.random() * available.length)] ?? hues[0];\n};\n\n/**\n * The options of a single- or multi-select property: an `OrderedList` of disclosure rows, each a hued `Tag` that opens\n * to its label and hue, with a remove action; options reorder by drag or Alt+Arrow, and \"Add option\" appends one\n * opened for editing.\n */\nexport const SelectOptionField = ({\n type,\n label,\n readonly,\n getValue,\n onValueChange,\n}: FormFieldRendererProps<SelectOption[] | undefined>) => {\n const { t } = Hooks.useTranslation(translationKey);\n const options = getValue();\n const [expandedId, setExpandedId] = useState<string>();\n\n useEffect(() => {\n if (options === undefined) {\n onValueChange(type, []);\n }\n }, [options, type, onValueChange]);\n\n const update = useCallback(\n (id: string, change: Partial<SelectOption>) =>\n onValueChange(\n type,\n (options ?? []).map((option) => (option.id === id ? { ...option, ...change } : option)),\n ),\n [options, type, onValueChange],\n );\n\n const handleAdd = useCallback(() => {\n const id = PublicKey.random().truncate();\n onValueChange(type, [...(options ?? []), { id, title: '', color: nextHue(options ?? []) }]);\n setExpandedId(id);\n }, [options, type, onValueChange]);\n\n const handleMove = useCallback(\n (from: number, to: number) => {\n const next = [...(options ?? [])];\n arrayMove(next, from, to);\n onValueChange(type, next);\n },\n [options, type, onValueChange],\n );\n\n return (\n <>\n <OrderedList.Root\n items={options ?? []}\n getId={(option) => option.id}\n getLabel={(option) => option.title}\n onMove={handleMove}\n readonly={!!readonly}\n >\n {({ items }) => (\n <OrderedList.Content scroll={false} gutter='inherit' aria-label={label}>\n {items.map((option) => (\n <OrderedList.Item\n key={option.id}\n id={option.id}\n canDrag={!readonly}\n open={expandedId === option.id}\n onOpenChange={(open) => setExpandedId(open ? option.id : undefined)}\n data-testid={`option-${option.id}`}\n >\n <OrderedList.DragHandle />\n <OrderedList.ItemText>\n <Tag.Tag hue={hues.find((hue) => hue === option.color)}>{option.title || '\\u200b'}</Tag.Tag>\n </OrderedList.ItemText>\n {!readonly && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--x--regular'\n label={t('select-option-delete.button')}\n onClick={() =>\n onValueChange(\n type,\n (options ?? []).filter((item) => item.id !== option.id),\n )\n }\n />\n )}\n <OrderedList.Detail>\n <Layout.Container layout='row' gutter='none' columns='minmax(0, 1fr) minmax(0, 1fr)' gap='sm'>\n <Field.Root>\n <Field.Label>{t('select-option.label')}</Field.Label>\n <Input.Root\n autoFocus={expandedId === option.id && option.title === ''}\n disabled={!!readonly}\n placeholder={t('select-option-label.placeholder')}\n value={option.title}\n onChange={(event) => update(option.id, { title: event.target.value })}\n onKeyDown={(event) => event.key === 'Enter' && setExpandedId(undefined)}\n />\n </Field.Root>\n <Field.Root>\n <Field.Label>{t('select-option-color.label')}</Field.Label>\n <HueSelect\n value={option.color}\n readonly={readonly}\n onValueChange={(color) => color && update(option.id, { color })}\n />\n </Field.Root>\n </Layout.Container>\n </OrderedList.Detail>\n </OrderedList.Item>\n ))}\n </OrderedList.Content>\n )}\n </OrderedList.Root>\n {!readonly && (\n <Button.Group>\n <Button.Root icon='ph--plus--regular' label={t('select-option-add.button')} onClick={handleAdd} />\n </Button.Group>\n )}\n </>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type FormFieldRendererProps } from '#types';\n\nimport { FormStaticValue } from '../FormField.tsx';\nimport { presentationFor } from '../presentation.tsx';\n\nexport const TextAreaField = ({\n type,\n format,\n readonly,\n placeholder,\n presentation,\n getValue,\n onValueChange,\n onBlur,\n}: FormFieldRendererProps<string>) => {\n const value = getValue() ?? '';\n if (presentationFor(presentation).isStatic) {\n return <FormStaticValue value={value} format={format} />;\n }\n\n return (\n <Input.Textarea\n autoResize\n disabled={!!readonly}\n placeholder={placeholder}\n value={value}\n onChange={(event) => onValueChange(type, event.target.value)}\n onBlur={onBlur}\n />\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n/**\n * Minimal XML-style DSL for laying out schema fields in a grid.\n *\n * Grammar:\n * <grid cols=\"N\" [fixed=\"true\"]> ...children... </grid>\n * <field name=\"x\" span=\"N\"/>\n *\n * - Attributes accept `\"…\"`, `'…'`, or unquoted integers.\n * - Whitespace between tags is ignored. Text content (between tags) is forbidden.\n * - Self-closing form (`<field … />`) is required for `field`; `grid` must use a closing tag.\n *\n * The parser is hand-rolled (no HTML parser) because the grammar is tiny.\n */\n\n/** Node type for the parsed layout tree. */\nexport type LayoutNode =\n | {\n readonly kind: 'grid';\n readonly cols: number;\n /** Keeps the columns in a narrow pane rather than stacking the cells. */\n readonly fixed?: boolean;\n readonly children: readonly LayoutNode[];\n }\n | { readonly kind: 'field'; readonly name: string; readonly span?: number };\n\nexport class LayoutParseError extends Error {\n readonly _tag = 'LayoutParseError';\n constructor(\n message: string,\n readonly position?: number,\n ) {\n super(position !== undefined ? `${message} (at position ${position})` : message);\n }\n}\n\nconst TAG_RE = /<\\s*(\\/?)\\s*(\\w+)([^>]*?)(\\/?)\\s*>/g;\nconst ATTR_RE = /([\\w-]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|(\\d+))/g;\n\ntype Token =\n | { type: 'open'; name: string; attrs: Record<string, string>; selfClosing: boolean; position: number }\n | { type: 'close'; name: string; position: number };\n\nconst parseAttrs = (raw: string): Record<string, string> => {\n const attrs: Record<string, string> = {};\n ATTR_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = ATTR_RE.exec(raw)) !== null) {\n const [, key, doubleQuoted, singleQuoted, bare] = match;\n attrs[key] = doubleQuoted ?? singleQuoted ?? bare;\n }\n return attrs;\n};\n\nconst tokenize = (input: string): Token[] => {\n const tokens: Token[] = [];\n TAG_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n let cursor = 0;\n while ((match = TAG_RE.exec(input)) !== null) {\n // Validate that any text between the previous tag and this one is whitespace-only.\n const between = input.slice(cursor, match.index);\n if (between.trim().length > 0) {\n throw new LayoutParseError(`unexpected text content: ${JSON.stringify(between.trim())}`, cursor);\n }\n const [, slash, name, attrsRaw, selfSlash] = match;\n if (slash) {\n tokens.push({ type: 'close', name, position: match.index });\n } else {\n tokens.push({\n type: 'open',\n name,\n attrs: parseAttrs(attrsRaw),\n selfClosing: selfSlash === '/',\n position: match.index,\n });\n }\n cursor = match.index + match[0].length;\n }\n // Any trailing text after the last tag must also be whitespace.\n const trailing = input.slice(cursor);\n if (trailing.trim().length > 0) {\n throw new LayoutParseError(`unexpected text content: ${JSON.stringify(trailing.trim())}`, cursor);\n }\n return tokens;\n};\n\nconst requireAttr = (attrs: Record<string, string>, key: string, tag: string, position: number): string => {\n const value = attrs[key];\n if (value === undefined) {\n throw new LayoutParseError(`<${tag}> missing required attribute \"${key}\"`, position);\n }\n return value;\n};\n\nconst parseInteger = (value: string, attr: string, tag: string, position: number): number => {\n if (!/^\\d+$/.test(value)) {\n throw new LayoutParseError(\n `<${tag}> attribute \"${attr}\" expects an integer, got ${JSON.stringify(value)}`,\n position,\n );\n }\n return Number.parseInt(value, 10);\n};\n\n/** Parses a layout template string into a single root node. The root must be `<grid>`. */\nexport const parseLayout = (template: string): LayoutNode => {\n const tokens = tokenize(template);\n if (tokens.length === 0) {\n throw new LayoutParseError('empty template');\n }\n\n let index = 0;\n\n const parseNode = (): LayoutNode => {\n const token = tokens[index];\n if (!token || token.type !== 'open') {\n throw new LayoutParseError(`expected an opening tag, got ${JSON.stringify(token)}`, token?.position);\n }\n\n if (token.name === 'field') {\n if (!token.selfClosing) {\n throw new LayoutParseError('<field> must be self-closing (e.g. <field name=\"x\"/>)', token.position);\n }\n const name = requireAttr(token.attrs, 'name', 'field', token.position);\n const spanRaw = token.attrs.span;\n const span = spanRaw !== undefined ? parseInteger(spanRaw, 'span', 'field', token.position) : undefined;\n index += 1;\n return { kind: 'field', name, span };\n }\n\n if (token.name === 'grid') {\n if (token.selfClosing) {\n throw new LayoutParseError('<grid> must wrap children (cannot self-close)', token.position);\n }\n const cols = parseInteger(\n requireAttr(token.attrs, 'cols', 'grid', token.position),\n 'cols',\n 'grid',\n token.position,\n );\n index += 1;\n const children: LayoutNode[] = [];\n while (index < tokens.length && !(tokens[index].type === 'close' && tokens[index].name === 'grid')) {\n children.push(parseNode());\n }\n const closing = tokens[index];\n if (!closing || closing.type !== 'close' || closing.name !== 'grid') {\n throw new LayoutParseError('<grid> not closed', token.position);\n }\n index += 1;\n const fixed = token.attrs.fixed === 'true';\n return { kind: 'grid', cols, ...(fixed ? { fixed } : {}), children };\n }\n\n throw new LayoutParseError(`unknown element <${token.name}>`, token.position);\n };\n\n const root = parseNode();\n if (index !== tokens.length) {\n const trailing = tokens[index];\n throw new LayoutParseError(\n `unexpected trailing tag <${trailing.type === 'open' ? '' : '/'}${trailing.name}>`,\n trailing.position,\n );\n }\n if (root.kind !== 'grid') {\n throw new LayoutParseError('root element must be <grid>');\n }\n return root;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as String from 'effect/String';\nimport React, { Fragment, useMemo } from 'react';\n\nimport { Annotation } from '@dxos/echo';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { type FormPresentation } from '#types';\n\nimport { useFormContext, useFormFieldState } from '../hooks/index.ts';\nimport { FormFieldErrorBoundary } from './field-binding.tsx';\nimport { FormFieldRow } from './FormField.tsx';\nimport { FormFieldDispatch } from './FormFieldDispatch.tsx';\nimport { type LayoutNode, LayoutParseError, parseLayout } from './layout/parser.ts';\nimport { resolveLayoutField } from './layout/resolve-layout-field.ts';\nimport { type FormFieldDispatchProps } from './resolve-field.ts';\n\nconst FORM_LAYOUT_NAME = 'Form.Layout';\n\nexport type FormLayoutProps = {\n /** Template in the FormLayout DSL (`<grid cols=…><field name=… span=…/></grid>`); else the schema's annotation. */\n template?: string;\n /** The named layout in `FormLayoutAnnotation` when there is no `template`; `'default'` by default. */\n name?: string;\n schema: Schema.Codec<AnyProperties, any>;\n} & Pick<FormFieldDispatchProps, 'path' | 'readonly' | 'layout' | 'projection' | 'fieldMap' | 'fieldProvider'>;\n\n/**\n * Lays out schema fields by a FormLayout DSL template: a `<grid cols=N>` is a row Container of N equal tracks, and a\n * `<field span=N>` a cell spanning N of them (Container `span`). Only the fields the template names render; a dotted\n * name drills into a nested struct, and a struct with a `LabelAnnotation` renders as its label, read-only.\n */\nexport const FormLayout = ({\n schema,\n template,\n name = Annotation.DEFAULT_LAYOUT_NAME,\n path,\n ...props\n}: FormLayoutProps) => {\n const annotated = Option.getOrUndefined(Annotation.FormLayoutAnnotation.get(schema));\n const source = template ?? annotated?.[name];\n if (source === undefined) {\n throw new LayoutParseError(\n annotated\n ? `no layout named \"${name}\" on schema (available: ${Object.keys(annotated).join(', ') || '∅'})`\n : 'no template provided and schema has no FormLayoutAnnotation',\n );\n }\n\n const tree = useMemo(() => parseLayout(source), [source]);\n return <LayoutNodeView node={tree} schema={schema} basePath={path ?? []} {...props} />;\n};\n\nFormLayout.displayName = FORM_LAYOUT_NAME;\n\ntype LayoutNodeViewProps = Omit<FormLayoutProps, 'template' | 'name' | 'path'> & {\n node: LayoutNode;\n basePath: (string | number)[];\n};\n\nconst LayoutNodeView = ({ node, schema, basePath, ...props }: LayoutNodeViewProps) => {\n if (node.kind === 'grid') {\n return (\n <Layout.Container\n layout='row'\n gutter='inherit'\n align='start'\n gap='md'\n columns={`repeat(${node.cols}, minmax(0, 1fr))`}\n fixed={node.fixed}\n >\n {node.children.map((child, index) => (\n <Fragment key={index}>\n <LayoutNodeView node={child} schema={schema} basePath={basePath} {...props} />\n </Fragment>\n ))}\n </Layout.Container>\n );\n }\n\n const resolved = resolveLayoutField(schema, node.name);\n if (!resolved) {\n throw new LayoutParseError(`field \"${node.name}\" not found on schema`);\n }\n\n const { type, segments, leafName, title, labelType, required } = resolved;\n const path = [...basePath, ...segments];\n return (\n // A cell is its own template root, so a group inside it (a nested object) finds the `content` lines.\n <Layout.Container gutter='none' span={node.span}>\n <FormFieldErrorBoundary path={path}>\n {labelType ? (\n <LabelField\n schema={Schema.make(labelType)}\n label={title ?? String.capitalize(leafName)}\n path={path}\n layout={props.layout}\n />\n ) : (\n <FormFieldDispatch type={type} name={leafName} path={path} required={required} {...props} />\n )}\n </FormFieldErrorBoundary>\n </Layout.Container>\n );\n};\n\ntype LabelFieldProps = {\n schema: Schema.Schema<any>;\n label: string;\n path: (string | number)[];\n layout?: FormPresentation;\n};\n\n/** A nested struct value as its computed label (`LabelAnnotation`), read-only; an empty value renders nothing. */\nconst LabelField = ({ schema, label, path, layout }: LabelFieldProps) => {\n const { getValue } = useFormFieldState(FORM_LAYOUT_NAME, path);\n const value = getValue();\n const text = value == null ? undefined : Annotation.getLabelWithSchema(schema, value);\n if (text == null || text.trim().length === 0) {\n return null;\n }\n\n return (\n <FormFieldRow label={label} readonly standalone presentation={layout}>\n <Typography.Text truncate>{text}</Typography.Text>\n </FormFieldRow>\n );\n};\n\n/** `Form.Layout`: the form's own schema laid out by a template (or the schema's annotation). */\nexport const FormLayoutController = ({\n schema,\n ...props\n}: Omit<FormLayoutProps, 'schema'> & Partial<Pick<FormLayoutProps, 'schema'>>) => {\n const { form, variant: _variant, testId: _testId, ...context } = useFormContext(FORM_LAYOUT_NAME);\n const resolved = schema ?? form.schema;\n return resolved ? <FormLayout schema={resolved} {...context} {...props} /> : null;\n};\n\nFormLayoutController.displayName = FORM_LAYOUT_NAME;\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as Schema from 'effect/Schema';\nimport { useMemo } from 'react';\n\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { type Merge } from '@dxos/util';\n\nimport { type FieldContext } from '#types';\n\nimport { getRootFormProperties } from '../util/index.ts';\nimport { type FormFieldDispatchProps } from './resolve-field.ts';\n\n/** A path into the form values: dotted from the root, or its segments. */\nexport type FormPath = string | (string | number)[];\n\nexport const toPathSegments = (path: FormPath | undefined): (string | number)[] =>\n path === undefined\n ? []\n : typeof path === 'string'\n ? SchemaEx.isJsonPath(path)\n ? SchemaEx.splitJsonPath(path)\n : []\n : path;\n\nexport type FormFieldsProps<T extends AnyProperties = AnyProperties> = Merge<\n {\n /** The object property whose fields to render; the root by default. */\n path?: FormPath;\n /** Renders these properties only, in schema order. */\n include?: string[];\n exclude?: string[];\n /** Property names in the order to render them. */\n sort?: string[];\n filter?: (props: SchemaEx.SchemaProperty[]) => SchemaEx.SchemaProperty[];\n /**\n * Picks a named layout out of `Annotation.FormLayoutAnnotation` when present. Falls back to `'default'`.\n * Ignored when the schema has no annotation (linear rendering then takes over).\n */\n layoutName?: string;\n /** The schema to walk in place of the form's, at the same path. */\n schema?: Schema.Codec<T, any>;\n },\n Pick<FormFieldDispatchProps, 'autoFocus'>,\n FieldContext\n>;\n\nexport type UseFormFieldsPropertiesParams = Pick<\n FormFieldsProps<any>,\n 'schema' | 'include' | 'exclude' | 'filter' | 'projection' | 'sort'\n> & {\n values: AnyProperties | undefined;\n};\n\n/**\n * Resolves ordered schema properties for a walk (projection order, include/exclude, filter, sort).\n */\nexport const useFormFieldsProperties = ({\n schema,\n include,\n exclude,\n filter,\n projection,\n values,\n sort,\n}: UseFormFieldsPropertiesParams): SchemaEx.SchemaProperty[] => {\n // TODO(burdon): Updates on every value change.\n // Remove values dep if can remove from getSchemaProperties.\n return useMemo(() => {\n if (!schema) {\n return [];\n }\n\n // TODO(wittjosiah): Reconcile FormInputAnnotation with projection hidden properties & filter function.\n const schemaProps = getRootFormProperties(schema.ast, values);\n const included = include ? schemaProps.filter((prop) => include.includes(prop.name.toString())) : schemaProps;\n const excluded = exclude ? included.filter((prop) => !exclude.includes(prop.name.toString())) : included;\n const filteredProps = filter ? filter(excluded) : excluded;\n\n // Use projection-based field management when view and projection are available.\n if (projection) {\n const fieldProjections = projection.getFieldProjections();\n const hiddenProperties = new Set(projection.getHiddenProperties());\n\n // Filter properties to only include visible ones and order by projection.\n const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));\n const orderedProps: SchemaEx.SchemaProperty[] = [];\n\n // Add properties in projection field order.\n for (const fieldProjection of fieldProjections) {\n const fieldPath = String(fieldProjection.field.path);\n const prop = visibleProps.find((prop) => prop.name === fieldPath);\n if (prop) {\n orderedProps.push(prop);\n }\n }\n\n // Add any remaining properties not in projection.\n const projectionPaths = new Set(fieldProjections.map((projection) => String(projection.field.path)));\n const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));\n orderedProps.push(...remainingProps);\n return orderedProps;\n }\n\n // Fallback to legacy filter/sort behavior.\n return sort\n ? [...filteredProps].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString()))\n : filteredProps;\n }, [schema, values, include, exclude, filter, sort, projection]);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Match from 'effect/Match';\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport { type ReactNode } from 'react';\n\nimport { Annotation, Format } from '@dxos/echo';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\n\nimport { type FieldContext, type FormFieldRenderer, type FormFieldRendererProps } from '#types';\n\nimport {\n type Autofill,\n AutofillAnnotation,\n HueAnnotation,\n type OptionsLookup,\n OptionsLookupAnnotation,\n} from '../annotations.ts';\nimport { getRefProps } from '../util/index.ts';\n\n/** The built-in control a scalar property gets. */\nexport type ScalarKind = 'text' | 'number' | 'boolean' | 'date' | 'geo-point' | 'markdown' | 'password' | 'text-area';\n\nexport type FormFieldDispatchProps = {\n /**\n * AST of the property to render.\n */\n type: SchemaAST.AST;\n\n /**\n * Name of the property. Used to derive a default label\n * (`title ?? capitalize(name)`) and as the projection lookup key. Pass\n * `null` to suppress the header label entirely -- the form still renders\n * the field/struct, but `FormFieldSet`'s top-level `<FormFieldLabel>` is\n * skipped. Used by `ArrayField` for object-array items, where every item\n * would otherwise repeat the array's parent name.\n */\n name: string | null;\n\n /**\n * Explicit label, overriding the `title ?? capitalize(name)` derivation. Used by `ArrayField` to\n * give scalar/ref items the array's resolved title (e.g. `Tags`) rather than re-capitalizing the\n * raw array property name (e.g. `_tags`), since the element type carries no title of its own.\n */\n label?: string;\n\n /**\n * Path to the current object from the root. Used with nested forms.\n */\n path?: (string | number)[];\n autoFocus?: boolean;\n /** Whether the field is required (non-optional in the schema). Drives the label asterisk. */\n required?: boolean;\n /**\n * Force a `Ref` field to render its target inline (a nested form) instead of the picker.\n * Set by `ArrayField` for owned-ref arrays (`FormCreateAnnotation`); equivalent to\n * `FormInlineAnnotation` but driven by the parent array rather than the element's own AST.\n */\n refInline?: boolean;\n} & FieldContext;\n\n/**\n * Decides which renderer a schema property gets, in priority order: a custom renderer from the form,\n * an annotation that names one (options lookup, autofill, hue), then the shape of the type (array,\n * scalar by format or tag, literal options, reference, nested object). Pure, so the decision can be\n * tested without rendering; {@link FormFieldDispatch} turns the result into an element.\n */\nexport const resolveFieldRenderer = ({\n type,\n name,\n jsonPath,\n value,\n fieldMap,\n fieldProvider,\n fieldProps,\n refInline,\n}: ResolveFieldRendererOptions): FieldRendererResolution | undefined => {\n const custom = fieldMap?.[jsonPath];\n if (custom) {\n return { kind: 'custom', component: custom };\n }\n\n if (fieldProvider) {\n const element = fieldProvider({ schema: Schema.make<Schema.Codec<any, any>>(type), prop: name ?? '', fieldProps });\n if (element) {\n return { kind: 'provided', element };\n }\n }\n\n const lookup = Option.getOrUndefined(OptionsLookupAnnotation.getFromAst(type));\n if (lookup) {\n return { kind: 'lookup', lookup, combobox: !!lookup.combobox };\n }\n\n const autofill = Option.getOrUndefined(AutofillAnnotation.getFromAst(type));\n if (autofill) {\n return { kind: 'autofill', autofill };\n }\n\n if (Option.getOrUndefined(HueAnnotation.getFromAst(type))) {\n return { kind: 'hue' };\n }\n\n if (SchemaEx.isArrayType(type)) {\n return { kind: 'array' };\n }\n\n const scalar = getScalarKind({ type, format: fieldProps.format });\n if (scalar) {\n return { kind: 'scalar', scalar };\n }\n\n const options = getSelectOptions(type);\n if (options) {\n return { kind: 'select', options };\n }\n\n const refProps = getRefProps(type);\n if (refProps) {\n const inline =\n refInline || Annotation.FormInlineAnnotation.getFromAst(refProps.ast).pipe(Option.getOrElse(() => false));\n return { kind: 'ref', refProps, inline: inline && !refProps.isArray };\n }\n\n if (SchemaEx.isNestedType(type)) {\n const baseNode = SchemaEx.findNode(type, SchemaEx.isDiscriminatedUnion);\n const typeLiteral = baseNode\n ? SchemaEx.getDiscriminatedType(baseNode, value as any)\n : SchemaEx.findNode(type, SchemaAST.isObjects);\n if (typeLiteral) {\n return { kind: 'object', schema: Schema.make<Schema.Codec<any, any>>(typeLiteral) };\n }\n }\n\n return undefined;\n};\n\nexport type ResolveFieldRendererOptions = {\n type: SchemaAST.AST;\n name: string | null;\n jsonPath: string;\n /** The property's current value; a discriminated union picks its member by it. */\n value: unknown;\n fieldProps: FormFieldRendererProps;\n refInline?: boolean;\n} & Pick<FieldContext, 'fieldMap' | 'fieldProvider'>;\n\ntype RefProps = NonNullable<ReturnType<typeof getRefProps>>;\n\nexport type FieldRendererResolution =\n | { kind: 'custom'; component: FormFieldRenderer }\n | { kind: 'provided'; element: ReactNode }\n | { kind: 'lookup'; lookup: OptionsLookup; combobox: boolean }\n | { kind: 'autofill'; autofill: Autofill }\n | { kind: 'hue' }\n | { kind: 'array' }\n | { kind: 'scalar'; scalar: ScalarKind }\n | { kind: 'select'; options: Format.Options[] }\n | { kind: 'ref'; refProps: RefProps; inline: boolean }\n | { kind: 'object'; schema: Schema.Codec<any, any> };\n\n/** The kind of control for a scalar: by its format first, then by the type's tag. */\nconst getScalarKind = ({ type, format }: Pick<FormFieldRendererProps, 'type' | 'format'>): ScalarKind | undefined => {\n // v4 has no `Refinement` node: `Schema.Number.pipe(Schema.check(...))` IS a `Number` node\n // carrying checks, so the base-type cases below already match it.\n\n //\n // Standard formats.\n //\n\n const formatField = Match.value(format).pipe(\n Match.withReturnType<ScalarKind | undefined>(),\n Match.when(Format.TypeFormat.Date, () => 'date'),\n Match.when(Format.TypeFormat.DateTime, () => 'date'),\n Match.when(Format.TypeFormat.GeoPoint, () => 'geo-point'),\n Match.when(Format.TypeFormat.Markdown, () => 'markdown'),\n Match.when(Format.TypeFormat.Password, () => 'password'),\n Match.when(Format.TypeFormat.Text, () => 'text-area'),\n Match.when(Format.TypeFormat.Time, () => 'date'),\n Match.orElse(() => undefined),\n );\n if (formatField) {\n return formatField;\n }\n\n //\n // Standard types.\n //\n\n switch (type._tag) {\n // TODO(wittjosiah): Schema.Any is currently used to represent template inputs.\n case 'Any':\n case 'String':\n return 'text';\n case 'Number':\n return 'number';\n case 'Boolean':\n return 'boolean';\n }\n\n return undefined;\n};\n\nconst getSelectOptions = (ast: SchemaAST.AST): Format.Options[] | undefined => {\n if (SchemaEx.isLiteralUnion(ast)) {\n return ast.types.map((type) => type.literal).filter((v): v is string | number => v !== null);\n }\n\n return Format.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option.getOrUndefined(annotation));\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as String from 'effect/String';\nimport React, { type ReactNode, useMemo } from 'react';\n\nimport { Annotation, Format } from '@dxos/echo';\nimport { type AnyProperties } from '@dxos/echo/internal';\nimport * as SchemaAST from '@dxos/effect/SchemaAST';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport * as Hooks from '@dxos/react-ui/Hooks';\n\nimport { translationKey } from '#translations';\nimport { type CreateOptions, type FormFieldRenderer, type FormFieldRendererProps } from '#types';\n\nimport { useFormContext, useFormFieldState, useFormValues } from '../hooks/index.ts';\nimport { getRefProps, getSchemaAtPath } from '../util/index.ts';\nimport { FormFieldErrorBoundary } from './field-binding.tsx';\nimport {\n ArrayField,\n AsyncSelectField,\n AutofillField,\n BooleanField,\n ComboboxField,\n DateField,\n GeoPointField,\n HueField,\n InlineRefField,\n MarkdownField,\n NumberField,\n PasswordField,\n RefArrayField,\n RefField,\n SelectField,\n TextAreaField,\n TextField,\n getArrayPresentation,\n} from './fields/index.ts';\nimport { FormFieldRow } from './FormField.tsx';\nimport { type FormFieldBinding } from './FormFieldContext.ts';\nimport { FormFieldSet } from './FormFieldSet.tsx';\nimport { FormLayout } from './FormLayout.tsx';\nimport { type FormFieldsProps, toPathSegments, useFormFieldsProperties } from './property-walk.ts';\nimport {\n type FieldRendererResolution,\n type FormFieldDispatchProps,\n type ScalarKind,\n resolveFieldRenderer,\n} from './resolve-field.ts';\n\n/**\n * The control for each scalar kind `resolveFieldRenderer` answers. A function, not a module-level table, so nothing\n * imported is read while the modules of this recursion evaluate.\n */\nconst scalarField = (kind: ScalarKind): FormFieldRenderer => {\n switch (kind) {\n case 'text':\n return TextField;\n case 'number':\n return NumberField;\n case 'boolean':\n return BooleanField;\n case 'date':\n return DateField;\n case 'geo-point':\n return GeoPointField;\n case 'password':\n return PasswordField;\n case 'text-area':\n return TextAreaField;\n case 'markdown':\n return MarkdownField;\n }\n};\n\nexport type { FormFieldDispatchProps, FormFieldsProps };\n\n/** One schema property, rendered by the Next renderer for whatever `resolveFieldRenderer` picks. */\nexport const FormFieldDispatch = (props: FormFieldDispatchProps) => {\n const {\n type,\n name,\n label: labelProp,\n path,\n required,\n projection,\n fieldMap,\n fieldProvider,\n readonly: readonlyProp,\n hideEmpty = true,\n layout,\n createTypename,\n createOptionLabel,\n createOptionIcon,\n createInitialValuePath,\n createFieldMap,\n db,\n useType,\n getOptions,\n onCreate,\n resolveCreateEntry,\n refInline,\n } = props;\n const { t } = Hooks.useTranslation(translationKey);\n const { variant, form } = useFormContext(FormFieldDispatch.displayName);\n // The caller's per-field override wins over what the schema says.\n const override = form.getOverride(path ?? []);\n const title = SchemaEx.getAnnotation<string>(SchemaAST.TitleAnnotationId)(type);\n const description = override?.description ?? SchemaEx.getAnnotation<string>(SchemaAST.DescriptionAnnotationId)(type);\n const examples = SchemaEx.getAnnotation<string[]>(SchemaAST.ExamplesAnnotationId)(type);\n const label = useMemo(\n () => override?.label ?? labelProp ?? title ?? (name == null ? '' : String.capitalize(name)),\n [override?.label, labelProp, title, name],\n );\n const readonly = override?.readonly ?? readonlyProp;\n // A settings row shows its description beside the control, so the description never doubles as the placeholder.\n const placeholder = useMemo(\n () =>\n examples?.length\n ? `${t('example.placeholder')}: ${examples[0]}`\n : variant === 'settings'\n ? undefined\n : (description ?? label),\n [examples, description, label, variant, t],\n );\n\n const fieldState = useFormFieldState(FormFieldDispatch.displayName, path);\n const jsonPath = SchemaEx.createJsonPath(path ?? []);\n const indeterminate = fieldState.getStatus().indeterminate;\n const fieldProps: FormFieldRendererProps = {\n type,\n format: Format.FormatAnnotation.getFromAst(type).pipe((annotation) => Option.getOrUndefined(annotation)),\n readonly,\n label,\n description,\n jsonPath,\n // An indeterminate value reads as none, so its placeholder says why rather than naming the field.\n placeholder: indeterminate\n ? (override?.placeholder ?? t('indeterminate.placeholder'))\n : (override?.placeholder ?? placeholder),\n presentation: layout,\n required,\n indeterminate,\n min: override?.min,\n max: override?.max,\n step: override?.step,\n db,\n ...fieldState,\n };\n\n if (override?.hidden || ((readonly || layout === 'static') && hideEmpty && fieldState.getValue() == null)) {\n return null;\n }\n\n const resolution = resolveFieldRenderer({\n type,\n name,\n jsonPath,\n value: fieldState.getValue(),\n fieldMap,\n fieldProvider,\n fieldProps,\n refInline,\n });\n if (!resolution) {\n return null;\n }\n\n if (resolution.kind === 'custom') {\n const CustomField = resolution.component;\n return <CustomField {...fieldProps} />;\n }\n if (resolution.kind === 'provided') {\n return resolution.element;\n }\n // An array of refs the form does not own (`FormCreateAnnotation` targets render inline per element) is a\n // RefArrayField: chips (`tag`) in a field row, or (`title`) rows under a header of their own.\n const refProps = resolution.kind === 'array' ? getRefProps(type) : undefined;\n const refArray =\n refProps?.isArray && Option.isNone(Annotation.FormCreateAnnotation.getFromAst(type)) ? refProps : undefined;\n if (resolution.kind === 'array' && !refArray) {\n return <ArrayField fieldProps={fieldState} label={label} {...props} />;\n }\n const refArrayField = refArray && (\n <RefArrayField\n {...fieldProps}\n {...createOptionsFor(refArray.typename)}\n elementType={refArray.ast}\n db={db}\n useType={useType}\n getOptions={getOptions}\n onCreate={onCreate}\n resolveCreateEntry={resolveCreateEntry}\n />\n );\n if (refArray && getArrayPresentation(type, refArray.typename).display === 'title') {\n return refArrayField;\n }\n if (resolution.kind === 'object') {\n return (\n <FormFieldSet label={label} collapsible nested data-testid={`group.${jsonPath}`}>\n <FormFields\n schema={resolution.schema}\n path={path}\n readonly={readonly}\n layout={layout}\n projection={projection}\n fieldMap={fieldMap}\n fieldProvider={fieldProvider}\n db={db}\n useType={useType}\n getOptions={getOptions}\n onCreate={onCreate}\n resolveCreateEntry={resolveCreateEntry}\n />\n </FormFieldSet>\n );\n }\n\n if (resolution.kind === 'ref' && resolution.inline) {\n return <InlineRefField {...fieldProps} db={db} useType={useType} onCreate={onCreate} />;\n }\n\n const control = renderControl(resolution);\n if (control === undefined) {\n return null;\n }\n\n const { status, error } = fieldState.getStatus();\n const binding: FormFieldBinding = {\n path: jsonPath,\n type,\n value: fieldState.getValue(),\n setValue: (next) => fieldState.onValueChange(type, next),\n onBlur: fieldState.onBlur,\n status,\n error,\n indeterminate,\n required: fieldProps.required,\n readonly,\n presentation: layout,\n };\n const scalar = resolution.kind === 'scalar' ? scalarField(resolution.scalar) : undefined;\n return (\n <FormFieldRow\n label={label}\n description={description}\n format={fieldProps.format}\n binding={binding}\n standalone={refArray ? true : scalar?.standalone}\n labelPlacement={scalar?.labelPlacement}\n renderStatic={resolution.kind === 'select' ? renderSelectStatic(resolution.options, projection, name) : undefined}\n >\n {control}\n </FormFieldRow>\n );\n\n /** The form's create options (e.g. a tag's), which apply only to refs of `createTypename`. */\n function createOptionsFor(typename: string | undefined): CreateOptions {\n return !createTypename || typename === createTypename\n ? { createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap }\n : {};\n }\n\n function renderControl(resolution: FieldRendererResolution): ReactNode | undefined {\n switch (resolution.kind) {\n case 'scalar': {\n const ScalarField = scalarField(resolution.scalar);\n return ScalarField ? <ScalarField {...fieldProps} /> : undefined;\n }\n case 'select':\n return <SelectField {...fieldProps} options={selectOptions(resolution.options, projection, name)} />;\n case 'lookup':\n return resolution.combobox ? (\n <ComboboxField {...fieldProps} lookup={resolution.lookup} />\n ) : (\n <AsyncSelectField {...fieldProps} lookup={resolution.lookup} />\n );\n case 'autofill':\n return <AutofillField {...fieldProps} autofill={resolution.autofill} />;\n case 'hue':\n return <HueField {...fieldProps} />;\n case 'array':\n return refArrayField;\n case 'ref': {\n return (\n <RefField\n {...fieldProps}\n {...resolution.refProps}\n {...createOptionsFor(resolution.refProps.typename)}\n db={db}\n useType={useType}\n getOptions={getOptions}\n onCreate={onCreate}\n resolveCreateEntry={resolveCreateEntry}\n />\n );\n }\n default:\n return undefined;\n }\n }\n};\n\nFormFieldDispatch.displayName = 'Form.FieldDispatch';\n\n/** The literal options, labelled by the projection's option titles where it has them. */\nconst selectOptions = (\n options: Format.Options[],\n projection: FormFieldDispatchProps['projection'],\n name: string | null,\n) => {\n const titles = projection?.getFieldProjections().find((candidate) => candidate.field.path === name)?.props.options;\n return options.map((option) => ({\n value: option,\n label: titles?.find((candidate) => candidate.id === globalThis.String(option))?.title ?? option.toString(),\n }));\n};\n\nconst renderSelectStatic =\n (options: Format.Options[], projection: FormFieldDispatchProps['projection'], name: string | null) =>\n (value: unknown) =>\n selectOptions(options, projection, name).find((candidate) => candidate.value === value)?.label ??\n globalThis.String(value ?? '');\n\n//\n// Fields\n//\n\nconst FORM_FIELDS_NAME = 'Form.Fields';\n\n/**\n * Walks the schema at `path`: one row per property, a nested group per object. Renders no element of its own, so its\n * rows are direct children of the enclosing grid. The layout DSL (`Form.Layout`) is out of the spike's scope.\n */\nexport const FormFields = ({\n path: pathProp,\n include,\n exclude,\n sort,\n filter,\n schema: schemaProp,\n layoutName = Annotation.DEFAULT_LAYOUT_NAME,\n ...props\n}: FormFieldsProps<any>) => {\n const { form, variant: _variant, testId: _testId, ...contextProps } = useFormContext(FORM_FIELDS_NAME);\n const path = useMemo(() => toPathSegments(pathProp), [typeof pathProp === 'string' ? pathProp : pathProp?.join('.')]);\n const values = useFormValues<AnyProperties>(FORM_FIELDS_NAME, path);\n const { readonly, layout, projection, ...fieldContext } = { ...contextProps, ...props };\n const schema = useMemo(() => {\n if (schemaProp) {\n return schemaProp;\n }\n if (!form.schema) {\n return undefined;\n }\n const ast = path.length ? getSchemaAtPath(form.schema.ast, path, form.values) : form.schema.ast;\n return ast ? Schema.make<Schema.Codec<any, any>>(ast) : undefined;\n // The AST at a path changes only with the discriminator value it depends on, which `values` carries.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [schemaProp, form.schema, path, values]);\n const properties = useFormFieldsProperties({ schema, values, include, exclude, filter, sort, projection });\n if ((readonly || layout === 'static') && values == null) {\n return null;\n }\n\n // A schema carrying a layout template renders by the DSL instead of one row per property.\n const layouts = schema ? Option.getOrUndefined(Annotation.FormLayoutAnnotation.get(schema)) : undefined;\n if (schema && layouts?.[layoutName] !== undefined) {\n return (\n <FormLayout\n schema={schema}\n name={layoutName}\n path={path}\n readonly={readonly}\n layout={layout}\n projection={projection}\n {...fieldContext}\n />\n );\n }\n\n return (\n <>\n {properties.map((property) => {\n const name = property.name.toString();\n return (\n <FormFieldErrorBoundary key={name} path={[...path, name]}>\n <FormFieldDispatch\n type={property.type}\n name={name}\n path={[...path, name]}\n required={!property.isOptional}\n readonly={readonly}\n layout={layout}\n projection={projection}\n {...fieldContext}\n />\n </FormFieldErrorBoundary>\n );\n })}\n </>\n );\n};\n\nFormFields.displayName = FORM_FIELDS_NAME;\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { type PropsWithChildren, type ReactNode } from 'react';\n\nimport { type Format } from '@dxos/echo';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Typography from '@dxos/react-ui/Typography';\n\nimport { type FormFieldLabelPlacement, type FormPresentation } from '#types';\n\nimport { useFormContext } from '../hooks/index.ts';\nimport { formatStaticValue, isEmptyValue, useFormFieldBindingAt, useFormSchemaProperty } from './field-binding.tsx';\nimport { type FormFieldBinding, FormFieldBindingProvider } from './FormFieldContext.ts';\nimport { FormFieldDispatch } from './FormFieldDispatch.tsx';\nimport { presentationFor } from './presentation.tsx';\n\nconst FORM_FIELD_NAME = 'Form.Field';\n\n/** A bound value rendered as text: what a `static` presentation shows in place of the control. */\nexport const FormStaticValue = ({ value, format }: { value: unknown; format?: Format.TypeFormat }) => (\n <Typography.Text truncate>{formatStaticValue(value, format)}</Typography.Text>\n);\n\nexport type FormFieldProps<T = any> = PropsWithChildren<{\n /** Binds the row to the form model at this path; with no children the dispatcher picks the control. */\n path?: string;\n label?: string;\n description?: string;\n error?: string;\n required?: boolean;\n readonly?: boolean;\n /** The label is text rather than a `<label>`: the row holds no single control. */\n standalone?: boolean;\n /** Read-only content after the label text, a sibling of the label so its text stays exactly `label`. */\n labelEnd?: ReactNode;\n /** `beside`: the control carries its own label (a Switch), so the row draws no header. */\n labelPlacement?: FormFieldLabelPlacement;\n presentation?: FormPresentation;\n renderStatic?: (value: T | undefined) => ReactNode;\n}>;\n\n/** The leaf row, bound (`path`) or not; same contract as the current `Form.Field`. */\nexport const FormField = <T,>({ path, children, ...props }: FormFieldProps<T>) => {\n if (path !== undefined) {\n return children === undefined ? (\n <FormBoundFieldDispatch path={path} {...props} />\n ) : (\n <FormBoundField<T> path={path} {...props}>\n {children}\n </FormBoundField>\n );\n }\n return <FormFieldRow<T> {...props}>{children}</FormFieldRow>;\n};\n\nFormField.displayName = FORM_FIELD_NAME;\n\ntype FormBoundFieldProps<T> = Omit<FormFieldProps<T>, 'path'> & { path: string };\n\nconst FormBoundField = <T,>({ path, children, ...props }: FormBoundFieldProps<T>) => {\n const property = useFormSchemaProperty(FORM_FIELD_NAME, path);\n const binding = useFormFieldBindingAt<T>(FORM_FIELD_NAME, path, property, props);\n return (\n <FormFieldRow<T>\n label={props.label ?? property?.label ?? ''}\n description={props.description ?? property?.description}\n format={property?.format}\n {...props}\n binding={binding}\n >\n {children}\n </FormFieldRow>\n );\n};\n\nconst FormBoundFieldDispatch = <T,>({ path, ...props }: FormBoundFieldProps<T>) => {\n const { form: _form, variant: _variant, testId: _testId, ...context } = useFormContext(FORM_FIELD_NAME);\n const property = useFormSchemaProperty(FORM_FIELD_NAME, path);\n if (!property) {\n return null;\n }\n const segments = SchemaEx.isJsonPath(path) ? SchemaEx.splitJsonPath(path) : [];\n return (\n <FormFieldDispatch\n {...context}\n type={property.type}\n name={String(segments[segments.length - 1])}\n label={props.label}\n path={segments}\n required={props.required ?? property.required}\n readonly={props.readonly ?? context.readonly}\n layout={props.presentation ?? context.layout}\n />\n );\n};\n\nexport type FormFieldRowProps<T = any> = Omit<FormFieldProps<T>, 'path'> & {\n format?: Format.TypeFormat;\n binding?: FormFieldBinding<T>;\n};\n\n/**\n * The row: `Field.Root` holding the header (label, `labelEnd`, error mark), the description, the control and the\n * error text. In the `settings` variant it is a bordered row of the content's two tracks (AUDIT §3.2 option 1).\n */\nexport const FormFieldRow = <T,>({\n children,\n label,\n description,\n error: errorProp,\n required: requiredProp,\n readonly: readonlyProp,\n standalone,\n labelEnd,\n labelPlacement = 'above',\n presentation: presentationProp,\n renderStatic,\n format,\n binding,\n}: FormFieldRowProps<T>) => {\n const { variant = 'default', layout } = useFormContext(FORM_FIELD_NAME);\n const settings = variant === 'settings';\n const resolved = presentationFor(presentationProp ?? binding?.presentation ?? layout);\n const error = binding?.error ?? errorProp;\n const readonly = binding?.readonly ?? readonlyProp;\n // An indeterminate value is unset only for display, not missing.\n const required = binding ? binding.required && !binding.indeterminate && isEmptyValue(binding.value) : requiredProp;\n\n let control: ReactNode = children;\n if (binding && resolved.isStatic) {\n if (binding.value == null) {\n return null;\n }\n control = renderStatic?.(binding.value) ?? <FormStaticValue value={binding.value} format={format} />;\n }\n\n // A toggle labels itself, except in a settings row, whose header column holds every label.\n const showHeader = resolved.showLabel && !!label && (labelPlacement !== 'beside' || settings);\n const row = (\n <Field.Root\n layout={settings ? 'row' : 'stack'}\n level={settings ? '+1' : undefined}\n invalid={!!error}\n required={!!required}\n readOnly={readonly}\n // Focus leaving the row (not moving between its segments, steppers or triggers) marks it touched, so controls need\n // no onBlur of their own.\n onBlur={\n binding\n ? (event) => {\n if (!(event.relatedTarget instanceof Node && event.currentTarget.contains(event.relatedTarget))) {\n binding.onBlur(event);\n }\n }\n : undefined\n }\n >\n {showHeader && (\n <Field.Header>\n {standalone || readonly ? (\n <Typography.Text truncate>{label}</Typography.Text>\n ) : (\n <Field.Label>{label}</Field.Label>\n )}\n {labelEnd}\n {error && (\n <Layout.Block>\n <Icon.Icon icon='ph--warning--regular' valence='error' label={error} />\n </Layout.Block>\n )}\n </Field.Header>\n )}\n {settings && description && <Field.HelperText>{description}</Field.HelperText>}\n {control}\n {resolved.showError && error && <Field.ErrorText>{error}</Field.ErrorText>}\n </Field.Root>\n );\n\n return binding ? <FormFieldBindingProvider {...binding}>{row}</FormFieldBindingProvider> : row;\n};\n\nFormFieldRow.displayName = 'Form.FieldRow';\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { type PropsWithChildren, forwardRef, useRef } from 'react';\n\nimport { useComposedRefs } from '@dxos/react-hooks';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Dialog from '@dxos/react-ui/Dialog';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Panel from '@dxos/react-ui/Panel';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as SystemButton from '@dxos/react-ui/SystemButton';\nimport * as Util from '@dxos/react-ui/Util';\n\nimport { translationKey } from '#translations';\n\nimport { useFormContext, useKeyHandler } from '../hooks/index.ts';\nimport { FormField } from './FormField.tsx';\nimport { FormFields } from './FormFieldDispatch.tsx';\nimport { FormFieldSet } from './FormFieldSet.tsx';\nimport { FormLayoutController } from './FormLayout.tsx';\nimport { FormRoot, type FormRootProps } from './FormRoot.tsx';\n\n/** The settings variant's two tracks (AUDIT §3.2 option 1): label and description, then the control. */\nexport const SETTINGS_COLUMNS = 'minmax(0, 1fr) [control] minmax(0, 1fr)';\n\n//\n// Viewport\n//\n\nexport type FormViewportProps = PropsWithChildren<{\n /**\n * Fill the parent and scroll: the form becomes its own pane (a `Panel` whose Body is a ScrollArea around the\n * gutter Container), so it is sized, collapses its rails against its own width and hosts the scrollbar in its end\n * rail. A form already inside a scrolling gutter Container needs no Viewport.\n */\n scroll?: boolean;\n /** The pane's size when `scroll`; otherwise the form inherits its host's. */\n size?: Panel.RootProps['size'];\n /** The form keeps the reading width (`document`, the default), centred in a wider host; `full` spans the host. */\n width?: 'document' | 'full';\n gutter?: Layout.Gutter;\n}>;\n\n/**\n * The gutter Container that owns the form's rails; with `scroll`, the Body of a pane of its own. Composable, so a\n * form component can be the `asChild` child of a host that merges its layout props and ref onto it. The gutter defaults\n * to the host's: a panel's (`sm`, the form inset) or a dialog or popover body's (`inherit`, joining its rails), else `sm`.\n */\nexport const FormViewport = Util.composable<HTMLDivElement, FormViewportProps>(\n ({ children, scroll, size, width = 'document', gutter, ...props }, forwardedRef) => {\n const defaultGutter = Layout.useDefaultGutter();\n const documentWidth = width === 'document' ? width : undefined;\n return scroll ? (\n <Panel.Root\n {...props}\n size={size}\n width={documentWidth}\n gutter={gutter === 'inherit' ? undefined : gutter}\n ref={forwardedRef}\n >\n <Panel.Body asChild>\n <ScrollArea.Root>\n <ScrollArea.Viewport asChild>\n {/* The block inset keeps the last section off the pane's bottom edge when scrolled to the end. */}\n <Layout.Container padBlock>{children}</Layout.Container>\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Panel.Body>\n </Panel.Root>\n ) : (\n // Padded on the block axis as the scrolling form is, so a form in a host that scrolls it still ends a gutter in.\n <Layout.Container\n {...props}\n gutter={gutter ?? defaultGutter ?? 'sm'}\n width={documentWidth}\n padBlock\n ref={forwardedRef}\n >\n {children}\n </Layout.Container>\n );\n },\n);\n\nFormViewport.displayName = 'Form.Viewport';\n\n//\n// Content\n//\n\nexport type FormContentProps = PropsWithChildren<{}>;\n\n/**\n * The `form` element: a subgrid of its host, or in the `settings` variant a fresh template of two tracks that every\n * settings row and section below it shares. Forwards its ref so a consumer can scope its own key handling to the form.\n */\nexport const FormContent = forwardRef<HTMLDivElement, FormContentProps>(({ children }, forwardedRef) => {\n const { form, readonly, testId, variant } = useFormContext('Form.Content');\n const localRef = useRef<HTMLDivElement>(null);\n const ref = useComposedRefs(forwardedRef, localRef);\n useKeyHandler(localRef, form, { readonly });\n const settings = variant === 'settings';\n // A settings form is a reading-width column of its own tracks (the current Form's `dx-document` settings content).\n return (\n <Layout.Container\n role='form'\n gutter={settings ? 'none' : 'inherit'}\n width={settings ? 'document' : undefined}\n gap={settings ? 'lg' : 'sm'}\n columns={settings ? SETTINGS_COLUMNS : undefined}\n data-testid={testId}\n ref={ref}\n >\n {children}\n </Layout.Container>\n );\n});\n\nFormContent.displayName = 'Form.Content';\n\n//\n// Actions\n//\n\nexport type FormActionsProps = {\n submitLabel?: string;\n submitIcon?: string;\n submitDisabled?: boolean;\n};\n\nexport const FormActions = ({ submitLabel, submitDisabled }: FormActionsProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const {\n form: { canSave, onSave, onCancel },\n readonly,\n layout,\n } = useFormContext('Form.Actions');\n if (readonly || layout === 'static') {\n return null;\n }\n\n return (\n <Button.Group justify='end'>\n {onCancel && (\n <SystemButton.Cancel\n iconOnly={false}\n label={t('cancel-button.label')}\n onClick={onCancel}\n data-testid='cancel-button'\n // Inside a dialog this claims the initial focus, so a reflexive Enter dismisses rather than commits.\n {...{ [Dialog.DIALOG_AUTOFOCUS_ATTRIBUTE]: '' }}\n />\n )}\n {onSave && (\n <SystemButton.Save\n iconOnly={false}\n type='submit'\n label={submitLabel ?? t('save-button.label')}\n disabled={!canSave || submitDisabled}\n onClick={() => onSave()}\n data-testid='save-button'\n />\n )}\n </Button.Group>\n );\n};\n\nFormActions.displayName = 'Form.Actions';\n\n//\n// Submit\n//\n\nexport type FormSubmitProps = {\n label?: string;\n disabled?: boolean;\n /** Replaces Save's check, for a submit that is not a save (e.g. send). */\n icon?: string;\n /** Spins the icon while the submission is in flight. */\n busy?: boolean;\n};\n\nexport const FormSubmit = ({ label, disabled, icon, busy }: FormSubmitProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const {\n form: { canSave, onSave },\n readonly,\n layout,\n } = useFormContext('Form.Submit');\n if (readonly || layout === 'static') {\n return null;\n }\n\n const buttonProps = {\n 'type': 'submit',\n 'label': label ?? t('save-button.label'),\n 'disabled': disabled ?? !canSave,\n 'onClick': () => onSave(),\n 'data-testid': 'save-button',\n } as const;\n\n return (\n <Button.Group fill>\n {icon || busy ? (\n <Button.Root {...buttonProps} variant='primary' icon={icon ?? 'ph--check--regular'} spin={busy} />\n ) : (\n <SystemButton.Save {...buttonProps} iconOnly={false} />\n )}\n </Button.Group>\n );\n};\n\nFormSubmit.displayName = 'Form.Submit';\n\n//\n// ErrorText\n//\n\nexport const FormErrorText = ({ children }: PropsWithChildren) =>\n children ? (\n <Field.Root invalid>\n <Field.ErrorText data-testid='form.error'>{children}</Field.ErrorText>\n </Field.Root>\n ) : null;\n\nFormErrorText.displayName = 'Form.ErrorText';\n\n/** The `Form` namespace of `@dxos/react-ui-form`, rendered with the `Next` namespace of `@dxos/react-ui`; `Root` is the shared one. */\nexport const Form = {\n Root: FormRoot,\n Viewport: FormViewport,\n Content: FormContent,\n FieldSet: FormFieldSet,\n Fields: FormFields,\n Layout: FormLayoutController,\n Field: FormField,\n Actions: FormActions,\n Submit: FormSubmit,\n ErrorText: FormErrorText,\n};\n\nexport type { FormRootProps };\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\nimport type * as Schema from 'effect/Schema';\nimport React, { type PropsWithChildren, useCallback, useMemo } from 'react';\n\nimport { type Database, Filter, Obj, Ref, Tag, Type } from '@dxos/echo';\nimport { useObject, useQuery, useType } from '@dxos/echo-react';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { invariant } from '@dxos/invariant';\nimport * as Util from '@dxos/react-ui/Util';\nimport { FactoryAnnotation } from '@dxos/schema';\n\nimport { translationKey } from '#translations';\nimport { type CreateOptions, type FormFieldMap, type RefFieldDataProps } from '#types';\n\nimport { omitId } from '../util/index.ts';\nimport { HueField } from './fields/index.ts';\nimport { Form } from './Form.tsx';\nimport { FormField } from './FormField.tsx';\nimport { META_TAGS_KEY, partitionMetaTags, withMetaTags } from './meta-tags.ts';\n\n/** The tags row's create option: `Add tag “{query}”`. */\nconst CREATE_TAG_LABEL: CreateOptions['createOptionLabel'] = ['add-tag-query.label', { ns: translationKey }];\n\n/** The create form for a tag (the meta-tags row's create target): its `hue` as a hue Select. */\nconst createFieldMap: FormFieldMap = {\n hue: (props) => (\n <FormField path={props.jsonPath} label={props.label} presentation={props.presentation}>\n <HueField {...props} />\n </FormField>\n ),\n};\n\n/** The form's values: the object's properties, and its editable meta tags (an array of Tag refs, per `withMetaTags`). */\ntype ObjectFormValues = { [META_TAGS_KEY]?: readonly Ref.Ref<Tag.Tag>[] } & Record<string, unknown>;\n\ntype ObjectFormModelOptions = {\n object: Obj.Unknown;\n /** The object's snapshot; a fresh value whenever the object changes. */\n snapshot: object;\n db: Database.Database | undefined;\n};\n\n/**\n * The form model shared by `ObjectForm` and `ObjectProperties`: the object's values with its editable meta tags under\n * {@link META_TAGS_KEY}, a change handler writing changed paths (and tags) back through `Obj.update`, and a create\n * handler that adds a ref field's new target to the object's database.\n */\nconst useObjectFormModel = ({ object, snapshot, db }: ObjectFormModelOptions) => {\n const meta = Obj.getMeta(object);\n // Provider-owned tags are held out of the form and written back untouched (see `partitionMetaTags`).\n const spaceTags = useQuery(db, Filter.type(Tag.Tag));\n const { editable: tags, preserved: preservedTags } = useMemo(\n () => partitionMetaTags([...meta.tags], spaceTags),\n [meta.tags, spaceTags],\n );\n const values = useMemo(() => ({ [META_TAGS_KEY]: tags, ...snapshot }), [snapshot, tags]);\n\n // A type whose structure `Obj.make` alone cannot produce (a required backing ref) declares a `FactoryAnnotation`.\n const handleCreate = useCallback(\n (type: Type.AnyEntity, values: any): Obj.Unknown => {\n invariant(db);\n invariant(Type.isObject(type));\n const factory = Option.getOrUndefined(FactoryAnnotation.get(Type.getSchema(type)));\n const made = factory ? factory(values) : Obj.make(type, values);\n invariant(Obj.isObject(made));\n const added = db.add(made);\n invariant(Obj.isObject(added));\n return added;\n },\n [db],\n );\n\n const handleChange = useCallback(\n (\n { [META_TAGS_KEY]: metaTags, ...values }: ObjectFormValues,\n { isValid, changed }: { isValid: boolean; changed: Record<SchemaEx.JsonPath, boolean> },\n ) => {\n if (!isValid) {\n return;\n }\n\n const changedPaths = Object.keys(changed)\n .filter(SchemaEx.isJsonPath)\n .filter((path) => changed[path]);\n const isTagPath = (path: SchemaEx.JsonPath) => SchemaEx.splitJsonPath(path)[0] === META_TAGS_KEY;\n if (changedPaths.some(isTagPath)) {\n Obj.update(object, (object) => {\n // A copy, so later in-place form edits stay outside `Obj.update`; this replaces `tags`, so restore the rest.\n Obj.getMeta(object).tags = [...preservedTags, ...(metaTags ?? [])];\n });\n }\n\n const propertyPaths = changedPaths.filter((path) => !isTagPath(path));\n if (propertyPaths.length > 0) {\n Obj.update(object, (object) => {\n for (const path of propertyPaths) {\n Obj.setValue(object, SchemaEx.splitJsonPath(path), SchemaEx.getValue(values, path));\n }\n });\n }\n },\n [object, preservedTags],\n );\n\n return { values, handleCreate, handleChange };\n};\n\nexport type ObjectFormProps = {\n type: Type.AnyEntity;\n object: Obj.Unknown;\n /**\n * Overrides the rendered fields, e.g. a projection of `type`'s schema; values are still read from and written to\n * `object` by path. Defaults to `type`'s schema.\n */\n schema?: Schema.Codec<any, any>;\n /** Render the meta-tags field. Defaults to `true`. */\n showTags?: boolean;\n};\n\n/** An object's properties (and meta tags) as a next Form in its host's grid, writing each change back. */\nexport const ObjectForm = ({ object, type, schema, showTags = true }: ObjectFormProps) => {\n const db = Obj.getDatabase(object);\n // ECHO reactivity is atom-based: reading the raw object in render does not subscribe, so subscribe explicitly.\n const [snapshot] = useObject(object);\n const { values, handleCreate, handleChange } = useObjectFormModel({ object, snapshot, db });\n const formSchema = useMemo(() => {\n const base = schema ?? Type.getSchema(type);\n return showTags ? withMetaTags(base) : omitId(base);\n }, [schema, type, showTags]);\n\n return (\n <Form.Root\n schema={formSchema}\n values={values}\n db={db}\n createTypename={Type.getTypename(Tag.Tag)}\n createOptionLabel={CREATE_TAG_LABEL}\n createOptionIcon='ph--tag--regular'\n createInitialValuePath='label'\n createFieldMap={createFieldMap}\n onValuesChanged={handleChange}\n onCreate={handleCreate}\n >\n <Form.Content>\n <Form.Fields />\n </Form.Content>\n </Form.Root>\n );\n};\n\nexport type ObjectPropertiesProps = PropsWithChildren<\n { object: Obj.Unknown } & Pick<RefFieldDataProps, 'getCreateDefaults' | 'resolveCreateEntry'>\n>;\n\n/**\n * An object's properties pane: its type's fields and meta tags in a scrolling form, then `children` (e.g. a plugin's\n * extra rows) in a set of their own. Composable, so a host's `Panel.Body asChild` merges its slot props and ref onto\n * the form's viewport.\n */\nexport const ObjectProperties = Util.composable<HTMLDivElement, ObjectPropertiesProps>(\n ({ children, object, getCreateDefaults, resolveCreateEntry, ...props }, forwardedRef) => {\n const db = Obj.getDatabase(object);\n const [snapshot] = useObject(object);\n const { values, handleCreate, handleChange } = useObjectFormModel({ object, snapshot, db });\n // `Obj.getType` misses database-registered (dynamic) schemas, which `useType` resolves by the stored type URI.\n const registered = useType(db, Obj.getTypeURI(object));\n const type = Obj.getType(object) ?? registered;\n const formSchema = useMemo(() => (type ? withMetaTags(Type.getSchema(type)) : undefined), [type]);\n if (!formSchema) {\n return null;\n }\n\n return (\n <Form.Root\n schema={formSchema}\n values={values}\n db={db}\n createTypename={Type.getTypename(Tag.Tag)}\n createOptionLabel={CREATE_TAG_LABEL}\n createOptionIcon='ph--tag--regular'\n createInitialValuePath='label'\n createFieldMap={createFieldMap}\n onValuesChanged={handleChange}\n onCreate={handleCreate}\n getCreateDefaults={getCreateDefaults}\n resolveCreateEntry={resolveCreateEntry}\n >\n <Form.Viewport {...props} scroll ref={forwardedRef}>\n <Form.Content>\n <Form.Fields />\n {children && <Form.FieldSet>{children}</Form.FieldSet>}\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n },\n);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport {\n EditorState,\n type Extension,\n RangeSetBuilder,\n StateEffect,\n StateField,\n type TransactionSpec,\n} from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, WidgetType } from '@codemirror/view';\n\nimport { Domino } from '@dxos/ui';\nimport { getHashHue, getStyles, mx } from '@dxos/ui-theme';\n\n/**\n * Display info for a resolved object reference.\n */\nexport type RefInfo = {\n label: string;\n hue?: string;\n};\n\n/**\n * Content model:\n * - `'ref'`: whitespace-separated tokens; `@<id>` references to existing objects (and raw tokens\n * accepted by the pluggable {@link RefEditorExtensionOptions.match} regexp).\n * - `'email'`: comma-separated RFC 5322 mailboxes (`Name <email>` or bare `email`); the comma\n * separators are consumed into the atomic tags so they are not visible.\n */\nexport type RefEditorMode = 'ref' | 'email';\n\n/** Matches an object reference token (`@<object id>`). */\nexport const REF_REGEX = /^@([A-Za-z0-9]+)$/;\n\n/** Matches a well-formed email address token. */\nexport const EMAIL_REGEX = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$/;\n\n/** Matches an RFC 5322 name-addr (`Name <email>`); group 1 = display name, group 2 = addr-spec. */\nexport const NAME_ADDR_REGEX = /^(.*?)\\s*<([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})>$/;\n\n/** Formats an RFC 5322 mailbox (`Name <email>`). */\nexport const formatMailbox = (name: string | undefined, email: string): string => (name ? `${name} <${email}>` : email);\n\n/**\n * Effect dispatched when reference data changes out-of-band (e.g. objects finish loading) so that\n * already-rendered reference decorations re-resolve without a document change.\n */\nexport const refEditorRedecorate = StateEffect.define<null>();\n\nexport type RefEditorExtensionOptions = {\n mode?: RefEditorMode;\n /** Resolve an object id referenced as `@<id>` to display info. */\n getRef?: (id: string) => RefInfo | undefined;\n /** Pluggable raw-token matcher (e.g. {@link EMAIL_REGEX}); matching tokens render as neutral tags. */\n match?: RegExp;\n colorize?: boolean;\n};\n\n/**\n * CodeMirror extension rendering reference-editor tokens as tags. Tags are atomic: the cursor\n * cannot enter them and deletion removes the whole token.\n * - `'ref'` mode: `@<id>` references resolve to the object's label (via\n * {@link RefEditorExtensionOptions.getRef}); tokens accepted by the pluggable `match` regexp\n * render as neutral tags.\n * - `'email'` mode: RFC 5322 mailboxes render as tags labelled with the display name (falling\n * back to the address); the trailing comma separator is hidden inside the tag's atomic range.\n */\nexport const refEditor = ({ mode = 'ref', getRef, match, colorize }: RefEditorExtensionOptions = {}): Extension => {\n // Forward declaration: the field is defined below but the widgets' delete affordance (built inside\n // the field's `create`/`update`) needs to read it back at click time.\n let decoField: StateField<DecorationSet>;\n\n /** Delete the tag whose delete affordance (`node`) was clicked, keeping the delimited list well-formed. */\n const removeToken = (view: EditorView, node: HTMLElement) => {\n // Tags render in document order, so the button's index among all delete affordances selects the\n // matching decoration. (A replace-widget's inner DOM has no reliable document position to query.)\n const index = [...view.contentDOM.querySelectorAll('button[aria-label=\"Remove\"]')].indexOf(node);\n if (index < 0) {\n return;\n }\n const cursor = view.state.field(decoField).iter();\n let range: { from: number; to: number } | undefined;\n for (let current = 0; cursor.value; current++, cursor.next()) {\n if (current === index) {\n range = { from: cursor.from, to: cursor.to };\n break;\n }\n }\n if (!range) {\n return;\n }\n\n const doc = view.state.doc.toString();\n let { from } = range;\n const { to } = range;\n if (mode === 'email' && !/,\\s*$/.test(doc.slice(from, to))) {\n // A last segment carries no trailing \", \"; drop the one left dangling by the previous segment.\n const dangling = doc.slice(0, from).match(/,\\s*$/);\n if (dangling) {\n from -= dangling[0].length;\n }\n }\n view.dispatch({ changes: { from, to }, selection: { anchor: from } });\n };\n\n const buildRefDecorations = (state: EditorState) => {\n const deco = new RangeSetBuilder<Decoration>();\n const text = state.doc.toString();\n const tokenRegex = /\\S+/g;\n let tokenMatch: RegExpExecArray | null;\n while ((tokenMatch = tokenRegex.exec(text))) {\n const token = tokenMatch[0];\n const from = tokenMatch.index;\n const to = from + token.length;\n\n const refMatch = token.match(REF_REGEX);\n if (refMatch) {\n const ref = getRef?.(refMatch[1]);\n if (ref) {\n deco.add(\n from,\n to,\n Decoration.replace({\n widget: new RefWidget(\n ref.label,\n ref.hue ?? (colorize ? getHashHue(refMatch[1]) : undefined),\n removeToken,\n ),\n }),\n );\n }\n continue;\n }\n\n if (match?.test(token)) {\n deco.add(\n from,\n to,\n Decoration.replace({\n widget: new RefWidget(token, undefined, removeToken),\n }),\n );\n }\n }\n\n return deco.finish();\n };\n\n const buildEmailDecorations = (state: EditorState) => {\n const addrRegex = match ?? EMAIL_REGEX;\n const deco = new RangeSetBuilder<Decoration>();\n const text = state.doc.toString();\n // Segments are comma-separated; a segment's atomic range includes its trailing comma (and\n // following whitespace) so the separator never renders.\n const segmentRegex = /[^,]+(?:,\\s*)?|,\\s*/g;\n let segmentMatch: RegExpExecArray | null;\n while ((segmentMatch = segmentRegex.exec(text))) {\n const segment = segmentMatch[0];\n const commaIndex = segment.indexOf(',');\n const content = (commaIndex === -1 ? segment : segment.slice(0, commaIndex)).trim();\n if (!content) {\n continue;\n }\n // Only tag committed segments (those with a trailing comma). The final segment being typed has\n // no comma yet, so a valid-looking address stays plain text until the user commits it (comma,\n // space, or Enter) — otherwise the tag would pop in mid-typing.\n if (commaIndex === -1) {\n continue;\n }\n const leading = segment.length - segment.trimStart().length;\n const from = segmentMatch.index + leading;\n const to = segmentMatch.index + segment.length;\n\n const nameAddr = content.match(NAME_ADDR_REGEX);\n if (nameAddr) {\n deco.add(\n from,\n to,\n Decoration.replace({\n widget: new RefWidget(\n nameAddr[1] || nameAddr[2],\n colorize ? getHashHue(nameAddr[2]) : undefined,\n removeToken,\n ),\n }),\n );\n } else if (addrRegex.test(content)) {\n deco.add(\n from,\n to,\n Decoration.replace({\n widget: new RefWidget(content, undefined, removeToken),\n }),\n );\n }\n }\n\n return deco.finish();\n };\n\n const buildDecorations = mode === 'email' ? buildEmailDecorations : buildRefDecorations;\n\n decoField = StateField.define<DecorationSet>({\n create: (state) => buildDecorations(state),\n update: (deco, tr) => {\n if (tr.docChanged || tr.effects.some((effect) => effect.is(refEditorRedecorate))) {\n return buildDecorations(tr.state);\n }\n\n return deco;\n },\n provide: (field) => [\n EditorView.decorations.from(field),\n // Every tag is atomic: arrow motion skips the whole range and deletion removes the whole token.\n EditorView.atomicRanges.of((view) => view.state.field(field)),\n ],\n });\n\n const separator = mode === 'email' ? ', ' : ' ';\n\n // Typing immediately before a tag would otherwise re-tokenize into it (e.g. `x` + `bob@e.com`\n // parses as the single email `xbob@e.com`); inject the delimiter after the inserted text so the\n // new characters begin their own token (and open a fresh completion) rather than joining the tag.\n const separatorFilter = EditorState.transactionFilter.of((tr) => {\n if (!tr.docChanged || !tr.isUserEvent('input')) {\n return tr;\n }\n const tags = tr.startState.field(decoField, false);\n if (!tags) {\n return tr;\n }\n\n let extra: TransactionSpec | undefined;\n tr.changes.iterChanges((fromA, toA, _fromB, toB, inserted) => {\n if (extra || fromA !== toA) {\n return;\n }\n const text = inserted.toString();\n if (!text || /[\\s,]$/.test(text)) {\n return;\n }\n // A tag starting exactly at the insertion point means the new text abuts it.\n let abutsTag = false;\n for (const cursor = tags.iter(); cursor.value; cursor.next()) {\n if (cursor.from === fromA) {\n abutsTag = true;\n break;\n }\n if (cursor.from > fromA) {\n break;\n }\n }\n if (abutsTag) {\n extra = { changes: { from: toB, insert: separator }, sequential: true, selection: { anchor: toB } };\n }\n });\n\n return extra ? [tr, extra] : tr;\n });\n\n return [styles, decoField, separatorFilter];\n};\n\n/** Delete an atomic tag given the DOM node of its widget. */\ntype RemoveToken = (view: EditorView, node: HTMLElement) => void;\n\n/**\n * The outer span vertically aligns the tag with the surrounding line and adds a trailing gap so\n * adjacent tags don't touch. The inner span carries the border; `overflow-hidden` clips the child\n * fills to its radius (a square-cornered fill otherwise peeks past the rounded border).\n */\nconst container = (classNames: string, ...children: Domino<HTMLElement>[]) => {\n const inner = Domino.of('span')\n .classNames(mx('inline-flex items-stretch border rounded-xs overflow-hidden', classNames))\n .append(...children);\n return Domino.of('span').classNames('inline-flex align-middle pe-1').append(inner).root;\n};\n\n/** Trailing `x` affordance that deletes the tag it belongs to. */\nconst deleteButton = (view: EditorView, remove: RemoveToken) => {\n const button = Domino.of('button')\n .classNames('flex items-center px-1 text-fg-muted hover:text-error cursor-pointer')\n .attributes({ 'type': 'button', 'aria-label': 'Remove' })\n .append(Domino.svg('ph--x--bold').classNames('shrink-0 w-3.5 h-3.5'))\n // `mousedown` + preventDefault so clicking the affordance does not move the editor selection.\n .on('mousedown', (event) => {\n event.preventDefault();\n remove(view, button.root);\n });\n return button;\n};\n\n/**\n * Resolved reference (object reference or RFC 5322 mailbox), rendered as the object's label with a\n * trailing delete affordance.\n */\nclass RefWidget extends WidgetType {\n constructor(\n private readonly _label: string,\n private readonly _hue: string | undefined,\n private readonly _remove: RemoveToken,\n ) {\n super();\n }\n\n override eq(other: this) {\n return this._label === other._label && this._hue === other._hue;\n }\n\n override toDOM(view: EditorView) {\n const styles = this._hue ? getStyles(this._hue) : undefined;\n return container(\n mx('border-separator rounded-sm', styles?.border),\n Domino.of('span').classNames('flex items-center ps-2 pe-1').text(this._label),\n deleteButton(view, this._remove),\n );\n }\n}\n\nconst styles = EditorView.theme({\n // Single-line editor: lay the line out as a centered flex row so text runs and the atomic tag\n // widgets share a vertical center (avoids `vertical-align` baseline guesswork between the two).\n '.cm-line': {\n padding: '0',\n display: 'flex',\n alignItems: 'center',\n },\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Extension, Prec } from '@codemirror/state';\nimport { type EditorView } from '@codemirror/view';\nimport { type ForwardedRef, useCallback, useEffect, useMemo, useRef } from 'react';\n\nimport { type Database, Filter, Obj, type Type } from '@dxos/echo';\nimport { useQuery } from '@dxos/echo-react';\nimport {\n type EditorController,\n type EditorMenuProviderProps,\n type EditorViewProps,\n type UseEditorMenuProps,\n} from '@dxos/react-ui-editor';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport type * as Util from '@dxos/react-ui/Util';\nimport { createBasicExtensions, createThemeExtensions, insertAtCursor, keymap } from '@dxos/ui-editor';\nimport { getHashHue } from '@dxos/ui-theme';\n\nimport { translationKey } from '#translations';\n\nimport {\n EMAIL_REGEX,\n NAME_ADDR_REGEX,\n type RefEditorMode,\n type RefInfo,\n formatMailbox,\n refEditor,\n refEditorRedecorate,\n} from './ref-editor-extension.ts';\n\nexport type RefEditorProps = Util.ThemedClassName<\n {\n /** Database queried for objects of {@link RefEditorProps.type}. */\n db?: Database.Database;\n /** ECHO object type whose instances are offered in the typeahead and referenced as `@<id>`. */\n type: Type.AnyObj;\n value?: string;\n readonly?: boolean;\n /**\n * Content model:\n * - `'ref'` (default): the picker only matches existing objects; selection inserts an\n * `@<id>` reference (raw tokens accepted by `match` are also allowed).\n * - `'email'`: the picker shows one item per (object, value) pair and selection captures the\n * value; the content is an RFC 5322 mailbox list (`Name <email>, ...`) with the comma\n * separators hidden inside the tags.\n */\n mode?: RefEditorMode;\n /** Pluggable raw-token matcher (e.g. {@link EMAIL_REGEX}); matching tokens are accepted as values. */\n match?: RegExp;\n /** Display label for an object; defaults to `Obj.getLabel` falling back to the id. */\n getLabel?: (object: Obj.Unknown) => string;\n /** Values an object can be captured as in `'email'` mode (e.g. a person's email addresses). */\n getValues?: (object: Obj.Unknown) => readonly string[];\n /** Menu item icon. */\n icon?: string;\n /** Already-translated placeholder; defaults to a generic hint. */\n placeholder?: string;\n /** Open the typeahead while typing (the `@` trigger remains available but is not required). */\n activateOnTyping?: boolean;\n } & Omit<EditorViewProps, 'initialValue'> &\n Pick<EditorMenuProviderProps, 'numItems'>\n>;\n\n/** The RefEditor's behaviour, without its chrome: the props for an `Editor.Root` around the caller's `Editor.View`. */\nexport type RefEditorOptions = Omit<\n RefEditorProps,\n 'classNames' | 'value' | keyof Omit<EditorViewProps, 'initialValue'>\n>;\n\n/**\n * The typeahead, decorations and keymap of a {@link RefEditor} as `Editor.Root` props, so a Next control can frame the\n * same editor (`ControlFrame`) instead of the current input chrome.\n */\nexport const useRefEditor = (\n {\n db,\n type,\n readonly,\n mode = 'ref',\n match,\n getLabel,\n getValues,\n icon = 'ph--link--regular',\n placeholder: placeholderProp,\n activateOnTyping,\n numItems = 8,\n }: RefEditorOptions,\n forwardedRef: ForwardedRef<EditorController>,\n) => {\n const { t } = Hooks.useTranslation(translationKey);\n const themeMode = Hooks.useThemeMode();\n const getObjectLabel = useCallback(\n (object: Obj.Unknown) => getLabel?.(object) ?? Obj.getLabel(object) ?? object.id,\n [getLabel],\n );\n\n // Reads go through a ref so the decoration extension stays stable: recreating extensions\n // destroys and recreates the editor, which would blur the input on data changes.\n const filter = useMemo(() => Filter.type(type), [type]);\n const objects = useQuery(db, filter);\n const refs = useMemo(\n () =>\n new Map<string, RefInfo>(\n objects.map((object) => [object.id, { label: getObjectLabel(object), hue: getHashHue(object.id) }]),\n ),\n [objects, getObjectLabel],\n );\n const refsRef = useRef(refs);\n refsRef.current = refs;\n\n // Internal controller (merged with the forwarded ref) used to re-resolve reference\n // decorations when object data changes after the document was rendered.\n const controllerRef = useRef<EditorController | null>(null);\n const composedRef = useCallback(\n (controller: EditorController | null) => {\n controllerRef.current = controller;\n if (typeof forwardedRef === 'function') {\n forwardedRef(controller);\n } else if (forwardedRef) {\n forwardedRef.current = controller;\n }\n },\n [forwardedRef],\n );\n useEffect(() => {\n controllerRef.current?.view?.dispatch({ effects: refEditorRedecorate.of(null) });\n }, [refs]);\n\n const getMenu = useCallback<NonNullable<UseEditorMenuProps['getMenu']>>(\n async ({ text }) => {\n // With `activateOnTyping` (no `@` trigger) an empty query would otherwise match every object\n // and anchor the popover at the viewport origin (no range to position against). Show nothing\n // until the user types. An explicit `@` trigger still browses (its `text` is '@', not empty).\n if (!text) {\n return [];\n }\n const query = text.replace(/^@/, '').toLowerCase();\n const matchesQuery = (object: Obj.Unknown) =>\n !query ||\n getObjectLabel(object).toLowerCase().includes(query) ||\n (getValues?.(object) ?? []).some((entry) => entry.toLowerCase().includes(query));\n\n if (mode === 'email') {\n // One item per (object, value) pair; selection captures the value as an RFC 5322 mailbox.\n const mailboxes = objects\n .flatMap((object) => (getValues?.(object) ?? []).map((entry) => ({ object, entry })))\n .filter(\n ({ object, entry }) =>\n !query || getObjectLabel(object).toLowerCase().includes(query) || entry.toLowerCase().includes(query),\n );\n\n return [\n {\n id: 'mailboxes',\n items: mailboxes.slice(0, numItems * 2).map(({ object, entry }) => ({\n id: `${object.id}-${entry}`,\n label: `${getObjectLabel(object)} (${entry})`,\n icon,\n onSelect: ({ view, head }: { view: EditorView; head: number }) =>\n insertMailbox(view, head, formatMailbox(getObjectLabel(object), entry)),\n })),\n },\n ];\n }\n\n // 'ref' mode: only match existing objects.\n return [\n {\n id: 'refs',\n items: objects\n .filter(matchesQuery)\n .slice(0, numItems * 2)\n .map((object) => {\n const label = getObjectLabel(object);\n const detail = getValues?.(object)?.[0];\n return {\n id: object.id,\n label: detail && detail !== label ? `${label} (${detail})` : label,\n icon,\n onSelect: ({ view, head }: { view: EditorView; head: number }) =>\n insertAtCursor(view, head, `@${object.id} `),\n };\n }),\n },\n ];\n },\n [objects, numItems, mode, icon, getObjectLabel, getValues],\n );\n\n // NOTE: The placeholder is supplied via the popover (Editor.Root) so the trigger hint and the\n // empty-state hint are a single message; a second basic-extension placeholder would stack with it.\n // Must be referentially stable: the menu extension is memoized on it, and a new extension\n // identity destroys and recreates the editor on every keystroke.\n const placeholder = useMemo(\n () => ({\n content: placeholderProp ?? t(activateOnTyping ? 'ref-editor-auto.placeholder' : 'ref-editor.placeholder'),\n focusOnly: false,\n }),\n [t, placeholderProp, activateOnTyping],\n );\n\n const extensions = useMemo<Extension[]>(\n () => [\n createBasicExtensions({ readOnly: readonly, lineWrapping: false }),\n createThemeExtensions({\n themeMode,\n slots: {\n editor: {\n className: 'w-full',\n },\n scroller: {\n className: 'scrollbar-none',\n },\n },\n }),\n refEditor({ mode, match, getRef: (id) => refsRef.current.get(id) }),\n Prec.highest(\n keymap.of([\n {\n key: 'Enter',\n // Commit the in-progress token when it matches (insert the mode's separator, the\n // same gesture as typing it); always consume the key (single-line input).\n run: (view) => {\n const { head } = view.state.selection.main;\n const line = view.state.doc.lineAt(head);\n const before = line.text.slice(0, head - line.from);\n if (mode === 'email') {\n const segment = before.slice(before.lastIndexOf(',') + 1).trim();\n if (NAME_ADDR_REGEX.test(segment) || (match ?? EMAIL_REGEX).test(segment)) {\n insertAtCursor(view, head, ', ');\n }\n } else {\n const token = before.slice(before.search(/\\S+$/));\n if (token && match?.test(token)) {\n insertAtCursor(view, head, ' ');\n }\n }\n return true;\n },\n },\n {\n key: 'Space',\n // In email mode, a space after a bare address commits it (a tag only forms once\n // committed). A partial `Name <…` segment still needs spaces, so only commit — and\n // consume the space — when the whole in-progress segment is an address.\n run: (view) => {\n if (mode !== 'email') {\n return false;\n }\n const { head } = view.state.selection.main;\n const line = view.state.doc.lineAt(head);\n const before = line.text.slice(0, head - line.from);\n const segment = before.slice(before.lastIndexOf(',') + 1).trim();\n if ((match ?? EMAIL_REGEX).test(segment)) {\n insertAtCursor(view, head, ', ');\n return true;\n }\n return false;\n },\n },\n ]),\n ),\n ],\n [readonly, themeMode, mode, match],\n );\n\n return {\n extensions,\n numItems,\n trigger: '@',\n activateOnTyping,\n placeholder,\n // The menu owns its own matching (labels AND values); the built-in label filter would\n // drop value-matched objects whose label doesn't start with the query.\n filter: false,\n getMenu,\n ref: composedRef,\n };\n};\n\n/**\n * Insert an RFC 5322 mailbox, replacing the in-progress segment (anything typed after the last\n * comma — multi-word queries can leave words outside the popover's completion range).\n */\nconst insertMailbox = (view: EditorView, head: number, mailbox: string) => {\n const line = view.state.doc.lineAt(head);\n const before = line.text.slice(0, head - line.from);\n const lastComma = before.lastIndexOf(',');\n const from = line.from + (lastComma === -1 ? 0 : lastComma + 1);\n const insert = `${lastComma === -1 ? '' : ' '}${mailbox}, `;\n view.dispatch({\n changes: { from, to: head, insert },\n selection: { anchor: from + insert.length, head: from + insert.length },\n });\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { forwardRef } from 'react';\n\nimport { Editor, type EditorController, type EditorViewProps } from '@dxos/react-ui-editor';\nimport * as Input from '@dxos/react-ui/Input';\n\nimport { type RefEditorOptions, useRefEditor } from './useRefEditor.ts';\n\nexport type RefEditorProps = RefEditorOptions &\n Pick<EditorViewProps, 'onChange' | 'autoFocus' | 'extensions'> & {\n 'value'?: string;\n /** Leading content inside the frame (e.g. an Icon). */\n 'start'?: Input.FrameProps['start'];\n /** Trailing content inside the frame (e.g. icon-only Buttons). */\n 'end'?: Input.FrameProps['end'];\n 'data-testid'?: string;\n };\n\n/**\n * The single-line reference editor (see the current `RefEditor`) in a `ControlFrame`: the frame draws the control's\n * well, size and focus ring around the editor, which fills it between the optional adornments.\n */\nexport const RefEditor = forwardRef<EditorController, RefEditorProps>(\n ({ value, onChange, autoFocus, extensions, start, end, 'data-testid': testId, ...options }, forwardedRef) => {\n const rootProps = useRefEditor(options, forwardedRef);\n return (\n <Editor.Root {...rootProps}>\n <Input.Frame start={start} end={end} disabled={options.readonly} data-testid={testId}>\n <Editor.View\n initialValue={value}\n extensions={extensions}\n onChange={onChange}\n autoFocus={autoFocus}\n selectionEnd\n />\n </Input.Frame>\n </Editor.Root>\n );\n },\n);\n\nRefEditor.displayName = 'RefEditor';\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Filter, Obj, type Registry, Type, type View } from '@dxos/echo';\nimport { Format, FormatEnums, formatToType } from '@dxos/echo/Format';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { log } from '@dxos/log';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport {\n type ProjectionModel,\n type PropertyType,\n formatToAdditionalPropertyAttributes,\n getFormatSchema,\n} from '@dxos/schema';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldMap } from '#types';\n\nimport { getFormProperties } from '../util/index.ts';\nimport { SelectField, SelectOptionField } from './fields/index.ts';\nimport { Form, type FormRootProps } from './Form.tsx';\n\nexport type FieldEditorProps = Pick<FormRootProps<PropertyType>, 'readonly'> & {\n projection: ProjectionModel;\n field: View.FieldType;\n registry?: Registry.Registry;\n view?: Obj.Unknown;\n onSave: () => void;\n onCancel?: () => void;\n};\n\nconst omitType = (props: SchemaEx.SchemaProperty[]) => props.filter((prop) => prop.name !== 'type');\n\n/**\n * Edits a view field's projection (property, format, options, reference) on `react-ui-form`; the current\n * FieldEditor's logic with Next renderers.\n */\nexport const FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }: FieldEditorProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const [props, setProps] = useState<PropertyType>(projection.getFieldProjection(field.id).props);\n useEffect(() => setProps(projection.getFieldProjection(field.id).props), [field, projection]);\n\n const [schemas, setSchemas] = useState<Type.Type[]>([]);\n Hooks.useAsyncEffect(async () => {\n if (!registry) {\n return;\n }\n const subscription = registry\n .query(Filter.type(Type.Type))\n .subscribe((query) => setSchemas(query.results), { fire: true });\n setSchemas(await registry.query(Filter.type(Type.Type)).run());\n return () => subscription?.();\n }, [registry]);\n\n // A `Type.Type` is a class, which a state setter would call as an updater, so it is stored through a lambda.\n const [referenceSchema, setReferenceSchema] = useState<Type.Type>();\n useEffect(() => {\n setReferenceSchema(() => schemas.find((schema) => Type.getTypename(schema) === props?.referenceSchema));\n }, [schemas, props?.referenceSchema]);\n\n // Wrapped in an object for the same reason: a schema class must not reach a setter directly.\n const [{ fieldSchema }, setFieldSchema] = useState({ fieldSchema: getFormatSchema(props?.format) });\n\n const fieldMap = useMemo<FormFieldMap>(\n () => ({\n ['format' satisfies keyof PropertyType]: (fieldProps) => (\n <Form.Field path={fieldProps.jsonPath}>\n <SelectField\n {...fieldProps}\n options={FormatEnums.filter((value) => value !== Format.TypeFormat.None).map((value) => ({\n value,\n label: t(`format.${value}.label`),\n }))}\n />\n </Form.Field>\n ),\n ['referenceSchema' satisfies keyof PropertyType]: (fieldProps) => (\n <Form.Field path={fieldProps.jsonPath}>\n <SelectField\n {...fieldProps}\n options={schemas\n .map((schema) => Type.getTypename(schema))\n .filter((typename): typename is string => typename != null)\n .map((typename) => ({ value: typename }))}\n />\n </Form.Field>\n ),\n ['referencePath' satisfies keyof PropertyType]: (fieldProps) => (\n <Form.Field path={fieldProps.jsonPath}>\n <SelectField\n {...fieldProps}\n options={\n referenceSchema\n ? getFormProperties(Type.getSchema(referenceSchema).ast)\n .sort((a, b) => a.name.toString().localeCompare(b.name.toString()))\n .map((prop) => ({ value: prop.name.toString() }))\n : []\n }\n />\n </Form.Field>\n ),\n ['options' satisfies keyof PropertyType]: (fieldProps) => (\n <Form.Field path={fieldProps.jsonPath} standalone>\n <SelectOptionField {...fieldProps} />\n </Form.Field>\n ),\n }),\n [t, schemas, referenceSchema],\n );\n\n const handleValuesChanged = useCallback<NonNullable<FormRootProps<PropertyType>['onValuesChanged']>>(\n (next) => {\n setFieldSchema((previous) => {\n const fieldSchema = getFormatSchema(next.format);\n return previous.fieldSchema === fieldSchema ? previous : { fieldSchema };\n });\n setReferenceSchema((previous) => {\n if (next.referenceSchema !== (previous ? Type.getTypename(previous) : undefined)) {\n return schemas.find((schema) => Type.getTypename(schema) === next.referenceSchema) ?? previous;\n }\n return previous;\n });\n setProps((current) => {\n const type = next.format ? formatToType[next.format] : current.type;\n // The format's extra JSON-schema attributes (e.g. a currency's multipleOf), not its JSON-schema `format` string.\n const { format: _format, ...additional } = next.format ? formatToAdditionalPropertyAttributes[next.format] : {};\n return current.type !== type ? { ...current, ...next, ...additional, type } : { ...current, ...next };\n });\n },\n [schemas],\n );\n\n const handleValidate = useCallback<NonNullable<FormRootProps<PropertyType>['onValidate']>>(\n ({ property }) => {\n if (property && projection.getFields().find((other) => other.path === property && other.path !== field.path)) {\n return [{ path: 'property', message: `property is not unique: '${property}'` }];\n }\n },\n [projection, field],\n );\n\n const handleSave = useCallback<NonNullable<FormRootProps<PropertyType>['onSave']>>(\n (next) => {\n if (view) {\n // The projection writes into the view, so the write runs inside the view's update.\n Obj.update(view, (view) => {\n projection.setFieldProjection({ field, props: next });\n });\n } else {\n projection.setFieldProjection({ field, props: next });\n }\n onSave();\n },\n [projection, field, view, onSave],\n );\n\n const handleCancel = useCallback(() => {\n onSave();\n // Deferred so the form can close first.\n requestAnimationFrame(() => onCancel?.());\n }, [onSave, onCancel]);\n\n if (!fieldSchema) {\n log.warn('invalid format', { props });\n return null;\n }\n\n return (\n <Form.Root<PropertyType>\n key={field.id}\n fieldMap={fieldMap}\n autoFocus\n readonly={readonly}\n schema={fieldSchema}\n values={props}\n onValuesChanged={handleValuesChanged}\n onValidate={handleValidate}\n onSave={handleSave}\n onCancel={handleCancel}\n >\n <Form.Content>\n <Form.Fields filter={omitType} sort={['property', 'format']} />\n <Form.Actions />\n </Form.Content>\n </Form.Root>\n );\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport * as Match from 'effect/Match';\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as Struct from 'effect/Struct';\nimport React, { forwardRef, useCallback, useContext, useImperativeHandle, useMemo, useState } from 'react';\n\nimport {\n DXN,\n EID,\n Entity,\n Feed,\n Filter,\n Format,\n Obj,\n Query,\n QueryAST,\n Ref,\n type Registry,\n Type,\n View,\n} from '@dxos/echo';\nimport { useObject, useQuery } from '@dxos/echo-react';\nimport * as SchemaEx from '@dxos/effect/SchemaEx';\nimport { invariant } from '@dxos/invariant';\nimport { OrderedList } from '@dxos/react-ui-list';\nimport { QueryForm, type QueryFormProps } from '@dxos/react-ui-query';\nimport * as Banner from '@dxos/react-ui/Banner';\nimport * as Button from '@dxos/react-ui/Button';\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as Typography from '@dxos/react-ui/Typography';\nimport {\n ParentLabelAnnotation,\n ProjectionModel,\n VIEW_FIELD_LIMIT,\n createEchoChangeCallback,\n getTypeURIFromQuery,\n} from '@dxos/schema';\n\nimport { translationKey } from '#translations';\nimport { type FormFieldMap, type FormFieldRendererProps } from '#types';\n\nimport { FieldEditor } from './FieldEditor.tsx';\nimport { Form } from './Form.tsx';\nimport { FormField } from './FormField.tsx';\nimport { type FormRootProps } from './FormRoot.tsx';\n\nexport type ViewEditorProps = {\n type?: Type.AnyEntity;\n view: View.View;\n mode?: 'schema' | 'tag';\n registry?: Registry.Registry;\n onQueryChanged?: (query: QueryAST.Query, target?: EID.EID) => void;\n onDelete?: (fieldId: string) => void;\n} & Pick<QueryFormProps, 'types' | 'tags'> &\n Pick<FormRootProps<any>, 'readonly' | 'db'>;\n\nconst isJsonProp = Schema.is(SchemaEx.JsonProp);\n\n/** The view's projection model: edits write through to the ECHO view, and to the type when its schema is mutable. */\nconst useProjectionModel = (type: Type.AnyEntity | undefined, view: View.View) => {\n const atomRegistry = useContext(RegistryContext);\n return useMemo(\n () =>\n type\n ? new ProjectionModel({\n registry: atomRegistry,\n view,\n baseSchema: type.jsonSchema,\n change: createEchoChangeCallback(view, Type.getDatabase(type) != null ? type : undefined),\n })\n : null,\n [atomRegistry, type, view],\n );\n};\n\n/**\n * Edits a view on `react-ui-form`: its query (a record type, or in `tag` mode a query and target feed) and the\n * ordered list of its field projections, each opening to a `FieldEditor`. A system (read-only) schema is announced in\n * a `Banner`.\n */\nexport const ViewEditor = forwardRef<ProjectionModel | null, ViewEditorProps>(\n ({ type, view, mode = 'schema', registry, db, readonly, types, tags, onQueryChanged, onDelete }, forwardedRef) => {\n const { t } = Hooks.useTranslation(translationKey);\n const schemaReadonly = type == null || Type.getDatabase(type) == null;\n const projectionModel = useProjectionModel(type, view);\n useImperativeHandle<ProjectionModel | null, ProjectionModel | null>(forwardedRef, () => projectionModel, [\n projectionModel,\n ]);\n\n const feedTarget = Match.value(view.query.ast).pipe(\n Match.when({ type: 'from' }, ({ from }) =>\n from._tag === 'scope'\n ? Option.fromNullishOr(from.scopes.find((scope) => scope._tag === 'feed')).pipe(\n Option.map((scope) => scope.feedUri),\n Option.getOrUndefined,\n )\n : undefined,\n ),\n Match.orElse(() => undefined),\n );\n\n const feeds = useQuery(db, Filter.type(Feed.Feed));\n const targetRef = useMemo(() => {\n const targetEid = feedTarget ? EID.tryParse(feedTarget) : undefined;\n const feed = targetEid\n ? feeds.find((feed) => {\n const feedEid = Feed.getFeedUri(feed);\n return feedEid != null && EID.equals(feedEid, targetEid);\n })\n : undefined;\n return feed ? Ref.fromURI(Entity.getURI(feed)) : undefined;\n }, [feedTarget, feeds]);\n\n const viewSchema = useMemo(() => {\n const base = Schema.Struct({\n query:\n mode === 'schema'\n ? Format.URL.annotate({ title: 'Record type' })\n : QueryAST.Query.annotate({ title: 'Query' }),\n });\n\n // `Schema.mutable` is arrays-only in v4; a struct's fields are made mutable key by key.\n return mode === 'tag'\n ? Schema.Struct({\n ...base.fields,\n target: Ref.Ref(Feed.Feed).pipe(\n Schema.annotate({ title: 'Target Feed' }),\n ParentLabelAnnotation.set(true),\n Schema.optional,\n ),\n }).mapFields(Struct.map(Schema.mutableKey))\n : base.mapFields(Struct.map(Schema.mutableKey));\n }, [mode]);\n\n const viewValues = useMemo(() => {\n // Schema mode edits a typename: the version-less name of the type DXN.\n const typeUri = getTypeURIFromQuery(view.query.ast);\n const typeDxn = typeUri ? DXN.tryMake(typeUri) : undefined;\n return {\n query: mode === 'schema' ? (typeDxn ? DXN.getName(typeDxn) : (typeUri ?? '')) : view.query.ast,\n target: targetRef,\n };\n }, [mode, view.query.ast, targetRef]);\n\n const fieldMap = useMemo<FormFieldMap | undefined>(\n () => (mode === 'tag' ? { query: (props) => <QueryField {...props} types={types} tags={tags} /> } : undefined),\n [mode, types, tags],\n );\n\n const handleUpdate = useCallback(\n (values: { query?: unknown; target?: unknown }) => {\n const feed = Ref.isRef(values.target)\n ? feeds.find((feed) => Ref.isRef(values.target) && Obj.getURI(feed) === values.target.uri)\n : undefined;\n const feedDxn = feed ? Feed.getFeedUri(feed) : undefined;\n if (mode === 'schema') {\n // A db-backed type has no DXN, so its `echo:` EID is kept verbatim; a bare name is wrapped as a DXN.\n const typename = typeof values.query === 'string' ? values.query : '';\n onQueryChanged?.(Query.select(Filter.type(EID.isEID(typename) ? typename : DXN.make(typename))).ast, feedDxn);\n } else if (Schema.is(QueryAST.Query)(values.query)) {\n // A plain copy: the form's value may hold ECHO proxy arrays, which serialize as objects with numeric keys.\n onQueryChanged?.(Schema.decodeUnknownSync(QueryAST.Query)(JSON.parse(JSON.stringify(values.query))), feedDxn);\n }\n },\n [onQueryChanged, mode, feeds],\n );\n\n return (\n <Form.Root schema={viewSchema} values={viewValues} fieldMap={fieldMap} db={db} onValuesChanged={handleUpdate}>\n <Form.Content>\n {/* A read-only editor needs no notice that the schema is read-only. */}\n {schemaReadonly && !readonly && (\n <Banner.Root valence='info'>\n <Banner.Title>{t('system-schema.description')}</Banner.Title>\n </Banner.Root>\n )}\n <Form.Fields />\n {type && projectionModel && (\n <FieldList\n type={type}\n view={view}\n projectionModel={projectionModel}\n registry={registry}\n readonly={readonly}\n onDelete={(fieldId) => {\n invariant(!readonly);\n onDelete?.(fieldId);\n }}\n />\n )}\n </Form.Content>\n </Form.Root>\n );\n },\n);\n\nViewEditor.displayName = 'ViewEditor';\n\n/** The `tag` mode's query: the query builder in a standalone form row. */\nconst QueryField = ({\n type,\n label,\n getValue,\n onValueChange,\n types,\n tags,\n}: FormFieldRendererProps & Pick<QueryFormProps, 'types' | 'tags'>) => (\n <FormField label={label} standalone>\n <QueryForm\n initialQuery={getValue()}\n types={types}\n tags={tags}\n onChange={(query) => onValueChange(type, query.ast)}\n />\n </FormField>\n);\n\ntype FieldListProps = {\n type: Type.AnyEntity;\n view: View.View;\n projectionModel: ProjectionModel;\n registry?: Registry.Registry;\n readonly?: boolean;\n onDelete: (fieldId: string) => void;\n};\n\n/** The view's field projections: reorderable rows that hide, show or delete a field and open to its editor. */\nconst FieldList = ({ type, view, projectionModel, registry, readonly, onDelete }: FieldListProps) => {\n const { t } = Hooks.useTranslation(translationKey);\n const schemaReadonly = Type.getDatabase(type) == null;\n // Subscribe to the view, so edits from elsewhere re-render the list.\n const [snapshot] = useObject(view);\n const [expandedId, setExpandedId] = useState<string>();\n const fields = useMemo(\n () => (snapshot?.projection.fields ?? []).filter(Schema.is(View.FieldSchema)),\n [snapshot?.projection.fields],\n );\n\n const handleAdd = useCallback(() => {\n invariant(!readonly);\n setExpandedId(projectionModel.createFieldProjection().id);\n }, [projectionModel, readonly]);\n\n const handleMove = useCallback(\n (from: number, to: number) => {\n invariant(!readonly);\n Obj.update(view, (view) => {\n // Splice a copy rather than `arrayMove` in place, which races the kanban model.\n const next = [...view.projection.fields];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n view.projection.fields = next;\n });\n },\n [view, readonly],\n );\n\n const handleDelete = useCallback(\n (fieldId: string) => {\n setExpandedId((expanded) => (expanded === fieldId ? undefined : expanded));\n onDelete(fieldId);\n },\n [onDelete],\n );\n\n return (\n <>\n <Field.Header>\n <Typography.Text truncate>{t('fields.label')}</Typography.Text>\n {!readonly && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--plus--regular'\n label={t('add-property-button.label')}\n disabled={fields.length >= VIEW_FIELD_LIMIT}\n onClick={handleAdd}\n />\n )}\n </Field.Header>\n <OrderedList.Root\n items={fields}\n getId={(field) => field.id}\n getLabel={(field) => field.path}\n onMove={handleMove}\n readonly={!!readonly || schemaReadonly}\n >\n {({ items }) => (\n <OrderedList.Content scroll={false} gutter='inherit' aria-label={t('fields.label')}>\n {items.map((field) => {\n const hidden = field.visible === false;\n return (\n <OrderedList.Item\n key={field.id}\n id={field.id}\n canDrag={!readonly && !schemaReadonly}\n collapsible={!readonly}\n open={expandedId === field.id}\n onOpenChange={(open) => setExpandedId(open ? field.id : undefined)}\n >\n <OrderedList.DragHandle />\n <OrderedList.ItemText tone={hidden ? 'muted' : undefined}>{field.path}</OrderedList.ItemText>\n <Button.Toggle\n iconOnly\n variant='ghost'\n pressed={hidden}\n icon='ph--eye--regular'\n activeIcon='ph--eye-closed--regular'\n label={t(hidden ? 'show-field.label' : 'hide-field.label')}\n disabled={readonly || (!hidden && projectionModel.getFields().length <= 1)}\n onPressedChange={() => {\n setExpandedId(undefined);\n if (hidden) {\n // A hidden field is a schema property, so its path is a property name.\n if (isJsonProp(field.path)) {\n projectionModel.showFieldProjection(field.path);\n }\n } else {\n projectionModel.hideFieldProjection(field.id);\n }\n }}\n data-testid={hidden ? 'show-field-button' : 'hide-field-button'}\n />\n {!readonly && (\n <Button.Root\n iconOnly\n variant='ghost'\n icon='ph--x--regular'\n label={t('delete-field.label')}\n disabled={schemaReadonly || fields.length <= 1}\n onClick={() => handleDelete(field.id)}\n data-testid='field.delete'\n />\n )}\n {!readonly && (\n <OrderedList.Detail>\n <FieldEditor\n readonly={readonly || schemaReadonly}\n registry={registry}\n projection={projectionModel}\n field={field}\n onSave={() => setExpandedId(undefined)}\n />\n </OrderedList.Detail>\n )}\n </OrderedList.Item>\n );\n })}\n </OrderedList.Content>\n )}\n </OrderedList.Root>\n </>\n );\n};\n"],"mappings":"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"}