import { DependencyGraph, type RecomputeState } from './dependencyGraph'
import { cloneSketch, solveSketch } from './sketcher'
import { composeAttachmentPlacement, identityAttachmentOffset } from './attachment'
import { classifyPlanarProfile } from './geometryRuntime'
import type { ApplyPlacementInput, AttachmentSupportValue, BooleanCutInput, BooleanIntersectionInput, BooleanUnionInput, ChamferInput, CreateBoxInput, CreateConeInput, CreateCylinderInput, CreateEllipsoidInput, CreateHelixInput, CreatePrismInput, CreateSphereInput, CreateTorusInput, CreateWedgeInput, DocumentObjectSnapshot, DocumentSnapshot, DraftInput, ExtrudeInput, FilletInput, GrooveInput, LoftInput, MirrorInput, ModeledThreadInput, MultiTransformStep, NativeFeatureHistorySide, NativeMultiTransformHistoryStep, NativeTopologyHistoryInput, ObjectTopologySnapshot, PadInput, PipeInput, PlacementValue, PlanarProfile, PocketInput, Point3, RevolutionInput, ShapeHandle, ShapeQualityReport, SubshapeTopology, ThicknessInput } from './types'
import { captureNativeTopologyHistoryStages, captureSignatureTopologyHistory, composeNativeTopologyHistoryLineage } from './topologyHistory'
import { createFinalShapeOnlyNamingEvidence } from './nativeNamingEvidence'
import { createElementMapSnapshot } from './elementMap'
import { migrateTopoRefs } from './topologyReferences'

export type RecomputeExecutionStatus = 'completed' | 'failed' | 'cancelled' | 'stale'

export type RecomputeExecutionError = {
  objectId: string
  code: string
  message: string
}

export type RecomputeNodeContext = {
  documentId: string
  documentVersion: number
  generation: number
  signal: AbortSignal
  isCurrent?: () => boolean
}

export type RecomputeNodeResult = {
  status: 'success' | 'suppressed' | 'failed'
  errors?: RecomputeExecutionError[]
  updatedObject?: DocumentObjectSnapshot
}

export type RecomputeNodeExecutor = (
  object: DocumentObjectSnapshot,
  document: DocumentSnapshot,
  context: RecomputeNodeContext,
) => Promise<RecomputeNodeResult>

export type RecomputeGeometryRuntime = {
  capabilities(): { status: string }
  nativeHistoryCapabilities?(): { availability: string; operations?: string[] }
  createBox(input: CreateBoxInput): Promise<ShapeHandle>
  createCylinder(input: CreateCylinderInput): Promise<ShapeHandle>
  createSphere(input: CreateSphereInput): Promise<ShapeHandle>
  createCone(input: CreateConeInput): Promise<ShapeHandle>
  createTorus?(input: CreateTorusInput): Promise<ShapeHandle>
  createHelix?(input: CreateHelixInput): Promise<ShapeHandle>
  modeledThread?(input: ModeledThreadInput): Promise<ShapeHandle>
  createPrism?(input: CreatePrismInput): Promise<ShapeHandle>
  createWedge?(input: CreateWedgeInput): Promise<ShapeHandle>
  createEllipsoid?(input: CreateEllipsoidInput): Promise<ShapeHandle>
  applyPlacement(input: ApplyPlacementInput): Promise<ShapeHandle>
  mirror?(input: MirrorInput): Promise<ShapeHandle>
  union(input: BooleanUnionInput): Promise<ShapeHandle>
  cut(input: BooleanCutInput): Promise<ShapeHandle>
  intersection(input: BooleanIntersectionInput): Promise<ShapeHandle>
  pad(input: PadInput): Promise<ShapeHandle>
  extrude?(input: ExtrudeInput): Promise<ShapeHandle>
  pocket(input: PocketInput): Promise<ShapeHandle>
  revolution(input: RevolutionInput): Promise<ShapeHandle>
  groove?(input: GrooveInput): Promise<ShapeHandle>
  loft?(input: LoftInput): Promise<ShapeHandle>
  pipe?(input: PipeInput): Promise<ShapeHandle>
  fillet(input: FilletInput): Promise<ShapeHandle>
  chamfer(input: ChamferInput): Promise<ShapeHandle>
  draft?(input: DraftInput): Promise<ShapeHandle>
  thickness?(input: ThicknessInput): Promise<ShapeHandle>
  topology?(shape: ShapeHandle, precision?: number): Promise<SubshapeTopology>
  qualityReport?(shape: ShapeHandle): Promise<ShapeQualityReport>
  linearLength?(shape: ShapeHandle): Promise<number>
  topologyHistory?(input: NativeTopologyHistoryInput): Promise<import('./types').NativeTopologyHistoryRecords>
  release(shape: ShapeHandle): Promise<void>
}

export type RecomputeProgress = {
  generation: number
  documentVersion: number
  objectId: string
  completed: number
  total: number
  state: RecomputeState
}

export type RecomputeExecutionOptions = {
  dirtyObjectIds?: string[]
  onProgress?: (progress: RecomputeProgress) => void
}

export type RecomputeExecutionResult = {
  generation: number
  documentVersion: number
  status: RecomputeExecutionStatus
  affected: string[]
  order: string[]
  levels: string[][]
  completed: string[]
  suppressed: string[]
  failed: string[]
  skipped: string[]
  dirtyObjects: string[]
  objectStates: Record<string, RecomputeState>
  objectUpdates: DocumentObjectSnapshot[]
  errors: RecomputeExecutionError[]
}

const isAbortError = (error: unknown) => error instanceof Error && error.name === 'AbortError'

export class RecomputeCoordinator {
  private active: { generation: number; controller: AbortController } | null = null
  private generation = 0

  constructor(
    private readonly executeNode: RecomputeNodeExecutor,
    private readonly currentDocumentVersion: (documentId: string) => number | null,
  ) {}

  cancel() {
    this.active?.controller.abort()
  }

  async run(document: DocumentSnapshot, options: RecomputeExecutionOptions = {}): Promise<RecomputeExecutionResult> {
    this.active?.controller.abort()
    const controller = new AbortController()
    const generation = Math.max(this.generation, document.recompute?.generation ?? 0) + 1
    this.generation = generation
    this.active = { generation, controller }

    const graph = new DependencyGraph(document.dependencies ?? [], document.objects.map((object) => object.id))
    const dirtyObjectIds = options.dirtyObjectIds ?? document.recompute?.dirtyObjects ?? []
    const plan = graph.plan(dirtyObjectIds)
    const objectStates: Record<string, RecomputeState> = {
      ...Object.fromEntries(document.objects.map((object) => [object.id, 'up-to-date' as const])),
      ...(document.recompute?.objectStates ?? {}),
    }
    for (const objectId of plan.affected) objectStates[objectId] = 'recomputing'

    const completed: string[] = []
    const suppressed: string[] = []
    const failed: string[] = []
    const skipped: string[] = []
    const errors: RecomputeExecutionError[] = []
    const objectUpdates: DocumentObjectSnapshot[] = []
    const objectById = new Map(document.objects.map((object) => [object.id, object]))

    for (const cycle of plan.cycles) {
      const message = `Dependency cycle: ${cycle.join(' -> ')}`
      for (const objectId of cycle) {
        objectStates[objectId] = 'error'
        failed.push(objectId)
        errors.push({ objectId, code: 'DEPENDENCY_CYCLE', message })
      }
    }

    const terminalResult = (status: RecomputeExecutionStatus): RecomputeExecutionResult => {
      if (status === 'cancelled' || status === 'stale') {
        for (const objectId of plan.affected) {
          if (objectStates[objectId] !== 'up-to-date' && objectStates[objectId] !== 'suppressed' && objectStates[objectId] !== 'upstream-suppressed') objectStates[objectId] = 'touched'
        }
      }
      if (this.active?.generation === generation) this.active = null
      return {
        generation,
        documentVersion: document.version,
        status,
        affected: plan.affected,
        order: plan.order,
        levels: plan.levels,
        completed,
        suppressed,
        failed,
        skipped,
        dirtyObjects: plan.affected.filter((objectId) => objectStates[objectId] === 'touched' || objectStates[objectId] === 'recomputing' || objectStates[objectId] === 'error' || objectStates[objectId] === 'upstream-failed'),
        objectStates,
        objectUpdates,
        errors,
      }
    }

    let processed = 0
    for (const level of plan.levels) {
      if (controller.signal.aborted || this.active?.generation !== generation) return terminalResult('cancelled')
      if (this.currentDocumentVersion(document.id) !== document.version) return terminalResult('stale')

      // Nodes in a level have no dependencies on each other. Execute them together,
      // then merge outcomes in plan order so persistence and UI events stay deterministic.
      const outcomes = await Promise.all(level.map(async (objectId) => {
        const dependencies = graph.dependenciesOf(objectId)
        const failedDependency = dependencies.find((dependencyId) => objectStates[dependencyId] === 'error' || objectStates[dependencyId] === 'upstream-failed')
        if (failedDependency) return { objectId, state: 'upstream-failed' as const, error: { objectId, code: 'UPSTREAM_FAILED', message: `Dependency ${failedDependency} did not recompute successfully.` } }
        const suppressedDependency = dependencies.find((dependencyId) => objectStates[dependencyId] === 'suppressed' || objectStates[dependencyId] === 'upstream-suppressed')
        if (suppressedDependency) return { objectId, state: 'upstream-suppressed' as const }

        const object = objectById.get(objectId)
        if (!object) return { objectId, state: 'error' as const, error: { objectId, code: 'OBJECT_NOT_FOUND', message: `Document object does not exist: ${objectId}` } }

        try {
          const result = await this.executeNode(object, document, {
            documentId: document.id,
            documentVersion: document.version,
            generation,
            signal: controller.signal,
            isCurrent: () => this.active?.generation === generation && this.currentDocumentVersion(document.id) === document.version,
          })
          if (result.status === 'failed') {
            return {
              objectId,
              state: 'error' as const,
              errors: result.errors?.length ? result.errors : [{ objectId, code: 'RECOMPUTE_FAILED', message: `${objectId} failed to recompute.` }],
            }
          }
          if (result.status === 'suppressed') return { objectId, state: 'suppressed' as const }
          return { objectId, state: 'up-to-date' as const, updatedObject: result.updatedObject }
        } catch (error) {
          if (controller.signal.aborted || isAbortError(error)) return { objectId, state: 'cancelled' as const }
          return { objectId, state: 'error' as const, error: { objectId, code: 'RECOMPUTE_EXCEPTION', message: error instanceof Error ? error.message : String(error) } }
        }
      }))

      if (controller.signal.aborted || this.active?.generation !== generation) return terminalResult('cancelled')
      if (this.currentDocumentVersion(document.id) !== document.version) return terminalResult('stale')

      for (const outcome of outcomes) {
        if (outcome.state === 'cancelled') return terminalResult('cancelled')
        objectStates[outcome.objectId] = outcome.state
        processed += 1
        if (outcome.state === 'up-to-date') {
          completed.push(outcome.objectId)
          if (outcome.updatedObject) objectUpdates.push(outcome.updatedObject)
        } else if (outcome.state === 'suppressed') {
          suppressed.push(outcome.objectId)
          skipped.push(outcome.objectId)
        } else if (outcome.state === 'upstream-suppressed') {
          skipped.push(outcome.objectId)
        } else if (outcome.state === 'upstream-failed') {
          skipped.push(outcome.objectId)
          if (outcome.error) errors.push(outcome.error)
        } else {
          failed.push(outcome.objectId)
          if ('errors' in outcome && outcome.errors) errors.push(...outcome.errors)
          else if (outcome.error) errors.push(outcome.error)
        }
        options.onProgress?.({ generation, documentVersion: document.version, objectId: outcome.objectId, completed: processed, total: plan.order.length, state: outcome.state })
      }
    }

    if (this.active?.generation === generation) this.active = null
    return terminalResult(errors.length > 0 ? 'failed' : 'completed')
  }
}

export const executeFacadeRecomputeNode: RecomputeNodeExecutor = async (object, _document, context) => {
  if (context.signal.aborted) throw new DOMException('Recompute cancelled.', 'AbortError')
  if (object.properties.some((property) => property.name === 'Suppressed' && property.value === true)) return { status: 'suppressed' }
  const expressionError = object.properties.find((property) => property.expressionError)
  if (expressionError) {
    return {
      status: 'failed',
      errors: [{ objectId: object.id, code: 'EXPRESSION_ERROR', message: expressionError.expressionError as string }],
    }
  }
  if (!object.sketch) return { status: 'success' }

  const solved = solveSketch(object.sketch)
  if (solved.status === 'conflicting' || solved.status === 'invalid') {
    return {
      status: 'failed',
      errors: solved.diagnostics.map((diagnostic) => ({ objectId: object.id, code: diagnostic.code, message: diagnostic.message })),
    }
  }
  const updatedObject: DocumentObjectSnapshot = {
    ...object,
    properties: object.properties.map((property) => property.name === 'ConstraintStatus'
      ? { ...property, value: solved.status === 'solved' ? 'Fully constrained' : `Under-constrained (${solved.degreesOfFreedom} DOF)` }
      : { ...property, options: property.options ? [...property.options] : undefined }),
    sketch: cloneSketch(solved.snapshot),
  }
  return { status: 'success', updatedObject }
}

const propertyValue = (object: DocumentObjectSnapshot, name: string) => object.properties.find((property) => property.name === name)?.value

const placementComponent = (value: unknown, name: string) => {
  if (typeof value !== 'number' || !Number.isFinite(value)) throw new TypeError(`Object Placement ${name} must be finite.`)
  return value
}

const structuredValue = (value: unknown): value is Record<string, unknown> => Boolean(value) && typeof value === 'object' && !Array.isArray(value)

const placementValueForObject = (object: DocumentObjectSnapshot, propertyName = 'Placement'): PlacementValue | null => {
  const property = object.properties.find((candidate) => candidate.name === propertyName)
  if (!property) return null
  if (property.type !== 'App::PropertyPlacement') throw new TypeError(`${propertyName} must use App::PropertyPlacement.`)
  const value = property.value
  if (!structuredValue(value)) throw new TypeError(`${propertyName} has an invalid structure.`)
  const placementValue = value as Record<string, unknown>
  const positionValue = placementValue.position
  const rotationValue = placementValue.rotation
  if (!structuredValue(positionValue) || !structuredValue(rotationValue) || !structuredValue(rotationValue.axis)) throw new TypeError(`${propertyName} has an invalid structure.`)
  const positionRecord = positionValue as Record<string, unknown>
  const rotationRecord = rotationValue as Record<string, unknown>
  const axisRecord = rotationRecord.axis as Record<string, unknown>
  const position = {
    x: placementComponent(positionRecord.x, `${propertyName} position.x`),
    y: placementComponent(positionRecord.y, `${propertyName} position.y`),
    z: placementComponent(positionRecord.z, `${propertyName} position.z`),
  }
  const axis = {
    x: placementComponent(axisRecord.x, `${propertyName} rotation.axis.x`),
    y: placementComponent(axisRecord.y, `${propertyName} rotation.axis.y`),
    z: placementComponent(axisRecord.z, `${propertyName} rotation.axis.z`),
  }
  const angle = placementComponent(rotationRecord.angle, `${propertyName} rotation.angle`)
  if (Math.hypot(axis.x, axis.y, axis.z) === 0) throw new RangeError(`${propertyName} rotation axis cannot be zero.`)
  if (angle < 0 || angle > 360) throw new RangeError(`${propertyName} rotation angle must be between 0 and 360 degrees.`)
  return { position, rotation: { axis, angle } }
}

const placementForObject = (object: DocumentObjectSnapshot, document: DocumentSnapshot) => {
  const own = placementValueForObject(object)
  const offset = placementValueForObject(object, 'AttachmentOffset')
  if (!offset) {
    if (!own) return null
    if (own.position.x === 0 && own.position.y === 0 && own.position.z === 0 && own.rotation.angle === 0) return null
    return {
      translation: [own.position.x, own.position.y, own.position.z] as [number, number, number],
      rotationAxis: [own.rotation.axis.x, own.rotation.axis.y, own.rotation.axis.z] as [number, number, number],
      rotationAngle: own.rotation.angle,
    }
  }
  const supportValue = propertyValue(object, 'Support')
  const support = supportValue && typeof supportValue === 'object' && !Array.isArray(supportValue) ? supportValue as AttachmentSupportValue : null
  const supportObject = support ? document.objects.find((candidate) => candidate.id === support.objectId) : undefined
  const supportPlacement = supportObject ? placementValueForObject(supportObject) : null
  let composed = composeAttachmentPlacement(supportPlacement ?? identityAttachmentOffset(), offset)
  if (own) composed = composeAttachmentPlacement(composed, own)
  return {
    translation: [composed.position.x, composed.position.y, composed.position.z] as [number, number, number],
    rotationAxis: [composed.rotation.axis.x, composed.rotation.axis.y, composed.rotation.axis.z] as [number, number, number],
    rotationAngle: composed.rotation.angle,
  }
}

const topologyForObject = async (
  geometry: RecomputeGeometryRuntime,
  object: DocumentObjectSnapshot,
  document: DocumentSnapshot,
  shapes: Map<string, ShapeHandle>,
  shape: ShapeHandle,
  context: RecomputeNodeContext,
): Promise<ObjectTopologySnapshot | undefined> => {
  if (!geometry.topology) return undefined
  const topology = await geometry.topology(shape, 0.05)
  const previous = object.topology?.entries ?? []
  const migration = migrateTopoRefs(object.id, previous, topology.entries, context.generation, object.topology?.adjacency, topology.adjacency)
  const entries = topology.entries.map((entry, index) => ({
    ref: {
      ...migration.matches[index].current,
      shapeId: shape.id,
      topologyVersion: context.documentVersion,
      candidates: migration.matches[index].current.candidates ? [...migration.matches[index].current.candidates as string[]] : undefined,
    },
    signature: { ...entry.signature, centroid: [...entry.signature.centroid], bounds: { min: [...entry.signature.bounds.min], max: [...entry.signature.bounds.max] }, normal: [...entry.signature.normal] },
  })) as ObjectTopologySnapshot['entries']
  // The matcher may retain a previous persistent ID while the kernel adjacency
  // still uses the current raw ID. Remap every adjacency endpoint through the
  // same entry index before persisting the snapshot.
  const rawToPersisted = new Map(topology.entries.map((entry, index) => [entry.ref.persistentId, entries[index].ref.persistentId]))
  const remapAdjacency = (map: Record<string, string[]>) => Object.fromEntries(Object.entries(map).map(([key, values]) => [rawToPersisted.get(key) ?? key, values.map((value) => rawToPersisted.get(value) ?? value)]))
  const operationId = `${object.id}:generation:${context.generation}`
  const linkedSources = ['Base', 'BaseFeature', 'Tool', 'Profile', 'Source', 'Spine', 'Path']
    .map((propertyName) => linkedObject(object, propertyName, document))
    .filter((candidate): candidate is DocumentObjectSnapshot => Boolean(candidate))
    .concat(linkedObjects(object, 'Sections', document))
  const sourceObjects = [...new Map(linkedSources.map((source) => [source.id, source])).values()]
  const nativeInputs = sourceObjects
    .map((source) => ({ source, shape: shapes.get(source.id) }))
    .filter((entry): entry is { source: DocumentObjectSnapshot; shape: ShapeHandle } => Boolean(entry.shape && entry.source.topology?.entries.length))
  const property = (name: string) => propertyValue(object, name)
  const numericProperty = (name: string, fallback: number) => {
    const value = property(name)
    return typeof value === 'number' && Number.isFinite(value) ? value : fallback
  }
  const vectorProperty = (name: string, fallback: Point3): Point3 | null => {
    const value = property(name)
    if (value === undefined || value === null) return fallback
    if (!structuredValue(value)) return null
    const { x, y, z } = value as { x?: unknown; y?: unknown; z?: unknown }
    return typeof x === 'number' && Number.isFinite(x) && typeof y === 'number' && Number.isFinite(y) && typeof z === 'number' && Number.isFinite(z) ? [x, y, z] : null
  }
  const simpleHole = object.typeId === 'PartDesign::Hole'
    && (property('Type') === undefined || property('Type') === 'Dimension' || property('Type') === 'Dimensioned' || property('Type') === 0)
    && (property('HoleCutType') === undefined || property('HoleCutType') === 'None' || property('HoleCutType') === 0)
    && property('Threaded') !== true && property('Threading') !== true
    && property('Tapered') !== true
    && property('DrillPoint') !== 'Angled' && property('DrillPoint') !== 1
  const draftBaseObject = object.typeId === 'PartDesign::Draft' ? linkedObject(object, 'Base', document) : undefined
  const draftFaceSelection = draftBaseObject ? dressUpFaceIndexes(object, draftBaseObject) : undefined
  const simpleDraft = object.typeId === 'PartDesign::Draft' && !draftFaceSelection?.code && draftFaceSelection?.indexes?.length === 1
  const thicknessBaseObject = object.typeId === 'PartDesign::Thickness' ? linkedObject(object, 'Base', document) : undefined
  const thicknessFaceSelection = thicknessBaseObject ? dressUpFaceIndexes(object, thicknessBaseObject, 'RemoveFaces', 'THICKNESS') : undefined
  const simpleThickness = object.typeId === 'PartDesign::Thickness' && !thicknessFaceSelection?.code && thicknessFaceSelection?.indexes?.length === 1
  const linearPatternMode = property('Mode')
  const simpleLinearPattern = object.typeId === 'PartDesign::LinearPattern'
    && numericProperty('Occurrences', 2) === 2
    && (linearPatternMode === undefined || linearPatternMode === 'Extent' || linearPatternMode === 'Spacing' || linearPatternMode === 0 || linearPatternMode === 1)
    && (property('Direction2') === undefined || property('Direction2') === null || property('Direction2') === 'None' || property('Direction2') === '')
    && property('Spacings') === undefined && property('SpacingPattern') === undefined
  const polarPatternMode = property('Mode')
  const simplePolarPattern = object.typeId === 'PartDesign::PolarPattern'
    && numericProperty('Occurrences', 2) === 2
    && (polarPatternMode === undefined || polarPatternMode === 'Extent' || polarPatternMode === 'Spacing' || polarPatternMode === 0 || polarPatternMode === 1)
    && property('Spacings') === undefined && property('SpacingPattern') === undefined
  const mirrorPlane = property('Plane')
  const mirrorTransformMode = property('TransformMode')
  const simpleMirrored = object.typeId === 'PartDesign::Mirrored'
    && linkedObjects(object, 'Originals', document).length === 0
    && property('Fuse') !== false
    && (mirrorPlane === undefined || mirrorPlane === 'XY plane' || mirrorPlane === 'XZ plane' || mirrorPlane === 'YZ plane')
    && (mirrorTransformMode === undefined || mirrorTransformMode === 'Whole shape' || mirrorTransformMode === 'WholeShape' || mirrorTransformMode === 1)
  const parsedMultiTransform = object.typeId === 'PartDesign::MultiTransform' ? multiTransformSteps(object) : undefined
  const multiTransformMode = property('TransformMode')
  const nativeMultiTransformSteps = parsedMultiTransform && !('error' in parsedMultiTransform)
    && linkedObjects(object, 'Originals', document).length === 0
    && (multiTransformMode === undefined || multiTransformMode === 'Whole shape' || multiTransformMode === 'WholeShape' || multiTransformMode === 1)
    && parsedMultiTransform.steps.every((step) => step.type === 'mirrored' || step.occurrences === 2)
    ? parsedMultiTransform.steps : undefined
  const loftSectionCount = object.typeId === 'Part::Loft'
    ? (() => {
        const profile = property('Profile')
        const sections = property('Sections')
        return (typeof profile === 'string' ? 1 : 0) + (Array.isArray(sections) ? sections.filter((value): value is string => typeof value === 'string').length : 0)
      })()
    : 0
  const simpleStandaloneLoft = object.typeId === 'Part::Loft'
    && property('Solid') !== false
    && property('Closed') !== true
    && property('Linearize') !== true
    && (property('MaxDegree') === undefined || property('MaxDegree') === 5)
    && loftSectionCount === 2
  const pipeSections = object.typeId === 'Part::Sweep' ? linkedObjects(object, 'Sections', document) : []
  const pipeSpine = object.typeId === 'Part::Sweep' ? linkedObject(object, 'Spine', document) : undefined
  const simpleStandalonePipe = object.typeId === 'Part::Sweep'
    && property('Solid') !== false
    && property('Frenet') !== true
    && property('Linearize') !== true
    && (property('Transition') === undefined || property('Transition') === 'Transformed')
    && pipeSections.length === 1
    && Boolean(pipeSpine)
  const normalizeMultiTransformStep = (step: MultiTransformStep): NativeMultiTransformHistoryStep => {
    if (step.type === 'linear') {
      const axis: Point3 = step.direction === 'Vertical' ? [0, 1, 0] : step.direction === 'Normal' ? [0, 0, 1] : [1, 0, 0]
      return { type: 'linear', direction: [axis[0] * step.length, axis[1] * step.length, axis[2] * step.length] }
    }
    if (step.type === 'polar') {
      const axis: Point3 = step.axis === 'Horizontal' ? [1, 0, 0] : step.axis === 'Vertical' ? [0, 1, 0] : [0, 0, 1]
      return { type: 'polar', axisOrigin: [0, 0, 0], direction: axis, angle: step.angle === 360 ? 180 : step.angle }
    }
    const normal: Point3 = step.plane === 'XZ plane' ? [0, 1, 0] : step.plane === 'YZ plane' ? [1, 0, 0] : [0, 0, 1]
    return { type: 'mirrored', axisOrigin: [0, 0, 0], direction: normal }
  }
  const scaledDirection = (direction: Point3, length: number, reversed = false): Point3 | undefined => {
    const magnitude = Math.hypot(...direction)
    if (!(length > 0) || !Number.isFinite(length) || magnitude <= 0) return undefined
    const scale = length * (reversed ? -1 : 1) / magnitude
    return direction.map((coordinate) => coordinate === 0 ? 0 : coordinate * scale) as Point3
  }
  const reverseDirection = (direction: Point3) => direction.map((coordinate) => coordinate === 0 ? 0 : -coordinate) as Point3
  const nativeProfile = () => {
    const source = linkedObject(object, 'Profile', document) ?? linkedObject(object, 'Base', document) ?? linkedObject(object, 'Source', document)
    return sketchProfile(source?.sketch).profile
  }
  const linearFeatureSides = (): NativeFeatureHistorySide[] | undefined => {
    if (object.typeId === 'Part::Extrusion' || object.typeId === 'Part::Extrude') {
      const direction = vectorProperty('Dir', [0, 0, 1])
      if (!direction) return undefined
      const directionLength = Math.hypot(...direction)
      const length = numericProperty('LengthFwd', 0) > 0 ? numericProperty('LengthFwd', 0) : directionLength
      const first = scaledDirection(direction, property('Symmetric') === true ? length / 2 : length, property('Reversed') === true)
      if (!first) return undefined
      if (property('Symmetric') === true) return [{ direction: first }, { direction: reverseDirection(first) }]
      const reverseLength = numericProperty('LengthRev', 0)
      const second = reverseLength > 0 ? scaledDirection(direction, reverseLength, property('Reversed') !== true) : undefined
      return second ? [{ direction: first }, { direction: second }] : [{ direction: first }]
    }
    if (object.typeId !== 'PartDesign::Pad' && object.typeId !== 'PartDesign::Pocket') return undefined
    const type = property('Type')
    const sideType = property('SideType')
    const legacyTwoLengths = type === '?TwoLengths' || type === 'TwoLengths' || type === 'Two dimensions' || type === 4
    const twoSides = sideType === 'Two sides' || sideType === 1 || legacyTwoLengths
    const midplane = property('Midplane') === true || sideType === 'Symmetric' || sideType === 2
    const reversed = property('Reversed') === true
    const upToFace = type === 'Up to face' || type === 'UpToFace' || type === 3
    const throughAll = object.typeId === 'PartDesign::Pocket' && (type === 'Through all' || type === 'ThroughAll' || type === 1)
    if (throughAll) return undefined
    let length = numericProperty('Length', 1)
    if (upToFace) {
      const profile = nativeProfile()
      if (!profile) return undefined
      const target = linearUpToFaceLength(object, document, profile, [0, 0, reversed ? -1 : 1])
      if ('code' in target) return undefined
      length = target.length
    }
    const firstLength = midplane && !twoSides ? length / 2 : length
    const first = scaledDirection([0, 0, 1], firstLength, reversed)
    if (!first) return undefined
    if (midplane && !twoSides) return [{ direction: first }, { direction: reverseDirection(first) }]
    if (twoSides) {
      const second = scaledDirection([0, 0, 1], numericProperty('Length2', 0), !reversed)
      return second ? [{ direction: first }, { direction: second }] : undefined
    }
    return [{ direction: first }]
  }
  const angularFeatureSides = (): NativeFeatureHistorySide[] | undefined => {
    if (object.typeId === 'Part::Revolution') {
      const direction = vectorProperty('Axis', [0, 0, 1])
      const angle = numericProperty('Angle', 360)
      if (!direction || Math.hypot(...direction) <= 0 || !(angle > 0)) return undefined
      if (property('Symmetric') === true) return [
        { direction, angle: angle / 2 },
        { direction: reverseDirection(direction), angle: angle / 2 },
      ]
      return [{ direction, angle }]
    }
    if (object.typeId !== 'PartDesign::Revolution' && object.typeId !== 'PartDesign::Groove') return undefined
    const angle = numericProperty('Angle', 360)
    const angle2 = numericProperty('Angle2', 0)
    const type = property('Type')
    const twoAngles = type === 'Two angles' || type === 'TwoAngles' || type === 4 || (type === undefined && angle2 > 0)
    const midplane = property('Midplane') === true
    const direction = (property('Reversed') === true ? [0, -1, 0] : [0, 1, 0]) as Point3
    const firstAngle = midplane ? angle / 2 : angle
    if (!(firstAngle > 0)) return undefined
    const first = { direction, angle: firstAngle }
    const secondAngle = midplane ? angle / 2 : twoAngles ? angle2 : 0
    return secondAngle > 0
      ? [first, { direction: reverseDirection(direction), angle: secondAngle }]
      : [first]
  }
  const nativeLinearFeatureSides = linearFeatureSides()
  const nativeAngularFeatureSides = angularFeatureSides()
  const nativeOperation: NativeTopologyHistoryInput['operation'] = object.typeId === 'Part::Fuse' ? 'fuse'
    : object.typeId === 'Part::Cut' ? 'cut'
      : object.typeId === 'Part::Common' ? 'common'
        : (object.typeId === 'PartDesign::Fillet' || object.typeId === 'Part::Fillet') && property('UseAllEdges') === true ? 'fillet'
          : (object.typeId === 'PartDesign::Chamfer' || object.typeId === 'Part::Chamfer') && property('UseAllEdges') === true ? 'chamfer'
            : simpleHole ? 'hole'
              : simpleDraft ? 'draft'
                  : simpleThickness ? 'thickness'
                    : simpleStandaloneLoft ? 'loft'
                      : simpleStandalonePipe ? 'pipe'
                      : simpleLinearPattern ? 'linear-pattern'
                    : simplePolarPattern ? 'polar-pattern'
                      : simpleMirrored ? 'mirrored'
                        : nativeMultiTransformSteps ? 'multi-transform'
                        : (object.typeId === 'Part::Extrusion' || object.typeId === 'Part::Extrude' || object.typeId === 'PartDesign::Pad') && property('Solid') !== false && nativeLinearFeatureSides && numericProperty('TaperAngle', 0) === 0 && numericProperty('TaperAngle2', 0) === 0 ? 'pad'
                            : (object.typeId === 'Part::Revolution' || object.typeId === 'PartDesign::Revolution') && nativeAngularFeatureSides ? 'revolution'
                              : object.typeId === 'PartDesign::Pocket' && nativeLinearFeatureSides && numericProperty('TaperAngle', 0) === 0 && numericProperty('TaperAngle2', 0) === 0 ? 'pocket'
                                : object.typeId === 'PartDesign::Groove' && nativeAngularFeatureSides ? 'groove' : undefined
  const orderedNativeInputs = nativeOperation === 'pipe'
    ? [pipeSections[0], pipeSpine]
        .filter((source): source is DocumentObjectSnapshot => Boolean(source))
        .map((source) => ({ source, shape: shapes.get(source.id) }))
        .filter((entry): entry is { source: DocumentObjectSnapshot; shape: ShapeHandle } => Boolean(entry.shape && entry.source.topology?.entries.length))
    : nativeInputs
  const nativeCapabilities = geometry.nativeHistoryCapabilities?.()
  const nativeReady = !nativeCapabilities || nativeCapabilities.availability === 'available'
  const expectedNativeInputCount = nativeOperation === 'fuse' || nativeOperation === 'cut' || nativeOperation === 'common' || nativeOperation === 'pocket' || nativeOperation === 'groove' || nativeOperation === 'loft' || nativeOperation === 'pipe' ? 2 : 1
  const nativeInputsReady = orderedNativeInputs.length === expectedNativeInputCount
  const featureSides = nativeOperation === 'pad' || nativeOperation === 'pocket' ? nativeLinearFeatureSides : nativeOperation === 'revolution' || nativeOperation === 'groove' ? nativeAngularFeatureSides : undefined
  const nativeCompositionOperations = featureSides?.length === 2
    ? nativeOperation === 'pad' ? [nativeOperation, 'fuse']
      : nativeOperation === 'pocket' ? ['pocket', 'pad', 'fuse', 'cut']
        : nativeOperation === 'revolution' ? ['rotate', 'revolution']
          : nativeOperation === 'groove' ? ['rotate', 'revolution', 'cut'] : []
    : []
  const nativeCompositionReady = !nativeCapabilities?.operations || nativeCompositionOperations.every((operation) => nativeCapabilities.operations!.includes(operation))
  const nativeRecords = geometry.topologyHistory && nativeReady && nativeOperation && nativeInputsReady && nativeCompositionReady
    ? await geometry.topologyHistory({
        documentId: context.documentId,
        documentVersion: context.documentVersion,
        operationId,
        operation: nativeOperation,
        inputs: orderedNativeInputs.map(({ source, shape: inputShape }, index) => ({
          objectId: source.id,
          shape: inputShape,
          inputId: `${object.id}:input:${index}`,
          role: index === 0 ? 'object' : 'tool',
          ...(source.nativeObjectTag === undefined ? {} : { objectTag: source.nativeObjectTag }),
          namingEvidence: source.topology?.history?.namingEvidence?.at(-1),
        })),
        stages: [{ stageId: `${object.id}:stage:0`, operation: nativeOperation, inputObjectIds: orderedNativeInputs.map(({ source }) => source.id), resultObjectId: object.id, ordinal: 0 }],
        ...(object.nativeObjectTag === undefined ? {} : { resultObjectTag: object.nativeObjectTag }),
        ...(nativeOperation === 'fillet' ? { radius: numericProperty('Radius', 1) } : {}),
        ...(nativeOperation === 'chamfer' ? { distance: numericProperty('Size', numericProperty('Distance', 1)) } : {}),
        ...(nativeOperation === 'hole' ? {
          radius: numericProperty('Diameter', 2) / 2,
          depth: numericProperty('Depth', numericProperty('Length', 1)),
          position: (() => { const value = property('Position'); return structuredValue(value) && typeof (value as Record<string, unknown>).x === 'number' && typeof (value as Record<string, unknown>).y === 'number' && typeof (value as Record<string, unknown>).z === 'number' ? [(value as Record<string, number>).x, (value as Record<string, number>).y, (value as Record<string, number>).z] as Point3 : [0, 0, 0] as Point3 })(),
          direction: (() => { const value = property('Direction'); return structuredValue(value) && typeof (value as Record<string, unknown>).x === 'number' && typeof (value as Record<string, unknown>).y === 'number' && typeof (value as Record<string, unknown>).z === 'number' ? [(value as Record<string, number>).x, (value as Record<string, number>).y, (value as Record<string, number>).z] as Point3 : [0, 0, 1] as Point3 })(),
        } : {}),
        ...(nativeOperation === 'draft' ? {
          faceIndexes: draftFaceSelection!.indexes,
          angle: numericProperty('Angle', 5),
          direction: (() => { const value = property('Direction'); return structuredValue(value) && typeof (value as Record<string, unknown>).x === 'number' && typeof (value as Record<string, unknown>).y === 'number' && typeof (value as Record<string, unknown>).z === 'number' ? [(value as Record<string, number>).x, (value as Record<string, number>).y, (value as Record<string, number>).z] as Point3 : [0, 1, 0] as Point3 })(),
          axisOrigin: (() => { const value = property('NeutralPlaneOrigin'); return structuredValue(value) && typeof (value as Record<string, unknown>).x === 'number' && typeof (value as Record<string, unknown>).y === 'number' && typeof (value as Record<string, unknown>).z === 'number' ? [(value as Record<string, number>).x, (value as Record<string, number>).y, (value as Record<string, number>).z] as Point3 : [0, 0, 0] as Point3 })(),
          neutralPlaneDirection: (() => { const value = property('NeutralPlaneDirection'); return structuredValue(value) && typeof (value as Record<string, unknown>).x === 'number' && typeof (value as Record<string, unknown>).y === 'number' && typeof (value as Record<string, unknown>).z === 'number' ? [(value as Record<string, number>).x, (value as Record<string, number>).y, (value as Record<string, number>).z] as Point3 : [0, 0, 1] as Point3 })(),
          reversed: property('Reversed') === true,
        } : {}),
        ...(nativeOperation === 'thickness' ? {
          faceIndexes: thicknessFaceSelection!.indexes,
          offset: numericProperty('Value', numericProperty('Thickness', 1)),
          joinType: property('Join') === 'Intersection' ? 'Intersection' as const : 'Arc' as const,
        } : {}),
        ...(nativeOperation === 'linear-pattern' ? {
          direction: (() => {
            const directionName = property('Direction')
            const axis: Point3 = directionName === 'Vertical' ? [0, 1, 0] : directionName === 'Normal' ? [0, 0, 1] : [1, 0, 0]
            const magnitude = linearPatternMode === 'Spacing' || linearPatternMode === 1 ? numericProperty('Offset', numericProperty('Length', 20)) : numericProperty('Length', 20)
            const sign = property('Reversed') === true ? -1 : 1
            return [axis[0] * magnitude * sign, axis[1] * magnitude * sign, axis[2] * magnitude * sign] as Point3
          })(),
        } : {}),
        ...(nativeOperation === 'polar-pattern' ? {
          axisOrigin: [0, 0, 0] as Point3,
          direction: (() => {
            const axisName = property('Axis')
            const axis: Point3 = axisName === 'Horizontal' ? [1, 0, 0] : axisName === 'Vertical' ? [0, 1, 0] : [0, 0, 1]
            const sign = property('Reversed') === true ? -1 : 1
            return [axis[0] * sign, axis[1] * sign, axis[2] * sign] as Point3
          })(),
          angle: (() => {
            const extent = numericProperty('Angle', 360)
            return polarPatternMode === 'Spacing' || polarPatternMode === 1 ? numericProperty('Offset', extent / 2) : extent === 360 ? 180 : extent
          })(),
        } : {}),
        ...(nativeOperation === 'mirrored' ? {
          axisOrigin: [0, 0, 0] as Point3,
          direction: mirrorPlane === 'XZ plane' ? [0, 1, 0] as Point3 : mirrorPlane === 'YZ plane' ? [1, 0, 0] as Point3 : [0, 0, 1] as Point3,
        } : {}),
        ...(nativeOperation === 'multi-transform' && nativeMultiTransformSteps ? (() => {
          const normalized = nativeMultiTransformSteps.map(normalizeMultiTransformStep)
          if (normalized.length >= 2) return { transforms: normalized }
          const [step] = normalized
          return step.type === 'linear'
            ? { transformKind: step.type, direction: step.direction }
            : step.type === 'polar'
              ? { transformKind: step.type, axisOrigin: step.axisOrigin, direction: step.direction, angle: step.angle }
              : { transformKind: step.type, axisOrigin: step.axisOrigin, direction: step.direction }
        })() : {}),
        ...(nativeOperation === 'pad' || nativeOperation === 'pocket' ? { featureSides: nativeLinearFeatureSides, direction: nativeLinearFeatureSides![0].direction } : {}),
        ...(nativeOperation === 'revolution' ? { featureSides: nativeAngularFeatureSides, axisOrigin: vectorProperty('Base', [0, 0, 0]) ?? [0, 0, 0] as Point3, direction: nativeAngularFeatureSides![0].direction, angle: nativeAngularFeatureSides![0].angle } : {}),
        ...(nativeOperation === 'groove' ? { featureSides: nativeAngularFeatureSides, axisOrigin: [0, 0, 0] as Point3, direction: nativeAngularFeatureSides![0].direction, angle: nativeAngularFeatureSides![0].angle } : {}),
        ...(nativeOperation === 'loft' ? { ruled: property('Ruled') === true } : {}),
        result: shape,
      })
    : undefined
  const fallbackHistoryInputs = [
    ...sourceObjects.filter((source) => source.topology && source.topology.entries.length > 0).map((source) => ({ objectId: source.id, entries: source.topology!.entries })),
    ...(previous.length > 0 ? [{ objectId: object.id, entries: previous }] : []),
  ].filter((input, index, all) => all.findIndex((candidate) => candidate.objectId === input.objectId) === index)
  let history: ObjectTopologySnapshot['history']
  let elementMapHistory: ObjectTopologySnapshot['history']
  if (nativeRecords) {
    const stageCaptures = nativeRecords.stageCaptures
    if (stageCaptures?.length) {
      const sourceTopology = new Map(orderedNativeInputs.map(({ source }) => [source.id, source.topology!]))
      const stageTopology = new Map(stageCaptures.map((capture) => [capture.resultObjectId, capture.topology]))
      elementMapHistory = captureNativeTopologyHistoryStages(operationId, stageCaptures.map((capture, index) => ({
        stageId: capture.stageId,
        operationId: `${operationId}:native-stage:${index}`,
        ordinal: capture.ordinal,
        inputs: capture.inputObjectIds.map((objectId) => {
          const source = sourceTopology.get(objectId)
          if (source) return { objectId, entries: source.entries, adjacency: source.adjacency }
          const intermediate = stageTopology.get(objectId)
          if (!intermediate) throw new RangeError(`Native topology history stage ${capture.stageId} references unavailable result ${objectId}.`)
          const sourceStage = stageCaptures.find((candidate) => candidate.resultObjectId === objectId)
          return { objectId, entries: intermediate.entries, adjacency: intermediate.adjacency, sourceStageId: sourceStage?.stageId }
        }),
        output: index === stageCaptures.length - 1 ? entries : capture.topology.entries,
        outputAdjacency: index === stageCaptures.length - 1 ? topology.adjacency : capture.topology.adjacency,
        records: capture.records,
        resultObjectId: capture.resultObjectId,
        namingEvidence: capture.namingEvidence,
      })))
    } else {
      elementMapHistory = captureNativeTopologyHistoryStages(operationId, [{
        stageId: `${object.id}:stage:0`,
        operationId,
        ordinal: 0,
        inputs: orderedNativeInputs.map(({ source }) => ({ objectId: source.id, entries: source.topology!.entries, adjacency: source.topology!.adjacency })),
        output: entries,
        outputAdjacency: topology.adjacency,
        records: nativeRecords,
        resultObjectId: object.id,
        namingEvidence: createFinalShapeOnlyNamingEvidence(`${object.id}:stage:0`, object.id),
      }])
    }
    history = composeNativeTopologyHistoryLineage(
      operationId,
      elementMapHistory,
      orderedNativeInputs.flatMap(({ source }) => source.topology?.history ? [{ objectId: source.id, history: source.topology.history }] : []),
    )
  } else {
    history = captureSignatureTopologyHistory(operationId, fallbackHistoryInputs, entries)
    elementMapHistory = history
  }
  const sourceElementMaps = new Map(sourceObjects.map((source) => [source.id, source.topology?.elementMap]))
  const nativeNamingEvidence = nativeRecords
    ? nativeRecords.stageCaptures?.flatMap((capture) => capture.namingEvidence ? [capture.namingEvidence] : []) ?? [createFinalShapeOnlyNamingEvidence(`${object.id}:stage:0`, object.id)]
    : undefined
  const elementMap = createElementMapSnapshot(object.topology?.elementMap, object.id, entries, elementMapHistory, sourceElementMaps, nativeNamingEvidence)
  return {
    shapeId: shape.id,
    documentVersion: context.documentVersion,
    generation: context.generation,
    entries,
    adjacency: topology.adjacency ? {
      faceNeighbors: remapAdjacency(topology.adjacency.faceNeighbors),
      faceEdges: remapAdjacency(topology.adjacency.faceEdges),
      edgeFaces: remapAdjacency(topology.adjacency.edgeFaces),
      edgeVertices: remapAdjacency(topology.adjacency.edgeVertices),
      vertexEdges: remapAdjacency(topology.adjacency.vertexEdges),
    } : undefined,
    migration: {
      previousGeneration: object.topology?.generation ?? null,
      matches: migration.matches.map((match) => ({ ...match, current: { ...match.current, candidates: match.current.candidates ? [...match.current.candidates] : undefined } })),
    },
    history,
    elementMap,
  }
}
const linkedObject = (object: DocumentObjectSnapshot, name: string, document: DocumentSnapshot) => {
  const value = propertyValue(object, name)
  const record = structuredValue(value) ? value as Record<string, unknown> : undefined
  const id = typeof value === 'string' ? value : record && typeof record.objectId === 'string' ? record.objectId : undefined
  return id ? document.objects.find((candidate) => candidate.id === id) : undefined
}

const linkedObjects = (object: DocumentObjectSnapshot, name: string, document: DocumentSnapshot) => {
  const value = propertyValue(object, name)
  if (!Array.isArray(value) || value.some((candidate) => typeof candidate !== 'string')) return []
  const byId = new Map(document.objects.map((candidate) => [candidate.id, candidate]))
  return (value as string[]).map((id) => byId.get(id)).filter((candidate): candidate is DocumentObjectSnapshot => Boolean(candidate))
}

const linearUpToFaceLength = (
  object: DocumentObjectSnapshot,
  document: DocumentSnapshot,
  profile: PlanarProfile,
  direction: Point3,
): { length: number } | { code: string; message: string } => {
  const value = propertyValue(object, 'UpToFace')
  if (!structuredValue(value)) return { code: 'UP_TO_FACE_REFERENCE_MISSING', message: 'Up-to-face requires one stable face TopoRef.' }
  const link = value as Record<string, unknown>
  const rawRefs = Array.isArray(link.subElements) ? link.subElements : [link]
  if (rawRefs.length !== 1 || !structuredValue(rawRefs[0])) return { code: 'UP_TO_FACE_REFERENCE_INVALID', message: 'Up-to-face requires exactly one stable face TopoRef.' }
  const ref = rawRefs[0] as Record<string, unknown>
  const objectId = typeof ref.objectId === 'string' ? ref.objectId : typeof link.objectId === 'string' ? link.objectId : undefined
  if (!objectId || ref.kind !== 'face' || typeof ref.persistentId !== 'string') return { code: 'UP_TO_FACE_REFERENCE_INVALID', message: 'Up-to-face reference must identify one face on a document object.' }
  if (ref.status === 'ambiguous' || ref.status === 'deleted') return { code: 'UP_TO_FACE_REFERENCE_UNRESOLVED', message: `Up-to-face reference is ${String(ref.status)} and must be repaired before recompute.` }
  const target = document.objects.find((candidate) => candidate.id === objectId)
  const face = target?.topology?.entries.find((entry) => entry.ref.kind === 'face' && entry.ref.persistentId === ref.persistentId && entry.ref.status !== 'deleted')
  if (!target || !face) return { code: 'UP_TO_FACE_REFERENCE_MISSING', message: 'Up-to-face target is not present in the current topology snapshot.' }
  const analyticType = face.signature.analytic?.type?.toLowerCase()
  if (analyticType && analyticType !== 'plane') return { code: 'UP_TO_FACE_NON_PLANAR', message: 'Up-to-face currently requires a planar target face.' }
  const directionLength = Math.hypot(...direction)
  const normalized = direction.map((coordinate) => coordinate / directionLength) as Point3
  const normalLength = Math.hypot(...face.signature.normal)
  if (normalLength <= 1e-9) return { code: 'UP_TO_FACE_NON_PLANAR', message: 'Up-to-face target has no stable planar normal.' }
  const alignment = Math.abs(face.signature.normal.reduce((sum, coordinate, index) => sum + coordinate / normalLength * normalized[index], 0))
  if (alignment < 1 - 1e-6) return { code: 'UP_TO_FACE_NOT_PARALLEL', message: 'Up-to-face target plane must be perpendicular to the feature direction.' }
  const origin = profile.outer[0]
  const length = face.signature.centroid.reduce((sum, coordinate, index) => sum + (coordinate - origin[index]) * normalized[index], 0)
  if (!(length > 1e-7) || !Number.isFinite(length)) return { code: 'UP_TO_FACE_BEHIND_PROFILE', message: 'Up-to-face target must lie in the active feature direction.' }
  return { length }
}

const pointsEqual = (left: [number, number, number], right: [number, number, number], tolerance = 1e-7) => left.every((value, index) => Math.abs(value - right[index]) <= tolerance)

type ProfilePoint = [number, number, number]

const profileSignedArea = (ring: ProfilePoint[]) => ring.reduce((area, point, index) => {
  const next = ring[(index + 1) % ring.length]
  return area + point[0] * next[1] - next[0] * point[1]
}, 0) / 2

const profilePointInRing = (point: ProfilePoint, ring: ProfilePoint[]) => {
  let inside = false
  for (let index = 0, previous = ring.length - 1; index < ring.length; previous = index, index += 1) {
    const left = ring[index]
    const right = ring[previous]
    if ((left[1] > point[1]) !== (right[1] > point[1]) && point[0] < (right[0] - left[0]) * (point[1] - left[1]) / (right[1] - left[1]) + left[0]) inside = !inside
  }
  return inside
}

const segmentIntersection = (a: ProfilePoint, b: ProfilePoint, c: ProfilePoint, d: ProfilePoint) => {
  const abX = b[0] - a[0]
  const abY = b[1] - a[1]
  const cdX = d[0] - c[0]
  const cdY = d[1] - c[1]
  const denominator = abX * cdY - abY * cdX
  if (Math.abs(denominator) <= 1e-9) return null
  const acX = c[0] - a[0]
  const acY = c[1] - a[1]
  const first = (acX * cdY - acY * cdX) / denominator
  const second = (acX * abY - acY * abX) / denominator
  if (first <= 1e-9 || first >= 1 - 1e-9 || second <= 1e-9 || second >= 1 - 1e-9) return null
  return { first, second }
}

const polygonizeProfileRing = (ring: ProfilePoint[]) => {
  const splitParameters = ring.map(() => [0, 1])
  for (let first = 0; first < ring.length; first += 1) {
    for (let second = first + 1; second < ring.length; second += 1) {
      if (second === first + 1 || (first === 0 && second === ring.length - 1)) continue
      const intersection = segmentIntersection(ring[first], ring[(first + 1) % ring.length], ring[second], ring[(second + 1) % ring.length])
      if (!intersection) continue
      splitParameters[first].push(intersection.first)
      splitParameters[second].push(intersection.second)
    }
  }

  const pointByKey = new Map<string, ProfilePoint>()
  const neighbors = new Map<string, Set<string>>()
  const pointKey = (point: ProfilePoint) => point.map((coordinate) => coordinate.toFixed(9)).join(':')
  const addEdge = (left: ProfilePoint, right: ProfilePoint) => {
    const leftKey = pointKey(left)
    const rightKey = pointKey(right)
    if (leftKey === rightKey) return
    pointByKey.set(leftKey, left)
    pointByKey.set(rightKey, right)
    if (!neighbors.has(leftKey)) neighbors.set(leftKey, new Set())
    if (!neighbors.has(rightKey)) neighbors.set(rightKey, new Set())
    neighbors.get(leftKey)?.add(rightKey)
    neighbors.get(rightKey)?.add(leftKey)
  }
  for (let index = 0; index < ring.length; index += 1) {
    const start = ring[index]
    const end = ring[(index + 1) % ring.length]
    const parameters = [...new Set(splitParameters[index].map((value) => Number(value.toFixed(12))))].sort((left, right) => left - right)
    for (let split = 0; split < parameters.length - 1; split += 1) {
      const interpolate = (parameter: number): ProfilePoint => start.map((coordinate, axis) => coordinate + (end[axis] - coordinate) * parameter) as ProfilePoint
      addEdge(interpolate(parameters[split]), interpolate(parameters[split + 1]))
    }
  }

  const orderedNeighbors = new Map([...neighbors].map(([key, values]) => {
    const origin = pointByKey.get(key) as ProfilePoint
    return [key, [...values].sort((leftKey, rightKey) => {
      const left = pointByKey.get(leftKey) as ProfilePoint
      const right = pointByKey.get(rightKey) as ProfilePoint
      return Math.atan2(left[1] - origin[1], left[0] - origin[0]) - Math.atan2(right[1] - origin[1], right[0] - origin[0])
    })] as const
  }))
  const visited = new Set<string>()
  const faces: ProfilePoint[][] = []
  for (const [start, destinations] of orderedNeighbors) {
    for (const destination of destinations) {
      if (visited.has(`${start}>${destination}`)) continue
      const cycle: ProfilePoint[] = []
      let previous = start
      let current = destination
      const startEdge = `${start}>${destination}`
      for (let guard = 0; guard <= pointByKey.size * 4; guard += 1) {
        const edge = `${previous}>${current}`
        if (visited.has(edge) && edge !== startEdge) break
        visited.add(edge)
        cycle.push(pointByKey.get(previous) as ProfilePoint)
        const options = orderedNeighbors.get(current) ?? []
        const reverseIndex = options.indexOf(previous)
        if (reverseIndex < 0 || options.length === 0) break
        const next = options[(reverseIndex - 1 + options.length) % options.length]
        previous = current
        current = next
        if (`${previous}>${current}` === startEdge) {
          if (cycle.length >= 3 && profileSignedArea(cycle) > 1e-9) faces.push(cycle)
          break
        }
      }
    }
  }
  return faces
}

const profileFromRings = (rings: ProfilePoint[][]): PlanarProfile | null => {
  const simpleRings = rings.flatMap(polygonizeProfileRing).sort((left, right) => Math.abs(profileSignedArea(right)) - Math.abs(profileSignedArea(left)))
  if (simpleRings.length === 0) return null
  const enclosing = simpleRings.map((ring, index) => simpleRings.map((candidate, candidateIndex) => ({ candidate, candidateIndex }))
    .filter(({ candidate, candidateIndex }) => candidateIndex !== index && Math.abs(profileSignedArea(candidate)) > Math.abs(profileSignedArea(ring)) + 1e-9 && profilePointInRing(ring[0], candidate))
    .map(({ candidateIndex }) => candidateIndex))
  const depth = enclosing.map((containers) => containers.length)
  const parent = enclosing.map((containers) => containers.reduce((best, candidate) => best < 0 || Math.abs(profileSignedArea(simpleRings[candidate])) < Math.abs(profileSignedArea(simpleRings[best])) ? candidate : best, -1))
  const regions = simpleRings.map((outer, index) => ({ outer, index })).filter(({ index }) => depth[index] % 2 === 0).map(({ outer, index }) => ({
    outer,
    holes: simpleRings.filter((_, candidate) => parent[candidate] === index && depth[candidate] % 2 === 1),
  }))
  if (regions.length === 0) return null
  const [primary, ...additionalRegions] = regions
  return { outer: primary.outer, ...(primary.holes.length > 0 ? { holes: primary.holes } : {}), ...(additionalRegions.length > 0 ? { additionalRegions } : {}) }
}

export const sketchProfile = (sketch: DocumentObjectSnapshot['sketch']): { profile?: PlanarProfile; code?: string; message?: string } => {
  if (!sketch) return { code: 'PROFILE_MISSING', message: 'Feature profile does not reference a Sketcher object.' }
  const geometry = sketch.geometry.filter((candidate) => !candidate.construction)
  if (geometry.some((candidate) => candidate.type !== 'line')) return { code: 'PROFILE_UNSUPPORTED', message: 'OCCT feature recompute currently requires a closed line-loop sketch profile.' }
  const remaining = geometry.filter((candidate): candidate is Extract<typeof candidate, { type: 'line' }> => candidate.type === 'line').slice()
  if (remaining.length < 3) return { code: 'PROFILE_OPEN', message: 'Feature profile requires at least three connected line segments.' }
  const rings: [number, number, number][][] = []
  while (remaining.length > 0) {
    const first = remaining.shift() as Extract<typeof geometry[number], { type: 'line' }>
    const ring: [number, number, number][] = [[first.start.x, first.start.y, 0]]
    let current: [number, number, number] = [first.end.x, first.end.y, 0]
    ring.push(current)
    while (!pointsEqual(current, ring[0])) {
      const index = remaining.findIndex((segment) => pointsEqual([segment.start.x, segment.start.y, 0], current) || pointsEqual([segment.end.x, segment.end.y, 0], current))
      if (index < 0) return { code: 'PROFILE_OPEN', message: 'Feature profile line segments do not form closed loops.' }
      const segment = remaining.splice(index, 1)[0]
      current = pointsEqual([segment.start.x, segment.start.y, 0], current) ? [segment.end.x, segment.end.y, 0] : [segment.start.x, segment.start.y, 0]
      ring.push(current)
    }
    ring.pop()
    if (ring.length < 3) return { code: 'PROFILE_DEGENERATE', message: 'Feature profile contains a loop with fewer than three edges.' }
    rings.push(ring)
  }
  const profile = profileFromRings(rings)
  if (!profile) return { code: 'PROFILE_DEGENERATE', message: 'Feature profile does not contain a bounded planar region.' }
  const classification = classifyPlanarProfile(profile)
  if (classification.status === 'self-intersecting') return { code: 'PROFILE_SELF_INTERSECTING', message: 'Feature profile could not split all self-intersecting edges into bounded regions.' }
  if (classification.status === 'invalid-nesting') return { code: 'PROFILE_INVALID_NESTING', message: 'Feature profile contains a region whose holes are not directly nested.' }
  if (classification.status === 'degenerate') return { code: 'PROFILE_DEGENERATE', message: 'Feature profile contains a degenerate loop.' }
  if (classification.status === 'non-planar') return { code: 'PROFILE_NON_PLANAR', message: 'Feature profile loops must be coplanar.' }
  return { profile }
}

const transformPoint = (point: [number, number, number], placement: ApplyPlacementInput['placement'] | null): [number, number, number] => {
  if (!placement) return [...point]
  const axisLength = Math.hypot(...placement.rotationAxis)
  const axis = placement.rotationAxis.map((coordinate) => coordinate / axisLength) as [number, number, number]
  const angle = placement.rotationAngle * Math.PI / 180
  const cosine = Math.cos(angle)
  const sine = Math.sin(angle)
  const axisDot = axis[0] * point[0] + axis[1] * point[1] + axis[2] * point[2]
  const axisCross: [number, number, number] = [
    axis[1] * point[2] - axis[2] * point[1],
    axis[2] * point[0] - axis[0] * point[2],
    axis[0] * point[1] - axis[1] * point[0],
  ]
  return point.map((coordinate, index) => coordinate * cosine + axisCross[index] * sine + axis[index] * axisDot * (1 - cosine) + placement.translation[index]) as [number, number, number]
}

const transformProfile = (profile: PlanarProfile, placement: ApplyPlacementInput['placement'] | null): PlanarProfile => {
  return {
    ...profile,
    outer: profile.outer.map((point) => transformPoint(point, placement)),
    holes: profile.holes?.map((ring) => ring.map((point) => transformPoint(point, placement))),
    additionalRegions: profile.additionalRegions?.map((region) => ({
      outer: region.outer.map((point) => transformPoint(point, placement)),
      holes: region.holes?.map((ring) => ring.map((point) => transformPoint(point, placement))),
    })),
  }
}

const sketchPath = (object: DocumentObjectSnapshot | undefined, document: DocumentSnapshot): { path?: [number, number, number][]; code?: string; message?: string } => {
  if (!object?.sketch) return { code: 'PIPE_PATH_MISSING', message: 'Pipe Spine/Path does not reference a Sketcher object.' }
  const geometry = object.sketch.geometry.filter((candidate) => !candidate.construction)
  if (geometry.some((candidate) => candidate.type !== 'line')) return { code: 'PIPE_PATH_UNSUPPORTED', message: 'Simple Pipe currently requires a connected line-segment path.' }
  const segments = geometry.filter((candidate): candidate is Extract<typeof candidate, { type: 'line' }> => candidate.type === 'line')
  if (segments.length < 1) return { code: 'PIPE_PATH_EMPTY', message: 'Pipe path requires at least one line segment.' }
  const endpoints = segments.flatMap((segment): [number, number, number][] => [[segment.start.x, segment.start.y, 0], [segment.end.x, segment.end.y, 0]])
  const unique = endpoints.filter((point, index) => endpoints.findIndex((candidate) => pointsEqual(candidate, point)) === index)
  const degrees = unique.map((point) => ({ point, degree: endpoints.filter((candidate) => pointsEqual(candidate, point)).length }))
  if (degrees.some(({ degree }) => degree > 2)) return { code: 'PIPE_PATH_BRANCH', message: 'Pipe path must not branch.' }
  const openEnds = degrees.filter(({ degree }) => degree === 1)
  if (openEnds.length !== 0 && openEnds.length !== 2) return { code: 'PIPE_PATH_DISCONNECTED', message: 'Pipe path must be one connected open or closed chain.' }
  const remaining = [...segments]
  const canonicalOpenEnds = [...openEnds].sort((left, right) => left.point[0] - right.point[0] || left.point[1] - right.point[1] || left.point[2] - right.point[2])
  let current = canonicalOpenEnds[0]?.point ?? [segments[0].start.x, segments[0].start.y, 0] as [number, number, number]
  const path: [number, number, number][] = [[...current]]
  while (remaining.length > 0) {
    const index = remaining.findIndex((segment) => pointsEqual([segment.start.x, segment.start.y, 0], current) || pointsEqual([segment.end.x, segment.end.y, 0], current))
    if (index < 0) return { code: 'PIPE_PATH_DISCONNECTED', message: 'Pipe path line segments are disconnected.' }
    const segment = remaining.splice(index, 1)[0]
    current = pointsEqual([segment.start.x, segment.start.y, 0], current) ? [segment.end.x, segment.end.y, 0] : [segment.start.x, segment.start.y, 0]
    path.push(current)
  }
  const placement = placementForObject(object, document)
  return { path: path.map((point) => transformPoint(point, placement)) }
}

const pipeDefinition = (object: DocumentObjectSnapshot, document: DocumentSnapshot): { profile?: PlanarProfile; path?: [number, number, number][]; code?: string; message?: string } => {
  if (object.typeId === 'Part::Sweep' && propertyValue(object, 'Solid') === false) return { code: 'PIPE_SHELL_UNSUPPORTED', message: 'Part::Sweep Solid=false requires a shell result that the Bitbybit pipe contract does not expose.' }
  if (object.typeId === 'Part::Sweep' && propertyValue(object, 'Frenet') === true) return { code: 'PIPE_FRENET_UNSUPPORTED', message: 'Part::Sweep Frenet=true is not exposed by the Bitbybit pipe contract.' }
  if (propertyValue(object, 'Linearize') === true) return { code: 'PIPE_LINEARIZE_UNSUPPORTED', message: 'Part::Sweep Linearize=true is not exposed by the Bitbybit pipe contract.' }
  const transition = propertyValue(object, 'Transition')
  if (transition !== undefined && transition !== 'Transformed' && transition !== 0) return { code: 'PIPE_TRANSITION_UNSUPPORTED', message: `Bitbybit 1.1.1 does not expose FreeCAD Pipe transition mode: ${String(transition)}` }
  const mode = propertyValue(object, 'Mode')
  if (mode !== undefined && mode !== 'Standard' && mode !== 0) return { code: 'PIPE_ORIENTATION_UNSUPPORTED', message: `Bitbybit 1.1.1 does not expose FreeCAD Pipe orientation mode: ${String(mode)}` }
  const transformation = propertyValue(object, 'Transformation')
  if (transformation !== undefined && transformation !== 'Constant' && transformation !== 0) return { code: 'PIPE_TRANSFORMATION_UNSUPPORTED', message: `Bitbybit 1.1.1 does not expose FreeCAD Pipe transformation mode: ${String(transformation)}` }
  if (propertyValue(object, 'AuxiliarySpine')) return { code: 'PIPE_AUXILIARY_SPINE_UNSUPPORTED', message: 'Bitbybit 1.1.1 simple Pipe does not expose an auxiliary spine.' }
  const spineValue = propertyValue(object, 'Spine')
  if (spineValue && typeof spineValue === 'object' && !Array.isArray(spineValue) && 'subElements' in spineValue && Array.isArray(spineValue.subElements) && spineValue.subElements.length > 0) return { code: 'PIPE_SPINE_SUBELEMENT_UNSUPPORTED', message: 'Part::Sweep Spine sub-element filtering is not exposed by the current Sketch path adapter.' }
  const profileLink = linkedObject(object, 'Profile', document)
  const sectionLinks = linkedObjects(object, 'Sections', document)
  if (!profileLink && sectionLinks.length !== 1) return { code: 'PIPE_PROFILE_MISSING', message: 'Pipe requires one Profile link or exactly one Sections link.' }
  if (!profileLink && Array.isArray(propertyValue(object, 'Sections')) && (propertyValue(object, 'Sections') as string[]).length !== sectionLinks.length) return { code: 'PIPE_PROFILE_NOT_FOUND', message: 'Pipe section profile link does not resolve to an object.' }
  const profileObject = profileLink ?? sectionLinks[0]
  const parsedProfile = sketchProfile(profileObject?.sketch)
  if (!parsedProfile.profile) return { code: parsedProfile.code || 'PROFILE_INVALID', message: parsedProfile.message || 'Pipe profile is invalid.' }
  const pathObject = linkedObject(object, 'Spine', document) ?? linkedObject(object, 'Path', document)
  const parsedPath = sketchPath(pathObject, document)
  if (!parsedPath.path) return parsedPath
  return { profile: transformProfile(parsedProfile.profile, placementForObject(profileObject as DocumentObjectSnapshot, document)), path: parsedPath.path }
}

const loftSections = (object: DocumentObjectSnapshot, document: DocumentSnapshot): { sections?: PlanarProfile[]; code?: string; message?: string } => {
  const profileValue = propertyValue(object, 'Profile')
  const sectionsValue = propertyValue(object, 'Sections')
  if (profileValue !== undefined && typeof profileValue !== 'string') return { code: 'LOFT_SECTIONS_INVALID', message: 'Loft Profile must be an object link.' }
  if (!Array.isArray(sectionsValue) || sectionsValue.some((candidate) => typeof candidate !== 'string')) return { code: 'LOFT_SECTIONS_INVALID', message: 'Loft Sections must be a LinkList.' }
  const ids = [...(typeof profileValue === 'string' ? [profileValue] : []), ...sectionsValue]
  if (ids.length < 2) return { code: 'LOFT_SECTIONS_MISSING', message: 'Loft requires at least two linked section sketches.' }
  if (new Set(ids).size !== ids.length) return { code: 'LOFT_SECTIONS_DUPLICATE', message: 'Loft section links must be unique.' }
  const sections: PlanarProfile[] = []
  for (const id of ids) {
    const sectionObject = document.objects.find((candidate) => candidate.id === id)
    if (!sectionObject) return { code: 'LOFT_SECTION_NOT_FOUND', message: `Loft section object does not exist: ${id}` }
    const parsed = sketchProfile(sectionObject.sketch)
    if (!parsed.profile) return { code: parsed.code || 'PROFILE_INVALID', message: `Loft section ${id}: ${parsed.message || 'profile is invalid.'}` }
    sections.push(transformProfile(parsed.profile, placementForObject(sectionObject, document)))
  }
  return { sections }
}

const geometryFailure = (objectId: string, code: string, message: string): RecomputeNodeResult => ({ status: 'failed', errors: [{ objectId, code, message }] })

const dressUpEdgeIndexes = (
  object: DocumentObjectSnapshot,
  baseObject: DocumentObjectSnapshot,
): { indexes?: number[]; code?: string; message?: string } => {
  if (propertyValue(object, 'UseAllEdges') === true) return {}
  const value = propertyValue(object, 'Base')
  if (!structuredValue(value)) return { code: 'DRESSUP_EDGE_SELECTION_MISSING', message: 'Dress-up Base must contain a stable edge TopoRef, or UseAllEdges must be true.' }
  const link = value as Record<string, unknown>
  const rawRefs = Array.isArray(link.subElements) ? link.subElements : [link]
  if (rawRefs.length === 0) return { code: 'DRESSUP_EDGE_SELECTION_MISSING', message: 'Dress-up Base does not contain any selected edges.' }
  if (rawRefs.some((entry) => !structuredValue(entry))) return { code: 'DRESSUP_LEGACY_SUBELEMENT_UNRESOLVED', message: 'Imported FreeCAD sub-element names require TopoRef binding before dress-up recompute.' }
  const refs = rawRefs as Array<Record<string, unknown>>
  if (link.objectId !== baseObject.id || refs.some((ref) => ref.objectId !== baseObject.id || ref.kind !== 'edge' || typeof ref.persistentId !== 'string')) return { code: 'DRESSUP_EDGE_REFERENCE_INVALID', message: 'Dress-up Base must reference edges on one linked base object.' }
  const unresolved = refs.find((ref) => ref.status === 'ambiguous' || ref.status === 'deleted')
  if (unresolved) return { code: 'DRESSUP_EDGE_REFERENCE_UNRESOLVED', message: `Dress-up edge TopoRef is ${String(unresolved.status)} and must be repaired before recompute.` }
  const edges = baseObject.topology?.entries.filter((entry) => entry.ref.kind === 'edge')
  if (!edges?.length) return { code: 'DRESSUP_TOPOLOGY_MISSING', message: 'Dress-up base requires a current edge topology snapshot.' }
  const indexes = refs.map((ref) => edges.findIndex((entry) => entry.ref.persistentId === ref.persistentId && entry.ref.status !== 'deleted'))
  const missingIndex = indexes.findIndex((index) => index < 0)
  if (missingIndex >= 0) return { code: 'DRESSUP_EDGE_REFERENCE_MISSING', message: `Dress-up edge is not present in the current topology: ${String(refs[missingIndex].persistentId)}` }
  return { indexes: [...new Set(indexes)] }
}

const dressUpFaceIndexes = (
  object: DocumentObjectSnapshot,
  baseObject: DocumentObjectSnapshot,
  referenceProperty = 'Base',
  operation = 'DRAFT',
): { indexes?: number[]; code?: string; message?: string } => {
  if (operation === 'DRAFT' && propertyValue(object, 'UseAllFaces') === true) return {}
  const value = propertyValue(object, referenceProperty)
  const label = operation === 'THICKNESS' ? 'Thickness RemoveFaces' : 'Draft Base'
  if (!structuredValue(value)) return { code: `${operation}_FACE_SELECTION_MISSING`, message: `${label} must contain a stable face TopoRef${operation === 'DRAFT' ? ', or UseAllFaces must be true' : ''}.` }
  const link = value as Record<string, unknown>
  const rawRefs = Array.isArray(link.subElements) ? link.subElements : [link]
  if (rawRefs.length === 0) return { code: `${operation}_FACE_SELECTION_MISSING`, message: `${label} does not contain any selected faces.` }
  if (rawRefs.some((entry) => !structuredValue(entry))) return { code: `${operation}_LEGACY_SUBELEMENT_UNRESOLVED`, message: `Imported FreeCAD sub-element names require TopoRef binding before ${operation.toLowerCase()} recompute.` }
  const refs = rawRefs as Array<Record<string, unknown>>
  if (link.objectId !== baseObject.id || refs.some((ref) => ref.objectId !== baseObject.id || ref.kind !== 'face' || typeof ref.persistentId !== 'string')) return { code: `${operation}_FACE_REFERENCE_INVALID`, message: `${label} must reference faces on one linked base object.` }
  const unresolved = refs.find((ref) => ref.status === 'ambiguous' || ref.status === 'deleted')
  if (unresolved) return { code: `${operation}_FACE_REFERENCE_UNRESOLVED`, message: `${operation === 'THICKNESS' ? 'Thickness remove' : 'Draft'} face TopoRef is ${String(unresolved.status)} and must be repaired before recompute.` }
  const faces = baseObject.topology?.entries.filter((entry) => entry.ref.kind === 'face')
  if (!faces?.length) return { code: `${operation}_TOPOLOGY_MISSING`, message: `${label} requires a current face topology snapshot.` }
  const indexes = refs.map((ref) => faces.findIndex((entry) => entry.ref.persistentId === ref.persistentId && entry.ref.status !== 'deleted'))
  const missingIndex = indexes.findIndex((index) => index < 0)
  if (missingIndex >= 0) return { code: `${operation}_FACE_REFERENCE_MISSING`, message: `${operation === 'THICKNESS' ? 'Thickness remove' : 'Draft'} face is not present in the current topology: ${String(refs[missingIndex].persistentId)}` }
  return { indexes: [...new Set(indexes)] }
}

const multiTransformSteps = (object: DocumentObjectSnapshot): { steps: MultiTransformStep[] } | { error: string } => {
  const value = propertyValue(object, 'Transformations')
  if (!structuredValue(value)) return { error: 'Transformations requires an ordered step list.' }
  const record = value as Record<string, unknown>
  if (!Array.isArray(record.steps)) return { error: 'Transformations requires an ordered step list.' }
  if (record.steps.length < 1 || record.steps.length > 6) return { error: 'Transformations requires between 1 and 6 steps.' }
  const ids = new Set<string>()
  const steps: MultiTransformStep[] = []
  let instances = 1
  for (const rawStep of record.steps) {
    if (!structuredValue(rawStep) || typeof rawStep.id !== 'string' || !rawStep.id.trim() || ids.has(rawStep.id)) return { error: 'Transformation step IDs must be non-empty and unique.' }
    ids.add(rawStep.id)
    if (rawStep.type === 'linear') {
      if (!Number.isSafeInteger(rawStep.occurrences) || (rawStep.occurrences as number) < 2 || (rawStep.occurrences as number) > 10) return { error: 'Linear occurrences must be an integer between 2 and 10.' }
      if (typeof rawStep.length !== 'number' || !Number.isFinite(rawStep.length) || rawStep.length <= 0) return { error: 'Linear length must be greater than zero.' }
      if (!['Horizontal', 'Vertical', 'Normal'].includes(String(rawStep.direction))) return { error: 'Linear direction is invalid.' }
      instances *= rawStep.occurrences as number
      steps.push({ id: rawStep.id, type: 'linear', occurrences: rawStep.occurrences as number, length: rawStep.length, direction: rawStep.direction as 'Horizontal' | 'Vertical' | 'Normal' })
    } else if (rawStep.type === 'polar') {
      if (!Number.isSafeInteger(rawStep.occurrences) || (rawStep.occurrences as number) < 2 || (rawStep.occurrences as number) > 10) return { error: 'Polar occurrences must be an integer between 2 and 10.' }
      if (typeof rawStep.angle !== 'number' || !Number.isFinite(rawStep.angle) || rawStep.angle <= 0 || rawStep.angle > 360) return { error: 'Polar angle must be greater than zero and no more than 360 degrees.' }
      if (!['Horizontal', 'Vertical', 'Normal'].includes(String(rawStep.axis))) return { error: 'Polar axis is invalid.' }
      instances *= rawStep.occurrences as number
      steps.push({ id: rawStep.id, type: 'polar', occurrences: rawStep.occurrences as number, angle: rawStep.angle, axis: rawStep.axis as 'Horizontal' | 'Vertical' | 'Normal' })
    } else if (rawStep.type === 'mirrored') {
      if (!['XY plane', 'XZ plane', 'YZ plane'].includes(String(rawStep.plane))) return { error: 'Mirror plane is invalid.' }
      instances *= 2
      steps.push({ id: rawStep.id, type: 'mirrored', plane: rawStep.plane as 'XY plane' | 'XZ plane' | 'YZ plane' })
    } else return { error: 'Transformation step type is invalid.' }
    if (instances > 100) return { error: 'Multi-transform cannot create more than 100 instances.' }
  }
  return { steps }
}

const numericListProperty = (object: DocumentObjectSnapshot, name: string): { values?: number[]; error?: string } => {
  const value = propertyValue(object, name)
  if (value === undefined || value === null) return {}
  if (!Array.isArray(value) || !value.every((entry) => typeof entry === 'number' && Number.isFinite(entry))) return { error: `${name} must contain only finite numbers.` }
  return { values: value as number[] }
}

const linearPatternSteps = (occurrences: number, mode: unknown, extent: number, offset: number, spacings: number[] | undefined, spacingPattern: number[] | undefined): { distances?: number[]; error?: string } => {
  const isSpacing = mode === 'Spacing' || mode === 1
  if (!isSpacing) return { distances: Array.from({ length: occurrences }, (_, index) => extent * index / (occurrences - 1)) }
  if (!(offset > 0)) return { error: 'Linear pattern spacing offset must be greater than zero.' }
  const targetCount = occurrences - 1
  const explicit = spacings ? [...spacings] : []
  if (explicit.length > targetCount) return { error: `Spacings must contain at most ${targetCount} values.` }
  while (explicit.length < targetCount) explicit.push(-1)
  if (explicit.some((value) => value !== -1 && !(value > 0))) return { error: 'Linear pattern custom spacings must be positive, or -1 to use the fallback.' }
  const pattern = spacingPattern ?? []
  if (pattern.some((value) => !(value > 0))) return { error: 'Linear pattern spacing pattern values must be positive.' }
  const distances = [0]
  let cumulative = 0
  for (let index = 1; index < occurrences; index += 1) {
    const individual = explicit[index - 1]
    const value = individual !== -1 ? individual : pattern.length > 1 ? pattern[(index - 1) % pattern.length] : offset
    cumulative += value
    distances.push(cumulative)
  }
  return { distances }
}

const polarPatternSteps = (occurrences: number, mode: unknown, extent: number, offset: number, spacings: number[] | undefined, spacingPattern: number[] | undefined): { angles?: number[]; error?: string } => {
  const isSpacing = mode === 'Spacing' || mode === 1
  if (!isSpacing) {
    const step = extent === 360 ? extent / occurrences : extent / (occurrences - 1)
    return { angles: Array.from({ length: occurrences }, (_, index) => step * index) }
  }
  if (!(offset > 0)) return { error: 'Polar pattern spacing offset must be greater than zero.' }
  const targetCount = occurrences - 1
  const explicit = spacings ? [...spacings] : []
  if (explicit.length > targetCount) return { error: `Polar Spacings must contain at most ${targetCount} values.` }
  while (explicit.length < targetCount) explicit.push(-1)
  if (explicit.some((value) => value !== -1 && !(value > 0))) return { error: 'Polar custom spacings must be positive, or -1 to use the fallback.' }
  const pattern = spacingPattern ?? []
  if (pattern.some((value) => !(value > 0))) return { error: 'Polar spacing pattern values must be positive.' }
  const angles = [0]
  let cumulative = 0
  for (let index = 1; index < occurrences; index += 1) {
    const individual = explicit[index - 1]
    const value = individual !== -1 ? individual : pattern.length > 1 ? pattern[(index - 1) % pattern.length] : offset
    cumulative += value
    angles.push(cumulative)
  }
  return { angles }
}

const unionOwnedShapes = async (
  geometry: RecomputeGeometryRuntime,
  context: { documentId: string; documentVersion: number },
  shapes: ShapeHandle[],
  keepEdges = false,
): Promise<ShapeHandle> => {
  if (shapes.length < 2) throw new RangeError('A composed feature requires at least two transient solids.')
  try {
    return await geometry.union({ ...context, shapes, keepEdges })
  } finally {
    await Promise.allSettled(shapes.map((shape) => geometry.release(shape)))
  }
}

/**
 * Adds real OCCT feature execution without putting transient ShapeHandles in the
 * persisted document snapshot. The map is deliberately owned by the Facade and
 * keeps the last successful shape when a later feature fails.
 */
export const createFacadeGeometryRecomputeExecutor = (
  geometry: RecomputeGeometryRuntime,
  shapes: Map<string, ShapeHandle> = new Map(),
): RecomputeNodeExecutor => async (object, document, context) => {
  const base = await executeFacadeRecomputeNode(object, document, context)
  if (base.status === 'suppressed') {
    const previous = shapes.get(object.id)
    shapes.delete(object.id)
    if (previous) await geometry.release(previous)
    return base
  }
  if (base.status === 'failed' || object.sketch || geometry.capabilities().status !== 'ready') return base
  if (!['Part::Box', 'Part::Cylinder', 'Part::Sphere', 'Part::Ellipsoid', 'Part::Cone', 'Part::Torus', 'Part::Helix', 'Part::Prism', 'Part::Wedge', 'Part::Fuse', 'Part::Cut', 'Part::Common', 'Part::Extrusion', 'Part::Extrude', 'Part::Revolution', 'Part::Loft', 'Part::Sweep', 'Part::Fillet', 'Part::Chamfer', 'PartDesign::Pad', 'PartDesign::Pocket', 'PartDesign::Revolution', 'PartDesign::Groove', 'PartDesign::AdditiveLoft', 'PartDesign::SubtractiveLoft', 'PartDesign::AdditivePipe', 'PartDesign::SubtractivePipe', 'PartDesign::Fillet', 'PartDesign::Chamfer', 'PartDesign::Draft', 'PartDesign::Thickness', 'PartDesign::Mirrored', 'PartDesign::MultiTransform', 'PartDesign::LinearPattern', 'PartDesign::PolarPattern', 'PartDesign::Hole'].includes(object.typeId)) return base

  const requiresProfile = object.typeId === 'Part::Extrusion' || object.typeId === 'Part::Extrude' || object.typeId === 'Part::Revolution' || object.typeId === 'PartDesign::Pad' || object.typeId === 'PartDesign::Pocket' || object.typeId === 'PartDesign::Revolution' || object.typeId === 'PartDesign::Groove'
  const profileObject = requiresProfile
    ? linkedObject(object, 'Profile', document) ?? linkedObject(object, 'Base', document) ?? linkedObject(object, 'Source', document)
    : undefined
  const profile = requiresProfile ? sketchProfile(profileObject?.sketch) : { profile: undefined }
  if (requiresProfile && !profile.profile) return geometryFailure(object.id, profile.code || 'PROFILE_INVALID', profile.message || 'Feature profile is invalid.')
  if (context.signal.aborted) throw new DOMException('Recompute cancelled.', 'AbortError')

  const numberProperty = (name: string, fallback: number) => {
    const value = propertyValue(object, name)
    return typeof value === 'number' && Number.isFinite(value) ? value : fallback
  }
  const vectorProperty = (name: string, fallback: Point3): Point3 | null => {
    const value = propertyValue(object, name)
    if (value === undefined || value === null) return fallback
    if (!structuredValue(value)) return null
    const { x, y, z } = value as { x?: unknown; y?: unknown; z?: unknown }
    return typeof x === 'number' && Number.isFinite(x) && typeof y === 'number' && Number.isFinite(y) && typeof z === 'number' && Number.isFinite(z)
      ? [x, y, z]
      : null
  }
  const documentContext = { documentId: context.documentId, documentVersion: context.documentVersion }
  const featureTransformMode = (value: unknown) => value === 'Features' || value === 'Feature' || value === 0
  const wholeTransformMode = (value: unknown) => value === undefined || value === null || value === 'Whole shape' || value === 'WholeShape' || value === 1
  const additiveTransformTypes = new Set(['PartDesign::Pad', 'PartDesign::Revolution', 'PartDesign::AdditiveLoft', 'PartDesign::AdditivePipe'])
  const subtractiveTransformTypes = new Set(['PartDesign::Pocket', 'PartDesign::Groove', 'PartDesign::SubtractiveLoft', 'PartDesign::SubtractivePipe', 'PartDesign::Hole'])
  const validateFeatureTransformSources = (sources: DocumentObjectSnapshot[]) => {
    if (sources.length === 0) return 'Feature transform mode requires at least one Original feature.'
    for (const source of sources) {
      if (!additiveTransformTypes.has(source.typeId) && !subtractiveTransformTypes.has(source.typeId)) return `Only additive and subtractive PartDesign features can be transformed; ${source.id} is ${source.typeId}.`
      if (!shapes.get(source.id)) return `Original feature ${source.id} has no valid recomputed Shape.`
      if (subtractiveTransformTypes.has(source.typeId)) {
        const sourceBase = linkedObject(source, 'Base', document) ?? linkedObject(source, 'BaseFeature', document)
        if (!sourceBase || !shapes.get(sourceBase.id)) return `Subtractive Original feature ${source.id} has no valid base Shape.`
      }
    }
    return null
  }
  const applyFeatureTransforms = async (
    support: ShapeHandle,
    sources: DocumentObjectSnapshot[],
    transformCopies: (tool: ShapeHandle) => Promise<ShapeHandle[]>,
  ) => {
    let current = support
    let currentOwned = false
    try {
      for (const source of sources) {
        const sourceShape = shapes.get(source.id) as ShapeHandle
        const sourceBase = linkedObject(source, 'Base', document) ?? linkedObject(source, 'BaseFeature', document)
        const sourceBaseShape = sourceBase ? shapes.get(sourceBase.id) : undefined
        const subtractive = subtractiveTransformTypes.has(source.typeId)
        let tool = sourceShape
        let toolOwned = false
        const copies: ShapeHandle[] = []
        try {
          if (subtractive) {
            tool = await geometry.cut({ ...documentContext, base: sourceBaseShape as ShapeHandle, tools: [sourceShape], keepEdges: true })
            toolOwned = true
          } else if (sourceBaseShape) {
            tool = await geometry.cut({ ...documentContext, base: sourceShape, tools: [sourceBaseShape], keepEdges: true })
            toolOwned = true
          }
          copies.push(...await transformCopies(tool))
          if (copies.length === 0) throw new Error('Feature transform did not create any transformed occurrence.')
          const next = subtractive
            ? await geometry.cut({ ...documentContext, base: current, tools: copies, keepEdges: true })
            : await geometry.union({ ...documentContext, shapes: [current, ...copies], keepEdges: true })
          if (currentOwned) await geometry.release(current)
          current = next
          currentOwned = true
        } finally {
          await Promise.allSettled(copies.map((copy) => geometry.release(copy)))
          if (toolOwned) await geometry.release(tool)
        }
      }
      return current
    } catch (error) {
      if (currentOwned) await geometry.release(current)
      throw error
    }
  }
  const rotatedTranslation = (origin: Point3, axis: Point3, angle: number): Point3 => {
    const length = Math.hypot(...axis)
    const [x, y, z] = axis.map((coordinate) => coordinate / length) as Point3
    const radians = angle * Math.PI / 180
    const cosine = Math.cos(radians)
    const sine = Math.sin(radians)
    const dot = x * origin[0] + y * origin[1] + z * origin[2]
    const rotated: Point3 = [
      origin[0] * cosine + (y * origin[2] - z * origin[1]) * sine + x * dot * (1 - cosine),
      origin[1] * cosine + (z * origin[0] - x * origin[2]) * sine + y * dot * (1 - cosine),
      origin[2] * cosine + (x * origin[1] - y * origin[0]) * sine + z * dot * (1 - cosine),
    ]
    return [origin[0] - rotated[0], origin[1] - rotated[1], origin[2] - rotated[2]]
  }
  try {
    let placement = placementForObject(object, document)
    const isPartPrimitive = object.typeId === 'Part::Box' || object.typeId === 'Part::Cylinder' || object.typeId === 'Part::Sphere' || object.typeId === 'Part::Ellipsoid' || object.typeId === 'Part::Cone' || object.typeId === 'Part::Torus' || object.typeId === 'Part::Helix' || object.typeId === 'Part::Prism' || object.typeId === 'Part::Wedge'
    const primitiveTranslation: Point3 = isPartPrimitive && placement?.rotationAngle === 0 ? placement.translation : [0, 0, 0]
    if (isPartPrimitive && placement?.rotationAngle === 0) placement = null
    let result: ShapeHandle
    let computedLinearLength: number | undefined
    if (object.typeId === 'Part::Box') {
      const length = numberProperty('Length', 10)
      const width = numberProperty('Width', 10)
      const height = numberProperty('Height', 10)
      result = await geometry.createBox({ ...documentContext, width: length, height: width, length: height, center: [primitiveTranslation[0] + length / 2, primitiveTranslation[1] + width / 2, primitiveTranslation[2] + height / 2], originOnCenter: true })
    } else if (object.typeId === 'Part::Cylinder') {
      result = await geometry.createCylinder({ ...documentContext, radius: numberProperty('Radius', 5), height: numberProperty('Height', 10), center: primitiveTranslation, direction: [0, 0, 1], angle: numberProperty('Angle', 360), originOnCenter: false })
    } else if (object.typeId === 'Part::Sphere') {
      const angle1 = numberProperty('Angle1', -90)
      const angle2 = numberProperty('Angle2', 90)
      const angle3 = numberProperty('Angle3', 360)
      if (angle1 < -90 || angle1 > 90) return geometryFailure(object.id, 'SPHERE_ANGLE1_INVALID', 'Part::Sphere Angle1 must be between -90 and 90 degrees.')
      if (angle2 < -90 || angle2 > 90) return geometryFailure(object.id, 'SPHERE_ANGLE2_INVALID', 'Part::Sphere Angle2 must be between -90 and 90 degrees.')
      if (angle1 >= angle2) return geometryFailure(object.id, 'SPHERE_LATITUDE_RANGE_INVALID', 'Part::Sphere Angle1 must be less than Angle2.')
      if (!(angle3 > 0) || angle3 > 360) return geometryFailure(object.id, 'SPHERE_ANGLE3_INVALID', 'Part::Sphere Angle3 must be greater than zero and no more than 360 degrees.')
      const extrude = geometry.extrude?.bind(geometry)
      if (angle3 !== 360 && !extrude) return geometryFailure(object.id, 'SPHERE_TRIM_RUNTIME_UNAVAILABLE', 'Bitbybit Extrude is required to build the spherical azimuth sector.')
      const radius = numberProperty('Radius', 5)
      const sphereCenter: Point3 = primitiveTranslation
      let current = await geometry.createSphere({ ...documentContext, radius, center: sphereCenter })
      const temporary: ShapeHandle[] = []
      const intersect = async (tool: ShapeHandle) => {
        temporary.push(tool)
        const previous = current
        const next = await geometry.intersection({ ...documentContext, shapes: [previous, tool], keepEdges: true })
        await geometry.release(previous)
        await geometry.release(tool)
        temporary.splice(temporary.indexOf(tool), 1)
        current = next
      }
      try {
        if (angle1 !== -90 || angle2 !== 90) {
          const zMin = sphereCenter[2] + radius * Math.sin(angle1 * Math.PI / 180)
          const zMax = sphereCenter[2] + radius * Math.sin(angle2 * Math.PI / 180)
          await intersect(await geometry.createBox({
            ...documentContext,
            width: radius * 4,
            height: radius * 4,
            length: zMax - zMin,
            center: [sphereCenter[0], sphereCenter[1], (zMin + zMax) / 2],
            originOnCenter: true,
          }))
        }
        if (angle3 !== 360) {
          const outerRadius = radius * 2
          const zMin = sphereCenter[2] - outerRadius
          const segments = Math.max(8, Math.ceil(angle3 / 10))
          const outer: Point3[] = [[sphereCenter[0], sphereCenter[1], zMin]]
          for (let index = 0; index <= segments; index += 1) {
            const angle = angle3 * index / segments * Math.PI / 180
            outer.push([sphereCenter[0] + outerRadius * Math.cos(angle), sphereCenter[1] + outerRadius * Math.sin(angle), zMin])
          }
          outer.push([sphereCenter[0], sphereCenter[1], zMin])
          await intersect(await (extrude as NonNullable<RecomputeGeometryRuntime['extrude']>)({ ...documentContext, profile: { outer, closed: true }, length: outerRadius * 2, direction: [0, 0, 1] }))
        }
      result = current
      } catch (error) {
        await Promise.allSettled([geometry.release(current), ...temporary.map((shape) => geometry.release(shape))])
        throw error
      }
    } else if (object.typeId === 'Part::Ellipsoid') {
      if (!geometry.createEllipsoid) return geometryFailure(object.id, 'ELLIPSOID_RUNTIME_UNAVAILABLE', 'Bitbybit Ellipsoid construction is unavailable in this runtime.')
      const radius1 = numberProperty('Radius1', 2)
      const radius2 = numberProperty('Radius2', 4)
      const radius3 = numberProperty('Radius3', 0)
      const angle1 = numberProperty('Angle1', -90)
      const angle2 = numberProperty('Angle2', 90)
      const angle3 = numberProperty('Angle3', 360)
      if (angle1 !== -90 || angle2 !== 90 || angle3 !== 360) return geometryFailure(object.id, 'ELLIPSOID_TRIM_UNSUPPORTED', 'Bitbybit 1.1.1 does not expose stable Ellipsoid trim angles.')
      result = await geometry.createEllipsoid({ ...documentContext, radius1, radius2, radius3, angle1, angle2, angle3, center: primitiveTranslation })
    } else if (object.typeId === 'Part::Cone') {
      result = await geometry.createCone({ ...documentContext, radius1: numberProperty('Radius1', 5), radius2: numberProperty('Radius2', 0), height: numberProperty('Height', 10), center: primitiveTranslation, direction: [0, 0, 1], angle: numberProperty('Angle', 360) })
    } else if (object.typeId === 'Part::Torus') {
      if (!geometry.createTorus) return geometryFailure(object.id, 'TORUS_RUNTIME_UNAVAILABLE', 'The Bitbybit geometry runtime does not provide Torus construction.')
      const angle1 = numberProperty('Angle1', -180)
      const angle2 = numberProperty('Angle2', 180)
      const angle3 = numberProperty('Angle3', 360)
      if (angle1 < -180 || angle1 > 180 || angle2 < -180 || angle2 > 180 || angle1 >= angle2) return geometryFailure(object.id, 'TORUS_MINOR_ANGLE_RANGE_INVALID', 'Part::Torus Angle1 and Angle2 must define an increasing range within -180 to 180 degrees.')
      if (!(angle3 > 0) || angle3 > 360) return geometryFailure(object.id, 'TORUS_ANGLE3_INVALID', 'Part::Torus Angle3 must be greater than zero and no more than 360 degrees.')
      if (angle1 !== -180 || angle2 !== 180) return geometryFailure(object.id, 'TORUS_MINOR_TRIM_UNSUPPORTED', 'Bitbybit 1.1.1 does not expose non-default FreeCAD Torus minor-circle trimming angles.')
      const majorRadius = numberProperty('Radius1', 10)
      const minorRadius = numberProperty('Radius2', 2)
      result = await geometry.createTorus({ ...documentContext, majorRadius, minorRadius, center: primitiveTranslation, direction: [0, 0, 1], angle: angle3 })
    } else if (object.typeId === 'Part::Helix') {
      if (!geometry.createHelix) return geometryFailure(object.id, 'HELIX_RUNTIME_UNAVAILABLE', 'Bitbybit Helix construction is unavailable in this runtime.')
      const pitch = numberProperty('Pitch', 1)
      const height = numberProperty('Height', 2)
      const radius = numberProperty('Radius', 1)
      const angle = numberProperty('Angle', 0)
      const segmentLength = numberProperty('SegmentLength', 0)
      if (!(pitch > 0)) return geometryFailure(object.id, 'HELIX_PITCH_INVALID', 'Part::Helix Pitch must be greater than zero.')
      if (!(height > 0)) return geometryFailure(object.id, 'HELIX_HEIGHT_INVALID', 'Part::Helix Height must be greater than zero.')
      if (!(radius > 0)) return geometryFailure(object.id, 'HELIX_RADIUS_INVALID', 'Part::Helix Radius must be greater than zero.')
      if (height / pitch > 10000) return geometryFailure(object.id, 'HELIX_TURN_LIMIT_EXCEEDED', 'Part::Helix cannot exceed 10000 turns.')
      if (angle <= -89.99999 || angle >= 89.99999) return geometryFailure(object.id, 'HELIX_ANGLE_INVALID', 'Part::Helix Angle must be between -89.99999 and 89.99999 degrees (exclusive).')
      const endRadius = radius + height * Math.tan(angle * Math.PI / 180)
      if (!(endRadius > 0) || !Number.isFinite(endRadius)) return geometryFailure(object.id, 'HELIX_END_RADIUS_INVALID', 'Part::Helix Angle produces a non-positive or non-finite end radius.')
      if (segmentLength !== 0) return geometryFailure(object.id, 'HELIX_SEGMENT_LENGTH_UNSUPPORTED', 'Bitbybit 1.1.1 does not expose FreeCAD Helix SegmentLength subdivisions.')
      const localCoord = propertyValue(object, 'LocalCoord')
      if (localCoord !== undefined && localCoord !== 'Right-handed' && localCoord !== 'Left-handed' && localCoord !== 0 && localCoord !== 1) return geometryFailure(object.id, 'HELIX_LOCAL_COORD_INVALID', `Part::Helix LocalCoord is invalid: ${String(localCoord)}`)
      const style = propertyValue(object, 'Style')
      if (style !== undefined && style !== 'Old style' && style !== 'New style' && style !== 0 && style !== 1) return geometryFailure(object.id, 'HELIX_STYLE_INVALID', `Part::Helix Style is invalid: ${String(style)}`)
      result = await geometry.createHelix({ ...documentContext, pitch, height, radius, angle, leftHanded: localCoord === 'Left-handed' || localCoord === 1, center: primitiveTranslation, direction: [0, 0, 1], tolerance: 1e-10 })
      if (geometry.linearLength) computedLinearLength = await geometry.linearLength(result)
      else if (angle === 0) computedLinearLength = height * Math.sqrt(1 + (2 * Math.PI * radius / pitch) ** 2)
    } else if (object.typeId === 'Part::Prism') {
      if (!geometry.createPrism) return geometryFailure(object.id, 'PRISM_RUNTIME_UNAVAILABLE', 'Bitbybit Prism construction is unavailable in this runtime.')
      const polygonValue = propertyValue(object, 'Polygon')
      const polygon = typeof polygonValue === 'number' && Number.isInteger(polygonValue) ? polygonValue : Math.trunc(numberProperty('Polygon', 6))
      const circumradius = numberProperty('Circumradius', 2)
      const height = numberProperty('Height', 10)
      const firstAngle = numberProperty('FirstAngle', 0)
      const secondAngle = numberProperty('SecondAngle', 0)
      if (polygon < 3 || polygon > 10000) return geometryFailure(object.id, 'PRISM_POLYGON_INVALID', 'Part::Prism Polygon must be an integer between 3 and 10000.')
      if (!(circumradius > 0) || !(height > 0)) return geometryFailure(object.id, 'PRISM_DIMENSION_INVALID', 'Part::Prism Circumradius and Height must be greater than zero.')
      if (firstAngle < -89.99999 || firstAngle > 89.99999 || secondAngle < -89.99999 || secondAngle > 89.99999) return geometryFailure(object.id, 'PRISM_ANGLE_INVALID', 'Part::Prism FirstAngle and SecondAngle must be between -89.99999 and 89.99999 degrees.')
      result = await geometry.createPrism({ ...documentContext, polygon, circumradius, height, firstAngle, secondAngle, center: primitiveTranslation })
    } else if (object.typeId === 'Part::Wedge') {
      if (!geometry.createWedge) return geometryFailure(object.id, 'WEDGE_RUNTIME_UNAVAILABLE', 'Bitbybit Wedge construction is unavailable in this runtime.')
      const wedge = (name: string, fallback: number) => numberProperty(name, fallback)
      const input: CreateWedgeInput = { ...documentContext, xmin: wedge('Xmin', 0), ymin: wedge('Ymin', 0), zmin: wedge('Zmin', 0), z2min: wedge('Z2min', 2), x2min: wedge('X2min', 2), xmax: wedge('Xmax', 10), ymax: wedge('Ymax', 10), zmax: wedge('Zmax', 10), z2max: wedge('Z2max', 8), x2max: wedge('X2max', 8), center: primitiveTranslation }
      if (!(input.xmax - input.xmin > Number.EPSILON) || !(input.ymax - input.ymin > Number.EPSILON) || !(input.zmax - input.zmin > Number.EPSILON)) return geometryFailure(object.id, 'WEDGE_DIMENSION_INVALID', 'Part::Wedge X/Y/Z spans must be greater than zero.')
      if (input.z2max - input.z2min < 0 || input.x2max - input.x2min < 0) return geometryFailure(object.id, 'WEDGE_REMOTE_SPAN_INVALID', 'Part::Wedge remote X2/Z2 spans must not be negative.')
      result = await geometry.createWedge(input)
    } else if (object.typeId === 'Part::Fuse' || object.typeId === 'Part::Cut' || object.typeId === 'Part::Common') {
      const baseObject = linkedObject(object, 'Base', document)
      const toolObject = linkedObject(object, 'Tool', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      const toolShape = toolObject ? shapes.get(toolObject.id) : undefined
      if (!baseShape || !toolShape) return geometryFailure(object.id, 'BOOLEAN_SHAPE_MISSING', 'Boolean operation requires recomputed Base and Tool shapes.')
      const keepEdges = propertyValue(object, 'Refine') !== true
      if (object.typeId === 'Part::Fuse') result = await geometry.union({ ...documentContext, shapes: [baseShape, toolShape], keepEdges })
      else if (object.typeId === 'Part::Cut') result = await geometry.cut({ ...documentContext, base: baseShape, tools: [toolShape], keepEdges })
      else result = await geometry.intersection({ ...documentContext, shapes: [baseShape, toolShape], keepEdges })
    } else if (object.typeId === 'Part::Extrusion' || object.typeId === 'Part::Extrude') {
      if (!geometry.extrude) return geometryFailure(object.id, 'EXTRUDE_RUNTIME_UNAVAILABLE', 'The geometry runtime does not provide standalone Part Extrude.')
      if (propertyValue(object, 'Solid') !== true) return geometryFailure(object.id, 'EXTRUDE_SHELL_UNSUPPORTED', 'Part::Extrusion Solid=false requires a shell/wire result that the planar Bitbybit contract does not expose.')
      const dirMode = propertyValue(object, 'DirMode')
      if (dirMode !== undefined && dirMode !== 'Custom' && dirMode !== 0) return geometryFailure(object.id, 'EXTRUDE_DIR_MODE_UNSUPPORTED', 'Part::Extrusion direction modes other than Custom are not available through Bitbybit.')
      if (propertyValue(object, 'DirLink')) return geometryFailure(object.id, 'EXTRUDE_DIR_LINK_UNSUPPORTED', 'Part::Extrusion DirLink requires a persistent edge direction and is not available through Bitbybit.')
      const direction = vectorProperty('Dir', [0, 0, 1])
      if (!direction || direction.every((coordinate) => coordinate === 0)) return geometryFailure(object.id, 'EXTRUDE_DIRECTION_INVALID', 'Part::Extrusion Dir must be a finite non-zero vector.')
      const lengthRev = numberProperty('LengthRev', 0)
      if (lengthRev < 0) return geometryFailure(object.id, 'EXTRUDE_REVERSE_LENGTH_INVALID', 'Part::Extrusion LengthRev must not be negative.')
      const taperAngle = numberProperty('TaperAngle', 0)
      const taperAngleRev = numberProperty('TaperAngleRev', 0)
      if (taperAngle !== 0 || taperAngleRev !== 0) return geometryFailure(object.id, 'EXTRUDE_TAPER_UNSUPPORTED', 'Part::Extrusion taper angles are not exposed by Bitbybit 1.1.1.')
      const dirLength = Math.hypot(...direction)
      const lengthFwd = numberProperty('LengthFwd', 0)
      const length = lengthFwd > 0 ? lengthFwd : dirLength
      if (!(length > 0)) return geometryFailure(object.id, 'EXTRUDE_LENGTH_INVALID', 'Part::Extrusion requires LengthFwd or a non-zero Dir magnitude.')
      const reversed = propertyValue(object, 'Reversed') === true
      if (lengthRev > 0 && propertyValue(object, 'Symmetric') === true) return geometryFailure(object.id, 'EXTRUDE_SIDE_MODE_INVALID', 'Part::Extrusion cannot combine LengthRev with Symmetric.')
      if (lengthRev > 0) {
        const first = await geometry.extrude({ ...documentContext, profile: profile.profile as PlanarProfile, length, direction, reversed })
        let second: ShapeHandle | undefined
        try {
          second = await geometry.extrude({ ...documentContext, profile: profile.profile as PlanarProfile, length: lengthRev, direction, reversed: !reversed })
          result = await unionOwnedShapes(geometry, documentContext, [first, second], true)
        } catch (error) {
          if (!second) await geometry.release(first)
          throw error
        }
      } else result = await geometry.extrude({ ...documentContext, profile: profile.profile as PlanarProfile, length, direction, reversed, symmetricToPlane: propertyValue(object, 'Symmetric') === true })
    } else if (object.typeId === 'Part::Revolution') {
      if (propertyValue(object, 'Solid') !== true) return geometryFailure(object.id, 'REVOLUTION_SHELL_UNSUPPORTED', 'Part::Revolution Solid=false requires a shell result that the planar Bitbybit contract does not expose.')
      if (propertyValue(object, 'AxisLink')) return geometryFailure(object.id, 'REVOLUTION_AXIS_LINK_UNSUPPORTED', 'Part::Revolution AxisLink requires a persistent edge axis and is not available through Bitbybit.')
      const symmetric = propertyValue(object, 'Symmetric') === true
      const axisOrigin = vectorProperty('Base', [0, 0, 0])
      const axisDirection = vectorProperty('Axis', [0, 0, 1])
      if (!axisOrigin || !axisDirection || axisDirection.every((coordinate) => coordinate === 0)) return geometryFailure(object.id, 'REVOLUTION_AXIS_INVALID', 'Part::Revolution Base/Axis must contain finite vectors and Axis must be non-zero.')
      const angle = numberProperty('Angle', 360)
      if (!(angle > 0) || angle > 360) return geometryFailure(object.id, 'REVOLUTION_ANGLE_INVALID', 'Part::Revolution Angle must be greater than zero and no more than 360 degrees.')
      if (symmetric) {
        result = await geometry.revolution({ ...documentContext, profile: profile.profile as PlanarProfile, angle, axisOrigin, axisDirection, profileRotationAngle: -angle / 2 })
      } else result = await geometry.revolution({ ...documentContext, profile: profile.profile as PlanarProfile, angle, axisOrigin, axisDirection })
    } else if (object.typeId === 'PartDesign::Pad') {
      const padType = propertyValue(object, 'Type')
      const sideType = propertyValue(object, 'SideType')
      const legacyTwoLengths = padType === '?TwoLengths' || padType === 'TwoLengths' || padType === 'Two dimensions' || padType === 4
      const twoSides = sideType === 'Two sides' || sideType === 1 || legacyTwoLengths
      const upToFace = padType === 'Up to face' || padType === 'UpToFace' || padType === 3
      if (padType !== undefined && !twoSides && !upToFace && padType !== 'Dimension' && padType !== 'Length' && padType !== 0) return geometryFailure(object.id, 'PAD_TYPE_UNSUPPORTED', `Bitbybit Pad does not expose FreeCAD pad type: ${String(padType)}`)
      const taperAngle = numberProperty('TaperAngle', 0)
      const taperAngle2 = numberProperty('TaperAngle2', 0)
      if ((taperAngle !== 0 || taperAngle2 !== 0) && (((profile.profile as PlanarProfile).holes?.length ?? 0) > 0 || ((profile.profile as PlanarProfile).additionalRegions?.length ?? 0) > 0)) return geometryFailure(object.id, 'PAD_TAPER_PROFILE_UNSUPPORTED', 'Tapered Pad currently requires one outer profile ring without holes.')
      let length = numberProperty('Length', 1)
      const length2 = numberProperty('Length2', 0)
      const reversed = propertyValue(object, 'Reversed') === true
      const midplane = propertyValue(object, 'Midplane') === true || sideType === 'Symmetric' || sideType === 2
      if (upToFace) {
        if (twoSides || midplane) return geometryFailure(object.id, 'PAD_UP_TO_FACE_MODE_INVALID', 'Up-to-face Pad cannot be combined with two-sided or symmetric mode.')
        const target = linearUpToFaceLength(object, document, profile.profile as PlanarProfile, [0, 0, reversed ? -1 : 1])
        if ('code' in target) return geometryFailure(object.id, target.code, target.message)
        length = target.length
      }
      if (twoSides) {
        if (!(length > 0) || !(length2 > 0)) return geometryFailure(object.id, 'PAD_SECOND_LENGTH_INVALID', 'Two-sided Pad requires positive Length and Length2.')
        const first = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length, direction: [0, 0, 1], reversed, symmetricToPlane: false, taperAngle })
        let second: ShapeHandle | undefined
        try {
          second = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length: length2, direction: [0, 0, 1], reversed: !reversed, symmetricToPlane: false, taperAngle: taperAngle2 })
          result = await unionOwnedShapes(geometry, documentContext, [first, second], true)
        } catch (error) {
          if (!second) await geometry.release(first)
          throw error
        }
      } else {
        if (length2 !== 0) return geometryFailure(object.id, 'PAD_SECOND_LENGTH_UNSUPPORTED', 'Pad Length2 requires SideType=Two sides or the legacy ?TwoLengths mode.')
        if (midplane && taperAngle !== 0) {
          const first = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length: length / 2, direction: [0, 0, 1], reversed, symmetricToPlane: false, taperAngle })
          let second: ShapeHandle | undefined
          try {
            second = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length: length / 2, direction: [0, 0, 1], reversed: !reversed, symmetricToPlane: false, taperAngle })
            result = await unionOwnedShapes(geometry, documentContext, [first, second], true)
          } catch (error) {
            if (!second) await geometry.release(first)
            throw error
          }
        } else result = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length, direction: [0, 0, 1], reversed, symmetricToPlane: midplane, taperAngle })
      }
    } else if (object.typeId === 'PartDesign::Pocket') {
      const pocketType = propertyValue(object, 'Type')
      const sideType = propertyValue(object, 'SideType')
      const legacyTwoLengths = pocketType === '?TwoLengths' || pocketType === 'TwoLengths' || pocketType === 'Two dimensions' || pocketType === 4
      const twoSides = sideType === 'Two sides' || sideType === 1 || legacyTwoLengths
      const upToFace = pocketType === 'Up to face' || pocketType === 'UpToFace' || pocketType === 3
      if (pocketType !== undefined && !twoSides && !upToFace && pocketType !== 'Dimension' && pocketType !== 'Length' && pocketType !== 'Through all' && pocketType !== 'ThroughAll' && pocketType !== 0 && pocketType !== 1) return geometryFailure(object.id, 'POCKET_TYPE_UNSUPPORTED', `Bitbybit Pocket does not expose FreeCAD pocket type: ${String(pocketType)}`)
      const taperAngle = numberProperty('TaperAngle', 0)
      const taperAngle2 = numberProperty('TaperAngle2', 0)
      if ((taperAngle !== 0 || taperAngle2 !== 0) && (((profile.profile as PlanarProfile).holes?.length ?? 0) > 0 || ((profile.profile as PlanarProfile).additionalRegions?.length ?? 0) > 0)) return geometryFailure(object.id, 'POCKET_TAPER_PROFILE_UNSUPPORTED', 'Tapered Pocket currently requires one outer profile ring without holes.')
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Pocket base has no valid recomputed Shape.')
      let length = numberProperty('Length', 1)
      const length2 = numberProperty('Length2', 0)
      const reversed = propertyValue(object, 'Reversed') === true
      const midplane = propertyValue(object, 'Midplane') === true || sideType === 'Symmetric' || sideType === 2
      if (upToFace) {
        if (twoSides || midplane) return geometryFailure(object.id, 'POCKET_UP_TO_FACE_MODE_INVALID', 'Up-to-face Pocket cannot be combined with two-sided or symmetric mode.')
        const target = linearUpToFaceLength(object, document, profile.profile as PlanarProfile, [0, 0, reversed ? -1 : 1])
        if ('code' in target) return geometryFailure(object.id, target.code, target.message)
        length = target.length
      }
      if (twoSides) {
        if (!(length > 0) || !(length2 > 0)) return geometryFailure(object.id, 'POCKET_SECOND_LENGTH_INVALID', 'Two-sided Pocket requires positive Length and Length2.')
        const first = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length, direction: [0, 0, 1], reversed, symmetricToPlane: false, taperAngle })
        let second: ShapeHandle | undefined
        try {
          second = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length: length2, direction: [0, 0, 1], reversed: !reversed, symmetricToPlane: false, taperAngle: taperAngle2 })
          const tool = await unionOwnedShapes(geometry, documentContext, [first, second])
          try {
            result = await geometry.cut({ ...documentContext, base: baseShape, tools: [tool] })
          } finally {
            await geometry.release(tool)
          }
        } catch (error) {
          if (!second) await geometry.release(first)
          throw error
        }
      } else {
        if (length2 !== 0) return geometryFailure(object.id, 'POCKET_SECOND_LENGTH_UNSUPPORTED', 'Pocket Length2 requires SideType=Two sides or the legacy ?TwoLengths mode.')
        const throughAll = pocketType === 'Through all' || pocketType === 'ThroughAll' || pocketType === 1
        if (midplane && taperAngle !== 0) {
          const first = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length: length / 2, direction: [0, 0, 1], reversed, symmetricToPlane: false, taperAngle })
          let second: ShapeHandle | undefined
          try {
            second = await geometry.pad({ ...documentContext, profile: profile.profile as PlanarProfile, length: length / 2, direction: [0, 0, 1], reversed: !reversed, symmetricToPlane: false, taperAngle })
            const tool = await unionOwnedShapes(geometry, documentContext, [first, second])
            try {
              result = await geometry.cut({ ...documentContext, base: baseShape, tools: [tool] })
            } finally {
              await geometry.release(tool)
            }
          } catch (error) {
            if (!second) await geometry.release(first)
            throw error
          }
        } else result = await geometry.pocket({ ...documentContext, base: baseShape, profile: profile.profile as PlanarProfile, length, direction: [0, 0, 1], reversed, symmetricToPlane: midplane, throughAll, taperAngle })
      }
    } else if (object.typeId === 'PartDesign::Revolution') {
      const angle = numberProperty('Angle', 360)
      const angle2 = numberProperty('Angle2', 0)
      if (!(angle > 0) || angle > 360) return geometryFailure(object.id, 'REVOLUTION_ANGLE_INVALID', 'PartDesign Revolution Angle must be greater than zero and no more than 360 degrees.')
      if (angle2 < 0 || angle2 > 360) return geometryFailure(object.id, 'REVOLUTION_ANGLE2_INVALID', 'PartDesign Revolution Angle2 must be between zero and 360 degrees.')
      const type = propertyValue(object, 'Type')
      if (type === 'To last' || type === 'To first' || type === 'Up to face' || type === 'UpToLast' || type === 'UpToFirst' || type === 'UpToFace' || type === 'ThroughAll' || type === 1 || type === 2 || type === 3) return geometryFailure(object.id, 'REVOLUTION_SUPPORT_MODE_UNSUPPORTED', `Bitbybit Revolution does not expose FreeCAD support mode: ${String(type)}`)
      const twoAngles = type === 'Two angles' || type === 'TwoAngles' || type === 4 || (type === undefined && angle2 > 0)
      const midplane = propertyValue(object, 'Midplane') === true
      if (midplane && twoAngles) return geometryFailure(object.id, 'REVOLUTION_MODE_INVALID', 'PartDesign Revolution Midplane is only valid for the Angle type, not Two angles.')
      const reversed = propertyValue(object, 'Reversed') === true
      const axisDirection = (reversed ? [0, -1, 0] : [0, 1, 0]) as Point3
      const firstAngle = midplane ? angle / 2 : angle
      const secondAngle = midplane ? angle / 2 : twoAngles ? angle2 : 0
      if (!(firstAngle > 0)) return geometryFailure(object.id, 'REVOLUTION_ANGLE_INVALID', 'PartDesign Revolution requires a positive first angle.')
      const totalAngle = firstAngle + secondAngle
      if (totalAngle > 360) return geometryFailure(object.id, 'REVOLUTION_TOTAL_ANGLE_INVALID', 'PartDesign Revolution Angle and Angle2 must total no more than 360 degrees.')
      result = await geometry.revolution({ ...documentContext, profile: profile.profile as PlanarProfile, angle: totalAngle, axisOrigin: [0, 0, 0], axisDirection, ...(secondAngle > 0 ? { profileRotationAngle: -secondAngle } : {}) })
    } else if (object.typeId === 'PartDesign::Groove') {
      if (!geometry.groove) return geometryFailure(object.id, 'GROOVE_RUNTIME_UNAVAILABLE', 'The geometry runtime does not provide Groove.')
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Groove base has no valid recomputed Shape.')
      const angle = numberProperty('Angle', 360)
      const angle2 = numberProperty('Angle2', 0)
      if (!(angle > 0) || angle > 360) return geometryFailure(object.id, 'GROOVE_ANGLE_INVALID', 'Groove Angle must be greater than zero and no more than 360 degrees.')
      if (angle2 < 0 || angle2 > 360) return geometryFailure(object.id, 'GROOVE_ANGLE2_INVALID', 'Groove Angle2 must be between zero and 360 degrees.')
      const type = propertyValue(object, 'Type')
      if (type === 'To last' || type === 'To first' || type === 'Up to face' || type === 'UpToLast' || type === 'UpToFirst' || type === 'UpToFace' || type === 'ThroughAll' || type === 1 || type === 2 || type === 3) return geometryFailure(object.id, 'GROOVE_SUPPORT_MODE_UNSUPPORTED', `Bitbybit Groove does not expose FreeCAD support mode: ${String(type)}`)
      const twoAngles = type === 'Two angles' || type === 'TwoAngles' || type === 4 || (type === undefined && angle2 > 0)
      const midplane = propertyValue(object, 'Midplane') === true
      if (midplane && twoAngles) return geometryFailure(object.id, 'GROOVE_MODE_INVALID', 'Groove Midplane is only valid for the Angle type, not Two angles.')
      const baseDirection = (propertyValue(object, 'Reversed') === true ? [0, -1, 0] : [0, 1, 0]) as Point3
      const firstAngle = midplane ? angle / 2 : angle
      const secondAngle = midplane ? angle / 2 : twoAngles ? angle2 : 0
      if (!(firstAngle > 0)) return geometryFailure(object.id, 'GROOVE_ANGLE_INVALID', 'Groove requires a positive first angle.')
      const totalAngle = firstAngle + secondAngle
      if (totalAngle > 360) return geometryFailure(object.id, 'GROOVE_TOTAL_ANGLE_INVALID', 'Groove Angle and Angle2 must total no more than 360 degrees.')
      result = await geometry.groove({ ...documentContext, base: baseShape, profile: profile.profile as PlanarProfile, angle: totalAngle, axisOrigin: [0, 0, 0], axisDirection: baseDirection, ...(secondAngle > 0 ? { profileRotationAngle: -secondAngle } : {}) })
    } else if (object.typeId === 'Part::Loft' || object.typeId === 'PartDesign::AdditiveLoft' || object.typeId === 'PartDesign::SubtractiveLoft') {
      if (!geometry.loft) return geometryFailure(object.id, 'LOFT_RUNTIME_UNAVAILABLE', 'The geometry runtime does not provide Loft.')
      if (object.typeId === 'Part::Loft' && propertyValue(object, 'Solid') === false) return geometryFailure(object.id, 'LOFT_SHELL_UNSUPPORTED', 'Part::Loft Solid=false requires a shell result that the Bitbybit loft contract does not expose.')
      if (propertyValue(object, 'Linearize') === true) return geometryFailure(object.id, 'LOFT_LINEARIZE_UNSUPPORTED', 'Part::Loft Linearize=true is not exposed by the Bitbybit loft contract.')
      const maxDegree = propertyValue(object, 'MaxDegree')
      if (maxDegree !== undefined && maxDegree !== 5) return geometryFailure(object.id, 'LOFT_MAX_DEGREE_UNSUPPORTED', 'Part::Loft non-default MaxDegree is not exposed by the Bitbybit loft contract.')
      const parsed = loftSections(object, document)
      if (!parsed.sections) return geometryFailure(object.id, parsed.code || 'LOFT_SECTIONS_INVALID', parsed.message || 'Loft sections are invalid.')
      const mode = object.typeId === 'PartDesign::AdditiveLoft' ? 'additive' : object.typeId === 'PartDesign::SubtractiveLoft' ? 'subtractive' : 'standalone'
      const baseObject = mode === 'standalone' ? undefined : linkedObject(object, 'Base', document) ?? linkedObject(object, 'BaseFeature', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (mode !== 'standalone' && !baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', `${mode === 'additive' ? 'Additive' : 'Subtractive'} loft base has no valid recomputed Shape.`)
      result = await geometry.loft({ ...documentContext, sections: parsed.sections, mode, base: baseShape, ruled: propertyValue(object, 'Ruled') === true, closed: propertyValue(object, 'Closed') === true })
    } else if (object.typeId === 'Part::Sweep' || object.typeId === 'PartDesign::AdditivePipe' || object.typeId === 'PartDesign::SubtractivePipe') {
      if (!geometry.pipe) return geometryFailure(object.id, 'PIPE_RUNTIME_UNAVAILABLE', 'The geometry runtime does not provide Pipe.')
      const parsed = pipeDefinition(object, document)
      if (!parsed.profile || !parsed.path) return geometryFailure(object.id, parsed.code || 'PIPE_INPUT_INVALID', parsed.message || 'Pipe profile or path is invalid.')
      const mode = object.typeId === 'PartDesign::AdditivePipe' ? 'additive' : object.typeId === 'PartDesign::SubtractivePipe' ? 'subtractive' : 'standalone'
      const baseObject = mode === 'standalone' ? undefined : linkedObject(object, 'Base', document) ?? linkedObject(object, 'BaseFeature', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (mode !== 'standalone' && !baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', `${mode === 'additive' ? 'Additive' : 'Subtractive'} pipe base has no valid recomputed Shape.`)
      result = await geometry.pipe({ ...documentContext, profile: parsed.profile, path: parsed.path, mode, base: baseShape })
    } else if (object.typeId === 'PartDesign::Fillet' || object.typeId === 'Part::Fillet') {
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Fillet base has no valid recomputed Shape.')
      const selected = dressUpEdgeIndexes(object, baseObject as DocumentObjectSnapshot)
      if (selected.code) return geometryFailure(object.id, selected.code, selected.message as string)
      result = await geometry.fillet({ ...documentContext, base: baseShape, radius: numberProperty('Radius', 1), indexes: selected.indexes })
    } else if (object.typeId === 'PartDesign::Draft') {
      if (!geometry.draft) return geometryFailure(object.id, 'DRAFT_RUNTIME_UNAVAILABLE', 'The geometry runtime does not provide PartDesign Draft.')
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseObject || !baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Draft base has no valid recomputed Shape.')
      const selected = dressUpFaceIndexes(object, baseObject)
      if (selected.code) return geometryFailure(object.id, selected.code, selected.message as string)
      const direction = vectorProperty('Direction', [0, 1, 0])
      const neutralPlaneOrigin = vectorProperty('NeutralPlaneOrigin', [0, 0, 0])
      const neutralPlaneDirection = vectorProperty('NeutralPlaneDirection', [0, 0, 1])
      if (!direction || direction.every((coordinate) => coordinate === 0)) return geometryFailure(object.id, 'DRAFT_DIRECTION_INVALID', 'Draft Direction must be a finite non-zero vector.')
      if (!neutralPlaneOrigin || !neutralPlaneDirection || neutralPlaneDirection.every((coordinate) => coordinate === 0)) return geometryFailure(object.id, 'DRAFT_NEUTRAL_PLANE_INVALID', 'Draft neutral plane origin and direction must be finite, with a non-zero direction.')
      result = await geometry.draft({ ...documentContext, base: baseShape, angle: numberProperty('Angle', 5), direction, neutralPlaneOrigin, neutralPlaneDirection, indexes: selected.indexes, reversed: propertyValue(object, 'Reversed') === true })
    } else if (object.typeId === 'PartDesign::Thickness') {
      if (!geometry.thickness) return geometryFailure(object.id, 'THICKNESS_RUNTIME_UNAVAILABLE', 'The geometry runtime does not provide PartDesign Thickness.')
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseObject || !baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Thickness base has no valid recomputed Shape.')
      const selectedFaces = dressUpFaceIndexes(object, baseObject, 'RemoveFaces', 'THICKNESS')
      if (selectedFaces.code) return geometryFailure(object.id, selectedFaces.code, selectedFaces.message as string)
      const join = propertyValue(object, 'Join')
      if (join !== undefined && join !== 'Arc' && join !== 'Intersection' && join !== 0) return geometryFailure(object.id, 'THICKNESS_JOIN_UNSUPPORTED', `Bitbybit Thickness does not expose join mode: ${String(join)}`)
      const thickness = numberProperty('Value', numberProperty('Thickness', 1))
      result = await geometry.thickness({ ...documentContext, base: baseShape, offset: propertyValue(object, 'Reversed') === true ? -thickness : thickness, removeFaceIndexes: selectedFaces.indexes, joinType: join === 'Intersection' ? 'Intersection' : 'Arc' })
    } else if (object.typeId === 'PartDesign::Mirrored') {
      if (!geometry.mirror) return geometryFailure(object.id, 'MIRROR_RUNTIME_UNAVAILABLE', 'The geometry runtime does not provide plane mirroring.')
      const transformMode = propertyValue(object, 'TransformMode')
      if (!wholeTransformMode(transformMode) && !featureTransformMode(transformMode)) return geometryFailure(object.id, 'TRANSFORM_MODE_UNSUPPORTED', `Mirrored does not expose transform mode: ${String(transformMode)}`)
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Mirrored feature base has no valid recomputed Shape.')
      const originalObjects = linkedObjects(object, 'Originals', document)
      const plane = propertyValue(object, 'Plane')
      const defaultNormal: Point3 = plane === 'XZ plane' ? [0, 1, 0] : plane === 'YZ plane' ? [1, 0, 0] : [0, 0, 1]
      const normal = vectorProperty('PlaneNormal', defaultNormal)
      const origin = vectorProperty('PlaneOrigin', [0, 0, 0])
      if (!normal || normal.every((coordinate) => coordinate === 0) || !origin) return geometryFailure(object.id, 'MIRROR_PLANE_INVALID', 'Mirror plane origin must be finite and its normal must be non-zero.')
      if (featureTransformMode(transformMode)) {
        const featureError = validateFeatureTransformSources(originalObjects)
        if (featureError) return geometryFailure(object.id, 'TRANSFORM_ORIGINALS_INVALID', featureError)
        result = await applyFeatureTransforms(baseShape, originalObjects, async (tool) => [await geometry.mirror!({ ...documentContext, shape: tool, origin, normal })])
      } else {
        const mirrored = await geometry.mirror({ ...documentContext, shape: baseShape, origin, normal })
        if (propertyValue(object, 'Fuse') === false) result = mirrored
        else {
          try { result = await geometry.union({ ...documentContext, shapes: [baseShape, mirrored] }) }
          finally { await geometry.release(mirrored) }
        }
      }
    } else if (object.typeId === 'PartDesign::MultiTransform') {
      const transformMode = propertyValue(object, 'TransformMode')
      if (!wholeTransformMode(transformMode) && !featureTransformMode(transformMode)) return geometryFailure(object.id, 'TRANSFORM_MODE_UNSUPPORTED', `MultiTransform does not expose transform mode: ${String(transformMode)}`)
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Multi-transform base has no valid recomputed Shape.')
      const originalObjects = linkedObjects(object, 'Originals', document)
      const parsed = multiTransformSteps(object)
      if ('error' in parsed) return geometryFailure(object.id, 'MULTITRANSFORM_INVALID', parsed.error)
      if (parsed.steps.some((step) => step.type === 'mirrored') && !geometry.mirror) return geometryFailure(object.id, 'MULTITRANSFORM_MIRROR_UNAVAILABLE', 'The geometry runtime does not provide plane mirroring.')
      const transformedCopies = async (source: ShapeHandle) => {
        let instances: ShapeHandle[] = [source]
        const createdAll: ShapeHandle[] = []
        try {
        for (const step of parsed.steps) {
          const parents = [...instances]
          const created: ShapeHandle[] = []
          if (step.type === 'mirrored') {
            const normal: [number, number, number] = step.plane === 'XZ plane' ? [0, 1, 0] : step.plane === 'YZ plane' ? [1, 0, 0] : [0, 0, 1]
            for (const parent of parents) {
              const copy = await geometry.mirror!({ ...documentContext, shape: parent, origin: [0, 0, 0], normal })
              created.push(copy)
              createdAll.push(copy)
            }
          } else if (step.type === 'linear') {
            const axis: [number, number, number] = step.direction === 'Vertical' ? [0, 1, 0] : step.direction === 'Normal' ? [0, 0, 1] : [1, 0, 0]
            for (const parent of parents) for (let index = 1; index < step.occurrences; index += 1) {
              const offset = step.length * index / (step.occurrences - 1)
              const copy = await geometry.applyPlacement({ ...documentContext, shape: parent, placement: { translation: [axis[0] * offset, axis[1] * offset, axis[2] * offset], rotationAxis: [0, 0, 1], rotationAngle: 0 } })
              created.push(copy)
              createdAll.push(copy)
            }
          } else {
            const axis: [number, number, number] = step.axis === 'Horizontal' ? [1, 0, 0] : step.axis === 'Vertical' ? [0, 1, 0] : [0, 0, 1]
            const angleStep = step.angle === 360 ? step.angle / step.occurrences : step.angle / (step.occurrences - 1)
            for (const parent of parents) for (let index = 1; index < step.occurrences; index += 1) {
              const copy = await geometry.applyPlacement({ ...documentContext, shape: parent, placement: { translation: [0, 0, 0], rotationAxis: axis, rotationAngle: angleStep * index } })
              created.push(copy)
              createdAll.push(copy)
            }
          }
          instances = [...parents, ...created]
        }
          return createdAll
        } catch (error) {
          await Promise.allSettled(createdAll.map((shape) => geometry.release(shape)))
          throw error
        }
      }
      if (featureTransformMode(transformMode)) {
        const featureError = validateFeatureTransformSources(originalObjects)
        if (featureError) return geometryFailure(object.id, 'TRANSFORM_ORIGINALS_INVALID', featureError)
        result = await applyFeatureTransforms(baseShape, originalObjects, transformedCopies)
      } else {
        const copies = await transformedCopies(baseShape)
        try { result = await geometry.union({ ...documentContext, shapes: [baseShape, ...copies] }) }
        finally { await Promise.allSettled(copies.map((shape) => geometry.release(shape))) }
      }
    } else if (object.typeId === 'PartDesign::LinearPattern') {
      const transformMode = propertyValue(object, 'TransformMode')
      if (!wholeTransformMode(transformMode) && !featureTransformMode(transformMode)) return geometryFailure(object.id, 'TRANSFORM_MODE_UNSUPPORTED', `LinearPattern does not expose transform mode: ${String(transformMode)}`)
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Linear pattern base has no valid recomputed Shape.')
      const originalObjects = linkedObjects(object, 'Originals', document)
      const occurrences = numberProperty('Occurrences', 2)
      if (!Number.isSafeInteger(occurrences) || occurrences < 2 || occurrences > 100) return geometryFailure(object.id, 'PATTERN_OCCURRENCES_INVALID', 'Linear pattern occurrences must be an integer between 2 and 100.')
      const length = numberProperty('Length', 20)
      if (!(length > 0)) return geometryFailure(object.id, 'PATTERN_LENGTH_INVALID', 'Linear pattern length must be greater than zero.')
      const mode = propertyValue(object, 'Mode')
      if (mode !== undefined && mode !== 'Extent' && mode !== 'Spacing' && mode !== 0 && mode !== 1) return geometryFailure(object.id, 'LINEAR_PATTERN_MODE_UNSUPPORTED', `Bitbybit linear pattern does not expose FreeCAD mode: ${String(mode)}`)
      const direction = propertyValue(object, 'Direction')
      const defaultAxis: Point3 = direction === 'Vertical' ? [0, 1, 0] : direction === 'Normal' ? [0, 0, 1] : [1, 0, 0]
      const directionVector = vectorProperty('DirectionVector', defaultAxis)
      if (!directionVector || directionVector.every((coordinate) => coordinate === 0)) return geometryFailure(object.id, 'LINEAR_PATTERN_DIRECTION_INVALID', 'Linear pattern direction vector must be finite and non-zero.')
      const directionLength = Math.hypot(...directionVector)
      const axis = directionVector.map((coordinate) => coordinate / directionLength) as Point3
      if (propertyValue(object, 'Reversed') === true) { axis[0] *= -1; axis[1] *= -1; axis[2] *= -1 }
      const spacing = numberProperty('Offset', length)
      const spacingValues = numericListProperty(object, 'Spacings')
      if (spacingValues.error) return geometryFailure(object.id, 'PATTERN_SPACINGS_INVALID', spacingValues.error)
      const spacingPatternValues = numericListProperty(object, 'SpacingPattern')
      if (spacingPatternValues.error) return geometryFailure(object.id, 'PATTERN_SPACING_PATTERN_INVALID', spacingPatternValues.error)
      const steps = linearPatternSteps(occurrences, mode, length, spacing, spacingValues.values, spacingPatternValues.values)
      if (steps.error) return geometryFailure(object.id, 'PATTERN_SPACING_INVALID', steps.error)
      const direction2 = propertyValue(object, 'Direction2')
      const hasSecondDirection = direction2 !== undefined && direction2 !== null && direction2 !== 'None' && direction2 !== ''
      if (hasSecondDirection && direction2 !== 'Horizontal' && direction2 !== 'Vertical' && direction2 !== 'Normal') return geometryFailure(object.id, 'LINEAR_PATTERN_DIRECTION_UNSUPPORTED', `Bitbybit linear pattern does not expose FreeCAD second-direction reference: ${String(direction2)}`)
      const occurrences2 = numberProperty('Occurrences2', 1)
      if (hasSecondDirection && (!Number.isSafeInteger(occurrences2) || occurrences2 < 2 || occurrences2 > 100)) return geometryFailure(object.id, 'PATTERN_OCCURRENCES_INVALID', 'Linear pattern second-direction occurrences must be an integer between 2 and 100.')
      if (hasSecondDirection && occurrences * occurrences2 > 100) return geometryFailure(object.id, 'PATTERN_INSTANCE_LIMIT', 'Linear pattern cannot create more than 100 instances across both directions.')
      const length2 = numberProperty('Length2', 20)
      if (hasSecondDirection && !(length2 > 0)) return geometryFailure(object.id, 'PATTERN_LENGTH_INVALID', 'Linear pattern second-direction length must be greater than zero.')
      const mode2 = propertyValue(object, 'Mode2')
      if (hasSecondDirection && mode2 !== undefined && mode2 !== 'Extent' && mode2 !== 'Spacing' && mode2 !== 0 && mode2 !== 1) return geometryFailure(object.id, 'LINEAR_PATTERN_MODE_UNSUPPORTED', `Bitbybit linear pattern does not expose FreeCAD second-direction mode: ${String(mode2)}`)
      const spacing2 = numberProperty('Offset2', length2)
      const spacingValues2 = numericListProperty(object, 'Spacings2')
      if (spacingValues2.error) return geometryFailure(object.id, 'PATTERN_SPACINGS_INVALID', spacingValues2.error)
      const spacingPatternValues2 = numericListProperty(object, 'SpacingPattern2')
      if (spacingPatternValues2.error) return geometryFailure(object.id, 'PATTERN_SPACING_PATTERN_INVALID', spacingPatternValues2.error)
      const steps2 = hasSecondDirection ? linearPatternSteps(occurrences2, mode2, length2, spacing2, spacingValues2.values, spacingPatternValues2.values) : { distances: [0] }
      if (steps2.error) return geometryFailure(object.id, 'PATTERN_SPACING_INVALID', `Second direction: ${steps2.error}`)
      const transformedCopies = async (sourceShape: ShapeHandle) => {
        const copies: ShapeHandle[] = []
        try {
          for (let index = 1; index < occurrences; index += 1) {
          const offset = steps.distances![index]
          copies.push(await geometry.applyPlacement({ ...documentContext, shape: sourceShape, placement: { translation: [axis[0] * offset, axis[1] * offset, axis[2] * offset], rotationAxis: [0, 0, 1], rotationAngle: 0 } }))
          }
          let instances: ShapeHandle[] = [sourceShape, ...copies]
        if (hasSecondDirection) {
          const firstDirectionInstances = [...instances]
          const firstCopiesCount = copies.length
          const axis2: [number, number, number] = direction2 === 'Vertical' ? [0, 1, 0] : direction2 === 'Normal' ? [0, 0, 1] : [1, 0, 0]
          if (propertyValue(object, 'Reversed2') === true) { axis2[0] *= -1; axis2[1] *= -1; axis2[2] *= -1 }
          for (let index = 1; index < occurrences2; index += 1) {
            const offset = steps2.distances![index]
            for (const parent of firstDirectionInstances) copies.push(await geometry.applyPlacement({ ...documentContext, shape: parent, placement: { translation: [axis2[0] * offset, axis2[1] * offset, axis2[2] * offset], rotationAxis: [0, 0, 1], rotationAngle: 0 } }))
          }
          instances = [...firstDirectionInstances, ...copies.slice(firstCopiesCount)]
        }
          return instances.slice(1)
        } catch (error) {
          await Promise.allSettled(copies.map((copy) => geometry.release(copy)))
          throw error
        }
      }
      if (featureTransformMode(transformMode)) {
        const featureError = validateFeatureTransformSources(originalObjects)
        if (featureError) return geometryFailure(object.id, 'TRANSFORM_ORIGINALS_INVALID', featureError)
        result = await applyFeatureTransforms(baseShape, originalObjects, transformedCopies)
      } else {
        const copies = await transformedCopies(baseShape)
        try { result = await geometry.union({ ...documentContext, shapes: [baseShape, ...copies] }) }
        finally { await Promise.allSettled(copies.map((copy) => geometry.release(copy))) }
      }
    } else if (object.typeId === 'PartDesign::PolarPattern') {
      const transformMode = propertyValue(object, 'TransformMode')
      if (!wholeTransformMode(transformMode) && !featureTransformMode(transformMode)) return geometryFailure(object.id, 'TRANSFORM_MODE_UNSUPPORTED', `PolarPattern does not expose transform mode: ${String(transformMode)}`)
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Polar pattern base has no valid recomputed Shape.')
      const originalObjects = linkedObjects(object, 'Originals', document)
      const occurrences = numberProperty('Occurrences', 3)
      if (!Number.isSafeInteger(occurrences) || occurrences < 2 || occurrences > 100) return geometryFailure(object.id, 'PATTERN_OCCURRENCES_INVALID', 'Polar pattern occurrences must be an integer between 2 and 100.')
      const angle = numberProperty('Angle', 360)
      if (!(angle > 0) || angle > 360) return geometryFailure(object.id, 'PATTERN_ANGLE_INVALID', 'Polar pattern angle must be greater than zero and no more than 360 degrees.')
      const mode = propertyValue(object, 'Mode')
      if (mode !== undefined && mode !== 'Extent' && mode !== 'Spacing' && mode !== 0 && mode !== 1) return geometryFailure(object.id, 'POLAR_PATTERN_MODE_UNSUPPORTED', `Bitbybit polar pattern does not expose FreeCAD mode: ${String(mode)}`)
      const axisName = propertyValue(object, 'Axis')
      const defaultAxis: Point3 = axisName === 'Horizontal' ? [1, 0, 0] : axisName === 'Vertical' ? [0, 1, 0] : [0, 0, 1]
      const axisDirection = vectorProperty('AxisDirection', defaultAxis)
      const axisOrigin = vectorProperty('AxisOrigin', [0, 0, 0])
      if (!axisDirection || axisDirection.every((coordinate) => coordinate === 0) || !axisOrigin) return geometryFailure(object.id, 'POLAR_PATTERN_AXIS_INVALID', 'Polar pattern axis origin must be finite and its direction must be non-zero.')
      const axisLength = Math.hypot(...axisDirection)
      const axis = axisDirection.map((coordinate) => coordinate / axisLength) as Point3
      if (propertyValue(object, 'Reversed') === true) { axis[0] *= -1; axis[1] *= -1; axis[2] *= -1 }
      const spacing = numberProperty('Offset', angle / occurrences)
      const spacingValues = numericListProperty(object, 'Spacings')
      if (spacingValues.error) return geometryFailure(object.id, 'PATTERN_SPACINGS_INVALID', spacingValues.error)
      const spacingPatternValues = numericListProperty(object, 'SpacingPattern')
      if (spacingPatternValues.error) return geometryFailure(object.id, 'PATTERN_SPACING_PATTERN_INVALID', spacingPatternValues.error)
      const steps = polarPatternSteps(occurrences, mode, angle, spacing, spacingValues.values, spacingPatternValues.values)
      if (steps.error) return geometryFailure(object.id, 'PATTERN_SPACING_INVALID', steps.error)
      const transformedCopies = async (sourceShape: ShapeHandle) => {
        const copies: ShapeHandle[] = []
        try {
          for (let index = 1; index < occurrences; index += 1) {
            const rotationAngle = steps.angles![index]
            copies.push(await geometry.applyPlacement({ ...documentContext, shape: sourceShape, placement: { translation: rotatedTranslation(axisOrigin, axis, rotationAngle), rotationAxis: axis, rotationAngle } }))
          }
          return copies
        } catch (error) {
          await Promise.allSettled(copies.map((copy) => geometry.release(copy)))
          throw error
        }
      }
      if (featureTransformMode(transformMode)) {
        const featureError = validateFeatureTransformSources(originalObjects)
        if (featureError) return geometryFailure(object.id, 'TRANSFORM_ORIGINALS_INVALID', featureError)
        result = await applyFeatureTransforms(baseShape, originalObjects, transformedCopies)
      } else {
        const copies = await transformedCopies(baseShape)
        try { result = await geometry.union({ ...documentContext, shapes: [baseShape, ...copies] }) }
        finally { await Promise.allSettled(copies.map((copy) => geometry.release(copy))) }
      }
    } else if (object.typeId === 'PartDesign::Hole') {
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Hole base has no valid recomputed Shape.')
      let diameter = numberProperty('Diameter', 5)
      if (!(diameter > 0)) return geometryFailure(object.id, 'HOLE_DIAMETER_INVALID', 'Hole diameter must be greater than zero.')
      const depth = numberProperty('Depth', 10)
      if (!(depth > 0)) return geometryFailure(object.id, 'HOLE_DEPTH_INVALID', 'Hole depth must be greater than zero.')
      const holeType = propertyValue(object, 'DepthType') ?? propertyValue(object, 'Type')
      if (holeType !== undefined && holeType !== 'Dimension' && holeType !== 'Through all' && holeType !== 'ThroughAll' && holeType !== 0 && holeType !== 1) return geometryFailure(object.id, 'HOLE_TYPE_UNSUPPORTED', `Bitbybit Hole does not expose FreeCAD hole type: ${String(holeType)}`)
      const cutType = propertyValue(object, 'HoleCutType')
      if (cutType !== undefined && cutType !== 'None' && cutType !== 'Counterbore' && cutType !== 'Countersink' && cutType !== 'Counterdrill' && cutType !== 0 && cutType !== 1 && cutType !== 2 && cutType !== 3) return geometryFailure(object.id, 'HOLE_CUT_TYPE_UNSUPPORTED', `Bitbybit Hole does not expose FreeCAD hole cut type: ${String(cutType)}`)
      const threaded = propertyValue(object, 'Threaded') === true || propertyValue(object, 'Threading') === true
      const modelThread = propertyValue(object, 'ModelThread') === true
      if (modelThread && !threaded) return geometryFailure(object.id, 'HOLE_MODEL_THREAD_INVALID', 'ModelThread requires Threaded to be enabled.')
      const threadTypes = ['None', 'ISOMetricProfile', 'ISOMetricFineProfile', 'UNC', 'UNF', 'UNEF', 'NPT', 'BSP', 'BSW', 'BSF', 'ISOTyre']
      const threadTypeValue = propertyValue(object, 'ThreadType')
      const threadType = typeof threadTypeValue === 'number' ? threadTypes[threadTypeValue] : typeof threadTypeValue === 'string' ? threadTypeValue : 'None'
      if (!threadTypes.includes(threadType)) return geometryFailure(object.id, 'HOLE_THREAD_TYPE_INVALID', `Hole thread type is invalid: ${String(threadTypeValue)}`)
      const threadSizeValue = propertyValue(object, 'ThreadSize')
      const threadSize = typeof threadSizeValue === 'string' ? threadSizeValue : ''
      const metricDesignation = /^M([0-9]+(?:\.[0-9]+)?)x([0-9]+(?:\.[0-9]+)?)$/i.exec(threadSize)
      const threadMajorDiameter = numberProperty('ThreadDiameter', metricDesignation ? Number(metricDesignation[1]) : 0)
      const threadPitch = numberProperty('ThreadPitch', metricDesignation ? Number(metricDesignation[2]) : 0)
      if (threaded && (threadType === 'None' || !(threadMajorDiameter > 0) || !(threadPitch > 0))) return geometryFailure(object.id, 'HOLE_THREAD_STANDARD_INVALID', 'Threaded Hole requires a standard ThreadType plus a positive ThreadDiameter and ThreadPitch (or a metric M<size>x<pitch> designation).')
      if (threaded && diameter >= threadMajorDiameter) diameter = threadMajorDiameter - threadPitch
      if (threaded && !(diameter > 0) || threaded && diameter >= threadMajorDiameter) return geometryFailure(object.id, 'HOLE_THREAD_DIAMETER_INVALID', 'Thread tap-drill diameter must be positive and smaller than the thread major diameter.')
      const threadDirectionValue = propertyValue(object, 'ThreadDirection')
      const threadLeftHanded = threadDirectionValue === 'Left' || threadDirectionValue === 1
      if (threadDirectionValue !== undefined && threadDirectionValue !== 'Right' && threadDirectionValue !== 'Left' && threadDirectionValue !== 0 && threadDirectionValue !== 1) return geometryFailure(object.id, 'HOLE_THREAD_DIRECTION_INVALID', `Hole thread direction is invalid: ${String(threadDirectionValue)}`)
      const drillPoint = propertyValue(object, 'DrillPoint')
      if (drillPoint !== undefined && drillPoint !== 'Flat' && drillPoint !== 'Angled' && drillPoint !== 0 && drillPoint !== 1) return geometryFailure(object.id, 'HOLE_DRILL_POINT_UNSUPPORTED', `Bitbybit Hole does not expose FreeCAD drill point: ${String(drillPoint)}`)
      const position = vectorProperty('Position', [0, 0, 0])
      if (!position) return geometryFailure(object.id, 'HOLE_POSITION_INVALID', 'Hole Position must contain finite x, y and z coordinates.')
      const direction = vectorProperty('Direction', [0, 0, 1])
      if (!direction || direction.every((coordinate) => coordinate === 0)) return geometryFailure(object.id, 'HOLE_DIRECTION_INVALID', 'Hole Direction must be a finite non-zero vector.')
      const reversed = propertyValue(object, 'Reversed') === true
      const cutDirection: Point3 = reversed ? [-direction[0], -direction[1], -direction[2]] : direction
      const radius = diameter / 2
      const outer = Array.from({ length: 32 }, (_, index): [number, number, number] => {
        const angle = 2 * Math.PI * index / 32
        return [position[0] + radius * Math.cos(angle), position[1] + radius * Math.sin(angle), position[2]]
      })
      const throughAll = holeType === 'Through all' || holeType === 'ThroughAll' || holeType === 1
      const tapered = propertyValue(object, 'Tapered') === true
      const angledDrill = drillPoint === 'Angled' || drillPoint === 1
      if (angledDrill && throughAll) return geometryFailure(object.id, 'HOLE_DRILL_POINT_UNSUPPORTED', 'Angled drill points require a finite Dimension hole depth.')
      const taperedAngle = tapered ? numberProperty('TaperedAngle', 90) : 90
      if (tapered && (!(taperedAngle > 0) || taperedAngle >= 180)) return geometryFailure(object.id, 'HOLE_TAPERED_ANGLE_INVALID', 'TaperedAngle must be greater than zero and less than 180 degrees; 90 degrees is a straight hole.')
      const taperSlope = tapered ? Math.tan((taperedAngle - 90) * Math.PI / 180) : 0
      if (!Number.isFinite(taperSlope)) return geometryFailure(object.id, 'HOLE_TAPERED_ANGLE_INVALID', 'TaperedAngle produces a non-finite taper slope.')
      const drillAngle = angledDrill ? numberProperty('DrillPointAngle', 118) : 180
      if (angledDrill && (!(drillAngle > 0) || drillAngle >= 180)) return geometryFailure(object.id, 'HOLE_DRILL_ANGLE_INVALID', 'Drill point angle must be greater than zero and less than 180 degrees.')
      const tipSlope = angledDrill ? Math.tan((180 - drillAngle) * Math.PI / 360) : Number.POSITIVE_INFINITY
      if (angledDrill && (!(tipSlope > 0) || !Number.isFinite(tipSlope))) return geometryFailure(object.id, 'HOLE_DRILL_ANGLE_INVALID', 'Drill point angle produces an invalid conical tip.')
      let cylindricalDepth = depth
      if (angledDrill && propertyValue(object, 'DrillForDepth') === true) {
        const denominator = 1 + taperSlope / tipSlope
        cylindricalDepth = (depth - radius / tipSlope) / denominator
        if (!(cylindricalDepth > 0) || !Number.isFinite(cylindricalDepth)) return geometryFailure(object.id, 'HOLE_DRILL_DEPTH_INVALID', 'Hole Depth is too short for the selected diameter, taper and included drill-point angle.')
      }
      let primary: ShapeHandle
      const holeBottomRadius = radius + taperSlope * cylindricalDepth
      if (!(holeBottomRadius > 0) || !Number.isFinite(holeBottomRadius)) return geometryFailure(object.id, 'HOLE_TAPERED_RADIUS_INVALID', 'TaperedAngle produces a non-positive or non-finite bottom radius.')
      if (tapered) {
        if (throughAll) return geometryFailure(object.id, 'HOLE_TAPERED_THROUGH_ALL_UNSUPPORTED', 'Tapered Hole requires a finite Dimension depth through the Bitbybit cone contract.')
        const tool = await geometry.createCone({ ...documentContext, radius1: radius, radius2: holeBottomRadius, height: cylindricalDepth, center: position, direction: cutDirection, angle: 360 })
        try {
          primary = await geometry.cut({ ...documentContext, base: baseShape, tools: [tool] })
        } finally {
          await geometry.release(tool)
        }
      } else if (throughAll || !geometry.topologyHistory) primary = await geometry.pocket({ ...documentContext, base: baseShape, profile: { outer }, length: cylindricalDepth, direction: cutDirection, throughAll })
      else {
        const tool = await geometry.createCylinder({ ...documentContext, radius, height: cylindricalDepth, center: position, direction: cutDirection, angle: 360 })
        try {
          primary = await geometry.cut({ ...documentContext, base: baseShape, tools: [tool] })
        } finally {
          await geometry.release(tool)
        }
      }
      if (angledDrill) {
        const tipHeight = holeBottomRadius / tipSlope
        const tipCenter: Point3 = [position[0] + cutDirection[0] * cylindricalDepth, position[1] + cutDirection[1] * cylindricalDepth, position[2] + cutDirection[2] * cylindricalDepth]
        const tip = await geometry.createCone({ ...documentContext, radius1: holeBottomRadius, radius2: 0, height: tipHeight, center: tipCenter, direction: cutDirection, angle: 360 })
        try {
          const pointed = await geometry.cut({ ...documentContext, base: primary, tools: [tip] })
          await geometry.release(primary)
          primary = pointed
        } finally {
          await geometry.release(tip)
        }
      }
      const counterbore = cutType === 'Counterbore' || cutType === 1
      const counterdrill = cutType === 'Counterdrill' || cutType === 3
      if (cutType === undefined || cutType === 'None' || cutType === 0) {
        result = primary
      } else {
        const cutDiameter = numberProperty('HoleCutDiameter', diameter * 1.5)
        if (!(cutDiameter > diameter)) {
          await geometry.release(primary)
          return geometryFailure(object.id, 'HOLE_CUT_DIAMETER_INVALID', 'Hole cut diameter must be greater than the drill diameter.')
        }
        const cutDepth = numberProperty('HoleCutDepth', 2)
        if (!(cutDepth > 0)) {
          await geometry.release(primary)
          return geometryFailure(object.id, 'HOLE_CUT_DEPTH_INVALID', 'Hole cut depth must be greater than zero.')
        }
        const secondary: ShapeHandle[] = []
        try {
          if (counterbore) {
            secondary.push(await geometry.createCylinder({ ...documentContext, radius: cutDiameter / 2, height: cutDepth, center: position, direction: cutDirection, angle: 360 }))
          } else {
            const sinkAngle = numberProperty('HoleCutCountersinkAngle', 90)
            if (!(sinkAngle > 0) || sinkAngle >= 180) {
              return geometryFailure(object.id, 'HOLE_CUT_ANGLE_INVALID', 'Countersink angle must be greater than zero and less than 180 degrees.')
            }
            const sinkHeight = (cutDiameter - diameter) / 2 / Math.tan(sinkAngle * Math.PI / 360)
            const sinkCenter: Point3 = counterdrill
              ? [position[0] + cutDirection[0] * cutDepth, position[1] + cutDirection[1] * cutDepth, position[2] + cutDirection[2] * cutDepth]
              : position
            if (counterdrill) secondary.push(await geometry.createCylinder({ ...documentContext, radius: cutDiameter / 2, height: cutDepth, center: position, direction: cutDirection, angle: 360 }))
            secondary.push(await geometry.createCone({ ...documentContext, radius1: cutDiameter / 2, radius2: radius, height: sinkHeight, center: sinkCenter, direction: cutDirection, angle: 360 }))
          }
          result = await geometry.cut({ ...documentContext, base: primary, tools: secondary })
        } finally {
          await Promise.allSettled([geometry.release(primary), ...secondary.map((shape) => geometry.release(shape))])
        }
      }
      if (modelThread) {
        if (!geometry.modeledThread) {
          await geometry.release(result)
          return geometryFailure(object.id, 'HOLE_MODEL_THREAD_RUNTIME_UNAVAILABLE', 'The geometry runtime does not provide modeled thread cutting.')
        }
        const threadDepthTypeValue = propertyValue(object, 'ThreadDepthType')
        const threadDepthType = typeof threadDepthTypeValue === 'number' ? ['Hole Depth', 'Dimension', 'Tapped (DIN76)'][threadDepthTypeValue] : threadDepthTypeValue ?? 'Hole Depth'
        if (!['Hole Depth', 'Dimension', 'Tapped (DIN76)'].includes(String(threadDepthType))) {
          await geometry.release(result)
          return geometryFailure(object.id, 'HOLE_THREAD_DEPTH_TYPE_INVALID', `Hole thread depth type is invalid: ${String(threadDepthTypeValue)}`)
        }
        const threadDepth = threadDepthType === 'Dimension' ? numberProperty('ThreadDepth', depth) : threadDepthType === 'Tapped (DIN76)' ? depth - 4 * threadPitch : depth
        if (!(threadDepth > 0) || threadDepth > depth) {
          await geometry.release(result)
          return geometryFailure(object.id, 'HOLE_THREAD_DEPTH_INVALID', 'Modeled thread depth must be positive and no greater than the finite hole depth.')
        }
        const clearance = propertyValue(object, 'UseCustomThreadClearance') === true ? numberProperty('CustomThreadClearance', 0) : 0
        if (!Number.isFinite(clearance) || threadMajorDiameter + clearance <= diameter) {
          await geometry.release(result)
          return geometryFailure(object.id, 'HOLE_THREAD_CLEARANCE_INVALID', 'Thread clearance must leave the major diameter greater than the tap-drill diameter.')
        }
        const threadedResult = await geometry.modeledThread({ ...documentContext, base: result, minorDiameter: diameter, majorDiameter: threadMajorDiameter + clearance, pitch: threadPitch, depth: threadDepth, center: position, direction: cutDirection, leftHanded: threadLeftHanded })
        await geometry.release(result)
        result = threadedResult
      }
    } else if (object.typeId === 'PartDesign::Chamfer' || object.typeId === 'Part::Chamfer') {
      const baseObject = linkedObject(object, 'Base', document)
      const baseShape = baseObject ? shapes.get(baseObject.id) : undefined
      if (!baseShape) return geometryFailure(object.id, 'BASE_SHAPE_MISSING', 'Chamfer base has no valid recomputed Shape.')
      const chamferType = propertyValue(object, 'ChamferType')
      if (chamferType !== undefined && chamferType !== 0 && chamferType !== 'Equal distance') return geometryFailure(object.id, 'CHAMFER_MODE_UNSUPPORTED', `Bitbybit 1.1.1 does not expose PartDesign Chamfer mode: ${String(chamferType)}`)
      if (propertyValue(object, 'FlipDirection') === true) return geometryFailure(object.id, 'CHAMFER_FLIP_UNSUPPORTED', 'Bitbybit 1.1.1 equal-distance Chamfer does not expose FlipDirection.')
      const selected = dressUpEdgeIndexes(object, baseObject as DocumentObjectSnapshot)
      if (selected.code) return geometryFailure(object.id, selected.code, selected.message as string)
      result = await geometry.chamfer({ ...documentContext, base: baseShape, distance: numberProperty('Size', numberProperty('Distance', 1)), indexes: selected.indexes })
    } else {
      return base
    }
    if (placement) {
      const unplaced = result
      let placed: ShapeHandle | undefined
      try {
        placed = await geometry.applyPlacement({ ...documentContext, shape: unplaced, placement })
        await geometry.release(unplaced)
        result = placed
      } catch (error) {
        if (placed) await Promise.allSettled([geometry.release(placed)])
        else await Promise.allSettled([geometry.release(unplaced)])
        throw error
      }
    }
    if (object.typeId.startsWith('PartDesign::') && geometry.qualityReport) {
      const quality = await geometry.qualityReport(result)
      if (quality.isNull || quality.solids !== 1) {
        await geometry.release(result)
        return geometryFailure(object.id, 'PARTDESIGN_SINGLE_SOLID_REQUIRED', `PartDesign feature result must contain exactly one solid; received ${quality.solids}.`)
      }
    }
    let topology: ObjectTopologySnapshot | undefined
    try {
      topology = await topologyForObject(geometry, object, document, shapes, result, context)
    } catch (error) {
      await Promise.allSettled([geometry.release(result)])
      throw error
    }
    if (context.signal.aborted || context.isCurrent?.() === false) {
      await geometry.release(result)
      throw new DOMException('Recompute result is no longer current.', 'AbortError')
    }
    const previous = shapes.get(object.id)
    shapes.set(object.id, result)
    if (previous && previous.id !== result.id) await geometry.release(previous)
    const outputObject = computedLinearLength === undefined ? (base.updatedObject ?? object) : {
      ...(base.updatedObject ?? object),
      properties: (base.updatedObject ?? object).properties.map((property) => property.name === 'Length' ? { ...property, value: computedLinearLength } : property),
    }
    return topology ? { ...base, updatedObject: { ...outputObject, topology } } : computedLinearLength === undefined ? base : { ...base, updatedObject: outputObject }
  } catch (error) {
    if (context.signal.aborted || isAbortError(error)) throw error
    return geometryFailure(object.id, 'GEOMETRY_EXECUTION_FAILED', error instanceof Error ? error.message : String(error))
  }
}
