{"version":3,"file":"bloklabs-angular.mjs","sources":["../../../../dist/.angular-build/angular/provide-blok.ts","../../../../dist/.angular-build/angular/block-context.ts","../../../../dist/.angular-build/angular/blok-instance.ts","../../../../dist/.angular-build/angular/block-portal-registry.ts","../../../../dist/.angular-build/angular/registry-map.ts","../../../../dist/.angular-build/angular/blok-content.directive.ts","../../../../dist/.angular-build/components/errors/tool-not-found.ts","../../../../dist/.angular-build/components/utils/id-generator.ts","../../../../dist/.angular-build/shared/flatten-tree.ts","../../../../dist/.angular-build/components/utils/blocks-tree.ts","../../../../dist/.angular-build/components/utils/blocks-api.ts","../../../../dist/.angular-build/components/utils/readonly-config.ts","../../../../dist/.angular-build/shared/deep-equal.ts","../../../../dist/.angular-build/shared/output-data.ts","../../../../dist/.angular-build/shared/prop-schema.ts","../../../../dist/.angular-build/components/constants/data-attributes.ts","../../../../dist/.angular-build/components/utils/html.ts","../../../../dist/.angular-build/tools/nested-blocks.ts","../../../../dist/.angular-build/tools/child-decoration.ts","../../../../dist/.angular-build/components/events/BlockChildrenMounted.ts","../../../../dist/.angular-build/angular/blok-editor.component.ts","../../../../dist/.angular-build/angular/createAngularBlock.ts","../../../../dist/.angular-build/angular/useBlocks.ts","../../../../dist/.angular-build/angular/useBlokReady.ts","../../../../dist/.angular-build/bloklabs-angular.ts"],"sourcesContent":["import {\n  InjectionToken,\n  makeEnvironmentProviders,\n  type EnvironmentProviders,\n} from '@angular/core';\nimport type { BlokAngularConfig } from './types';\n\n/**\n * DI token holding app-wide Blok defaults (shared tools registry, default theme,\n * i18n). Merged under per-instance inputs by `BlokEditorComponent`.\n */\nexport const BLOK_DEFAULT_CONFIG = new InjectionToken<Partial<BlokAngularConfig>>(\n  'BLOK_DEFAULT_CONFIG'\n);\n\n/**\n * Standalone provider registering app-wide Blok defaults.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n *   providers: [provideBlok({ theme: 'dark', tools: sharedTools })],\n * });\n * ```\n */\nexport function provideBlok(defaults: Partial<BlokAngularConfig>): EnvironmentProviders {\n  return makeEnvironmentProviders([{ provide: BLOK_DEFAULT_CONFIG, useValue: defaults }]);\n}\n","import type { API, BlockAPI } from '@bloklabs/core';\n// packages/angular/src/block-context.ts\nimport { InjectionToken, type Signal } from '@angular/core';\n\n\n/**\n * One child's decoration: attribute name → value. `null`/`undefined` removes the\n * attribute; a boolean or number is stringified (so `false` writes\n * `data-active=\"false\"`, which CSS can select, rather than dropping the hook).\n */\nexport type ChildAttributes = Record<string, string | number | boolean | null | undefined>;\n\n/** The per-child decorator accepted by {@link AngularBlockRenderContext.mountChildren}. */\nexport type ChildAttributesFn = (child: BlockAPI, index: number) => ChildAttributes;\n\n/**\n * Context handed to a `createAngularBlock` component. Delivered via DI (the\n * BLOK_BLOCK_CONTEXT token) rather than @Input, because core constructs the tool\n * outside Angular and the signal-input() form does not compile under the repo's\n * JIT test harness. The ONLY data write path is `commit`.\n */\nexport interface AngularBlockRenderContext<Data> {\n  /** Reactive, FROZEN snapshot of the block data. Read `data()`; never mutate. */\n  data: Signal<Readonly<Data>>;\n  /** The ONLY data write path: merge a partial patch and sync once. */\n  commit: (patch: Partial<Data>) => void;\n  /** This block's per-block API (id, getChildren, dispatchChange…). */\n  block: BlockAPI;\n  /**\n   * The EDITOR-level API this block belongs to (`api.blocks`, `api.caret`,\n   * `api.toolbar`…) — the same object a vanilla tool receives in its\n   * constructor. Reach for it when a block has to drive the document around it\n   * instead of routing everything through `block.call()` string dispatch.\n   *\n   * For the reactive, id/parentId-relative view of the tree (and to re-render\n   * when your own children change), pair `injectBlocks` with\n   * `injectBlokInstance()` instead — the api handle itself is not reactive.\n   */\n  api: API;\n  /**\n   * Reactive read-only flag. Read `readOnly()` in the template to disable\n   * editing (drop `contenteditable`, hide controls). Toggled IN PLACE by core's\n   * read-only switch — the component reacts without a remount, so ephemeral\n   * state survives. A block that ignores it stays interactive when the editor is\n   * read-only (same contract as a vanilla tool's `setReadOnly`).\n   */\n  readOnly: Signal<boolean>;\n  /**\n   * Container blocks only: append this block's real child holders into `host`\n   * (a `data-blok-nested` element the author owns). Call it once in\n   * `ngAfterViewInit`; the factory re-runs the same mount on every data change\n   * so late-added children appear. Angular must NOT manage these child holders.\n   *\n   * `childAttributes` decorates each child's HOLDER after the holders are\n   * mounted, and is REMEMBERED — every later remount re-applies it. Named hooks\n   * (`data-step-index`, `data-active`…) replace positional `:nth-child()` CSS\n   * over Blok's holders, which breaks the moment a child is inserted, removed or\n   * reordered. The holders stay DIRECT children of `host` — core requires that\n   * (hierarchy reparenting and caret navigation compare `holder.parentElement`\n   * by identity), so decoration is attributes, never wrapper elements.\n   * Attributes the callback stops producing are removed on the next pass.\n   *\n   * `childContentAttributes` is the same decoration applied one level IN — on\n   * each child's `[data-blok-element-content]` wrapper instead of its holder —\n   * and is remembered the same way. Core's decoration law blesses both, and a\n   * container needs both: the holder is the child's outer box (rails, indices,\n   * hover states), the content wrapper is where the child's own text box begins,\n   * which is what a numbered rail or a connector line has to align to. Reach for\n   * it instead of walking core's wrapper chain from a holder hook (`[data-step] >\n   * [data-blok-element-content] > …`) — those selectors encode engine DOM in host\n   * CSS and break when that structure changes. A child whose DOM has not\n   * committed yet has no wrapper to write to and is stamped on the next pass.\n   *\n   * Writing on a child's holder is inert by design: core's mutation filter drops\n   * a holder-targeted attribute record for the child block and suppresses it for\n   * the container. The guarantee stops at the holder and its\n   * `[data-blok-element-content]` wrapper — writing AT or BELOW a child's tool\n   * root DOES score as that child's edit.\n   */\n  mountChildren: (\n    host: HTMLElement,\n    childAttributes?: ChildAttributesFn,\n    childContentAttributes?: ChildAttributesFn\n  ) => void;\n  /**\n   * Name the element the +/drag toolbar should vertically center on, from inside\n   * the component: `ctx.setToolbarAnchor(this.head().nativeElement)` in\n   * `ngAfterViewInit`. The Angular counterpart of React's/Vue's\n   * `toolbarAnchorRef` — core's `getToolbarAnchorElement` is otherwise a\n   * `(host, block) => Element` hook resolved OUTSIDE the component, so pointing\n   * at an element the template renders meant inventing a data attribute and\n   * `querySelector`-ing for it from\n   * `CreateAngularBlockSpec.getToolbarAnchorElement`.\n   *\n   * A container block whose own chrome is not editable needs an anchor: with\n   * none, core centers the toolbar on the first `[contenteditable]` under the\n   * host, which for a container is its FIRST CHILD BLOCK — parking the +/drag\n   * handles halfway down, beside content that has a toolbar of its own.\n   *\n   * The element set here outranks the declared hook while it is MOUNTED; once it\n   * detaches (or `null` is passed) the hook takes over again, so the toolbar is\n   * never positioned against a stale node. Never calling it keeps core's default.\n   */\n  setToolbarAnchor: (element: HTMLElement | null) => void;\n}\n\n/** DI token carrying the per-block render context into the authored component. */\nexport const BLOK_BLOCK_CONTEXT = new InjectionToken<AngularBlockRenderContext<unknown>>(\n  'BLOK_BLOCK_CONTEXT'\n);\n","import type { Blok } from '@bloklabs/core';\n// packages/angular/src/blok-instance.ts\nimport { inject, InjectionToken, signal, type Signal } from '@angular/core';\n\n\n/**\n * DI token carrying the LIVE editor instance (as a signal) into every block\n * mounted by `createAngularBlock`. `BlokContentDirective` publishes its own\n * `instance` signal through it, so the value is null before the editor is ready\n * and after teardown — matching the React/Vue adapters' pre-ready contract.\n *\n * Provided on the block's ELEMENT injector by the portal registry, so it is\n * per-EDITOR: two editors on one page each publish their own instance.\n */\nexport const BLOK_EDITOR_INSTANCE = new InjectionToken<Signal<Blok | null>>(\n  'BLOK_EDITOR_INSTANCE'\n);\n\n/** Stable \"no editor here\" signal for components mounted outside an editor. */\nconst NO_EDITOR: Signal<Blok | null> = signal(null).asReadonly();\n\n/**\n * The live Blok instance the component is mounted inside, as a signal, or a\n * signal of null before it exists. Inside a `createAngularBlock` component this\n * is the block's OWN editor — so a block can drive the tree it lives in without\n * the host prop-drilling the instance into it:\n *\n * ```ts\n * private readonly editor = injectBlokInstance();\n * private readonly blocks = injectBlocks(this.editor);\n * ```\n *\n * That pairing is also what makes a container block REACTIVE to its own child\n * tree: `injectBlocks` refreshes on the editor's `block changed` event, which\n * core emits for every structural mutation — including children the adapter\n * itself never sees (a pasted paragraph, a Tab-indent from the keyboard).\n *\n * Call it in an injection context (a field initializer or the constructor).\n * Outside an editor it returns a signal of null.\n */\nexport function injectBlokInstance(): Signal<Blok | null> {\n  return inject(BLOK_EDITOR_INSTANCE, { optional: true }) ?? NO_EDITOR;\n}\n","import type { Blok } from '@bloklabs/core';\n// packages/angular/src/block-portal-registry.ts\nimport {\n  ApplicationRef,\n  createComponent,\n  EnvironmentInjector,\n  ErrorHandler,\n  Injector,\n  type ComponentRef,\n  type Signal,\n  type Type,\n} from '@angular/core';\n\n\nimport { BLOK_BLOCK_CONTEXT, type AngularBlockRenderContext } from './block-context';\nimport { BLOK_EDITOR_INSTANCE } from './blok-instance';\n\n/**\n * Tool-config key carrying the editor's portal registry into a\n * `createAngularBlock` tool. The tool is constructed by CORE (outside any Angular\n * injection context), so it cannot `inject()` — the directive injects the\n * editor-scoped registry through each Angular-block tool's `config`, and the tool\n * reads it back from there.\n */\nexport const BLOK_PORTAL_REGISTRY_CONFIG_KEY = '__blokAngularPortalRegistry';\n\n/** One mounted Angular block: the Blok-owned host the component renders into. */\nexport interface BlockPortalEntry {\n  hostEl: HTMLElement;\n  component: Type<unknown>;\n  context: AngularBlockRenderContext<unknown>;\n}\n\n/**\n * Per-editor registry of Angular blocks. Mounts each authored component directly\n * into its core-owned host via `createComponent({ hostElement })` (the Teleport\n * analog) and enrolls it in `ApplicationRef` for change detection. A plain Map —\n * Angular has no reactive-proxy hazard, so no `markRaw` equivalent is needed.\n */\nexport interface BlockPortalRegistry {\n  /** Mount (or replace) the component for `id` into `entry.hostEl`. */\n  register(id: string, entry: BlockPortalEntry): void;\n  /**\n   * Detach + destroy the component for `id`. Safe (no-op) when absent.\n   *\n   * Pass the caller's own `hostEl` to make the teardown OWNERSHIP-CHECKED: the\n   * mount is destroyed only when it is still the one that host registered. Core\n   * composes a replacement block (which registers under the SAME id) BEFORE it\n   * destroys the block it replaces, so a superseded tool's `removed()`/\n   * `destroy()` teardown arrives after the live mount already exists — without\n   * the check it destroys that live componentRef and clears its host.\n   */\n  unregister(id: string, hostEl?: HTMLElement): void;\n  /** Re-run change detection on the block's component (in-place update). */\n  flush(id: string): void;\n  /** Detach + destroy every mounted block (editor teardown / recreate). */\n  destroyAll(): void;\n}\n\n/**\n * Create a fresh portal registry bound to a live Angular environment. One per\n * editor instance (associated via the registry map). The injectors/appRef are\n * passed in (captured by the directive in an injection context) because the\n * registry itself is built outside one.\n *\n * `editor` is the directive's own instance signal. It is passed at CREATION\n * (before the editor exists) rather than set later precisely because it is a\n * signal: blocks mounted during boot read null and re-read the real instance\n * once it resolves.\n * @param envInjector - the app environment injector (parent of each block's)\n * @param appRef - the ApplicationRef each mounted block view is attached to\n * @param errorHandler - where a throwing author component is reported\n * @param editor - signal of the live Blok instance, published to blocks via\n *   {@link BLOK_EDITOR_INSTANCE}; omit for registries with no editor to publish\n */\nexport const createBlockPortalRegistry = (\n  envInjector: EnvironmentInjector,\n  appRef: ApplicationRef,\n  errorHandler: ErrorHandler,\n  editor?: Signal<Blok | null>\n): BlockPortalRegistry => {\n  const mounted = new Map<string, { ref: ComponentRef<unknown>; injector: Injector }>();\n\n  // Change detection runs outside NgZone here; a throwing author component must\n  // degrade to a blank holder, not break core's block insertion.\n  const safe = (fn: () => void): void => {\n    try {\n      fn();\n    } catch (error) {\n      errorHandler.handleError(error);\n    }\n  };\n\n  const teardown = (id: string, ownerHostEl?: HTMLElement): void => {\n    const entry = mounted.get(id);\n\n    if (entry === undefined) {\n      return;\n    }\n\n    const { ref, injector } = entry;\n    // Capture host before deletion so we can clear it below.\n    const hostEl = ref.location.nativeElement as HTMLElement;\n\n    // A superseded owner may not destroy the mount that replaced it.\n    if (ownerHostEl !== undefined && hostEl !== ownerHostEl) {\n      return;\n    }\n\n    mounted.delete(id);\n    appRef.detachView(ref.hostView);\n    ref.destroy();\n    // `Injector.create({ parent })` returns an injector that is NOT torn down by\n    // `ref.destroy()`. We must destroy it explicitly to prevent one small injector\n    // accumulating per block over a long editor session.\n    const destroyable = injector as Injector & { destroy?: () => void };\n    destroyable.destroy?.();\n    // createComponent({ hostElement }) renders INTO an external div. Angular's\n    // destroy() tears down the component instance and CD but does NOT clear the\n    // host's DOM children — we must do it explicitly.\n    hostEl.replaceChildren();\n  };\n\n  return {\n    register(id: string, entry: BlockPortalEntry): void {\n      // Idempotent: replace any prior mount for this id.\n      teardown(id);\n\n      // The context is provided through an ELEMENT injector (a node injector),\n      // so it is destroyed automatically with the component view — no leaked\n      // EnvironmentInjector. The shared app envInjector is the parent, so author\n      // blocks still see app-level providers (HttpClient, etc.).\n      const elementInjector = Injector.create({\n        providers: [\n          { provide: BLOK_BLOCK_CONTEXT, useValue: entry.context },\n          // Per-EDITOR, so two editors on one page each publish their own\n          // instance to their own blocks.\n          ...(editor === undefined\n            ? []\n            : [{ provide: BLOK_EDITOR_INSTANCE, useValue: editor }]),\n        ],\n        parent: envInjector,\n      });\n\n      safe(() => {\n        const ref = createComponent(entry.component, {\n          environmentInjector: envInjector,\n          elementInjector,\n          hostElement: entry.hostEl,\n        });\n\n        appRef.attachView(ref.hostView);\n        mounted.set(id, { ref, injector: elementInjector });\n        // createComponent does not auto-run CD; render synchronously into the\n        // (still-detached) host before core inserts it into the document.\n        ref.changeDetectorRef.detectChanges();\n      });\n    },\n    unregister(id: string, hostEl?: HTMLElement): void {\n      teardown(id, hostEl);\n    },\n    flush(id: string): void {\n      const entry = mounted.get(id);\n\n      if (entry === undefined) {\n        return;\n      }\n\n      safe(() => entry.ref.changeDetectorRef.detectChanges());\n    },\n    destroyAll(): void {\n      for (const id of Array.from(mounted.keys())) {\n        teardown(id);\n      }\n    },\n  };\n};\n","// packages/angular/src/registry-map.ts\nimport type { BlockPortalRegistry } from './block-portal-registry';\n\n/**\n * Associates each live Blok instance with its portal registry. `BlokContentDirective`\n * sets it at creation so consumers (and future composables) can reach an editor's\n * registry. WeakMap → no leak when the editor is destroyed.\n */\nconst registries = new WeakMap<WeakKey, BlockPortalRegistry>();\n\nexport function setRegistry(editor: WeakKey, registry: BlockPortalRegistry): void {\n  registries.set(editor, registry);\n}\n\nexport function getRegistry(editor: WeakKey): BlockPortalRegistry | undefined {\n  return registries.get(editor);\n}\n\nexport function removeRegistry(editor: WeakKey): void {\n  registries.delete(editor);\n}\n","import {\n  Directive,\n  ElementRef,\n  EventEmitter,\n  NgZone,\n  Output,\n  PLATFORM_ID,\n  Input,\n  ApplicationRef,\n  EnvironmentInjector,\n  ErrorHandler,\n  afterNextRender,\n  inject,\n  signal,\n  type OnDestroy,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n// Imported via the package's public specifier so ng-packagr externalizes the\n// core as a peer dependency (consumers share a single Blok instance + CSS).\nimport { Blok as BlokRuntime, type Blok } from '@bloklabs/core';\nimport { BLOK_DEFAULT_CONFIG } from './provide-blok';\nimport type { BlokAngularConfig } from './types';\nimport {\n  BLOK_PORTAL_REGISTRY_CONFIG_KEY,\n  createBlockPortalRegistry,\n  type BlockPortalRegistry,\n} from './block-portal-registry';\nimport { removeRegistry, setRegistry } from './registry-map';\n\n/**\n * Escape-hatch directive and lifecycle engine for Blok (mirrors React's\n * `useBlok` + `BlokContent`). Constructs a Blok instance into its own host\n * element and tears it down on destroy.\n *\n * The editor renders directly into the directive's host element — so the host\n * IS the holder. This sidesteps the fact that Blok core exposes no public\n * `holder` accessor: the adapter never has to read it back, it owns it.\n *\n * `BlokEditorComponent` applies this directive to its internal `<div>` and reads\n * the instance back; consumers can also use it directly for full control:\n * `<div blokContent [config]=\"cfg\" (ready)=\"onReady($event)\"></div>`.\n *\n * Implementation note: classic `@Input()`/`@Output()` are used (not signal\n * `input()`/`output()`) because the repo's Vitest+Analog harness compiles the\n * adapter via JIT, which does not register signal-based members. `instance`\n * remains a plain `signal` (runtime API, JIT-safe) for reactive consumption.\n */\n@Directive({\n  selector: '[blokContent]',\n  standalone: true,\n})\nexport class BlokContentDirective implements OnDestroy {\n  private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n  private readonly ngZone = inject(NgZone);\n  private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n  /**\n   * App-wide defaults from `provideBlok()`, merged UNDER the bound `[config]` so\n   * the escape-hatch path honors them just like `<blok-editor>` (which also\n   * merges, idempotently). Mirrors React's `useBlok` merging context defaults.\n   */\n  private readonly defaults = inject(BLOK_DEFAULT_CONFIG, { optional: true }) ?? {};\n  // Captured in the injection context (field initializers) so the registry can\n  // mount author components via createComponent — core constructs tools outside\n  // Angular DI and cannot inject these itself.\n  private readonly envInjector = inject(EnvironmentInjector);\n  private readonly appRef = inject(ApplicationRef);\n  private readonly errorHandler = inject(ErrorHandler);\n\n  /** Construction-time Blok config (everything except `holder`, which the directive owns). */\n  @Input() config: Partial<BlokAngularConfig> = {};\n\n  /** Changing this input's identity (after the first build) destroys + recreates the editor. */\n  @Input() set recreateKey(value: unknown) {\n    const changed = this.built && value !== this.currentKey;\n    this.currentKey = value;\n\n    if (changed) {\n      this.current?.destroy();\n      this.build();\n    }\n  }\n\n  /** Emits the live Blok instance once it is ready, after `instance` is populated. */\n  @Output() readonly ready = new EventEmitter<Blok>();\n\n  /** The live Blok instance, or null before `isReady` resolves / after destroy. */\n  readonly instance = signal<Blok | null>(null);\n\n  /** The editor created by the most recent construction; used as the staleness key. */\n  private current: Blok | null = null;\n  private destroyed = false;\n  private built = false;\n  private currentKey: unknown;\n  /** The portal registry for the current editor (Angular-block mounting). */\n  private registry: BlockPortalRegistry | undefined;\n\n  constructor() {\n    // afterNextRender is browser-only (skipped during SSR) and runs after the\n    // host element exists and inputs are bound.\n    afterNextRender(() => {\n      // afterNextRender is browser-only by contract, but guard explicitly so the\n      // editor is never constructed during SSR / on a non-browser platform.\n      if (this.destroyed || !this.isBrowser) {\n        return;\n      }\n\n      this.build();\n      this.built = true;\n    });\n  }\n\n  /** Construct a Blok into the host element and publish it once ready. */\n  private build(): void {\n    this.destroyed = false;\n    this.instance.set(null);\n\n    // Tear down any registry from a superseded editor (recreate path) before\n    // building a new one.\n    this.registry?.destroyAll();\n\n    // Merge provideBlok defaults under the bound config (instance wins; tools\n    // registries compose across both layers rather than replacing).\n    const merged: Partial<BlokAngularConfig> = { ...this.defaults, ...this.config };\n\n    if (this.defaults.tools !== undefined || this.config.tools !== undefined) {\n      merged.tools = { ...this.defaults.tools, ...this.config.tools };\n    }\n\n    // Create the editor-scoped portal registry and thread it into every\n    // Angular-block tool's config (vanilla tools pass through untouched).\n    // `this.instance` is handed over at creation: it is a SIGNAL, so blocks\n    // mounted during boot read null and re-read the real editor once isReady\n    // resolves — no ordering problem, and `injectBlokInstance()` inside a block\n    // component tracks the swap.\n    const registry = createBlockPortalRegistry(\n      this.envInjector,\n      this.appRef,\n      this.errorHandler,\n      this.instance\n    );\n\n    this.registry = registry;\n    merged.tools = injectPortalRegistry(merged.tools, registry);\n\n    // Construct outside Angular's zone so the editor's internal DOM churn never\n    // schedules change detection.\n    const blok = this.ngZone.runOutsideAngular(\n      () =>\n        new BlokRuntime({\n          ...merged,\n          holder: this.host.nativeElement,\n        }) as unknown as Blok\n    );\n\n    this.current = blok;\n    setRegistry(blok, registry);\n\n    void blok.isReady.then(() =>\n      this.ngZone.run(() => {\n        // Guard on the constructor-returned reference (not isReady's resolved\n        // value): a superseded or torn-down editor must not publish itself.\n        if (this.current !== blok || this.destroyed) {\n          return;\n        }\n\n        this.instance.set(blok); // assign FIRST…\n        this.ready.emit(blok); // …THEN emit, so consumers see a populated instance.\n      })\n    );\n  }\n\n  ngOnDestroy(): void {\n    this.destroyed = true;\n    this.registry?.destroyAll();\n\n    if (this.current !== null) {\n      removeRegistry(this.current);\n    }\n\n    this.current?.destroy();\n    this.current = null;\n    this.registry = undefined;\n    this.instance.set(null);\n  }\n}\n\n/**\n * Return a NEW tools map (never mutate the consumer's config) where each\n * Angular-block tool carries the portal registry under\n * BLOK_PORTAL_REGISTRY_CONFIG_KEY in its `config`. Vanilla tools are returned\n * unchanged. Handles both entry shapes: a bare constructor and `{ class, config }`.\n */\nfunction injectPortalRegistry(\n  tools: BlokAngularConfig['tools'],\n  registry: BlockPortalRegistry\n): BlokAngularConfig['tools'] {\n  if (tools === undefined) {\n    return tools;\n  }\n\n  const result: Record<string, unknown> = {};\n\n  for (const [name, entry] of Object.entries(tools)) {\n    const asObject = entry as { class?: unknown; config?: Record<string, unknown> } | undefined;\n    const toolClass = (typeof entry === 'function' ? entry : asObject?.class) as\n      | { __isBlokAngularBlock?: boolean }\n      | undefined;\n\n    if (toolClass?.__isBlokAngularBlock === true) {\n      const base = typeof entry === 'function' ? { class: entry } : { ...asObject };\n\n      result[name] = {\n        ...base,\n        config: { ...(base.config ?? {}), [BLOK_PORTAL_REGISTRY_CONFIG_KEY]: registry },\n      };\n    } else {\n      result[name] = entry;\n    }\n  }\n\n  return result as BlokAngularConfig['tools'];\n}\n","/**\n * Thrown when a block tool cannot be resolved during a creation/conversion\n * operation (insert, insertMany/composeBlock, composeBlockData, convert).\n *\n * A typed error lets adapters (React/Vue/Angular useBlocks) distinguish a\n * genuinely-unknown tool — an EXPECTED, recoverable outcome they surface as a\n * `null`/`[]` no-op — from a real bug, WITHOUT brittle `message.includes('not\n * found')` substring matching (which both mis-catches unrelated errors whose\n * message happens to contain \"not found\" and breaks under message localization).\n */\nexport class ToolNotFoundError extends Error {\n  /**\n   * @param toolName - the tool type that could not be resolved\n   * @param message - optional override; defaults to a descriptive message\n   */\n  constructor(public readonly toolName: string, message?: string) {\n    super(message ?? `Block Tool «${toolName}» not found.`);\n    this.name = 'ToolNotFoundError';\n  }\n}\n","/**\n * ID generation utilities\n */\n\n// nanoid replaced with inline crypto implementation for the Angular adapter bundle.\nconst _ID_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-';\nconst _nanoid = (n: number): string => {\n  const buf = crypto.getRandomValues(new Uint8Array(n));\n  return Array.from(buf, (b) => _ID_CHARS[b % 64]).join('');\n};\nconst nanoid = _nanoid;\n\n/**\n * Constants for ID generation\n */\nconst ID_RANDOM_MULTIPLIER = 100_000_000; // 1e8\nconst HEXADECIMAL_RADIX = 16;\n\n/**\n * Create a block id\n * @returns unique block ID\n */\nexport const generateBlockId = (): string => {\n  const idLen = 10;\n\n  return nanoid(idLen);\n};\n\n/**\n * Nanoid-compatible block ID pattern: exactly 10 URL-safe characters (A-Z, a-z, 0-9, _, -)\n */\nconst BLOCK_ID_PATTERN = /^[A-Za-z0-9_-]{10}$/;\n\n/**\n * Returns true if the given string is a valid block ID (nanoid format).\n * @param id - string to check\n */\nexport const isValidBlockId = (id: string): boolean => BLOCK_ID_PATTERN.test(id);\n\n/**\n * Returns random generated identifier\n * @param prefix - identifier prefix\n * @returns unique identifier with prefix\n */\nexport const generateId = (prefix = ''): string => {\n  return `${prefix}${(Math.floor(Math.random() * ID_RANDOM_MULTIPLIER)).toString(HEXADECIMAL_RADIX)}`;\n};\n","import type { OutputBlockData, BlockId, BlockRunSpec, BlockTreeNode, BlockTreeSpec, FlattenTreeOptions } from '@bloklabs/core';\nimport { generateBlockId } from '../components/utils/id-generator';\n\n/** A flattened block with its `id` resolved (generated when the spec omitted one). */\ntype FlattenedBlock = OutputBlockData & { id: BlockId };\n\n/**\n * Whether a spec node is a pre-flat run (`{ blocks: [...] }`) rather than a\n * tree node. Keyed on the `blocks` array, the only field the two shapes cannot\n * share.\n * @param node - spec node to classify\n */\nconst isRunSpec = (node: BlockTreeNode): node is BlockRunSpec => {\n  return Array.isArray((node as BlockRunSpec).blocks);\n};\n\n/**\n * Wire-tolerant id read: `null` and `''` mean \"absent\", as everywhere else a\n * loaded document is normalized.\n * @param id - id as it arrived on a saved block\n */\nconst nonEmptyId = (id: string | null | undefined): string | undefined => {\n  return typeof id === 'string' && id !== '' ? id : undefined;\n};\n\n/**\n * Reject an already-flat block passed where a TREE node is expected. A spec\n * node has no `parent`/`content` fields, so such a block would be flattened\n * with its links silently DROPPED — the structure it described is gone and\n * nothing reports it. Pre-flat blocks belong in a run node instead.\n * @param node - tree node about to be flattened\n * @throws if the node carries link information a tree node cannot express\n */\nconst assertNotPreFlat = (node: BlockTreeSpec): void => {\n  const asFlat = node as OutputBlockData;\n  const carriesParent = typeof asFlat.parent === 'string' && asFlat.parent !== '';\n  const carriesContent = Array.isArray(asFlat.content) && asFlat.content.length > 0;\n\n  if (carriesParent || carriesContent) {\n    throw new Error(\n      `flattenTree: block \"${node.id ?? '(no id)'}\" carries \\`parent\\`/\\`content\\` links, which a tree node cannot express — pass pre-flat blocks as a run node: { blocks: [...] }.`\n    );\n  }\n};\n\n/**\n * Flatten a hierarchical block spec (nodes with `children`) into the flat DFS\n * pre-order `OutputBlockData[]` Blok stores, wiring every node's `parent` and\n * `content` id links.\n *\n * This is the pure counterpart of the live `insertTree` mutation: the same DFS,\n * without an editor. Use it to seed nested content — columns, tables, a whole\n * document — without hand-authoring `parent`/`content` arrays:\n *\n * @example\n * new Blok({\n *   data: {\n *     blocks: flattenTree([\n *       { type: 'column_list', children: [\n *         { type: 'column', children: [{ type: 'paragraph', data: { text: 'L' } }] },\n *         { type: 'column', children: [{ type: 'paragraph', data: { text: 'R' } }] },\n *       ] },\n *     ]),\n *   },\n * });\n *\n * Content that is not tree-shaped to begin with — an already-flat saved\n * document a migration is splicing into a page — goes in as a RUN node,\n * `{ blocks: [...] }`, at the root or as a child. A run is spliced verbatim:\n * ids, `data`, `tunes` and existing `parent`/`content` links are kept, and only\n * the blocks it left un-parented are re-parented onto the enclosing node.\n *\n * @example\n * flattenTree({ type: 'column', children: [{ blocks: saved.blocks }] });\n *\n * @param spec - a single root node or an array of root nodes; each is either a\n *   tree node or a pre-flat run.\n * @param options - `parentId` sets the `parent` of the root node(s);\n *   `generateId` overrides id generation for nodes that omit an `id` (default:\n *   Blok's nanoid scheme).\n * @returns DFS pre-order blocks with `parent`/`content` wired. Leaves omit the\n *   empty `content` array, matching the documented `OutputBlockData` shape.\n * @throws if an explicit `id` is reused within the spec — a duplicate id would\n *   corrupt every id-keyed lookup, so it is surfaced loudly rather than encoded\n *   — or if a TREE node carries `parent`/`content` links, which it cannot\n *   express (that is a pre-flat block; wrap it in a run node).\n */\nexport function flattenTree(\n  spec: BlockTreeNode | BlockTreeNode[],\n  options: FlattenTreeOptions = {}\n): FlattenedBlock[] {\n  const generateId = options.generateId ?? generateBlockId;\n  const rootParent = options.parentId ?? undefined;\n\n  const flat: FlattenedBlock[] = [];\n  const usedIds = new Set<string>();\n\n  /**\n   * Resolve a node's id and reserve it. A duplicate would corrupt every\n   * id-keyed lookup, so it is surfaced loudly rather than encoded.\n   * @param explicitId - id the spec carried, if any\n   */\n  const claimId = (explicitId: string | undefined): string => {\n    const id = explicitId ?? generateId();\n\n    if (usedIds.has(id)) {\n      throw new Error(`flattenTree: duplicate block id \"${id}\" — every block id must be unique.`);\n    }\n    usedIds.add(id);\n\n    return id;\n  };\n\n  /**\n   * Splice a pre-flat run in verbatim: every block keeps its id, `data`,\n   * `tunes` and its existing `parent`/`content` links, and only the blocks the\n   * run left un-parented are re-parented onto the enclosing node. Mirrors\n   * `useBlocks.insertMarkdown`, which nests a converted run the same way.\n   * @param run - the run node\n   * @param parent - id of the node the run is spliced into (undefined at root)\n   * @returns ids of the run's top-level blocks, in run order\n   */\n  const visitRun = (run: BlockRunSpec, parent: string | undefined): string[] => {\n    const rootIds: string[] = [];\n\n    for (const block of run.blocks) {\n      const { parent: incomingParent, id: incomingId, content: incomingContent, data, ...rest } = block;\n      const id = claimId(nonEmptyId(incomingId));\n      const incomingParentId = nonEmptyId(incomingParent);\n      const isRunRoot = incomingParentId === undefined;\n      const resolvedParent = isRunRoot ? parent : incomingParentId;\n\n      flat.push({\n        ...rest,\n        id,\n        data: data ?? {},\n        // `null`/`[]` content means \"no children\" — omitted, like a tree leaf.\n        ...(Array.isArray(incomingContent) && incomingContent.length > 0 ? { content: incomingContent } : {}),\n        ...(resolvedParent !== undefined ? { parent: resolvedParent } : {}),\n      });\n\n      if (isRunRoot) {\n        rootIds.push(id);\n      }\n    }\n\n    return rootIds;\n  };\n\n  // Pre-order DFS: push self FIRST, then recurse each child, so the flat array\n  // is DFS-contiguous. `content` is filled as each child is visited and returns\n  // its id; it is omitted for leaves.\n  const visit = (node: BlockTreeSpec, parent: string | undefined): string => {\n    assertNotPreFlat(node);\n\n    const id = claimId(node.id);\n\n    const childIds: string[] = [];\n    const flatNode = {\n      id,\n      // `type` is OMITTED (not present-with-undefined) when absent so core's\n      // `type || defaultBlock` fallback resolves the default block cleanly.\n      ...(node.type !== undefined ? { type: node.type } : {}),\n      data: node.data ?? {},\n      ...(node.tunes !== undefined ? { tunes: node.tunes } : {}),\n      ...(parent !== undefined ? { parent } : {}),\n    } as FlattenedBlock;\n\n    flat.push(flatNode);\n\n    for (const child of node.children ?? []) {\n      childIds.push(...(isRunSpec(child) ? visitRun(child, id) : [visit(child, id)]));\n    }\n\n    // Only wire `content` when there are children — leaves stay clean.\n    if (childIds.length > 0) {\n      flatNode.content = childIds;\n    }\n\n    return id;\n  };\n\n  const roots = Array.isArray(spec) ? spec : [spec];\n\n  for (const root of roots) {\n    if (isRunSpec(root)) {\n      visitRun(root, rootParent);\n    } else {\n      visit(root, rootParent);\n    }\n  }\n\n  return flat;\n}\n","import type { BlockToolData, BlockTuneData, OutputBlockData, OutputData, MarkdownImportConfig } from '@bloklabs/core';\n\n/**\n * Where to place the caret within a block. `position` selects the input\n * (`'start'`/`'end'`/`'default'`) and `offset` is the character offset within it\n * — the same shape core's `caret.setToBlock` accepts.\n */\nexport interface CaretTarget {\n  position?: 'start' | 'end' | 'default';\n  offset?: number;\n}\n\n/**\n * A plain, serializable view of one block in the tree.\n *\n * Snapshot-volatile: every read allocates a fresh `BlockNode`, and `contentIds`\n * is DERIVED per read from the children that currently name this block as parent\n * (it is not a stored field). Read a node in render and re-read after a change —\n * don't stash one in a `useMemo`/`useEffect` dependency array expecting stable\n * identity; depend on the `id` instead.\n */\nexport interface BlockNode {\n  id: string;\n  type: string;\n  parentId: string | null;\n  contentIds: readonly string[];\n}\n\n/** Where to place a block among its siblings. */\nexport type InsertPosition = 'start' | 'end' | { before: string } | { after: string };\n\nexport interface InsertSpec {\n  type?: string;\n  data?: BlockToolData;\n  parentId?: string | null;\n  position?: InsertPosition;\n  /**\n   * Move the caret into the new block. Defaults to `false`: a programmatic\n   * insert from React must not steal focus from wherever the user is typing.\n   * Set `true` for an explicit \"add a block and start editing it\" flow.\n   */\n  focus?: boolean;\n  /**\n   * Replace the block at the resolved slot instead of inserting a new one — a\n   * programmatic \"turn into\". Combine with a `position` that targets the block\n   * to replace, e.g. `{ position: { before: id }, replace: true }`.\n   */\n  replace?: boolean;\n  /**\n   * Explicit id for the new block (generated when omitted). Passing a stable id\n   * makes the insert idempotent: if a block with this id already exists the\n   * existing node is returned and nothing is inserted (\"insert if absent\"),\n   * so an effect that re-runs won't create duplicates.\n   */\n  id?: string;\n  /** Block tune data to apply at creation, keyed by tune name. */\n  tunes?: { [name: string]: BlockTuneData };\n  /**\n   * Place the caret inside the newly-created block at a specific position/offset\n   * (e.g. `{ offset: 3 }`). Implies focus. Applied ONLY when a block is actually\n   * created — an insert-if-absent hit (existing id) does not move the caret.\n   * Use this instead of the boolean `focus` when you need a specific offset.\n   */\n  caret?: CaretTarget;\n}\n\n/**\n * One node of a pre-built nested subtree for {@link UseBlocksApi.insertTree}.\n *\n * Each node maps to one block; `children` are inserted nested under it (their\n * `parentId` set to this node's id) in array order, recursively. Placement\n * options (`parentId`/`position`) are ROOT-ONLY — they position the whole\n * subtree among existing blocks and are ignored on nested children, whose parent\n * is always their enclosing node.\n */\nexport interface TreeInsertSpec {\n  type?: string;\n  data?: BlockToolData;\n  tunes?: { [name: string]: BlockTuneData };\n  /**\n   * Explicit id for this node (generated when omitted). Unlike `insert`, this is\n   * NOT insert-if-absent: a tree insert always creates fresh blocks. A colliding\n   * id — one that already exists in the document, or is reused by another node\n   * in the same spec — is REJECTED up front: nothing is inserted and `insertTree`\n   * returns `null` (a duplicate id would corrupt every id-keyed lookup).\n   */\n  id?: string;\n  /** Direct children, inserted nested under this node, in array order. */\n  children?: TreeInsertSpec[];\n  /** Root-only: where to place the whole subtree. Ignored on nested children. */\n  parentId?: string | null;\n  /** Root-only: slot among siblings of `parentId`. Ignored on nested children. */\n  position?: InsertPosition;\n}\n\n/**\n * Where to move an existing block.\n *\n * `before`/`after` are POSITION targets, not parent assignments: the block is\n * relocated to that flat slot and — because Blok keeps the flat array as the\n * canonical document order — ADOPTS the parent of wherever it lands. Moving a\n * nested block to `{ after: someRootBlock }` therefore unnests it to root, and\n * moving a root block in among a container's children nests it. Use\n * `nest`/`unnest` when you want to change the parent without choosing a sibling\n * slot. `toIndex` is an absolute flat index (clamped into range).\n */\nexport type MoveTarget = { before: string } | { after: string } | { toIndex: number };\n\nexport interface UseBlocksApi {\n  getById(id: string): BlockNode | null;\n  getChildren(parentId: string | null): BlockNode[];\n  /**\n   * Insert one block; returns the created node or null when rejected (unknown\n   * tool type, dangling `parentId`, or a `replace` whose target is missing). An\n   * explicit `id` that already exists is insert-if-absent (returns the existing\n   * node, creates nothing). Atomic — one undo step. The returned node is\n   * {@link BlockNode}-volatile; read it now, don't put it in a dep array.\n   */\n  insert(spec?: InsertSpec): BlockNode | null;\n  /**\n   * Insert several blocks atomically, in array order, as ONE undo step. Each\n   * spec is a full {@link InsertSpec} (own type/data/parentId/position), routed\n   * through the same single-`insert` path, so per-spec parent assertion and\n   * positioning still apply. Specs that fail to insert (e.g. a dangling\n   * parentId, or a replace whose target is missing) are dropped; the returned\n   * array holds only the successfully created nodes. An empty input is a no-op\n   * (returns `[]`, opens no transaction). Like `insert`, the returned nodes are\n   * fresh-snapshot volatile — read them now, don't stash them in dep arrays.\n   */\n  insertMany(specs: InsertSpec[]): BlockNode[];\n  /**\n   * Insert a pre-built NESTED subtree in ONE atomic operation (one undo step).\n   * Each {@link TreeInsertSpec} node becomes a block; its `children` are inserted\n   * nested under it (recursively, in array order) so the whole hierarchy lands in\n   * a single call — no follow-up `nest` round-trips. Delegates to core's\n   * tree-aware `blocks.insertMany`, which composes the flat DFS pre-order array\n   * honoring each node's `parent`/`content` links.\n   *\n   * Placement is root-only: the root node's `parentId`/`position` position the\n   * whole subtree among existing blocks (default: appended at the document end);\n   * nested children ignore those fields (their parent is their enclosing node). A\n   * dangling root `parentId` is rejected — nothing is inserted and `null` is\n   * returned (mirrors {@link insert}). Returns the root {@link BlockNode}, which\n   * is fresh-snapshot volatile — read it now, don't stash it in a dep array.\n   */\n  insertTree(spec: TreeInsertSpec): BlockNode | null;\n  /**\n   * Convert a Markdown string to blocks and insert them ADDITIVELY at a\n   * position, WITHOUT clearing the document (unlike core's `importMarkdown` /\n   * `renderFromHTML`, which replace the whole document). This is the React\n   * \"paste markdown → blocks appear\" path.\n   *\n   * Async: the markdown converter is lazy-loaded (kept out of the main bundle),\n   * so this is the ONE async creator in the API — `await` the returned promise.\n   * The whole batch is inserted as a single atomic undo step.\n   *\n   * `position` (default `'end'`) places the converted run among `parentId`'s\n   * children (or root siblings when `parentId` is omitted/null), reusing the\n   * same `start`/`end`/`before`/`after` semantics as {@link insert}.\n   *\n   * `parentId` (default `null` = root) nests the import: every TOP-LEVEL\n   * converted block (one the converter left un-parented) is reparented under\n   * `parentId`, while blocks the markdown nested internally (e.g. table-cell\n   * children) keep their intra-import parent. A dangling `parentId` is a no-op\n   * (returns `[]`, opens no transaction), matching {@link insert}.\n   *\n   * `config` (optional {@link MarkdownImportConfig}) is forwarded to the\n   * converter so custom-tool consumers can map markdown nodes into their tools\n   * (`toolMap`/`onUnknownNode`), toggle GFM, or add micromark/mdast extensions.\n   *\n   * Returns ALL created {@link BlockNode}s in document order — including any the\n   * markdown nested internally (e.g. a table's cell children), not just the\n   * top-level run (this differs from {@link insertTree}, which returns only the\n   * root). Empty or whitespace-only markdown, a dangling `parentId` (checked\n   * again after the async convert, so a parent removed mid-flight also no-ops),\n   * and a converter failure (chunk-load or parse error, swallowed) all return\n   * `[]` and open no transaction. The nodes are fresh-snapshot volatile — read\n   * them now, don't stash them in dep arrays.\n   */\n  insertMarkdown(\n    markdown: string,\n    options?: { parentId?: string | null; position?: InsertPosition; config?: MarkdownImportConfig }\n  ): Promise<BlockNode[]>;\n  /**\n   * Serialize the WHOLE document to a Markdown string — the outbound twin of\n   * core's `blocks.exportMarkdown` (and the read-side counterpart of the\n   * additive {@link insertMarkdown}). Async: the serializer is lazy-loaded, like\n   * the importer. Markdown cannot express every block, so some structure is\n   * dropped (table `colspan`/`rowspan`, heading columns). Returns `''` for an\n   * empty document. Pre-ready: resolves to `''`.\n   */\n  exportMarkdown(): Promise<string>;\n  move(id: string, target: MoveTarget): void;\n  nest(id: string, parentId: string): void;\n  unnest(id: string): void;\n  remove(id: string): void;\n  /**\n   * Update a block's data and/or tunes by id. Delegates to core's async\n   * `blocks.update`, which forms its OWN undo step — the call is NOT wrapped in\n   * `transact` (that would close the group before the async write lands). An\n   * unknown id is a silent no-op; a rejected update is swallowed so it can't\n   * surface as an unhandled rejection. Reads refresh reactively once core emits\n   * 'block changed'. Returns `void`.\n   */\n  update(id: string, data?: BlockToolData, tunes?: { [name: string]: BlockTuneData }): void;\n  /**\n   * Convert a block to another type (\"turn into\") by id. Delegates to core's\n   * async `blocks.convert`; both tools must provide a `conversionConfig` or core\n   * rejects — that rejection (and any other) is swallowed so a non-convertible\n   * block is a graceful no-op rather than an unhandled rejection. An unknown id\n   * is a silent no-op. Not wrapped in `transact` (core owns its history step).\n   * Returns `void`.\n   */\n  convert(\n    id: string,\n    newType: string,\n    dataOverrides?: BlockToolData,\n    options?: { caret?: CaretTarget }\n  ): void;\n  transact(fn: () => void): void;\n  /**\n   * Run `fn` as one atomic operation that is NOT captured in the undo history —\n   * the React-surface counterpart of core's `transactWithoutCapture`. Use for\n   * silent auto-repair/normalization that a user's CMD+Z should never step\n   * through. Mutations inside still emit reactively. Pre-ready it just runs `fn`.\n   */\n  transactWithoutCapture(fn: () => void): void;\n  /**\n   * The current block count. Reactive (re-reads on 'block changed'). Pre-ready: 0.\n   */\n  getBlocksCount(): number;\n  /**\n   * The flat index of the block holding the caret, or -1 when none. Pre-ready: -1.\n   */\n  getCurrentBlockIndex(): number;\n  /** The block at a flat index as a snapshot {@link BlockNode}, or null. */\n  getBlockByIndex(index: number): BlockNode | null;\n  /**\n   * The absolute flat index of a block by id, or null when unknown. The\n   * counterpart to {@link getBlockByIndex} — use it to target an off-caret\n   * {@link splitBlock} (whose `insertIndex` is absolute) without the ref. Unknown\n   * ids return null silently (no console warn). Pre-ready: null.\n   */\n  getBlockIndex(id: string): number | null;\n  /**\n   * Read a block's current `data` and `tunes` by id WITHOUT mutating anything —\n   * the synchronous last-extracted view (the same snapshot clipboard ops use).\n   * Makes a client-side duplicate composable from the hook alone: read a node,\n   * then `insert({ type, data, tunes, position })`, no ref escape hatch. Unknown\n   * id returns null. Pre-ready: null.\n   */\n  getBlockData(id: string): { data: BlockToolData; tunes: { [name: string]: BlockTuneData } } | null;\n  /**\n   * The block whose holder contains/equals `element`, as a snapshot\n   * {@link BlockNode}, or null. Useful for mapping a DOM event target back to a\n   * block.\n   */\n  getBlockByElement(element: HTMLElement): BlockNode | null;\n  /**\n   * Read a tool's default empty data WITHOUT inserting anything — delegates to\n   * core's `composeBlockData`. Async (a tool's data may be composed lazily).\n   * Rejects (via core) for an unknown tool. Pre-ready: resolves to `{}`.\n   */\n  composeBlockData(toolName: string): Promise<BlockToolData>;\n  /**\n   * Replace the WHOLE document with blocks parsed from an HTML string —\n   * delegates to core's `renderFromHTML`. Unlike {@link insertMarkdown} (which is\n   * additive), this CLEARS existing content first, so it's a document-load\n   * primitive, not an insert. Async. Pre-ready: resolves immediately (no-op).\n   */\n  renderFromHTML(html: string): Promise<void>;\n  /**\n   * Insert a flat array of already-serialized {@link OutputBlockData} (the\n   * `save()` shape) directly, honoring each block's `parent`/`content` links —\n   * the raw counterpart of core's `blocks.insertMany`. Use to re-insert a saved\n   * document fragment without reshaping it into {@link TreeInsertSpec}. One\n   * atomic undo step. Returns the created nodes; pre-ready: `[]` (no insert).\n   */\n  insertOutputData(blocks: OutputBlockData[], options?: { index?: number }): BlockNode[];\n  /**\n   * Atomically split a block: update `currentBlockId` with `currentBlockData`\n   * and insert a new `newBlockType` block at `insertIndex`, as ONE undo step.\n   * Delegates to core's `splitBlock`. Returns the new node, or null pre-ready /\n   * on an unknown id.\n   */\n  splitBlock(\n    currentBlockId: string,\n    currentBlockData: Partial<BlockToolData>,\n    newBlockType: string,\n    newBlockData: BlockToolData,\n    insertIndex: number\n  ): BlockNode | null;\n  /**\n   * Insert a single child block under `parentId` at flat `insertIndex`, atomically\n   * (block creation AND parent assignment in ONE undo step) — delegates to core's\n   * `blocks.insertInsideParent`. This is the atomic nested-child creator: prefer it\n   * over `insert()` + `nest()`, which is TWO undo steps. A dangling `parentId` is a\n   * no-op returning `null` (mirrors {@link insert}); an unknown child tool returns\n   * `null`. `childData` defaults to an empty paragraph. Returns the created\n   * {@link BlockNode}, fresh-snapshot volatile — read it now, don't stash it in a\n   * dep array. Pre-ready: `null`.\n   */\n  insertInsideParent(parentId: string, insertIndex: number, childData?: BlockToolData): BlockNode | null;\n  /**\n   * Replace the WHOLE document with blocks parsed from saved {@link OutputData}\n   * (the `save()` shape) — delegates to core's `blocks.render`. Unlike\n   * {@link insertOutputData}/{@link insertMarkdown} (which are ADDITIVE), this\n   * CLEARS existing content first: a document-LOAD primitive, not an insert. The\n   * HTML counterpart is {@link renderFromHTML}. Async. Pre-ready: resolves\n   * immediately (no-op).\n   */\n  render(data: OutputData): Promise<void>;\n  /**\n   * Remove EVERY block from the document — delegates to core's `blocks.clear`. A\n   * document-reset primitive (pairs with {@link render}). Async. Pre-ready:\n   * resolves immediately (no-op).\n   */\n  clear(): Promise<void>;\n  /**\n   * Whether a Yjs sync (undo/redo) is currently in progress — the React mirror of\n   * core's `blocks.isSyncingFromYjs`. A METHOD (not a property) so it reads the\n   * LIVE flag at call time even though the api handle is memoized. Use it to skip\n   * cleanup that would fight Yjs state during an undo/redo. Pre-ready: `false`.\n   */\n  isSyncingFromYjs(): boolean;\n}\n\n/** The minimal slice of editor.blocks that the snapshot helpers read. */\nexport interface BlocksReader {\n  getBlocksCount(): number;\n  getBlockByIndex(index: number): { id: string; name: string; parentId: string | null } | undefined;\n}\n\n/**\n * Enumerate the editor's blocks once into BlockNode records, in flat order,\n * deriving each node's contentIds from the children that name it as parent.\n */\nexport const snapshotNodes = (reader: BlocksReader): BlockNode[] => {\n  const count = reader.getBlocksCount();\n  const flat = Array.from({ length: count }, (_, i) => reader.getBlockByIndex(i))\n    .filter((b): b is { id: string; name: string; parentId: string | null } => b !== undefined)\n    .map((b) => ({ id: b.id, type: b.name, parentId: b.parentId }));\n\n  const childrenByParent = new Map<string, string[]>();\n\n  for (const b of flat) {\n    if (b.parentId === null) {\n      continue;\n    }\n    const bucket = childrenByParent.get(b.parentId) ?? [];\n\n    bucket.push(b.id);\n    childrenByParent.set(b.parentId, bucket);\n  }\n\n  return flat.map((b) => ({\n    id: b.id,\n    type: b.type,\n    parentId: b.parentId,\n    contentIds: childrenByParent.get(b.id) ?? [],\n  }));\n};\n\n/** BlocksReader plus id→flat-index lookup. */\nexport interface IndexReader extends BlocksReader {\n  getBlockIndex(id: string): number | undefined;\n}\n\n/** Flat indices of a parent's direct children, ascending. Empty if none. */\nconst childFlatIndices = (reader: IndexReader, parentId: string): number[] => {\n  const count = reader.getBlocksCount();\n\n  return Array.from({ length: count }, (_, i) => i).filter(\n    (i) => reader.getBlockByIndex(i)?.parentId === parentId\n  );\n};\n\n/** Map of block id -> parentId, in flat order. */\nexport const parentMap = (reader: IndexReader): Map<string, string | null> => {\n  const count = reader.getBlocksCount();\n  const entries = Array.from({ length: count }, (_, i) => reader.getBlockByIndex(i))\n    .filter((b): b is { id: string; name: string; parentId: string | null } => b !== undefined)\n    .map((b): [string, string | null] => [b.id, b.parentId]);\n\n  return new Map(entries);\n};\n\n/** True if `id` descends from `ancestorId` via the parentId chain. */\nexport const isDescendantOf = (\n  parentOf: Map<string, string | null>,\n  id: string,\n  ancestorId: string\n): boolean => {\n  const parent = parentOf.get(id) ?? null;\n\n  if (parent === null) {\n    return false;\n  }\n\n  return parent === ancestorId || isDescendantOf(parentOf, parent, ancestorId);\n};\n\n/**\n * The flat index of the last block in the contiguous subtree rooted at `index`.\n * In flat (DFS) order a block's descendants sit immediately after it, so this\n * walks forward while blocks remain descendants of the block at `index`.\n * Returns `index` itself when the block has no descendants.\n */\nconst subtreeEndIndex = (reader: IndexReader, index: number): number => {\n  const root = reader.getBlockByIndex(index);\n\n  if (root === undefined) {\n    return index;\n  }\n\n  const parentOf = parentMap(reader);\n  const count = reader.getBlocksCount();\n  // Walk forward from index+1 while blocks remain descendants (DFS contiguity).\n  // The subtree ends just before the first non-descendant, or at the last block\n  // when every follower is a descendant.\n  const followers = Array.from({ length: count - (index + 1) }, (_, k) => index + 1 + k);\n  const breakAt = followers.find((i) => {\n    const b = reader.getBlockByIndex(i);\n\n    return b === undefined || !isDescendantOf(parentOf, b.id, root.id);\n  });\n\n  return breakAt === undefined ? count - 1 : breakAt - 1;\n};\n\n/**\n * The flat index at which a new block should be inserted.\n *\n * `replace` flips the meaning of a before/after `position`: under replace the\n * ref IS the block being overwritten (a \"turn into\"), not a sibling anchor, so\n * it resolves to the ref's OWN flat slot regardless of which parent it lives in\n * — bypassing the sibling-relative parent guard that would otherwise redirect a\n * nested target to the requested parent's end and replace the wrong block.\n */\nexport const resolveInsertIndex = (\n  reader: IndexReader,\n  parentId: string | null,\n  position: InsertPosition,\n  replace = false\n): number => {\n  if (typeof position === 'object') {\n    const ref = 'before' in position ? position.before : position.after;\n    const refIndex = reader.getBlockIndex(ref);\n\n    if (replace && refIndex !== undefined) {\n      return refIndex;\n    }\n\n    const refParent =\n      refIndex === undefined ? undefined : reader.getBlockByIndex(refIndex)?.parentId ?? null;\n\n    // before/after is sibling-relative: the ref must be a child of the requested\n    // parent. When the ref is missing or lives in a DIFFERENT parent, the\n    // parentId constraint wins — fall back to appending at the end of the\n    // requested parent rather than splicing into an unrelated subtree (the\n    // cross-parent mis-place) or silently landing at the document end.\n    if (refIndex === undefined || refParent !== parentId) {\n      return resolveInsertIndex(reader, parentId, 'end');\n    }\n\n    // 'after' must clear the ref's entire subtree, not just the ref node, or the\n    // new block splits the ref's descendants in flat (DFS) order.\n    return 'before' in position ? refIndex : subtreeEndIndex(reader, refIndex) + 1;\n  }\n\n  if (parentId === null) {\n    return position === 'start' ? 0 : reader.getBlocksCount();\n  }\n\n  const parentIndex = reader.getBlockIndex(parentId);\n\n  if (parentIndex === undefined) {\n    return reader.getBlocksCount();\n  }\n\n  if (position === 'start') {\n    const childIndices = childFlatIndices(reader, parentId);\n\n    return childIndices.length === 0 ? parentIndex + 1 : childIndices[0];\n  }\n\n  // 'end': insert after the parent's last descendant.\n  return subtreeEndIndex(reader, parentIndex) + 1;\n};\n\n/** The flat toIndex for editor.blocks.move. */\nexport const resolveMoveIndex = (reader: IndexReader, target: MoveTarget): number => {\n  if ('toIndex' in target) {\n    // Blok's Blocks.move() silently no-ops on an out-of-range index, so clamp\n    // an explicit toIndex into [0, count-1] rather than dropping the move.\n    const lastIndex = Math.max(0, reader.getBlocksCount() - 1);\n\n    return Math.min(Math.max(target.toIndex, 0), lastIndex);\n  }\n\n  const ref = 'before' in target ? target.before : target.after;\n  const refIndex = reader.getBlockIndex(ref);\n\n  if (refIndex === undefined) {\n    return reader.getBlocksCount();\n  }\n\n  // 'after' must clear the ref's entire subtree (see resolveInsertIndex), or the\n  // moved block lands among the ref's descendants instead of past them.\n  return 'before' in target ? refIndex : subtreeEndIndex(reader, refIndex) + 1;\n};\n","import type { Blok, BlockToolData, BlockTuneData, OutputBlockData, OutputData, MarkdownImportConfig } from '@bloklabs/core';\n// src/components/utils/blocks-api.ts\nimport { ToolNotFoundError } from '../errors/tool-not-found';\n\nimport { flattenTree } from '../../shared/flatten-tree';\nimport {\n  snapshotNodes,\n  resolveInsertIndex,\n  resolveMoveIndex,\n  parentMap,\n  isDescendantOf,\n  type BlockNode,\n  type CaretTarget,\n  type IndexReader,\n  type InsertPosition,\n  type InsertSpec,\n  type MoveTarget,\n  type TreeInsertSpec,\n  type UseBlocksApi,\n} from './blocks-tree';\n\n/** Adapt the live editor to the IndexReader the snapshot helpers expect. */\nexport const readerFor = (editor: Blok): IndexReader => {\n  const blocks = editor.blocks;\n\n  return {\n    getBlocksCount: () => blocks.getBlocksCount(),\n    getBlockByIndex: (i: number) => {\n      const b = blocks.getBlockByIndex(i);\n\n      return b === undefined ? undefined : { id: b.id, name: b.name, parentId: b.parentId };\n    },\n    getBlockIndex: (id: string) => blocks.getBlockIndex(id),\n  };\n};\n\n/**\n * Stable API returned while the editor is null (before the adapter resolves).\n * Every read returns empty/null and every MUTATOR is a no-op — EXCEPT\n * `transact`/`transactWithoutCapture`, which still invoke their callback so a\n * consumer wrapping conditional work in `transact` still runs that work even\n * pre-ready.\n */\nexport const EMPTY_API: UseBlocksApi = {\n  getById: () => null,\n  getChildren: () => [],\n  insert: () => null,\n  insertMany: () => [],\n  insertTree: () => null,\n  insertMarkdown: async () => [],\n  exportMarkdown: async () => '',\n  move: () => undefined,\n  nest: () => undefined,\n  unnest: () => undefined,\n  remove: () => undefined,\n  update: () => undefined,\n  convert: () => undefined,\n  // Not a no-op: still runs the callback (see EMPTY_API doc above).\n  transact: (fn: () => void) => fn(),\n  // Like transact, still runs the callback even pre-ready.\n  transactWithoutCapture: (fn: () => void) => fn(),\n  getBlocksCount: () => 0,\n  getCurrentBlockIndex: () => -1,\n  getBlockByIndex: () => null,\n  getBlockByElement: () => null,\n  getBlockData: () => null,\n  getBlockIndex: () => null,\n  composeBlockData: async () => ({}),\n  renderFromHTML: async () => undefined,\n  insertOutputData: () => [],\n  splitBlock: () => null,\n  insertInsideParent: () => null,\n  render: async () => undefined,\n  clear: async () => undefined,\n  isSyncingFromYjs: () => false,\n};\n\n/**\n * Read the changed block's id out of a `block changed` payload, tolerating any\n * shape that is not core's `{ event: { detail: { target } } }`.\n * @param payload - whatever the dispatcher handed the listener\n * @returns the target block id, or null when the payload does not carry one\n */\nconst changedBlockId = (payload: unknown): string | null => {\n  const detail = (payload as { event?: { detail?: { target?: { id?: unknown } } } } | undefined)\n    ?.event?.detail?.target?.id;\n\n  return typeof detail === 'string' ? detail : null;\n};\n\n/**\n * Does a `block changed` event touch the subtree rooted at `withinId`?\n *\n * The reactivity filter behind `useBlocks(editor, { within })` in all three\n * adapters. Without it every consumer of `useBlocks` re-renders on every change\n * anywhere in the document — so a container block that only renders its own\n * children still re-rendered on each keystroke in an unrelated block, and a page\n * of N such containers turned one keystroke into N re-renders.\n *\n * INDETERMINATE READS AS \"TOUCHED\". The walk resolves ancestry through the LIVE\n * tree, and a removal commonly emits after the block is already gone, so its\n * parent chain cannot be read. Answering `false` there would leave a container\n * rendering a child that no longer exists; answering `true` costs one extra\n * render pass. Same for a payload with no readable target.\n *\n * Ancestry is walked UPWARD one `getById` at a time rather than snapshotted with\n * `parentMap`: this runs on every emission — i.e. on every keystroke — so it must\n * cost O(depth), not O(document).\n * @param editor - the live Blok instance\n * @param payload - the `block changed` payload\n * @param withinId - id of the block whose subtree is the scope\n * @returns true when the change is inside the scope (or cannot be placed)\n */\nexport const changeTouchesSubtree = (\n  editor: Blok,\n  payload: unknown,\n  withinId: string\n): boolean => {\n  const targetId = changedBlockId(payload);\n\n  if (targetId === null) {\n    return true;\n  }\n\n  /** Ids already visited on this walk — one Set for the whole climb. */\n  const seen = new Set<string>();\n\n  /**\n   * Walk one link up the parentId chain.\n   * @param id - the block to test, or null once the root is passed\n   * @returns true when `withinId` is `id` or one of its ancestors\n   */\n  const climbs = (id: string | null): boolean => {\n    if (id === null) {\n      return false;\n    }\n\n    if (id === withinId) {\n      return true;\n    }\n\n    // A parentId cycle is a corrupt tree, not a scope hit — bail rather than spin.\n    if (seen.has(id)) {\n      return false;\n    }\n\n    seen.add(id);\n\n    const node = editor.blocks.getById(id);\n\n    // The target (or one of its ancestors) is no longer in the tree.\n    if (node === null || node === undefined) {\n      return true;\n    }\n\n    return climbs(node.parentId);\n  };\n\n  return climbs(targetId);\n};\n\n/**\n * Build the framework-agnostic, id/parentId-relative block-tree API over a LIVE\n * editor. Mutators route through the editor-level `blocks` API (core's\n * chokepoints), so undo/redo and Yjs sync are inherited rather than\n * re-implemented; readers enumerate the live tree on every call.\n *\n * This is the shared engine behind both the React (`useSyncExternalStore`) and\n * Vue (`shallowRef` version) `useBlocks` wrappers — one implementation so the\n * two adapters cannot drift. Each adapter supplies the `onRead` seam:\n *\n * - React leaves it the default no-op: `useSyncExternalStore` re-renders the\n *   whole component on `block changed`, and the reads run live during that\n *   render, so no per-call dependency tracking is needed.\n * - Vue passes `() => { void version.value }` so a read inside a `computed` /\n *   template touches the reactive version ref and re-runs on every structural\n *   mutation.\n *\n * `onRead` is invoked at the top of every read method; mutators never call it.\n * The editor MUST be the raw (non-proxied) instance — adapters `toRaw`-unwrap\n * before calling, so a Vue reactive proxy never reaches core (Risk R0).\n *\n * @param editor - the live Blok instance (never null; callers gate on EMPTY_API)\n * @param onRead - reactivity seam called at the start of each read (default no-op)\n */\nexport const createBlocksApiForEditor = (\n  editor: Blok,\n  onRead: () => void = () => undefined\n): UseBlocksApi => {\n  const reader = readerFor(editor);\n\n  const getById = (id: string): BlockNode | null => {\n    onRead();\n    const nodes = snapshotNodes(reader);\n\n    return nodes.find((n) => n.id === id) ?? null;\n  };\n\n  const getChildren = (parentId: string | null): BlockNode[] => {\n    onRead();\n\n    return snapshotNodes(reader).filter((n) => n.parentId === parentId);\n  };\n\n  const transact = (fn: () => void): void => {\n    if (editor.blocks.transact !== undefined) {\n      editor.blocks.transact(fn);\n    } else {\n      fn();\n    }\n  };\n\n  /** Flat list of id + all transitive descendants, via the parentId graph. */\n  const collectSubtreeIds = (rootId: string): string[] => {\n    const nodes = snapshotNodes(reader);\n    const childrenOf = new Map<string, string[]>();\n\n    for (const n of nodes) {\n      if (n.parentId === null) {\n        continue;\n      }\n      const bucket = childrenOf.get(n.parentId) ?? [];\n\n      bucket.push(n.id);\n      childrenOf.set(n.parentId, bucket);\n    }\n\n    const out: string[] = [];\n    const visited = new Set<string>();\n    const stack: string[] = [rootId];\n\n    // A parentId cycle (possible from a concurrent remote Yjs reparent) would\n    // make this DFS spin forever — track visited ids and skip re-entry so each\n    // block is emitted at most once and the traversal always terminates.\n    while (stack.length > 0) {\n      const id = stack.pop() as string;\n\n      if (visited.has(id)) {\n        continue;\n      }\n      visited.add(id);\n      out.push(id);\n      const kids = childrenOf.get(id);\n\n      if (kids !== undefined) {\n        stack.push(...kids);\n      }\n    }\n\n    return out;\n  };\n\n  /** Each subtree member's parentId, captured from the current snapshot. */\n  const captureSubtreeParents = (rootId: string): Array<{ id: string; parentId: string | null }> => {\n    const parentOf = new Map(snapshotNodes(reader).map((n) => [n.id, n.parentId]));\n\n    return collectSubtreeIds(rootId).map((id) => ({ id, parentId: parentOf.get(id) ?? null }));\n  };\n\n  /**\n   * Relocate id AND its whole subtree to sit contiguously starting at a\n   * PRE-removal flat slot. Blok's Blocks.move() is post-removal index space and\n   * only carries DOM-contained descendants (resortNestedBlocks) — indent /\n   * parentId-nested children are NOT, so move each subtree member that a single\n   * root move didn't already pull into place. Keeps the flat array DFS-contiguous,\n   * the invariant the flat-index insert API and getChildren ordering depend on.\n   */\n  const relocateSubtree = (rootId: string, preRemovalSlot: number): 'moved' | 'skipped' | 'blocked' => {\n    // Subtree members in current flat (document) order — root first.\n    const members = collectSubtreeIds(rootId)\n      .map((id) => ({ id, idx: editor.blocks.getBlockIndex(id) }))\n      .filter((m): m is { id: string; idx: number } => m.idx !== undefined)\n      .sort((a, b) => a.idx - b.idx)\n      .map((m) => m.id);\n\n    const rootFrom = editor.blocks.getBlockIndex(rootId);\n\n    if (rootFrom === undefined) {\n      return 'blocked';\n    }\n\n    // Self-overlap guard. `preRemovalSlot` is the destination the caller\n    // computed as the END of the (new or former) parent's WHOLE subtree — and\n    // when that parent is an ANCESTOR of the relocating block (always so for\n    // unnest, and for a nest into a block this one already sits under), that\n    // span still CONTAINS this block's own subtree. Moving the root to a slot\n    // at the tail of (or inside) its own footprint splices it in right after\n    // one of its OWN descendants; core's post-move auto-heal then reparents the\n    // block under that descendant (setBlockParent(B, B) when the neighbour is\n    // the block's last child), which BlockHierarchy REFUSES with a thrown cycle\n    // error — crashing the caller. But the block is already DFS-contiguous at\n    // that destination (its subtree is the tail of the parent's subtree), so\n    // the relocation is a no-op: skip the move and report 'skipped', leaving the\n    // caller to assert the reparent. Window: `rootFrom < preRemovalSlot <=\n    // subtreeEnd + 1`. A backward move (`preRemovalSlot <= rootFrom`) or a\n    // genuine forward move past unrelated content (`preRemovalSlot > subtreeEnd\n    // + 1`) is untouched.\n    //\n    // 'skipped' (vs 'moved') is reported DISTINCTLY because no `editor.blocks.\n    // move()` ran — so core's post-move parent auto-heal never fired. nest/unnest\n    // re-assert the root's parent explicitly (reparentSubtree), so they don't\n    // care; but move() leans on that auto-heal for the root's parent-adoption, so\n    // it must apply the adopted parent itself on this path (see move()).\n    const subtreeEnd = collectSubtreeIds(rootId)\n      .map((memberId) => editor.blocks.getBlockIndex(memberId))\n      .filter((i): i is number => i !== undefined)\n      .reduce((max, i) => Math.max(max, i), rootFrom);\n\n    if (preRemovalSlot > rootFrom && preRemovalSlot <= subtreeEnd + 1) {\n      return 'skipped';\n    }\n\n    // Defensive clamp into [0, count-1]: Blok's move() silently no-ops on an\n    // out-of-range index, so an over-large preRemovalSlot would strand the\n    // root instead of appending it. (In practice resolveInsertIndex stays in\n    // range; this guards a concurrently-shrunk tree.)\n    const lastIndex = Math.max(0, editor.blocks.getBlocksCount() - 1);\n    const rootTarget = Math.min(\n      Math.max(rootFrom < preRemovalSlot ? preRemovalSlot - 1 : preRemovalSlot, 0),\n      lastIndex\n    );\n\n    editor.blocks.move(rootTarget, rootFrom);\n\n    // Detect a BLOCKED relocation: Blok's move() clamps a cross-`column`-\n    // boundary move to a no-op. If the root could not reach its target (it\n    // didn't move and wasn't already there), the relocation failed — report\n    // it so the caller skips the reparent that would otherwise corrupt DFS\n    // contiguity (a child wedged outside its parent's flat run). A legitimate\n    // no-op (already at target, rootFrom === rootTarget) still counts as\n    // relocated so an in-place nest/unnest reparents as intended.\n    if (rootFrom !== rootTarget && editor.blocks.getBlockIndex(rootId) === rootFrom) {\n      return 'blocked';\n    }\n\n    // Place each descendant immediately after the previously-positioned member,\n    // re-reading the anchor's LIVE index every iteration. A cached root index\n    // (rootNew + k + 1) only holds for a BACKWARD relocation, where descendants\n    // already sit after the root. For a FORWARD relocation each descendant\n    // move() splices an element out from BEFORE the root, sliding the root (and\n    // a cached index) down one slot per step — so the target overshoots, trips\n    // Blocks.move()'s out-of-range no-op guard, and strands the descendant.\n    // Re-anchoring to the predecessor's current slot absorbs the drift in both\n    // directions and keeps the subtree DFS-contiguous. A descendant already in\n    // place (carried by resortNestedBlocks for a DOM-nested child) is skipped.\n    // The anchor for the k-th descendant is the (k-1)-th — read live each step.\n    const descendants = members.filter((memberId) => memberId !== rootId);\n\n    descendants.forEach((memberId, k) => {\n      const anchorId = k === 0 ? rootId : descendants[k - 1];\n      const from = editor.blocks.getBlockIndex(memberId);\n      const anchor = editor.blocks.getBlockIndex(anchorId);\n\n      if (from === undefined || anchor === undefined) {\n        return;\n      }\n      const target = anchor + 1;\n\n      if (from !== target) {\n        editor.blocks.move(from < target ? target - 1 : target, from);\n      }\n    });\n\n    return 'moved';\n  };\n\n  // Reparent `id` (root → newParentId, descendants → their original parent).\n  // Re-asserting after relocateSubtree heals move()'s auto-reparent (which sets\n  // a moved block's parentId to its new neighbour) and never relocates the flat\n  // array, so contiguity established by relocateSubtree is preserved.\n  const reparentSubtree = (\n    members: Array<{ id: string; parentId: string | null }>,\n    rootId: string,\n    newParentId: string | null\n  ): void => {\n    for (const m of members) {\n      editor.blocks.setBlockParent(m.id, m.id === rootId ? newParentId : m.parentId);\n    }\n  };\n\n  // Re-assert ONLY the descendants' captured parents after a subtree relocation,\n  // leaving the ROOT's parent as core's post-move auto-heal set it — used by\n  // move(), whose documented side effect is that the root ADOPTS the parent of\n  // the slot it lands in while its subtree travels with it.\n  const reassertDescendantParents = (\n    members: Array<{ id: string; parentId: string | null }>,\n    rootId: string\n  ): void => {\n    members\n      .filter((m) => m.id !== rootId)\n      .forEach((m) => editor.blocks.setBlockParent(m.id, m.parentId));\n  };\n\n  /**\n   * Whether `id` is a DIRECT child of a `column` block. Column membership is\n   * owned by the drag UI, so a programmatic nest/unnest that would change it is\n   * a graceful no-op (see the nest/unnest docs). Checking this EXPLICITLY makes\n   * that contract reliable: relying on core's move-clamp alone leaks, because\n   * when the relocation needs no actual move (a tail column child already sits\n   * at its relocation target) no boundary-crossing move fires, so nothing\n   * clamps and the reparent would slip through.\n   */\n  const isColumnChild = (id: string): boolean => {\n    const parent = getById(id)?.parentId ?? null;\n\n    return parent !== null && getById(parent)?.type === 'column';\n  };\n\n  /**\n   * Nest `id` (and its whole subtree) under `parentId`, as one undo step.\n   * No-op when either id is unknown (probed via the silent snapshot, NOT\n   * getBlockIndex, which warns on unknown ids), or when `parentId` is `id`\n   * itself or one of `id`'s own descendants — that would form a cycle, which\n   * core's setBlockParent THROWS on, so the hook guards it up front.\n   *\n   * Column boundary caveat: nesting a block that lives inside a `column`, or\n   * nesting directly INTO one, is a GRACEFUL no-op — column membership is owned\n   * by the drag UI. This is detected explicitly (via the block's and target's\n   * parent type), so the no-op holds even when no boundary-crossing move fires.\n   * Returns void.\n   */\n  const nest = (id: string, parentId: string): void => {\n    if (getById(parentId) === null || getById(id) === null) {\n      return;\n    }\n\n    // Cycle guard: a block can't become a child of itself or of one of its\n    // own descendants. Without this, the relocate/reparent reaches core's\n    // setBlockParent, which throws on a cycle and crashes the caller.\n    if (parentId === id || isDescendantOf(parentMap(reader), parentId, id)) {\n      return;\n    }\n\n    // Column-boundary no-op: pulling a block out of a `column`, or pushing one\n    // directly into a column, changes column membership — owned by the drag UI.\n    if (isColumnChild(id) || getById(parentId)?.type === 'column') {\n      return;\n    }\n\n    // Relocate id's whole subtree to after the new parent's existing subtree,\n    // THEN assert the parents. Blok keeps the flat array as the canonical\n    // document order, and the flat-index insert API only resolves a parent's\n    // \"end\" slot when that parent's descendants are contiguous — a bare reparent\n    // (no relocation) would wedge unrelated blocks between the parent and its new\n    // child, corrupting later inserts/reads. Mirrors the drag move-then-reparent.\n    //\n    // Only reparent when the relocation actually placed the block: a clamped\n    // cross-column move leaves it where it was, and reparenting in place would\n    // break DFS contiguity.\n    const members = captureSubtreeParents(id);\n\n    transact(() => {\n      // reparentSubtree sets the root's parent EXPLICITLY, so nest is correct on\n      // both the 'moved' and 'skipped' paths — it only bails on a 'blocked'\n      // (clamped cross-column) relocation.\n      if (relocateSubtree(id, resolveInsertIndex(reader, parentId, 'end')) !== 'blocked') {\n        reparentSubtree(members, id, parentId);\n      }\n    });\n  };\n\n  /**\n   * Promote `id` (and its subtree) to root, as one undo step. No-op when the\n   * id is unknown or already at root. Same column-boundary caveat as\n   * {@link nest}: unnesting a `column` member out to root is a graceful no-op\n   * (column membership changes go through the drag UI). Returns void.\n   */\n  const unnest = (id: string): void => {\n    const node = getById(id);\n\n    if (node === null) {\n      return;\n    }\n    const parentId = node.parentId;\n\n    if (parentId === null) {\n      return;\n    }\n\n    // Column-boundary no-op: a column member is detached only via the drag UI.\n    if (isColumnChild(id)) {\n      return;\n    }\n\n    // Move id's subtree out past its former parent's whole subtree before\n    // clearing the parent, so the promoted block doesn't strand itself between\n    // the parent and its remaining children (which would break contiguity).\n    // As with nest, only clear the parent when the relocation succeeded — a\n    // clamped cross-column move must stay a graceful no-op.\n    const members = captureSubtreeParents(id);\n\n    transact(() => {\n      // As with nest, reparentSubtree asserts the root's (null) parent on both\n      // 'moved' and 'skipped'; only a 'blocked' clamp keeps it a no-op.\n      if (relocateSubtree(id, resolveInsertIndex(reader, parentId, 'end')) !== 'blocked') {\n        reparentSubtree(members, id, null);\n      }\n    });\n  };\n\n  const remove = (id: string): void => {\n    if (editor.blocks.getBlockIndex(id) === undefined) {\n      return;\n    }\n\n    // Remove the block AND its descendants. Blok's single-block delete promotes\n    // a (non-columns) container's children to root, which would orphan the\n    // nested structure the caller meant to discard. Delete deepest-first (by\n    // descending flat index) so a parent is childless by the time it's deleted\n    // (no promotion). One undo step.\n    //\n    // Re-resolve each member's index by id AT DELETE TIME rather than reusing a\n    // pre-captured snapshot: a core delete can cascade (deleting a column's last\n    // child auto-removes the empty column) or shift indices, so a stale index\n    // could target the wrong — or an already-gone — block.\n    const orderedIds = collectSubtreeIds(id)\n      .map((subId) => ({ subId, index: editor.blocks.getBlockIndex(subId) }))\n      .filter((m): m is { subId: string; index: number } => m.index !== undefined)\n      .sort((a, b) => b.index - a.index)\n      .map((m) => m.subId);\n\n    transact(() => {\n      for (const subId of orderedIds) {\n        const index = editor.blocks.getBlockIndex(subId);\n\n        // Already removed by a cascading delete of one of its descendants.\n        if (index === undefined) {\n          continue;\n        }\n        void editor.blocks.delete(index, false);\n      }\n    });\n  };\n\n  /**\n   * Move `id` to a flat slot, as a single operation. No-op when `id` is\n   * unknown (probed via the silent snapshot, NOT getBlockIndex, which warns on\n   * unknown ids); when a relative `{ before|after }` target references `id`\n   * itself, one of its descendants (a block can't be a sibling of its own\n   * child), or a ref that does not exist (an unresolved relative target must\n   * not silently dump the block at the document end); or for ANY absolute\n   * `{ toIndex }` of a block that HAS descendants (a multi-block subtree can't\n   * land on one index — see the subtree note below). Guards run BEFORE the\n   * index is resolved into a final move.\n   *\n   * Parent-adoption side effect: `before`/`after` make the moved block a\n   * SIBLING of the ref — it adopts the REF's parent (moving before/after a\n   * child of a container nests it into that container; moving before/after a\n   * root block unnests it to root). `after` clears the ref's WHOLE subtree, so\n   * the block lands past the ref's descendants, not among them. The adopted\n   * parent is the ref's — NOT the parent of whatever block happens to sit at the\n   * landing slot, which would nest under the ref for `after` a ref-with-children.\n   * Use {@link nest}/{@link unnest} to change the parent without choosing a\n   * sibling slot. Returns void.\n   *\n   * Subtree-aware: a block WITH descendants relocates its WHOLE subtree as one\n   * undo step (core's single move() carries only DOM-contained descendants, so\n   * a naive move would strand indent/parentId-nested children before their\n   * parent and corrupt DFS contiguity). Only relative `{ before|after }`\n   * targets name an unambiguous slot for a multi-block subtree; an absolute\n   * `{ toIndex }` of a block that HAS descendants is ambiguous (k blocks can't\n   * all land on one index) and is a graceful no-op — use `{ before|after }` to\n   * relocate a subtree.\n   */\n  const move = (id: string, target: MoveTarget): void => {\n    // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n    if (getById(id) === null) {\n      return;\n    }\n    // id is known, so getBlockIndex won't warn.\n    const fromIndex = editor.blocks.getBlockIndex(id);\n\n    if (fromIndex === undefined) {\n      return;\n    }\n\n    if (!('toIndex' in target)) {\n      const ref = 'before' in target ? target.before : target.after;\n\n      // A relative target can't reference the block itself or any of its own\n      // descendants — a block can't become a sibling of its child.\n      if (ref === id || isDescendantOf(parentMap(reader), ref, id)) {\n        return;\n      }\n\n      // An unresolved relative ref must NOT fall through to a relocate-to-end:\n      // a missing target is a no-op, not a surprise jump to the document end.\n      if (getById(ref) === null) {\n        return;\n      }\n    }\n    // NB: an absolute { toIndex } needs no early guard here. A block WITH\n    // descendants no-ops EVERY toIndex move in the subtree branch below\n    // (ambiguous for a multi-block subtree); a leaf has no own-subtree range to\n    // land inside. So a dedicated \"toIndex inside own subtree\" guard would be\n    // dead code — the subtree-branch no-op already covers the cycle it guarded.\n\n    // Subtree-aware relocation. A block WITH descendants can't ride a single\n    // core move(): core carries only DOM-contained descendants (resortNested\n    // Blocks), so indent/parentId-nested children are left at their old slot —\n    // stranded BEFORE their now-moved parent in flat order, breaking the DFS\n    // contiguity getChildren ordering and flat-index inserts depend on, and\n    // corrupting saved document order. Relocate the whole subtree (as\n    // nest/unnest do) and re-assert each descendant's own parent; the ROOT\n    // keeps the parent core's post-move auto-heal gives it — move()'s\n    // documented parent-adoption side effect — so only descendants are\n    // re-parented. A blocked relocation (a clamped cross-`column` move) leaves\n    // everything in place, a graceful no-op like nest/unnest. An absolute\n    // { toIndex } is ambiguous for a multi-block subtree (see the move() doc),\n    // so it is a graceful no-op here — relative targets relocate the subtree.\n    // A leaf block (no descendants) falls through to the single-move fast path.\n    const subtreeMembers = captureSubtreeParents(id);\n\n    if (subtreeMembers.length > 1) {\n      if ('toIndex' in target) {\n        return;\n      }\n\n      const preRemovalSlot = resolveMoveIndex(reader, target);\n      // The relative ref whose parent the moved block adopts (toIndex returned\n      // above, so target is { before | after }).\n      const ref = 'before' in target ? target.before : target.after;\n\n      transact(() => {\n        const outcome = relocateSubtree(id, preRemovalSlot);\n\n        if (outcome === 'blocked') {\n          return;\n        }\n        reassertDescendantParents(subtreeMembers, id);\n\n        // Adopt the REF's parent (sibling-of-ref) on BOTH the 'moved' and\n        // 'skipped' paths. The position is already sibling-of-ref: resolveMoveIndex\n        // clears the ref's WHOLE subtree for `after` and uses the ref's own slot\n        // for `before`, so id lands as the ref's sibling. The parent must match.\n        // Core's post-move auto-heal does NOT give that — it adopts the parent of\n        // the block at the landing SLOT (pre-removal), which for `after` a\n        // ref-with-descendants is the ref's last descendant (parent = the ref →\n        // nests id UNDER the ref) and for `before` a ref whose flat predecessor\n        // sits in another container is that predecessor's parent. On the 'skipped'\n        // path no move() ran, so no auto-heal fired at all. Assert ref.parentId so\n        // position and parent agree regardless of path. Guarded (mirrors\n        // insertWithinTransaction) so a same-container reorder — the common case,\n        // where the landed parent already matches — fires no redundant reparent.\n        // Can't cycle: ref is neither id nor a descendant (guarded above), so\n        // ref's parent is outside id's subtree.\n        const intendedParent = getById(ref)?.parentId ?? null;\n\n        if ((getById(id)?.parentId ?? null) !== intendedParent) {\n          editor.blocks.setBlockParent(id, intendedParent);\n        }\n      });\n\n      return;\n    }\n\n    const resolved = resolveMoveIndex(reader, target);\n\n    // Blok's Blocks.move() removes the block (splice fromIndex) BEFORE\n    // re-inserting at toIndex, so toIndex lives in the POST-removal index\n    // space. For a relative (before/after) forward move the reference index\n    // shifts down by one once the block is removed, so compensate — this also\n    // keeps a move-to-end within Blok's `toIndex < length` bound. A literal\n    // { toIndex } is the caller's explicit final resting index: pass through.\n    const isRelative = !('toIndex' in target);\n    const toIndex = isRelative && fromIndex < resolved ? resolved - 1 : resolved;\n\n    if (!isRelative) {\n      // Absolute { toIndex }: the caller chose the slot, so let core's auto-heal\n      // adopt that slot's container (the documented absolute-move semantics).\n      editor.blocks.move(toIndex, fromIndex);\n\n      return;\n    }\n\n    // Relative leaf move: same sibling-of-ref rule as the subtree branch — the\n    // moved block adopts the REF's parent, not the landing-slot neighbour's\n    // (which auto-heal would give: the ref's descendant for `after`, or a\n    // cross-container predecessor for `before`). Assert it in the same undo step\n    // as the move, guarded so a same-container reorder fires no redundant\n    // reparent. Can't cycle: ref is guarded to be neither id nor a descendant,\n    // and a leaf has no descendants for ref's parent to fall inside.\n    const ref = 'before' in target ? target.before : target.after;\n\n    transact(() => {\n      editor.blocks.move(toIndex, fromIndex);\n      const intendedParent = getById(ref)?.parentId ?? null;\n\n      if ((getById(id)?.parentId ?? null) !== intendedParent) {\n        editor.blocks.setBlockParent(id, intendedParent);\n      }\n    });\n  };\n\n  /**\n   * Perform one insert (create + intended-parent assertion) WITHOUT opening a\n   * transaction — the caller owns the undo grouping. `insert` wraps a single\n   * call in its own transact; `insertMany` shares ONE transact across the whole\n   * batch so the bulk insert is a single undo step. Returns the created node,\n   * or null when nothing was inserted (idempotent hit returns the existing\n   * node; a guard failure returns null).\n   */\n  const insertWithinTransaction = (spec: InsertSpec): { node: BlockNode | null; created: boolean } => {\n    const parentId = spec.parentId ?? null;\n    const position = spec.position ?? 'end';\n    const data = spec.data ?? {};\n    // Programmatic insert must not steal the caret unless explicitly asked.\n    const needToFocus = spec.focus ?? false;\n    const replace = spec.replace ?? false;\n\n    // Every pre-insert guard (id-exists, dangling-parent, missing-ref) and the\n    // replace-parent lookup used to call `getById`, which re-enumerates the\n    // WHOLE tree each time — O(probes·n) per spec, O(k·probes·n) per batch.\n    // The tree can't change until `editor.blocks.insert` runs below, so take\n    // ONE snapshot here and resolve every pre-insert probe against it.\n    const preById = new Map(snapshotNodes(reader).map((n) => [n.id, n]));\n    const probe = (id: string): BlockNode | null => preById.get(id) ?? null;\n\n    // Idempotent insert-if-absent: a stable explicit id that already exists\n    // returns the existing node without inserting a duplicate, so a re-running\n    // effect is safe. Probe via the silent snapshot getById, NOT\n    // editor.blocks.getBlockIndex — the latter logs a `warn` for any unknown\n    // id, which would spam the console on this (expected-absent) happy path.\n    //\n    // Skipped under `replace`: a replace is an explicit overwrite, not an\n    // insert, so an existing id must not short-circuit it (the two would\n    // otherwise silently conflict and replace nothing).\n    if (spec.id !== undefined && !replace) {\n      const existing = probe(spec.id);\n\n      if (existing !== null) {\n        // Insert-if-absent hit: the block already existed, nothing was created.\n        // insert() still returns the existing node (documented), but insertMany\n        // must EXCLUDE it from its created[] result — hence created: false.\n        return { node: existing, created: false };\n      }\n    }\n\n    // A dangling parentId would make core throw (dev) or silently misplace the\n    // block at the document end (prod). Honor the null contract instead. Probe\n    // via the silent snapshot getById, NOT editor.blocks.getBlockIndex, which\n    // logs a `warn` for any unknown id and would spam the console on this\n    // expected-absent no-op path. Skipped under replace: a replace ignores\n    // parentId entirely (the overwritten block's own parent governs), so a\n    // stale parentId must not abort the overwrite.\n    if (!replace && parentId !== null && probe(parentId) === null) {\n      return { node: null, created: false };\n    }\n\n    // A replace targets the before/after ref block ITSELF (the \"turn into\"\n    // block being overwritten), not a sibling anchor. It therefore REQUIRES an\n    // object position naming that ref:\n    //   - with position 'start'/'end' (or omitted) there is no target ref, so\n    //     a replace has nothing to overwrite — return null rather than silently\n    //     overwriting whatever block happens to sit at the resolved slot;\n    //   - with an object position whose ref doesn't exist there is likewise\n    //     nothing to overwrite — return null instead of falling through to\n    //     resolveInsertIndex's end-slot fallback (which would insert/replace at\n    //     the wrong place and reparent a dangling target).\n    // Validation is skipped for a plain insert (above), so this is the only\n    // guard that protects the replace path.\n    if (replace) {\n      if (typeof position !== 'object') {\n        return { node: null, created: false };\n      }\n\n      const replaceTargetRef = 'before' in position ? position.before : position.after;\n\n      if (probe(replaceTargetRef) === null) {\n        return { node: null, created: false };\n      }\n    }\n\n    // A plain insert with an object position naming a ref that does NOT exist\n    // must be a no-op (return null), NOT a silent append at the document/parent\n    // end. resolveInsertIndex falls back to the end slot for an unresolved ref,\n    // which would dump the block somewhere surprising — a DX footgun. Mirror\n    // move(), which already bails on a missing relative ref. (Skipped under\n    // replace: the block above already validated the replace ref.)\n    if (!replace && typeof position === 'object') {\n      const positionTargetRef = 'before' in position ? position.before : position.after;\n\n      if (probe(positionTargetRef) === null) {\n        return { node: null, created: false };\n      }\n    }\n\n    const flatIndex = resolveInsertIndex(reader, parentId, position, replace);\n\n    // A replace is a positional type-swap that PRESERVES the replaced block's\n    // parent link, so the intended parent is the target's existing parent, not\n    // the caller's (root-defaulting) parentId. Capture it from the pre-insert\n    // snapshot so the post-insert assertion re-nests the replacement correctly\n    // instead of un-nesting it to root. A plain insert uses parentId as-is.\n    const positionRef = ((): string | null => {\n      if (typeof position !== 'object') {\n        return null;\n      }\n\n      return 'before' in position ? position.before : position.after;\n    })();\n    const replaceRef = replace ? positionRef : null;\n    const intendedParentId =\n      replaceRef !== null ? probe(replaceRef)?.parentId ?? null : parentId;\n\n    const created = ((): { id: string } | null | undefined => {\n      try {\n        return editor.blocks.insert(spec.type, data, {}, flatIndex, needToFocus, replace, spec.id, spec.tunes);\n      } catch (error) {\n        // The only EXPECTED throw here is an unknown/missing tool — core throws\n        // a typed ToolNotFoundError. (A missing replace TARGET is a bare Error,\n        // not this type, so it would re-throw — but the replace ref is already\n        // pre-validated above, so it never reaches here.) Honor the null contract\n        // for ToolNotFoundError; re-throw anything else so a genuine\n        // bug surfaces instead of being masked as a null return. Keyed on the\n        // error TYPE, not a 'not found' substring, so an unrelated error whose\n        // message happens to contain \"not found\" is not wrongly swallowed.\n        if (error instanceof ToolNotFoundError) {\n          return null;\n        }\n        throw error;\n      }\n    })();\n\n    if (created === undefined || created === null) {\n      return { node: null, created: false };\n    }\n\n    // Assert the intended parent. Core derives a new block's parent from its\n    // flat predecessor, so a block appended right after a `column` child is\n    // auto-nested into that column. We know the caller's intent: for a\n    // parented insert set the parent; for a root insert (parentId === null)\n    // override back to root ONLY if core nested it, keeping the natural\n    // `insert({ position: 'end' })` a root sibling instead of a stowaway. For\n    // a replace, intendedParentId is the overwritten block's own parent, so\n    // the replacement keeps its place in the tree.\n    // ONE post-insert snapshot for both the landed-parent check and the return\n    // node (was two separate getById enumerations). A freshly-created block has\n    // no children, so reparenting it only flips its own parentId — its derived\n    // contentIds stay `[]`. We therefore reconstruct the corrected node in place\n    // rather than re-enumerating the tree a third time after setBlockParent.\n    const createdNode = snapshotNodes(reader).find((n) => n.id === created.id) ?? null;\n    const landedParentId = createdNode?.parentId ?? null;\n\n    const node =\n      landedParentId === intendedParentId\n        ? createdNode\n        : ((): BlockNode | null => {\n            editor.blocks.setBlockParent(created.id, intendedParentId);\n\n            return createdNode === null ? null : { ...createdNode, parentId: intendedParentId };\n          })();\n\n    // Position the caret inside the freshly-created block when the caller asked\n    // for a specific spot (beyond the boolean `focus`). Applied only on a real\n    // creation — an insert-if-absent hit returned earlier, so it never reaches\n    // here. setToBlock takes the block id directly.\n    if (spec.caret !== undefined) {\n      editor.caret.setToBlock(created.id, spec.caret.position ?? 'default', spec.caret.offset ?? 0);\n    }\n\n    return { node, created: true };\n  };\n\n  /**\n   * Insert one block. Returns the created {@link BlockNode}, or null when the\n   * insert is rejected — an unknown tool type (core \"…not found\"), a dangling\n   * `parentId`, or a `replace` whose target ref doesn't exist. An explicit\n   * `id` that already exists is insert-if-absent: the existing node is returned\n   * and nothing is created (skipped under `replace`, which is an explicit\n   * overwrite). Validation runs BEFORE the slot is resolved; a `replace`\n   * preserves the overwritten block's parent. Always one atomic undo step.\n   *\n   * The returned node is a fresh-snapshot view (its `contentIds` are derived\n   * per call) — read it immediately; do NOT place it in a `useMemo`/`useEffect`\n   * dependency array expecting per-mutation identity.\n   */\n  const insert = (spec: InsertSpec = {}): BlockNode | null => {\n    // Mutable property on a const holder (no `let`): the node captured from\n    // inside the transact closure for the post-transact return.\n    const result: { node: BlockNode | null } = { node: null };\n\n    // Always atomic: a single undo step removes the new block (and, for a\n    // parented insert, its reparent) — and gives the insert its own boundary\n    // instead of merging into adjacent typing history.\n    transact(() => {\n      // insert() returns the resolved node — including an insert-if-absent hit's\n      // existing node (documented) — so it reads only `.node`, not `.created`.\n      result.node = insertWithinTransaction(spec).node;\n    });\n\n    return result.node;\n  };\n\n  const insertMany = (specs: InsertSpec[]): BlockNode[] => {\n    // An empty batch opens no transaction (no spurious undo boundary).\n    if (specs.length === 0) {\n      return [];\n    }\n\n    const created: BlockNode[] = [];\n\n    // ONE transact for the whole batch → a single atomic undo step. Each spec\n    // still runs the full single-insert path (parent assertion, positioning).\n    // Per the documented contract, the result holds ONLY successfully-created\n    // nodes: specs that fail to insert (null node) AND insert-if-absent hits\n    // (existing block, created: false) are both dropped.\n    transact(() => {\n      for (const spec of specs) {\n        const result = insertWithinTransaction(spec);\n\n        if (result.created && result.node !== null) {\n          created.push(result.node);\n        }\n      }\n    });\n\n    return created;\n  };\n\n  /**\n   * Insert a pre-built nested subtree as ONE atomic operation. See the\n   * {@link UseBlocksApi.insertTree} contract. Flattens the spec to a DFS\n   * pre-order `OutputBlockData[]` — wiring every node's `parent`/`content`\n   * links from ids generated up front — then delegates to core's tree-aware\n   * `blocks.insertMany` inside a single transact.\n   */\n  const insertTree = (spec: TreeInsertSpec): BlockNode | null => {\n    const parentId = spec.parentId ?? null;\n    const position = spec.position ?? 'end';\n\n    // Dangling root parentId: mirror `insert`'s guard via the silent snapshot\n    // getById (NOT getBlockIndex, which warns on unknown ids). Reject so the\n    // subtree isn't silently dumped at the document end.\n    if (parentId !== null && getById(parentId) === null) {\n      return null;\n    }\n\n    // Dangling relative position ref: an object { before|after } naming a block\n    // that does not exist must be a no-op, NOT a silent append at the document\n    // end (resolveInsertIndex's unresolved-ref fallback). Mirror insert()'s\n    // missing-ref guard and reject before flattening anything.\n    if (typeof position === 'object') {\n      const positionTargetRef = 'before' in position ? position.before : position.after;\n\n      if (getById(positionTargetRef) === null) {\n        return null;\n      }\n    }\n\n    // Flatten the nested spec to a DFS pre-order array with wired\n    // `parent`/`content` links — the same transform used to seed nested data,\n    // shared as the pure `flattenTree` helper. `parentId` becomes the root's\n    // `parent`. flattenTree throws on an id reused WITHIN the spec (a duplicate\n    // would corrupt every id-keyed lookup); a tree insert always creates fresh\n    // blocks (NOT insert-if-absent), so that is rejected up front — null,\n    // mirroring insert's null contract.\n    const flat = (() => {\n      try {\n        return flattenTree(spec, { parentId: parentId ?? undefined });\n      } catch {\n        return null;\n      }\n    })();\n\n    if (flat === null) {\n      return null;\n    }\n\n    // External collision: an explicit id already present in the live tree would\n    // also create a duplicate-id block. Snapshot the existing ids once and\n    // reject if any flat node reuses one. Generated ids never collide.\n    const existingIds = new Set(snapshotNodes(reader).map((n) => n.id));\n\n    if (flat.some((node) => existingIds.has(node.id))) {\n      return null;\n    }\n\n    const rootId = flat[0].id;\n\n    // flattenTree omits `content` on leaves (clean seed-data shape). insertMany\n    // wants every node to carry an explicit child-id array — a leaf's\n    // `contentIds: []` states \"no children\" rather than leaving it undefined —\n    // so stamp the empty array back on before handing the batch to core.\n    for (const node of flat) {\n      if (node.content === undefined) {\n        node.content = [];\n      }\n    }\n\n    const flatIndex = resolveInsertIndex(reader, parentId, position);\n\n    // ONE transact for the whole subtree → a single atomic undo step. Core's\n    // insertMany composes EVERY node before inserting any, so an unknown tool\n    // type throws a typed ToolNotFoundError with nothing inserted. Honor the\n    // same null-on-unknown-tool contract as insert/insertMany rather than\n    // surfacing the throw to the caller; re-throw any other (genuine-bug)\n    // error. Keyed on the error TYPE, not a 'not found' substring.\n    try {\n      transact(() => {\n        editor.blocks.insertMany(flat, flatIndex);\n      });\n    } catch (error) {\n      if (error instanceof ToolNotFoundError) {\n        return null;\n      }\n      throw error;\n    }\n\n    return getById(rootId);\n  };\n\n  /**\n   * Convert markdown to blocks and insert them ADDITIVELY — see the\n   * {@link UseBlocksApi.insertMarkdown} doc for the full contract. Async\n   * because the converter is lazy-loaded; the insert itself is one atomic\n   * undo step. parentId nesting is supported: top-level converted blocks are\n   * reparented under parentId, internally-nested ones keep their parent.\n   */\n  const insertMarkdown = async (\n    markdown: string,\n    options?: { parentId?: string | null; position?: InsertPosition; config?: MarkdownImportConfig }\n  ): Promise<BlockNode[]> => {\n    const parentId = options?.parentId ?? null;\n    const position = options?.position ?? 'end';\n\n    // A dangling parentId is a no-op (no insert), matching `insert`/`insertMany`.\n    if (parentId !== null && getById(parentId) === null) {\n      return [];\n    }\n\n    // A dangling relative position ref is likewise a no-op (no insert), NOT a\n    // silent append at the document end — mirror insert()/insertTree's guard.\n    if (typeof position === 'object') {\n      const positionTargetRef = 'before' in position ? position.before : position.after;\n\n      if (getById(positionTargetRef) === null) {\n        return [];\n      }\n    }\n\n    // Lazy-load the converter (dynamic import mirrors core's markdown lazy\n    // loading and keeps the parser out of the main bundle) and run it,\n    // forwarding the optional MarkdownImportConfig so custom-tool consumers can\n    // map markdown nodes into their tools (gfm toggle, toolMap, extensions).\n    // Both awaits can fail — a chunk-load error or a malformed-markdown throw;\n    // swallow them and return [] so a converter failure is a graceful no-op\n    // (matching update/convert) rather than an unhandled promise rejection in\n    // the caller. This await resolves BEFORE the synchronous transact.\n    // Mutable property on a const holder (no `let`): captured from the try.\n    const conversion: { blocks: OutputBlockData[] } = { blocks: [] };\n\n    try {\n      const { markdownToBlocks } = await import('@bloklabs/core/markdown');\n\n      conversion.blocks = await markdownToBlocks(markdown, options?.config);\n    } catch (error) {\n      // Graceful no-op: a converter failure (chunk-load or parse error) returns\n      // [] rather than surfacing an unhandled rejection to the caller. But\n      // surface it to the console so a genuine converter bug is DISTINGUISHABLE\n      // from empty markdown (which returns [] via the blocks.length === 0 path\n      // below, without ever reaching this catch) instead of being swallowed\n      // silently and losing all diagnostics.\n      console.warn('useBlocks.insertMarkdown: markdown conversion failed', error);\n\n      return [];\n    }\n\n    const blocks = conversion.blocks;\n\n    // Empty / whitespace-only markdown opens no transaction (no undo boundary).\n    if (blocks.length === 0) {\n      return [];\n    }\n\n    // Re-validate the parent AFTER the await: the pre-await existence check can\n    // go stale if the parent was removed while the converter was in flight.\n    // Stamping a now-dangling parent would orphan the blocks instead of the\n    // promised [] no-op, so re-check and bail out here.\n    if (parentId !== null && getById(parentId) === null) {\n      return [];\n    }\n\n    // Re-validate the relative position ref after the await too: the target\n    // could have been removed while the converter was in flight, in which case\n    // inserting at the stale slot would surprise the caller. No-op instead.\n    if (typeof position === 'object') {\n      const positionTargetRef = 'before' in position ? position.before : position.after;\n\n      if (getById(positionTargetRef) === null) {\n        return [];\n      }\n    }\n\n    // Nest under the parent by stamping `parent` on each TOP-LEVEL block (one\n    // the converter left un-parented). Blocks the markdown nested internally\n    // (their `parent` already points at a sibling in this batch) are untouched,\n    // so the import's own structure is preserved.\n    const seeded: OutputBlockData[] =\n      parentId === null\n        ? blocks\n        : blocks.map((block) =>\n          block.parent === undefined || block.parent === null\n            ? { ...block, parent: parentId }\n            : block\n        );\n\n    const flatIndex = resolveInsertIndex(reader, parentId, position);\n\n    // Mutable property on a const holder (no `let`): captured from inside the\n    // transact closure. insertMany returns BlockAPI[] (each has `.id`) — the\n    // reliable record of what was created, since the converter's ids may not\n    // survive composition. ONE transact → a single atomic undo step.\n    const result: { created: Array<{ id: string }> } = { created: [] };\n\n    // The insert lives OUTSIDE the conversion try/catch, so an unknown mapped\n    // tool (core throws a typed ToolNotFoundError) would otherwise surface as an\n    // unhandled promise rejection. Honor the same null-on-unknown-tool contract\n    // as insertTree — return [] — and re-throw any other (genuine-bug) error.\n    // Keyed on the error TYPE, not a 'not found' substring.\n    try {\n      transact(() => {\n        result.created = editor.blocks.insertMany(seeded, flatIndex);\n      });\n    } catch (error) {\n      if (error instanceof ToolNotFoundError) {\n        return [];\n      }\n      throw error;\n    }\n\n    return result.created\n      .map((block) => getById(block.id))\n      .filter((node): node is BlockNode => node !== null);\n  };\n\n  const update = (\n    id: string,\n    data?: BlockToolData,\n    tunes?: { [name: string]: BlockTuneData }\n  ): void => {\n    // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n    if (getById(id) === null) {\n      return;\n    }\n\n    // Core update is async and forms its own undo/Yjs step, so it is NOT\n    // wrapped in transact (that would close the group before the write lands).\n    // Swallow any rejection so it can't surface as an unhandled rejection.\n    void Promise.resolve(editor.blocks.update(id, data, tunes)).catch(() => undefined);\n  };\n\n  const convert = (\n    id: string,\n    newType: string,\n    dataOverrides?: BlockToolData,\n    options?: { caret?: CaretTarget }\n  ): void => {\n    if (getById(id) === null) {\n      return;\n    }\n\n    // Core convert is async and rejects when a tool lacks a conversionConfig.\n    // Like update, it owns its own history step (no transact). Position the\n    // caret only AFTER a successful convert (matching the in-editor keyboard\n    // turn-into, which preserves the caret) when the caller asked for it.\n    // Swallow the rejection so a non-convertible block is a graceful no-op —\n    // and on rejection the caret is left untouched.\n    void Promise.resolve(editor.blocks.convert(id, newType, dataOverrides))\n      .then((converted) => {\n        if (options?.caret !== undefined) {\n          // Core convert routes through replace(), which regenerates the block\n          // id — the resolved BlockAPI carries the NEW id. Target it (falling\n          // back to the original only if a faithless path resolves nothing) so\n          // the caret lands in the converted block instead of a stale id.\n          const targetId = converted?.id ?? id;\n\n          editor.caret.setToBlock(\n            targetId,\n            options.caret.position ?? 'default',\n            options.caret.offset ?? 0\n          );\n        }\n      })\n      .catch(() => undefined);\n  };\n\n  const transactWithoutCapture = (fn: () => void): void => {\n    if (editor.blocks.transactWithoutCapture !== undefined) {\n      editor.blocks.transactWithoutCapture(fn);\n    } else {\n      fn();\n    }\n  };\n\n  const getBlocksCount = (): number => {\n    onRead();\n\n    return editor.blocks.getBlocksCount();\n  };\n\n  const getCurrentBlockIndex = (): number => {\n    onRead();\n\n    return editor.blocks.getCurrentBlockIndex();\n  };\n\n  const getBlockByIndex = (index: number): BlockNode | null => {\n    onRead();\n    const block = editor.blocks.getBlockByIndex(index);\n\n    return block === undefined ? null : getById(block.id);\n  };\n\n  const getBlockByElement = (element: HTMLElement): BlockNode | null => {\n    onRead();\n    const block = editor.blocks.getBlockByElement(element);\n\n    return block === undefined ? null : getById(block.id);\n  };\n\n  const composeBlockData = (toolName: string): Promise<BlockToolData> =>\n    editor.blocks.composeBlockData(toolName);\n\n  const getBlockData = (\n    id: string\n  ): { data: BlockToolData; tunes: { [name: string]: BlockTuneData } } | null => {\n    // Silent existence probe via the snapshot getById (NOT editor.blocks.getById,\n    // which logs a `warn` for an unknown id) so a miss is a quiet null, matching\n    // getBlockIndex and the other id-taking readers.\n    if (getById(id) === null) {\n      return null;\n    }\n\n    const block = editor.blocks.getById(id);\n\n    if (block === null) {\n      return null;\n    }\n\n    // preservedData/preservedTunes are core's SYNCHRONOUS last-extracted view —\n    // the same snapshot clipboard ops read. Returning it (rather than the async\n    // save()) keeps this reader synchronous so a block can be read and re-inserted\n    // (duplicated) inside one render/handler without the ref escape hatch.\n    return { data: block.preservedData, tunes: block.preservedTunes };\n  };\n\n  const getBlockIndex = (id: string): number | null => {\n    if (getById(id) === null) {\n      // Silent existence probe (NOT editor.blocks.getBlockIndex, which warns on\n      // unknown ids) so a miss is a quiet null, matching every other reader.\n      return null;\n    }\n\n    return editor.blocks.getBlockIndex(id) ?? null;\n  };\n\n  const renderFromHTML = (html: string): Promise<void> => editor.blocks.renderFromHTML(html);\n\n  const splitBlock = (\n    currentBlockId: string,\n    currentBlockData: Partial<BlockToolData>,\n    newBlockType: string,\n    newBlockData: BlockToolData,\n    insertIndex: number\n  ): BlockNode | null => {\n    // Silent no-op for an unknown current block, matching every other id-taking\n    // mutator. Probe via the snapshot getById (NOT getBlockIndex, which warns).\n    if (getById(currentBlockId) === null) {\n      return null;\n    }\n\n    // A negative insertIndex is malformed — core would forward it to a splice\n    // (which counts from the array end) and silently split at the wrong slot.\n    // Honor the silent-no-op convention instead (consistent with\n    // insertOutputData's negative-index guard): return null without touching core.\n    if (insertIndex < 0) {\n      return null;\n    }\n\n    // An unknown newBlockType makes core's compose path throw a typed\n    // ToolNotFoundError — honor the null contract (mirroring insert/insertTree);\n    // re-throw any other (genuine-bug) error. Keyed on the error TYPE.\n    const created = ((): { id: string } | null | undefined => {\n      try {\n        return editor.blocks.splitBlock(\n          currentBlockId,\n          currentBlockData,\n          newBlockType,\n          newBlockData,\n          insertIndex\n        );\n      } catch (error) {\n        if (error instanceof ToolNotFoundError) {\n          return null;\n        }\n        throw error;\n      }\n    })();\n\n    return created === undefined || created === null ? null : getById(created.id);\n  };\n\n  const insertOutputData = (\n    blocks: OutputBlockData[],\n    options?: { index?: number }\n  ): BlockNode[] => {\n    // An empty batch opens no transaction (no spurious undo boundary).\n    if (blocks.length === 0) {\n      return [];\n    }\n\n    // A negative index is malformed — core throws a bare validation Error. Honor\n    // the silent-no-op convention instead: return [] without inserting (no\n    // transaction, no surprise end-append), consistent with the rest of the API.\n    if (options?.index !== undefined && options.index < 0) {\n      return [];\n    }\n\n    // ONE transact for the whole batch → a single atomic undo step. Delegates\n    // to core's raw insertMany, which honors each block's parent/content links.\n    // Honor the same null/[]-on-unknown-tool contract as insertTree (core throws\n    // a typed ToolNotFoundError); re-throw any other (genuine-bug) error.\n    const result: { created: Array<{ id: string }> } = { created: [] };\n\n    try {\n      transact(() => {\n        result.created =\n          options?.index !== undefined\n            ? editor.blocks.insertMany(blocks, options.index)\n            : editor.blocks.insertMany(blocks);\n      });\n    } catch (error) {\n      if (error instanceof ToolNotFoundError) {\n        return [];\n      }\n      throw error;\n    }\n\n    return result.created\n      .map((block) => getById(block.id))\n      .filter((node): node is BlockNode => node !== null);\n  };\n\n  /**\n   * Insert one child block under `parentId` at flat `insertIndex`, atomically.\n   * Delegates to core's `insertInsideParent`, which groups the block creation\n   * AND the parent assignment into a single undo entry itself — so this is NOT\n   * wrapped in the hook's `transact` (that would be a redundant nested group).\n   * A dangling parentId is a no-op (null), mirroring `insert`'s parent guard;\n   * an unknown child tool throws a typed ToolNotFoundError from core's compose\n   * path — honor the null contract and re-throw anything else (genuine bug).\n   */\n  const insertInsideParent = (\n    parentId: string,\n    insertIndex: number,\n    childData?: BlockToolData\n  ): BlockNode | null => {\n    // Silent existence probe (NOT getBlockIndex, which warns on unknown ids).\n    if (getById(parentId) === null) {\n      return null;\n    }\n\n    const created = ((): { id: string } | null | undefined => {\n      try {\n        return editor.blocks.insertInsideParent(parentId, insertIndex, childData);\n      } catch (error) {\n        if (error instanceof ToolNotFoundError) {\n          return null;\n        }\n        throw error;\n      }\n    })();\n\n    return created === undefined || created === null ? null : getById(created.id);\n  };\n\n  /**\n   * Replace the whole document with saved {@link OutputData} — a document-LOAD\n   * primitive (clears existing content first), the counterpart of the additive\n   * {@link insertOutputData}. Pure delegation to core's async `render`.\n   */\n  const render = (data: OutputData): Promise<void> => editor.blocks.render(data);\n\n  /** Remove every block — document reset. Pure delegation to core's async `clear`. */\n  const clear = (): Promise<void> => editor.blocks.clear();\n\n  /**\n   * Serialize the document to Markdown — the read-side twin of\n   * {@link UseBlocksApi.insertMarkdown}. Pure delegation to core's async\n   * `exportMarkdown` (which lazy-loads the serializer).\n   */\n  const exportMarkdown = (): Promise<string> => editor.blocks.exportMarkdown();\n\n  /**\n   * The LIVE Yjs-sync flag, read at call time (the api handle is memoized, so a\n   * cached property would go stale). Pure delegation to core's read-only flag.\n   */\n  const isSyncingFromYjs = (): boolean => {\n    onRead();\n\n    return editor.blocks.isSyncingFromYjs;\n  };\n\n  // Every key is listed EXPLICITLY — do NOT spread `...EMPTY_API` here. The\n  // return is typed `UseBlocksApi`, so an explicit list makes a forgotten live\n  // wiring a COMPILE error (missing property). Spreading EMPTY_API would instead\n  // backfill the missing key with its pre-ready no-op stub, silently shipping a\n  // method that does nothing when the editor IS ready — a hole no key-presence\n  // test can catch (the key is present, just wrong). Keep it exhaustive.\n  return {\n    getById,\n    getChildren,\n    insert,\n    insertMany,\n    insertTree,\n    insertMarkdown,\n    exportMarkdown,\n    move,\n    nest,\n    unnest,\n    remove,\n    update,\n    convert,\n    transact,\n    transactWithoutCapture,\n    getBlocksCount,\n    getCurrentBlockIndex,\n    getBlockByIndex,\n    getBlockByElement,\n    getBlockData,\n    getBlockIndex,\n    composeBlockData,\n    renderFromHTML,\n    insertOutputData,\n    splitBlock,\n    insertInsideParent,\n    render,\n    clear,\n    isSyncingFromYjs,\n  };\n};\n","import type { ReadOnlyModeConfig } from '@bloklabs/core';\n\n/**\n * Normalized shape of the `readOnly` config option\n */\nexport interface NormalizedReadOnlyConfig {\n  enabled: boolean;\n  hideControls: boolean;\n}\n\n/**\n * Single source of truth for interpreting the `readOnly` config option.\n * The object form always means read-only is enabled.\n * @param value - raw `readOnly` value from BlokConfig\n */\nexport function normalizeReadOnlyConfig(value: boolean | ReadOnlyModeConfig | undefined): NormalizedReadOnlyConfig {\n  if (typeof value === 'object' && value !== null) {\n    return { enabled: true, hideControls: value.hideControls === true };\n  }\n\n  return { enabled: value === true, hideControls: false };\n}\n","/**\n * Structural deep equality for JSON-like values (Blok `OutputData`).\n *\n * Framework-agnostic: shared by the React and Angular adapters to dedupe\n * reactive `data` updates so identical content does not trigger a redundant\n * re-render that would clobber the caret/selection. Handles the value shapes\n * that appear in editor data: plain objects, arrays, and primitives (including\n * `null`/`undefined`).\n * @param a - first value to compare\n * @param b - second value to compare\n * @returns true when both values are structurally equal\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n  if (a === b) {\n    return true;\n  }\n\n  if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {\n    return false;\n  }\n\n  const aIsArray = Array.isArray(a);\n  const bIsArray = Array.isArray(b);\n\n  if (aIsArray !== bIsArray) {\n    return false;\n  }\n\n  if (aIsArray && bIsArray) {\n    if (a.length !== b.length) {\n      return false;\n    }\n\n    return a.every((item, index) => deepEqual(item, b[index]));\n  }\n\n  const aObj = a as Record<string, unknown>;\n  const bObj = b as Record<string, unknown>;\n  const aKeys = Object.keys(aObj);\n  const bKeys = Object.keys(bObj);\n\n  if (aKeys.length !== bKeys.length) {\n    return false;\n  }\n\n  return aKeys.every(\n    (key) => Object.prototype.hasOwnProperty.call(bObj, key) && deepEqual(aObj[key], bObj[key])\n  );\n}\n","import type { LooseOutputBlockData, LooseOutputData, OutputBlockData, OutputData } from '@bloklabs/core';\n/**\n * Public utilities for working with saved editor documents (`OutputData`).\n *\n * Consumers persisting editor content need two recurring predicates that the\n * editor itself already relies on internally:\n *\n * - structural equality, to dedupe the `data → render → onSave → data` echo\n *   round-trip without clobbering the caret;\n * - emptiness, to decide whether a document carries any user content\n *   (placeholder states, \"save\" button gating, skipping empty submissions).\n *\n * Both accept the loose wire shape (`data: null`, `id: null`, `parent: null`,\n * `content: null`, nullish documents) so backend DTOs can be passed as-is.\n */\nimport { deepEqual } from './deep-equal';\n\n\ntype AnyOutputData = OutputData | LooseOutputData | null | undefined;\n\n/**\n * Normalizes one block from the loose wire shape into the strict saved shape.\n * The single definition of how the wire spells \"absent\": `null`/`''` ids and\n * parents, `null`/`[]` content, `null`/missing data. Shared by\n * {@link normalizeOutputBlocks} and {@link equalsOutputBlock} so a DTO and its\n * saved echo are judged under the same rules.\n * @param block - a block in either the strict or the loose wire shape\n * @returns the block in the strict saved shape\n */\nfunction normalizeOutputBlock(block: OutputBlockData | LooseOutputBlockData): OutputBlockData {\n  const { id, data, parent, content, ...rest } = block;\n\n  return {\n    ...rest,\n    ...(typeof id === 'string' && id !== '' ? { id } : {}),\n    ...(typeof parent === 'string' && parent !== '' ? { parent } : {}),\n    ...(Array.isArray(content) && content.length > 0 ? { content } : {}),\n    data: data ?? {},\n  };\n}\n\n/**\n * Compares two blocks structurally. Both sides are normalized first\n * ({@link normalizeOutputBlock}), so the loose wire spellings of \"absent\"\n * (`parent: null`, `content: null`, `data: null`) equal the saved shape that\n * omits them. The `id` participates only when BOTH blocks carry one: the editor\n * mints a fresh id whenever content arrives without one, so an id-less origin\n * document must still compare equal to its saved echo.\n *\n * Edit metadata (`lastEditedAt`/`lastEditedBy`) never participates: it records\n * WHO touched the block and WHEN, not what it says, so a document whose only\n * delta is a stamp is not a content change.\n * @param a - first block to compare\n * @param b - second block to compare\n * @returns true when the blocks are structurally equal\n */\nfunction equalsOutputBlock(\n  a: OutputBlockData | LooseOutputBlockData,\n  b: OutputBlockData | LooseOutputBlockData\n): boolean {\n  const { id: idA, lastEditedAt: _editedAtA, lastEditedBy: _editedByA, ...restA } = normalizeOutputBlock(a);\n  const { id: idB, lastEditedAt: _editedAtB, lastEditedBy: _editedByB, ...restB } = normalizeOutputBlock(b);\n\n  const hasIdA = typeof idA === 'string' && idA !== '';\n  const hasIdB = typeof idB === 'string' && idB !== '';\n\n  if (hasIdA && hasIdB && idA !== idB) {\n    return false;\n  }\n\n  return deepEqual(restA, restB);\n}\n\n/**\n * The tool a pristine editor seeds its first (empty) block with. An empty block\n * of this type is UI scaffolding, not user content — see\n * {@link EqualsOutputDataOptions.ignoreEmptyDefaultBlocks}.\n */\nconst DEFAULT_BLOCK_TYPE = 'paragraph';\n\n/**\n * Options for {@link equalsOutputData}.\n */\nexport interface EqualsOutputDataOptions {\n  /**\n   * Ignore empty default blocks on both sides before comparing. A fresh editor\n   * always seeds one empty default paragraph, so a pristine document\n   * (`[{ type: 'paragraph', data: { text: '' } }]`) does not content-equal a\n   * saved-empty baseline (`[]`) by default. Turn this on for dirty-vs-baseline\n   * checks (\"has the user actually typed anything?\"): empty blocks of the\n   * default paragraph tool are dropped from both documents first, so pristine\n   * scaffolding and trailing empty lines don't register as a change. Empty\n   * NON-default blocks (a content-less divider, an empty image) are kept — they\n   * are meaningful content.\n   */\n  ignoreEmptyDefaultBlocks?: boolean;\n}\n\n/**\n * True for an empty block of the default paragraph tool — the editor's own\n * scaffolding, not user content.\n * @param block - block to inspect\n * @returns true when the block is an empty default paragraph\n */\nfunction isEmptyDefaultBlock(block: OutputBlockData | LooseOutputBlockData): boolean {\n  return block.type === DEFAULT_BLOCK_TYPE && isEmptyValue(block.data);\n}\n\n/**\n * Resolves the blocks to compare for a document, dropping empty default blocks\n * when {@link EqualsOutputDataOptions.ignoreEmptyDefaultBlocks} is set.\n * @param data - document whose blocks are collected\n * @param options - comparison options\n * @returns the blocks to compare\n */\nfunction comparableBlocks(\n  data: AnyOutputData,\n  options?: EqualsOutputDataOptions\n): Array<OutputBlockData | LooseOutputBlockData> {\n  const blocks = data?.blocks ?? [];\n\n  if (options?.ignoreEmptyDefaultBlocks === true) {\n    return blocks.filter((block) => !isEmptyDefaultBlock(block));\n  }\n\n  return blocks;\n}\n\n/**\n * Structural equality for saved documents. Compares the `blocks` arrays\n * deeply; the volatile `time` and `version` envelope fields are ignored, so a\n * document round-tripped through `save()` compares equal to its echo. Block\n * ids are compared only when both sides carry one — the editor mints fresh\n * ids for id-less content, so a legacy document still equals its saved echo.\n * Edit metadata (`lastEditedAt`/`lastEditedBy`) is ignored for the same reason:\n * it records who touched a block and when, not what it says. Nullish documents\n * compare equal to `{ blocks: [] }`.\n *\n * Pass `{ ignoreEmptyDefaultBlocks: true }` for dirty-vs-baseline checks so a\n * pristine editor (one empty default paragraph) equals a saved-empty baseline —\n * see {@link EqualsOutputDataOptions}.\n * @param a - first document to compare\n * @param b - second document to compare\n * @param options - comparison options\n * @returns true when both documents hold structurally equal blocks\n */\nexport function equalsOutputData(a: AnyOutputData, b: AnyOutputData, options?: EqualsOutputDataOptions): boolean {\n  const blocksA = comparableBlocks(a, options);\n  const blocksB = comparableBlocks(b, options);\n\n  return blocksA.length === blocksB.length && blocksA.every((block, index) => equalsOutputBlock(block, blocksB[index]));\n}\n\n/**\n * A bounded window of the editor's recently emitted `onSave` payloads, used by\n * the framework adapters to recognize controlled-`data` echoes. Deduping\n * against only the LAST emitted payload is not enough: a host that persists on\n * save and refetches can hand the adapter a STALE echo — an earlier save\n * arriving after a newer one already replaced the baseline — and re-rendering\n * it would clobber the caret and any content typed since. Matching is\n * structural ({@link equalsOutputData}), so envelopes reshaped in transit\n * (fresh `time`, stripped ids) still count as echoes.\n * @param capacity - number of payloads retained before the oldest is evicted\n * @returns the echo window\n */\nexport function createEmittedEchoWindow(capacity: number = 20): {\n  /** Records a payload the editor emitted via `onSave`. */\n  record(data: OutputData | LooseOutputData): void;\n  /** True when the document content-equals any recorded payload. */\n  matches(data: AnyOutputData): boolean;\n  /** Forgets all recorded payloads (external content took over). */\n  clear(): void;\n} {\n  const emitted: Array<OutputData | LooseOutputData> = [];\n\n  return {\n    record(data: OutputData | LooseOutputData): void {\n      emitted.push(data);\n      if (emitted.length > capacity) {\n        emitted.shift();\n      }\n    },\n    matches(data: AnyOutputData): boolean {\n      return emitted.some((payload) => equalsOutputData(payload, data));\n    },\n    clear(): void {\n      emitted.length = 0;\n    },\n  };\n}\n\n/**\n * A shared, deeply frozen empty document. Consumers persisting editor content\n * repeatedly hand-write `{ blocks: [] }` for cleared/pristine baselines; this\n * is the canonical value to use instead. Frozen (blocks array included) so a\n * shared reference can never be mutated into a stale non-empty baseline.\n */\nexport const EMPTY_OUTPUT_DATA: OutputData = Object.freeze({\n  // Freeze the array too, so a shared reference can't be mutated. The public\n  // `blocks` type is mutable (`OutputBlockData[]`), so the frozen (readonly)\n  // array is re-widened through `unknown` — runtime stays frozen.\n  blocks: Object.freeze([]) as unknown as OutputBlockData[],\n});\n\n/**\n * Maps a controlled `data` value to something the editor's `render()` accepts.\n * A whole-document `null` — a controlled \"clear to empty\" — becomes\n * `{ blocks: [] }`; any real document passes through untouched.\n *\n * The framework adapters (React/Vue/Angular) route their reactive `data` path\n * through this so a `null` never reaches `render()`, whose strict guard reads\n * `data.blocks` and would throw on `null`. `undefined` (uncontrolled) is handled\n * by the adapters before this point, so it is intentionally not an input here.\n * @param data - a controlled document, or `null` for an empty document\n * @returns a document `render()` can consume\n */\nexport function toRenderableData(data: OutputData | LooseOutputData | null): OutputData | LooseOutputData {\n  return data === null ? { blocks: [] } : data;\n}\n\n/**\n * Normalizes blocks from the loose wire shape into the strict saved shape at\n * the editor's input boundaries: a `null`/missing `data` becomes `{}`, a\n * `null`/empty `id` is dropped so the block factory generates a fresh one, and\n * nullish/empty hierarchy references (`parent`, `content`) are dropped so a\n * root-level, childless block is spelled the one way the editor and `save()`\n * both spell it — absent. Idempotent — strict blocks pass through unchanged\n * (shallow-copied).\n * @param blocks - blocks in either the strict or the loose wire shape\n * @returns blocks in the strict saved shape\n */\nexport function normalizeOutputBlocks(blocks: Array<OutputBlockData | LooseOutputBlockData>): OutputBlockData[] {\n  return blocks.map(normalizeOutputBlock);\n}\n\n/**\n * Normalizes a whole loose wire document into the strict saved\n * {@link OutputData} shape at an input boundary. A nullish document becomes\n * `{ blocks: [] }`; `null` envelope fields (`time`/`version`) are dropped; each\n * block is passed through {@link normalizeOutputBlocks}, so `null`/missing\n * `data` becomes `{}`, `null`/empty ids are dropped for regeneration and\n * nullish/empty `parent`/`content` references are dropped as absent.\n *\n * Unlike a hand-written `blocks.map(...)` mapper, this preserves every block\n * passthrough field — `tunes`, real `parent`/`content` references, `indent`,\n * edit metadata — so a backend DTO can be turned into strict `OutputData`\n * without silently losing hierarchy or tunes. Idempotent: a strict document\n * passes through unchanged (shallow-copied).\n * @param data - a document in the strict or loose wire shape, or nullish\n * @returns the document in the strict saved shape\n */\nexport function normalizeOutputData(data: AnyOutputData): OutputData {\n  if (data === null || data === undefined) {\n    return { blocks: [] };\n  }\n\n  return {\n    ...(typeof data.version === 'string' ? { version: data.version } : {}),\n    ...(typeof data.time === 'number' ? { time: data.time } : {}),\n    blocks: normalizeOutputBlocks(data.blocks),\n  };\n}\n\n/**\n * True when the value carries no user content: blank/whitespace-only strings,\n * empty arrays, plain objects whose values are all empty, and nullish values.\n * Numbers and booleans are presentation metadata (`level`, `checked`, styles)\n * and never count as content on their own.\n * @param value - block data value to inspect\n * @returns true when the value carries no user content\n */\nfunction isEmptyValue(value: unknown): boolean {\n  if (value === null || value === undefined) {\n    return true;\n  }\n\n  if (typeof value === 'string') {\n    return value.trim() === '';\n  }\n\n  if (Array.isArray(value)) {\n    return value.every(isEmptyValue);\n  }\n\n  if (typeof value === 'object') {\n    return Object.values(value).every(isEmptyValue);\n  }\n\n  // Numbers, booleans and other primitives are metadata, not content.\n  return true;\n}\n\n/**\n * True when the document carries no user content: it is nullish, has no\n * blocks, or every block's data holds only empty values (see\n * {@link isEmptyValue}). Note that content-less visual blocks (e.g. a divider,\n * whose data is `{}`) count as empty — check `blocks.length` when mere block\n * presence matters.\n * @param data - document to inspect\n * @returns true when the document carries no user content\n */\nexport function isEmptyOutputData(data: AnyOutputData): boolean {\n  const blocks = data?.blocks ?? [];\n\n  return blocks.every((block) => isEmptyValue(block.data));\n}\n","// src/shared/prop-schema.ts\n\n/** One field of a block's prop schema. */\nexport interface PropSchemaEntry {\n  /** Default value, used when the incoming data omits this key. */\n  default: unknown;\n  /** Optional allowed values (advisory; not enforced at runtime in v1). */\n  values?: readonly unknown[];\n}\n\n/**\n * Declarative data shape. The keys here are EXACTLY the keys `save()` returns to\n * Yjs — this closes the per-key-sync key-resurrection gap (a cleared field is\n * written as its explicit default, never dropped).\n */\nexport type PropSchema = Record<string, PropSchemaEntry>;\n\n/**\n * Fill a data object against the schema: every schema key present, incoming\n * value when defined else the schema default, and ONLY schema keys (so `save()`\n * is never partial). Returns a frozen plain object — safe to hand straight to\n * core's per-key Yjs sync.\n */\nexport const fillDefaults = <Data>(\n  schema: PropSchema,\n  data: Record<string, unknown>\n): Readonly<Data> => {\n  const result: Record<string, unknown> = {};\n\n  for (const key of Object.keys(schema)) {\n    result[key] = data[key] !== undefined ? data[key] : schema[key].default;\n  }\n\n  return Object.freeze(result) as Readonly<Data>;\n};\n","/**\n * Centralized data attributes used across the Blok editor.\n * This is the single source of truth for all data-blok-* attributes.\n *\n * Exported as Blok.DATA_ATTR for users.\n *\n * Naming convention:\n * - Remove 'data-blok-' prefix and convert to camelCase\n * - Global attributes: hidden, disabled, focused\n * - Component prefixed: popover, popoverItem, toolbar, etc.\n */\nexport const DATA_ATTR = {\n  // ============================================\n  // Core Element Identifiers\n  // ============================================\n\n  /** Interface type identifier (blok, inline-toolbar, tooltip) */\n  interface: 'data-blok-interface',\n  /** Block element wrapper */\n  element: 'data-blok-element',\n  /** Block element content wrapper */\n  elementContent: 'data-blok-element-content',\n  /** Editor wrapper container */\n  editor: 'data-blok-editor',\n  /** Per-instance discriminator on the editor wrapper (a monotonic counter, as a\n   *  string). Two editors on one page share every other scope attribute, so this\n   *  is what lets a page-level stylesheet — Blok's own injected `style.fontSize`\n   *  sheet, or a host rule — address ONE editor. Public styling hook. */\n  instance: 'data-blok-instance',\n  /** Redactor zone */\n  redactor: 'data-blok-redactor',\n  /** Present on the editor wrapper once a `blocks.render()` batch has finished\n   *  inserting blocks into the DOM; removed while a re-render is in flight.\n   *  Acts as a stable render-readiness gate for consumers (e.g. E2E waits). */\n  rendered: 'data-blok-rendered',\n  /** Blok version number stamped on the editor wrapper (e.g. '1.10.0', 'dev').\n   *  Consumed by browser extensions to identify the running version. */\n  version: 'data-blok-version',\n\n  // ============================================\n  // Block Identifiers\n  // ============================================\n\n  /** Block unique identifier */\n  id: 'data-blok-id',\n  /** Block component/tool type */\n  component: 'data-blok-component',\n  /** Tool type attribute */\n  tool: 'data-blok-tool',\n  /** Block nesting depth (derived from the parentId chain) */\n  depth: 'data-blok-depth',\n  /** Flat list-nesting indentation level (0 = root); tool-agnostic, mirrors list depth */\n  indent: 'data-blok-indent',\n  /** Header tool's heading level (1-6). Public styling hook — keyed by level rather\n   *  than by tag name, so a level remapped to a custom tag via `levelOverrides[n].tag`\n   *  (types/tools/header.d.ts) still matches its level's typography rules. */\n  headingLevel: 'data-blok-heading-level',\n\n  // ============================================\n  // Global States\n  // ============================================\n\n  /** Element is hidden from view */\n  hidden: 'data-blok-hidden',\n  /** Element is disabled and non-interactive */\n  disabled: 'data-blok-disabled',\n  /** Element is focused via keyboard navigation */\n  focused: 'data-blok-focused',\n  /** Block is selected */\n  selected: 'data-blok-selected',\n  /** Block is stretched */\n  stretched: 'data-blok-stretched',\n  /** Editor or element is empty */\n  empty: 'data-blok-empty',\n  /** Present on the editor wrapper while read-only mode is active.\n   *  Public styling hook — lets hosts key rules off the editing state\n   *  without JS. Deliberately does NOT collapse the gutter: plain\n   *  read-only still shows the block-hover copy-link control there, and\n   *  in-place readOnly.set() flips must not shift the layout. */\n  readonly: 'data-blok-readonly',\n  /** Present on the editor wrapper while read-only mode hides ALL editor\n   *  controls (readOnly: { hideControls: true }). Public styling hook —\n   *  drives the gutter auto-collapse for genuinely chromeless read-only. */\n  controlsHidden: 'data-blok-controls-hidden',\n  /** Present on the editor wrapper when config.hideToolbar is true.\n   *  Public styling hook — drives the gutter auto-collapse (the gutter\n   *  exists solely to house the toolbar's +/⠿ controls). */\n  toolbarHidden: 'data-blok-toolbar-hidden',\n  /** Which gutter the floating block controls occupy: 'left' (default,\n   *  inline-start) or 'right' (inline-end). Written on the editor wrapper from\n   *  config.toolbarPosition and kept in sync by `toolbar.setPosition()`.\n   *  Public styling hook — drives the gutter swap and the actions-bar side. */\n  toolbarPosition: 'data-blok-toolbar-position',\n\n  // ============================================\n  // Editor Modes\n  // ============================================\n\n  /** Content alignment mode (left, center, right) */\n  contentAlign: 'data-blok-content-align',\n  /** Right-to-left mode */\n  rtl: 'data-blok-rtl',\n  /** Editor content width mode (present with value \"full\" for wide mode; absent = narrow) */\n  width: 'data-blok-width',\n  /** Present on the editor wrapper when config.style.nativeSelection is true.\n   *  Public styling hook — disables Blok's ::selection repaint (preflight.css)\n   *  and re-points the fake-background highlight at the UA Highlight color\n   *  (colors.css), so selection falls back to native/host-defined colors. */\n  nativeSelection: 'data-blok-native-selection',\n  /** Present on the editor wrapper while a cross-block TEXT selection is painted.\n   *  Suppresses the engine's own ::selection paint (main.css) so the\n   *  ::highlight() sub-ranges are the only thing drawn — Chromium and Firefox\n   *  paint such a range natively too and would otherwise double it up. */\n  crossSelection: 'data-blok-cross-selection',\n\n  // ============================================\n  // Drag and Drop\n  // ============================================\n\n  /** Block is being dragged */\n  dragging: 'data-blok-dragging',\n  /** Multiple blocks being dragged */\n  draggingMulti: 'data-blok-dragging-multi',\n  /** Block is being duplicated (Alt+drag) */\n  duplicating: 'data-blok-duplicating',\n  /** Drag handle element */\n  dragHandle: 'data-blok-drag-handle',\n\n  // ============================================\n  // Toolbar\n  // ============================================\n\n  /** Toolbar element */\n  toolbar: 'data-blok-toolbar',\n  /** The floating block-controls bar (plus button + drag/settings handle)\n   *  inside the toolbar. Public styling hook — the side it docks to is driven\n   *  from the wrapper's `data-blok-toolbar-position`. */\n  toolbarActions: 'data-blok-toolbar-actions',\n  /** Settings toggler button */\n  settingsToggler: 'data-blok-settings-toggler',\n  /** Toolbox is open */\n  toolboxOpened: 'data-blok-toolbox-opened',\n  /** Block settings is open */\n  blockSettingsOpened: 'data-blok-block-settings-opened',\n  /** Element is opened (generic) */\n  opened: 'data-blok-opened',\n\n  // ============================================\n  // Popover Container\n  // ============================================\n\n  /** Root popover element */\n  popover: 'data-blok-popover',\n  /** Popover container wrapper */\n  popoverContainer: 'data-blok-popover-container',\n  /** Popover items list */\n  popoverItems: 'data-blok-popover-items',\n  /** Custom, engine-independent scrollbar thumb overlaid on the popover items */\n  popoverScrollbar: 'data-blok-popover-scrollbar',\n  /** Stamped on the custom scrollbar thumb while it is being dragged (keeps it revealed) */\n  popoverScrollbarDragging: 'data-blok-dragging',\n  /** Stamped on a scroll container while it is actively scrolling (reveals the auto-hidden scrollbar thumb) */\n  scrolling: 'data-blok-scrolling',\n  /** Popover overlay element */\n  popoverOverlay: 'data-blok-popover-overlay',\n  /** Popover custom content area */\n  popoverCustomContent: 'data-blok-popover-custom-content',\n  /** Popover custom class */\n  popoverCustomClass: 'data-blok-popover-custom-class',\n  /** Inline popover variant */\n  popoverInline: 'data-blok-popover-inline',\n  /** Popover is open */\n  popoverOpened: 'data-blok-popover-opened',\n  /** Popover opens upward */\n  popoverOpenTop: 'data-blok-popover-open-top',\n  /** Popover opens leftward */\n  popoverOpenLeft: 'data-blok-popover-open-left',\n\n  // ============================================\n  // Popover Nesting\n  // ============================================\n\n  /** Nested popover indicator */\n  nested: 'data-blok-nested',\n  /** Nesting level value */\n  nestedLevel: 'data-blok-nested-level',\n  /** Group label for promoted search results from nested children */\n  promotedGroupLabel: 'data-blok-promoted-group-label',\n  /** Group label for top-level matches in search results */\n  topLevelGroupLabel: 'data-blok-top-level-group-label',\n\n  // ============================================\n  // Popover Header\n  // ============================================\n\n  /** Header container */\n  popoverHeader: 'data-blok-popover-header',\n  /** Header text element */\n  popoverHeaderText: 'data-blok-popover-header-text',\n  /** Back button in nested popover */\n  popoverHeaderBackButton: 'data-blok-popover-header-back-button',\n\n  // ============================================\n  // Popover Items\n  // ============================================\n\n  /** Item container */\n  popoverItem: 'data-blok-popover-item',\n  /** Item icon wrapper */\n  popoverItemIcon: 'data-blok-popover-item-icon',\n  /** Chevron icon for nested items */\n  popoverItemIconChevronRight: 'data-blok-popover-item-icon-chevron-right',\n  /** Item title text */\n  popoverItemTitle: 'data-blok-popover-item-title',\n  /** Item secondary title */\n  popoverItemSecondaryTitle: 'data-blok-popover-item-secondary-title',\n  /** Item is active/selected */\n  popoverItemActive: 'data-blok-popover-item-active',\n  /** Item's child menu is currently open — keeps the trigger looking selected */\n  popoverItemChildrenOpen: 'data-blok-popover-item-children-open',\n  /** Confirmation state */\n  popoverItemConfirmation: 'data-blok-popover-item-confirmation',\n  /** Disable hover styling */\n  popoverItemNoHover: 'data-blok-popover-item-no-hover',\n  /** Disable focus handling */\n  popoverItemNoFocus: 'data-blok-popover-item-no-focus',\n  /** Destructive action item (e.g. delete) */\n  popoverItemDestructive: 'data-blok-popover-item-destructive',\n  /** Separator item */\n  popoverItemSeparator: 'data-blok-popover-item-separator',\n  /** Separator line element */\n  popoverItemSeparatorLine: 'data-blok-popover-item-separator-line',\n  /** HTML-based item */\n  popoverItemHtml: 'data-blok-popover-item-html',\n  /** Item has child menu */\n  hasChildren: 'data-blok-has-children',\n  /** Item name identifier */\n  itemName: 'data-blok-item-name',\n  /** No search results shown */\n  nothingFoundDisplayed: 'data-blok-nothing-found-displayed',\n\n  // ============================================\n  // Overlay / Selection\n  // ============================================\n\n  /** Selection overlay */\n  overlay: 'data-blok-overlay',\n  /** Overlay container */\n  overlayContainer: 'data-blok-overlay-container',\n  /** Selection rectangle */\n  overlayRectangle: 'data-blok-overlay-rectangle',\n  /** Overlay is hidden */\n  overlayHidden: 'data-blok-overlay-hidden',\n  /** Fake cursor indicator */\n  fakeCursor: 'data-blok-fake-cursor',\n  /** Fake background for selection */\n  fakeBackground: 'data-blok-fake-background',\n\n  // ============================================\n  // Scroll\n  // ============================================\n\n  /** Auto-scroll zone (top/bottom) */\n  scrollZone: 'data-blok-scroll-zone',\n  /** Scroll is locked */\n  scrollLocked: 'data-blok-scroll-locked',\n  /** Hard scroll lock */\n  scrollLockedHard: 'data-blok-scroll-locked-hard',\n\n  // ============================================\n  // Caret\n  // ============================================\n\n  /** Shadow caret element */\n  shadowCaret: 'data-blok-shadow-caret',\n\n  // ============================================\n  // Placeholders\n  // ============================================\n\n  /** Placeholder text */\n  placeholder: 'data-blok-placeholder',\n  /** Active placeholder text */\n  placeholderActive: 'data-blok-placeholder-active',\n\n  // ============================================\n  // Columns Layout\n  // ============================================\n\n  /** The columns row rendered by the column_list tool (the flex container).\n   *  Public styling hook — its direct `[data-blok-element]` children are the\n   *  column holders, whose shrink floor reads `--blok-column-min-width` and\n   *  whose gutter reads `--blok-column-gutter`. */\n  columns: 'data-blok-columns',\n  /** A single column inside a columns row. */\n  column: 'data-blok-column',\n  /** Drag-to-resize separator between two adjacent columns. Present only in\n   *  edit mode — the separators ARE the gutter there. */\n  columnResizer: 'data-blok-column-resizer',\n  /** Present on a columns row whose gutter comes from the container's own\n   *  column-gap instead of from resizer elements. Set in read-only mode, where\n   *  no resizers are built — the discriminator between an editable row and a\n   *  published one. */\n  columnsStaticGutter: 'data-blok-columns-static-gutter',\n\n  // ============================================\n  // Nested Blocks\n  // ============================================\n\n  /** Container that hosts nested block holders (table cells, toggle/callout/header children).\n   *  Used as a universal guard: before moving a block holder via appendChild,\n   *  check `holder.closest([nestedBlocks])` — if truthy, the holder is already\n   *  claimed by another container and must not be stolen. */\n  nestedBlocks: 'data-blok-nested-blocks',\n\n  // ============================================\n  // Mutation Tracking\n  // ============================================\n\n  /** Element excluded from mutation tracking */\n  mutationFree: 'data-blok-mutation-free',\n\n  // ============================================\n  // Keyboard Ownership\n  // ============================================\n\n  /** Marks a subtree whose keyboard belongs to the Tool that rendered it, not to\n   *  the editor. Blok's block-level keydown/keyup handling stands down entirely\n   *  for events originating inside it — Escape, Tab, the arrows, \"/\" and the\n   *  Enter/Backspace/Delete structural keys all reach the element untouched.\n   *\n   *  Blok already exempts native `<input>`/`<textarea>` from the STRUCTURAL keys\n   *  (Enter/Backspace/Delete and \"/\") because those are contenteditable-shaped\n   *  and would splice the document around a form field. Escape/Tab/arrows are\n   *  deliberately NOT exempt — they are how a user leaves a field. That default\n   *  is right for a one-line title input and wrong for a field with its own\n   *  keyboard semantics (Tab between sub-fields, Escape to cancel an edit, arrows\n   *  to walk a suggestion list), which is exactly what this attribute is for.\n   *  Public authoring hook. */\n  keyboardOwner: 'data-blok-keyboard-owner',\n\n  // ============================================\n  // Navigation\n  // ============================================\n\n  /** Block has navigation focus */\n  navigationFocused: 'data-blok-navigation-focused',\n  /** Flipper navigation target */\n  flipperNavigationTarget: 'data-blok-flipper-navigation-target',\n\n  // ============================================\n  // Inline Toolbar\n  // ============================================\n\n  /** Inline toolbar enabled on external element */\n  inlineToolbar: 'data-blok-inline-toolbar',\n\n  // ============================================\n  // Link Tool\n  // ============================================\n\n  /** Link tool is active */\n  linkToolActive: 'data-blok-link-tool-active',\n  /** Link tool unlink mode */\n  linkToolUnlink: 'data-blok-link-tool-unlink',\n  /** Link tool input is opened */\n  linkToolInputOpened: 'data-blok-link-tool-input-opened',\n\n  // ============================================\n  // Bold Tool\n  // ============================================\n\n  /** Bold collapsed length tracking */\n  boldCollapsedLength: 'data-blok-bold-collapsed-length',\n  /** Bold collapsed active state */\n  boldCollapsedActive: 'data-blok-bold-collapsed-active',\n  /** Bold previous length tracking */\n  boldPrevLength: 'data-blok-bold-prev-length',\n  /** Bold leading whitespace */\n  boldLeadingWs: 'data-blok-bold-leading-ws',\n  /** Bold marker */\n  boldMarker: 'data-blok-bold-marker',\n\n  // ============================================\n  // Tooltip\n  // ============================================\n\n  /** Tooltip is shown */\n  shown: 'data-blok-shown',\n  /** Tooltip placement */\n  placement: 'data-blok-placement',\n\n  // ============================================\n  // Notifier\n  // ============================================\n\n  /** Bounce in animation */\n  bounceIn: 'data-blok-bounce-in',\n\n  // ============================================\n  // Announcer (Accessibility)\n  // ============================================\n\n  /** Live region announcer */\n  announcer: 'data-blok-announcer',\n\n  // ============================================\n  // Stub Block\n  // ============================================\n\n  /** Stub block element */\n  stub: 'data-blok-stub',\n  /** Stub info section */\n  stubInfo: 'data-blok-stub-info',\n  /** Stub title */\n  stubTitle: 'data-blok-stub-title',\n  /** Stub subtitle */\n  stubSubtitle: 'data-blok-stub-subtitle',\n\n  // ============================================\n  // Slash Search\n  // ============================================\n\n  /** Slash search active on content editable */\n  slashSearch: 'data-blok-slash-search',\n\n  // ============================================\n  // Testing\n  // ============================================\n\n  /** Test identifier (for E2E tests) */\n  testid: 'data-blok-testid',\n  /** Force hover state (for tests/storybook) */\n  forceHover: 'data-blok-force-hover',\n} as const;\n\n/**\n * Type for DATA_ATTR keys\n */\nexport type DataAttrKey = keyof typeof DATA_ATTR;\n\n/**\n * Type for DATA_ATTR values\n */\nexport type DataAttrValue = (typeof DATA_ATTR)[DataAttrKey];\n\n/**\n * Helper function to create a CSS selector from an attribute\n *\n * @param attr - The data attribute name from DATA_ATTR\n * @param value - Optional value for the attribute (defaults to presence selector)\n * @returns CSS selector string\n *\n * @example\n * createSelector(DATA_ATTR.element) // '[data-blok-element]'\n * createSelector(DATA_ATTR.selected, true) // '[data-blok-selected=\"true\"]'\n * createSelector(DATA_ATTR.tool, 'paragraph') // '[data-blok-tool=\"paragraph\"]'\n */\nexport const createSelector = (attr: DataAttrValue, value?: string | boolean): string => {\n  if (value === undefined) {\n    return `[${attr}]`;\n  }\n\n  return `[${attr}=\"${value}\"]`;\n};\n","/**\n * HTML manipulation utilities\n */\n\n/**\n * Strips fake background wrapper elements from HTML content.\n * These elements are used by the inline toolbar for visual selection highlighting\n * and should not be persisted in saved data.\n * @param html - HTML content that may contain fake background elements\n * @returns HTML content with fake background wrappers removed but their content preserved\n */\nexport const stripFakeBackgroundElements = (html: string): string => {\n  if (!html || !html.includes('data-blok-fake-background')) {\n    return html;\n  }\n\n  const tempDiv = document.createElement('div');\n\n  tempDiv.innerHTML = html;\n\n  const fakeBackgrounds = tempDiv.querySelectorAll('[data-blok-fake-background=\"true\"]');\n\n  fakeBackgrounds.forEach((element) => {\n    const parent = element.parentNode;\n\n    if (!parent) {\n      return;\n    }\n\n    while (element.firstChild) {\n      parent.insertBefore(element.firstChild, element);\n    }\n\n    parent.removeChild(element);\n  });\n\n  return tempDiv.innerHTML;\n};\n\n/**\n * An intersection rather than `interface extends Element`: TypeScript 6's\n * lib.dom.d.ts declares `moveBefore` as a required member of ParentNode, and an\n * interface may not redeclare an inherited member as optional. Intersections\n * skip that declaration-compatibility check, so this compiles on both the 5.9\n * libs (no `moveBefore` at all) and the 6.0 libs (required `moveBefore`).\n */\ntype StatefulMoveParent = Element & {\n  moveBefore?(node: Node, reference: Node | null): void;\n};\n\n/**\n * Repositions an already-attached node within `parent`, inserting it before\n * `reference` (or at the end when `reference` is null), while preserving the\n * node's live state — an iframe keeps its loaded document, media keeps playing,\n * form fields keep focus and value.\n *\n * A plain insertBefore/appendChild detaches and re-attaches the node, which\n * resets exactly that state (re-parented iframes reload). The browser's\n * state-preserving move (`moveBefore`, Chrome 133+) avoids the detach; we fall\n * back to insertBefore where it is unavailable or throws (e.g. cross-document\n * moves, or a node that is not connected).\n */\nconst statefulMove = (parent: StatefulMoveParent, node: Node, reference: Node | null): void => {\n  if (reference === node) {\n    return;\n  }\n\n  if (typeof parent.moveBefore === 'function' && node.isConnected && parent.isConnected) {\n    try {\n      parent.moveBefore(node, reference);\n\n      return;\n    } catch {\n      // moveBefore enforces stricter invariants than insertBefore (same\n      // document, connected node); fall back to a plain, state-resetting insert.\n    }\n  }\n\n  parent.insertBefore(node, reference);\n};\n\n/**\n * Moves `node` to sit immediately before `reference`, preserving live state.\n * @see statefulMove\n */\nexport const moveElementBefore = (node: Node, reference: Element): void => {\n  const parent = reference.parentNode;\n\n  if (parent instanceof Element) {\n    statefulMove(parent, node, reference);\n  }\n};\n\n/**\n * Moves `node` to sit immediately after `reference`, preserving live state.\n * @see statefulMove\n */\nexport const moveElementAfter = (node: Node, reference: Element): void => {\n  const parent = reference.parentNode;\n\n  if (parent instanceof Element) {\n    statefulMove(parent, node, reference.nextSibling);\n  }\n};\n\n/**\n * Moves `node` to the end of `parent`'s children, preserving live state.\n * @see statefulMove\n */\nexport const moveElementToEnd = (parent: Element, node: Node): void => {\n  statefulMove(parent, node, null);\n};\n","import { DATA_ATTR } from '../components/constants/data-attributes';\nimport { moveElementBefore, moveElementToEnd } from '../components/utils/html';\n\n/**\n * The caret, captured as raw primitives.\n *\n * A Range cannot stand in for this: every Range is LIVE, so the removal a\n * non-preserving move performs relocates its boundary points out of the moved\n * subtree before they could be re-applied. The (node, offset) pairs read out\n * beforehand are the only thing that survives.\n */\ninterface CaretSnapshot {\n  /** The focused element, when it sits inside the holder being moved. */\n  focused: HTMLElement | null;\n  /** Range start, when the range sits inside the holder being moved. */\n  start: [Node, number] | null;\n  /** Range end, matching {@link CaretSnapshot.start}. */\n  end: [Node, number] | null;\n}\n\n/**\n * Captures focus + caret, but only the part of it that lives inside `holder` —\n * a selection anywhere else is none of this move's business and must be left\n * exactly as it is.\n * @param holder - the holder about to be moved\n * @returns the snapshot, or null when the caret is elsewhere\n */\nconst captureCaretWithin = (holder: HTMLElement): CaretSnapshot | null => {\n  const ownerDocument = holder.ownerDocument;\n  const activeElement = ownerDocument.activeElement;\n  const focused =\n    activeElement instanceof HTMLElement && holder.contains(activeElement) ? activeElement : null;\n\n  const selection = ownerDocument.defaultView?.getSelection() ?? null;\n  const range = selection !== null && selection.rangeCount > 0 ? selection.getRangeAt(0) : null;\n  const rangeInside =\n    range !== null && holder.contains(range.startContainer) && holder.contains(range.endContainer);\n\n  if (focused === null && !rangeInside) {\n    return null;\n  }\n\n  return {\n    focused,\n    start: rangeInside && range !== null ? [range.startContainer, range.startOffset] : null,\n    end: rangeInside && range !== null ? [range.endContainer, range.endOffset] : null,\n  };\n};\n\n/**\n * Re-applies a snapshot, but only where the move actually destroyed it —\n * a browser with the state-preserving move keeps focus and the caret itself,\n * and re-setting an identical range there would emit a spurious\n * `selectionchange` at every container render.\n * @param snapshot - what {@link captureCaretWithin} read, or null\n */\nconst restoreCaret = (snapshot: CaretSnapshot | null): void => {\n  if (snapshot === null) {\n    return;\n  }\n\n  const { focused, start, end } = snapshot;\n\n  if (focused !== null && focused.isConnected && focused.ownerDocument.activeElement !== focused) {\n    focused.focus({ preventScroll: true });\n  }\n\n  if (start === null || end === null || !start[0].isConnected) {\n    return;\n  }\n\n  const ownerDocument = start[0].ownerDocument;\n  const selection = ownerDocument?.defaultView?.getSelection() ?? null;\n\n  if (ownerDocument === null || selection === null) {\n    return;\n  }\n\n  const live = selection.rangeCount > 0 ? selection.getRangeAt(0) : null;\n  const intact =\n    live !== null &&\n    live.startContainer === start[0] &&\n    live.startOffset === start[1] &&\n    live.endContainer === end[0] &&\n    live.endOffset === end[1];\n\n  if (intact) {\n    return;\n  }\n\n  const range = ownerDocument.createRange();\n\n  range.setStart(start[0], start[1]);\n  range.setEnd(end[0], end[1]);\n  selection.removeAllRanges();\n  selection.addRange(range);\n};\n\n/**\n * Mount child block holders into a container, skipping children that are\n * already in place or claimed by another nested-blocks container.\n *\n * Used by toggle, header, column, and callout tools — and by the React, Vue and\n * Angular block adapters — to reconcile child holders during the `rendered()`\n * lifecycle hook. It is the standing DOM↔model reconciler for container blocks:\n * safe to call on every render, and the only thing that heals a child holder\n * that core parked outside the container while the container's own slot had not\n * been created yet.\n * @param container - the container element child holders belong in; usually the\n *   element carrying `data-blok-nested-blocks`.\n * @param children - the container block's MODEL children, in model order (e.g.\n *   `api.blocks.getChildren(blockId)`).\n */\nexport const mountChildBlocks = (\n  container: HTMLElement,\n  children: { holder: HTMLElement }[],\n): void => {\n  /**\n   * Places a holder at its MODEL position: before the first later child that is\n   * already mounted here, or at the end when there is none. A plain appendChild\n   * would put a reclaimed middle child last — children [A, B, C] with only B\n   * stranded would render A, C, B.\n   *\n   * The move goes through the state-preserving helpers rather than raw\n   * insertBefore/appendChild: re-parenting a live node runs the DOM removing\n   * steps, which blur the focused contenteditable and relocate every live Range\n   * out of the moved subtree — the user's caret vanishes to <body> mid-typing.\n   * Where the browser has no state-preserving move, the caret is put back by\n   * hand around the move.\n   * @param holder - the holder to mount\n   * @param index - the holder's position in `children`\n   */\n  const mountAtModelPosition = (holder: HTMLElement, index: number): void => {\n    const anchor = children\n      .slice(index + 1)\n      .find(next => next.holder.parentElement === container)?.holder ?? null;\n\n    const caret = captureCaretWithin(holder);\n\n    anchor !== null ? moveElementBefore(holder, anchor) : moveElementToEnd(container, holder);\n\n    restoreCaret(caret);\n  };\n\n  for (const [index, child] of children.entries()) {\n    if (child.holder.parentElement === container) {\n      continue;\n    }\n\n    const nested = child.holder.closest(`[${DATA_ATTR.nestedBlocks}]`);\n\n    // Claim a holder stranded in an ANCESTOR nested container. Callers pass\n    // this container's own MODEL children, and a container that ENCLOSES this\n    // one can never be a legitimate home for them — that is model/DOM\n    // divergence by definition. Two ways to get there: a drag reparent into a\n    // column drops the moved holder directly into the [data-blok-columns] row\n    // (where it renders as a rogue extra column), and a newly inserted first\n    // child is anchored as the container block's DOM *sibling*, i.e. inside\n    // whatever nested container encloses it — permanent when the destination\n    // slot had not committed yet (a framework adapter's portal commits a render\n    // later than core inserts), because nothing else ever re-runs the mount.\n    if (nested !== null && nested !== container && nested.contains(container)) {\n      mountAtModelPosition(child.holder, index);\n      continue;\n    }\n\n    // Otherwise leave holders that already live inside another nested container\n    // (a sibling, or a deeper nesting within this one) where they are.\n    if (nested !== null) {\n      continue;\n    }\n\n    mountAtModelPosition(child.holder, index);\n  }\n};\n","import { DATA_ATTR } from '../components/constants/data-attributes';\n\n/**\n * One child's decoration: attribute name → value. `null`/`undefined` removes the\n * attribute; a boolean or number is stringified (so `false` writes\n * `data-active=\"false\"`, which CSS can select, rather than dropping the hook).\n */\nexport type ChildAttributes = Record<string, string | number | boolean | null | undefined>;\n\n/** The minimum a child must expose for a decoration pass. */\nexport interface DecoratableChild {\n  id: string;\n  holder: HTMLElement;\n}\n\n/**\n * A per-child decorator: what to write for the child at `index`.\n *\n * Generic over the child so an adapter can declare its decorators in terms of the\n * full `BlockAPI` its authors receive. A non-generic `(child: DecoratableChild)`\n * parameter would REJECT those: a function that demands a full BlockAPI is not\n * assignable to one promising to accept the structural minimum.\n */\nexport type ChildAttributesFn<Child extends DecoratableChild = DecoratableChild> = (\n  child: Child,\n  index: number\n) => ChildAttributes;\n\n/** What the previous decoration pass wrote for one child, so it can be undone. */\ninterface StampedChild {\n  /** The element written to — a holder for one ledger, a content wrapper for the other. */\n  target: HTMLElement;\n  names: string[];\n}\n\n/** The ledgers a container keeps between passes; create one per child slot. */\nexport interface ChildDecorationLedger {\n  holders: Map<string, StampedChild>;\n  contents: Map<string, StampedChild>;\n}\n\n/**\n * A fresh pair of ledgers for one container's child slot.\n * @returns empty holder/content ledgers\n */\nexport const createChildDecorationLedger = (): ChildDecorationLedger => ({\n  holders: new Map(),\n  contents: new Map(),\n});\n\n/**\n * The child's OWN content wrapper, or null when its DOM has not committed yet.\n *\n * The first `[data-blok-element-content]` in document order under a holder is\n * always that block's own: a descendant block's wrapper necessarily sits INSIDE\n * it. Not `firstElementChild` — block tunes wrap the content node, so it is not\n * reliably a direct child (this is the same lookup core's own\n * `refreshToolRootElement` uses).\n * @param holder - the child block's holder\n * @returns the content wrapper, or null\n */\nconst contentWrapperOf = (holder: HTMLElement): HTMLElement | null =>\n  holder.querySelector<HTMLElement>(`[${DATA_ATTR.elementContent}]`);\n\n/**\n * Apply one decoration pass and clear the previous pass's leftovers — including\n * on a child that has since left the container, which would otherwise keep a\n * dead index forever.\n * @param ledger - what the last pass wrote (mutated)\n * @param children - the container's model children, in model order\n * @param decorate - the per-child decorator for the child HOLDERS, if any\n * @param resolveTarget - which element of a child this pass writes to\n */\nconst applyPass = <Child extends DecoratableChild>(\n  ledger: Map<string, StampedChild>,\n  children: Child[],\n  decorate: ChildAttributesFn<Child> | undefined,\n  resolveTarget: (holder: HTMLElement) => HTMLElement | null\n): void => {\n  const next = new Map<string, StampedChild>();\n\n  children.forEach((child, index) => {\n    const target = resolveTarget(child.holder);\n\n    /**\n     * A portal-rendered child commits its DOM a frame after core inserts it, so\n     * its content wrapper can legitimately be missing on this pass. Skipping\n     * (rather than throwing) leaves the next pass to stamp it.\n     */\n    if (target === null) {\n      return;\n    }\n\n    const names: string[] = [];\n\n    for (const [name, value] of Object.entries(decorate?.(child, index) ?? {})) {\n      if (value === null || value === undefined) {\n        target.removeAttribute(name);\n        continue;\n      }\n\n      target.setAttribute(name, String(value));\n      names.push(name);\n    }\n\n    next.set(child.id, { target, names });\n  });\n\n  for (const [id, previous] of ledger) {\n    const current = next.get(id);\n\n    previous.names\n      .filter(name => current === undefined || !current.names.includes(name))\n      .forEach(name => previous.target.removeAttribute(name));\n  }\n\n  ledger.clear();\n  next.forEach((entry, id) => ledger.set(id, entry));\n};\n\n/**\n * Decorate a container's children: named attributes on each child's HOLDER and,\n * separately, on each child's `[data-blok-element-content]` wrapper.\n *\n * The single implementation behind the React, Vue and Angular per-child\n * decoration channels, so the three cannot drift on which element a hook lands\n * on or on when a dropped hook is cleaned up.\n *\n * BOTH levels exist because core's child-holder decoration law blesses both, and\n * a container needs both: the holder is the child's outer box (rails, indices,\n * hover states), while the content wrapper is where the child's own text box\n * begins — which is what a numbered rail or a connector line has to align to.\n * With only the holder reachable, a container had to encode core's wrapper chain\n * in its own CSS (`[data-step] > [data-blok-element-content] > …`) and broke\n * whenever that chain changed. Neither hook may introduce an element: holders\n * stay DIRECT children of the slot because core's reparenting and caret\n * sibling checks compare `holder.parentElement` by identity.\n *\n * Both are inert with respect to change tracking: core's mutation filter drops a\n * holder- or content-targeted attribute record for the CHILD block (both are\n * ancestors of the child's tool element, not descendants) and scores it\n * mutation-free for the CONTAINER (whose own `data-blok-mutation-free` host is\n * the nearest such ancestor).\n * @param ledger - the slot's ledgers from {@link createChildDecorationLedger}\n * @param children - the container's model children, in model order\n * @param decorators - the authored per-child decorators\n * @param decorators.childAttributes - written on each child's holder\n * @param decorators.childContentAttributes - written on each child's content wrapper\n */\nexport const applyChildDecoration = <Child extends DecoratableChild>(\n  ledger: ChildDecorationLedger,\n  children: Child[],\n  decorators: {\n    childAttributes?: ChildAttributesFn<Child>;\n    childContentAttributes?: ChildAttributesFn<Child>;\n  }\n): void => {\n  applyPass(ledger.holders, children, decorators.childAttributes, holder => holder);\n  applyPass(ledger.contents, children, decorators.childContentAttributes, contentWrapperOf);\n};\n","export type { BlockChildrenMountedPayload } from '@bloklabs/core';\n\n/**\n * Fired when a CONTAINER block's child holders have been mounted into its\n * child slot — the moment the child DOM has settled and a caret set into a\n * freshly inserted child sticks.\n *\n * Emitted by the React, Vue and Angular block adapters, whose portals commit a\n * frame AFTER core's `rendered()` hook; a vanilla container tool mounts its\n * children synchronously inside `rendered()`, so for those `block:rendered`\n * already means \"settled\". It fires on every reconciliation pass of the slot,\n * not only the first, so treat it as a settle signal rather than a change\n * signal.\n *\n * Public event name: `block:childrenMounted`.\n */\nexport const BlockChildrenMounted = 'block:childrenMounted';\n","import {\n  ChangeDetectionStrategy,\n  Component,\n  EventEmitter,\n  Input,\n  NgZone,\n  Output,\n  ViewChild,\n  computed,\n  effect,\n  forwardRef,\n  inject,\n  signal,\n  type AfterViewInit,\n  type DoCheck,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR, type ControlValueAccessor } from '@angular/forms';\nimport { BlokContentDirective } from './blok-content.directive';\nimport { BLOK_DEFAULT_CONFIG } from './provide-blok';\nimport { deepEqual } from '../adapters-contract';\nimport { equalsOutputData } from '../adapters-contract';\nimport { normalizeReadOnlyConfig } from '../adapters-contract';\nimport { toRenderableData } from '../adapters-contract';\nimport type {\n  API,\n  Blok,\n  BlockMutationEvent,\n  BlockRenderedPayload,\n  BlocksRenderedPayload,\n  BlokConfig,\n  EditorWidth,\n  LiveHandlers,\n  LooseOutputData,\n  OutputBlockData,\n  OutputData,\n  ResolvedTheme,\n  ThemeMode,\n} from '@bloklabs/core';\nimport type { BlokAngularConfig } from './types';\n\n/**\n * The blessed all-in-one Angular component for embedding Blok (mirrors React's\n * `BlokEditor`). Delegates instance lifecycle to an internal `BlokContentDirective`\n * and layers the typed reactive input/output API on top.\n *\n * Reactive inputs (`readOnly`, `hideToolbar`, `toolbarPosition`,\n * `inlineToolbar`, `theme`, `width`, `placeholder`, `autofocus`, `styleTokens`,\n * `i18n`, `data`) are synced in place after mount via effects — `hideToolbar`\n * through `editor.toolbar.setHidden()`, `toolbarPosition` through\n * `editor.toolbar.setPosition()`, `inlineToolbar` through\n * `editor.tools.setInlineToolbar()` (content-compared),\n * `styleTokens` through `editor.tokens.set()` (replace semantics),\n * `i18n` through `editor.i18n.update()` (deep-equal–deduped; seeded at\n * construction so the locale resolves during boot) and `data`\n * through `editor.render()` (content-deduped via `equalsOutputData`); everything\n * else seeds construction.\n *\n * Implementation note: classic `@Input()`/`@ViewChild()` decorators are used\n * (not signal `input()`/`viewChild()`) for JIT compatibility — see\n * `BlokContentDirective`. Each reactive input is backed by an internal `signal`\n * so effect-based syncing still works; the public template API is unchanged.\n */\n@Component({\n  selector: 'blok-editor',\n  standalone: true,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  exportAs: 'blok',\n  imports: [BlokContentDirective],\n  template: `<div blokContent [config]=\"buildConfig()\" [recreateKey]=\"recreateKey\"></div>`,\n  providers: [\n    {\n      provide: NG_VALUE_ACCESSOR,\n      useExisting: forwardRef(() => BlokEditorComponent),\n      multi: true,\n    },\n  ],\n})\nexport class BlokEditorComponent implements AfterViewInit, DoCheck, ControlValueAccessor {\n  private readonly ngZone = inject(NgZone);\n  /** App-wide defaults from `provideBlok()`; merged UNDER per-instance inputs. */\n  private readonly defaults = inject(BLOK_DEFAULT_CONFIG, { optional: true }) ?? {};\n\n  @ViewChild(BlokContentDirective) private contentQuery?: BlokContentDirective;\n  /** Signal bridge for the @ViewChild directive so effects react to its arrival. */\n  private readonly content = signal<BlokContentDirective | null>(null);\n\n  /**\n   * Output half of two-way `[(data)]`. Emits the editor's serialized content on\n   * every change. Wiring the core `onSave` callback is gated on this being\n   * observed, since its mere presence makes the core serialize on every batch.\n   */\n  /** Emits the live Blok instance once ready, after `instance()` is populated. */\n  @Output() readonly ready = new EventEmitter<Blok>();\n\n  @Output() readonly dataChange = new EventEmitter<OutputData>();\n\n  /** Fires with the full serialized content on every change (notification half). */\n  @Output() readonly save = new EventEmitter<OutputData>();\n\n  /** Raw block mutation channel (core `onChange`). */\n  @Output() readonly change = new EventEmitter<{\n    api: API;\n    event: BlockMutationEvent | BlockMutationEvent[];\n  }>();\n\n  /** Fires after the editor finishes (re-)rendering (core `onAfterRender`). */\n  @Output() readonly afterRender = new EventEmitter<API>();\n\n  /** Fires with the resolved theme whenever it changes (core `onThemeChange`). */\n  @Output() readonly themeChange = new EventEmitter<ResolvedTheme>();\n\n  /** Fires after a batch render completes (core `blocks:rendered` event). */\n  @Output() readonly blocksRendered = new EventEmitter<BlocksRenderedPayload>();\n\n  /** Fires for each block rendered into the DOM (core `block:rendered` event). */\n  @Output() readonly blockRendered = new EventEmitter<BlockRenderedPayload>();\n\n  /**\n   * Transform hook applied to blocks before render (core `onBeforeRender`). Must\n   * return the (possibly modified) block list. An input, not an output, because\n   * it returns a value.\n   */\n  @Input() onBeforeRender?: (blocks: OutputBlockData[]) => OutputBlockData[];\n\n  /**\n   * Transform hook applied to pasted HTML (core `onBeforePaste`). Returns the\n   * (possibly modified) html, or null to drop the paste.\n   */\n  @Input() onBeforePaste?: (html: string) => string | null;\n\n  /**\n   * Error channel (core `onError`). Fires with the raised error whenever an\n   * editor operation — currently serialization — fails instead of only logging.\n   */\n  @Input() onError?: BlokConfig['onError'];\n\n  // ---- Reactive inputs (signal-backed setters; synced in place, never recreate) ----\n  // Default undefined (not false) so an unset input falls back to a provideBlok\n  // default; the readOnly effect / buildConfig coerce undefined to false.\n  // Accepts the object form (`{ hideControls }`) too — it flows through\n  // buildConfig unchanged and the effect expands it to\n  // `readOnly.set(enabled, { hideControls })`.\n  private readonly readOnly$ = signal<BlokConfig['readOnly'] | undefined>(undefined);\n  @Input() set readOnly(value: BlokConfig['readOnly'] | undefined) {\n    this.readOnly$.set(value);\n  }\n\n  private readonly hideToolbar$ = signal<boolean | undefined>(undefined);\n  @Input() set hideToolbar(value: boolean | undefined) {\n    this.hideToolbar$.set(value);\n  }\n\n  private readonly toolbarPosition$ = signal<BlokConfig['toolbarPosition'] | undefined>(undefined);\n  @Input() set toolbarPosition(value: BlokConfig['toolbarPosition'] | undefined) {\n    this.toolbarPosition$.set(value);\n  }\n\n  private readonly inlineToolbar$ = signal<boolean | string[] | undefined>(undefined);\n  @Input() set inlineToolbar(value: boolean | string[] | undefined) {\n    this.inlineToolbar$.set(value);\n  }\n\n  private readonly theme$ = signal<ThemeMode | undefined>(undefined);\n  @Input() set theme(value: ThemeMode | undefined) {\n    this.theme$.set(value);\n  }\n\n  private readonly width$ = signal<EditorWidth | undefined>(undefined);\n  @Input() set width(value: EditorWidth | undefined) {\n    this.width$.set(value);\n  }\n\n  private readonly placeholder$ = signal<string | false | undefined>(undefined);\n  @Input() set placeholder(value: string | false | undefined) {\n    this.placeholder$.set(value);\n  }\n\n  /**\n   * Theme tokens. Construction-only config forced hosts with a live light/dark\n   * toggle to recreate the editor or hand-write the global stylesheet Blok\n   * already injects; this drives the runtime `tokens` API instead.\n   */\n  private readonly styleTokens$ = signal<Record<string, string> | undefined>(undefined);\n  @Input() set styleTokens(value: Record<string, string> | undefined) {\n    this.styleTokens$.set(value);\n  }\n\n  /**\n   * Locale, host message overrides and text direction. `config.i18n` was\n   * consumed once at boot, so a host driving a language switcher had to\n   * recreate the editor (losing caret, focus and undo stack) to relabel the\n   * UI; this drives the runtime `i18n.update` API instead. `defaultLocale` is\n   * not forwarded — it only affects the INITIAL locale resolution.\n   */\n  private readonly i18n$ = signal<BlokConfig['i18n'] | undefined>(undefined);\n  @Input() set i18n(value: BlokConfig['i18n'] | undefined) {\n    this.i18n$.set(value);\n  }\n\n  private readonly autofocus$ = signal<boolean | undefined>(false);\n  @Input() set autofocus(value: boolean | undefined) {\n    this.autofocus$.set(value);\n  }\n\n  // ---- Reactive content (seeds construction, then re-renders on change) ----\n  private readonly data$ = signal<OutputData | LooseOutputData | null | undefined>(undefined);\n  @Input() set data(value: OutputData | LooseOutputData | null | undefined) {\n    this.data$.set(value);\n  }\n\n  // ---- Construction-only seed inputs (read once at construction) ----\n  @Input() tools?: BlokConfig['tools'];\n  /** Host-supplied per-type block migrations applied at load (merged across layers). */\n  @Input() migrations?: BlokConfig['migrations'];\n\n  /**\n   * Escape hatch: a full config object for keys without a dedicated input\n   * (sanitizer, minHeight, …). Layered between provideBlok\n   * defaults and the discrete inputs.\n   */\n  @Input() config?: Partial<BlokAngularConfig>;\n\n  /** Changing this input's identity destroys and recreates the editor (≙ React `deps`). */\n  @Input() recreateKey: unknown;\n\n  /**\n   * Content the editor currently reflects. Set when seeded, when the data effect\n   * renders, when the editor emits its own output (`coreOnSave`) and when the\n   * imperative `render()` facade lands. A controlled `data` echo that\n   * content-equals this baseline is a no-op, so it won't clobber the caret.\n   * Renders are serialized via `renderChain`. `undefined` means \"nothing recorded\n   * yet\" — never an empty document.\n   */\n  private lastRenderedData?: OutputData | LooseOutputData | null;\n\n  /** Last token set pushed through `tokens.set`, for deep-equal deduping. */\n  private appliedTokens?: Record<string, string>;\n  /** Last i18n config pushed through `i18n.update`, for deep-equal deduping. */\n  private appliedI18n?: BlokConfig['i18n'];\n  /** Editor instance the i18n baseline above belongs to. */\n  private i18nAppliedFor: Blok | null = null;\n  /** Last value pushed through `tools.setInlineToolbar`, for content-compare deduping. */\n  private appliedInlineToolbar?: boolean | string[];\n  private seededEditor: Blok | null = null;\n  private renderChain: Promise<void> = Promise.resolve();\n\n  /** Registered by `ControlValueAccessor.registerOnChange` (Angular forms). */\n  private cvaOnChange?: (data: OutputData) => void;\n  private cvaOnTouched?: () => void;\n\n  /**\n   * Core `onSave` wrapper. Records the editor's own serialized output as the\n   * rendered baseline BEFORE notifying Angular, so a controlled consumer echoing\n   * it straight back into `data` deep-equals the baseline and is deduped to a\n   * no-op (no redundant render, no caret reset). Re-enters the Angular zone since\n   * the editor runs outside it.\n   *\n   * Falls back to an escape-hatch `[config]` callback when nothing Angular-side\n   * consumes the save — the baseline is recorded either way, so the controlled\n   * `data` dedupe works on both paths.\n   */\n  private readonly coreOnSave = (data: OutputData, api: API): void => {\n    this.lastRenderedData = data;\n\n    if (this.hasSaveConsumer()) {\n      this.ngZone.run(() => {\n        this.dataChange.emit(data);\n        this.save.emit(data);\n        this.cvaOnChange?.(data);\n        this.cvaOnTouched?.();\n      });\n\n      return;\n    }\n\n    this.escapeHatchConfig().onSave?.(data, api);\n  };\n\n  /**\n   * Stable wrappers for the remaining live callbacks. Each resolves its target\n   * at call time (an observed output, else the `[config]` escape hatch), so a\n   * pushed handler never goes stale and only PRESENCE has to be synced.\n   */\n  private readonly coreOnChange = (\n    api: API,\n    event: BlockMutationEvent | BlockMutationEvent[]\n  ): void => {\n    if (this.change.observed) {\n      this.ngZone.run(() => this.change.emit({ api, event }));\n\n      return;\n    }\n\n    this.escapeHatchConfig().onChange?.(api, event);\n  };\n\n  private readonly coreOnAfterRender = (api: API): void => {\n    if (this.afterRender.observed) {\n      this.ngZone.run(() => this.afterRender.emit(api));\n\n      return;\n    }\n\n    this.escapeHatchConfig().onAfterRender?.(api);\n  };\n\n  /*\n   * Transforms run synchronously inside core's render pipeline and must return a\n   * value — never wrap them in ngZone.run.\n   */\n  private readonly coreOnBeforeRender = (blocks: OutputBlockData[]): OutputBlockData[] => {\n    const transform = this.onBeforeRender ?? this.escapeHatchConfig().onBeforeRender;\n\n    return transform?.(blocks) ?? blocks;\n  };\n\n  private readonly coreOnEnter = (event: KeyboardEvent, api: API): boolean | void =>\n    this.escapeHatchConfig().onEnter?.(event, api);\n\n  private readonly coreOnSubmit = (data: OutputData, api: API): void => {\n    this.escapeHatchConfig().onSubmit?.(data, api);\n  };\n\n  /** provideBlok defaults merged under the `[config]` escape hatch. */\n  private escapeHatchConfig(): Partial<BlokAngularConfig> {\n    return { ...this.defaults, ...this.config };\n  }\n\n  /** True when an output, a two-way binding or Angular forms consumes `onSave`. */\n  private hasSaveConsumer(): boolean {\n    return this.dataChange.observed || this.save.observed || this.cvaOnChange !== undefined;\n  }\n\n  /**\n   * The live callbacks this component currently wires into core, keyed by\n   * handler name — `undefined` for the ones nothing consumes.\n   *\n   * PRESENCE is the semantics in core (an `onSubmit` turns Enter into\n   * serialize-and-submit, an `onSave` arms the change-observation pipeline), so\n   * an unconsumed callback must stay absent. One source of truth for both the\n   * construction config and the runtime sync in `ngDoCheck`, so the two cannot\n   * drift.\n   * @returns the wrappers to install, `undefined` where nothing is wired\n   */\n  private liveHandlers(): LiveHandlers {\n    const cfg = this.escapeHatchConfig();\n\n    return {\n      onChange: this.change.observed || cfg.onChange !== undefined ? this.coreOnChange : undefined,\n      onSave: this.hasSaveConsumer() || cfg.onSave !== undefined ? this.coreOnSave : undefined,\n      onEnter: cfg.onEnter !== undefined ? this.coreOnEnter : undefined,\n      onSubmit: cfg.onSubmit !== undefined ? this.coreOnSubmit : undefined,\n      onBeforeRender:\n        this.onBeforeRender !== undefined || cfg.onBeforeRender !== undefined\n          ? this.coreOnBeforeRender\n          : undefined,\n      onAfterRender:\n        this.afterRender.observed || cfg.onAfterRender !== undefined\n          ? this.coreOnAfterRender\n          : undefined,\n    };\n  }\n\n  /** Handler presence installed on the live editor (the sync dedupe baseline). */\n  private appliedHandlers: LiveHandlers = {};\n\n  /** Live Blok instance, or null until `isReady` resolves / after destroy. */\n  readonly instance = computed<Blok | null>(() => this.content()?.instance() ?? null);\n\n  /** Guards `ready` to one emission per editor instance. */\n  private lastReadyInstance: Blok | null = null;\n\n  /**\n   * Construction config handed to the directive. Seeds the editor's initial\n   * values; the directive only reads it once (at construction), so post-mount\n   * changes to construction-only inputs are no-ops by design.\n   */\n  buildConfig(): Partial<BlokAngularConfig> {\n    // Precedence: provideBlok defaults < [config] escape hatch < discrete inputs.\n    const cfg: Partial<BlokAngularConfig> = { ...this.defaults, ...this.config };\n\n    // The object form ({ hideControls }) is preserved as-is; the readOnly\n    // effect expands it into `readOnly.set(enabled, { hideControls })`.\n    cfg.readOnly = this.readOnly$() ?? this.config?.readOnly ?? this.defaults.readOnly ?? false;\n\n    const hideToolbar = this.hideToolbar$();\n\n    if (hideToolbar !== undefined) {\n      cfg.hideToolbar = hideToolbar;\n    }\n\n    const toolbarPosition = this.toolbarPosition$();\n\n    if (toolbarPosition !== undefined) {\n      cfg.toolbarPosition = toolbarPosition;\n    }\n\n    const inlineToolbar = this.inlineToolbar$();\n\n    if (inlineToolbar !== undefined) {\n      cfg.inlineToolbar = inlineToolbar;\n    }\n\n    // tools registries are MERGED (not replaced) across all three layers so a\n    // shared registry composes with per-instance additions.\n    if (\n      this.tools !== undefined ||\n      this.config?.tools !== undefined ||\n      this.defaults.tools !== undefined\n    ) {\n      cfg.tools = { ...this.defaults.tools, ...this.config?.tools, ...this.tools };\n    }\n\n    // migration registries merge like tools: shared defaults compose with\n    // per-instance rules.\n    if (\n      this.migrations !== undefined ||\n      this.config?.migrations !== undefined ||\n      this.defaults.migrations !== undefined\n    ) {\n      cfg.migrations = { ...this.defaults.migrations, ...this.config?.migrations, ...this.migrations };\n    }\n\n    const data = this.data$();\n\n    if (data !== undefined) {\n      cfg.data = data;\n    }\n\n    const theme = this.theme$();\n\n    if (theme !== undefined) {\n      cfg.theme = theme;\n    }\n\n    const width = this.width$();\n\n    if (width !== undefined) {\n      cfg.width = width;\n    }\n\n    const placeholder = this.placeholder$();\n\n    if (placeholder !== undefined) {\n      cfg.placeholder = placeholder;\n    }\n\n    // Seeded at construction (not applied by the i18n effect) so the locale is\n    // resolved during boot instead of flashing the default language first.\n    const i18n = this.i18n$();\n\n    if (i18n !== undefined) {\n      cfg.i18n = i18n;\n    }\n\n    // Opt-in: only attach each live callback when the consumer actually consumes\n    // it (an observed output, a registered forms hook, a provided transform or an\n    // escape-hatch config callback). Their mere presence makes the core serialize\n    // / run hooks on every change. The same map drives the runtime sync in\n    // `ngDoCheck`, so construction and post-mount can never disagree.\n    const handlers = this.liveHandlers();\n\n    cfg.onChange = handlers.onChange;\n    cfg.onSave = handlers.onSave;\n    cfg.onEnter = handlers.onEnter;\n    cfg.onSubmit = handlers.onSubmit;\n    cfg.onBeforeRender = handlers.onBeforeRender;\n    cfg.onAfterRender = handlers.onAfterRender;\n\n    this.appliedHandlers = handlers;\n\n    if (this.themeChange.observed) {\n      cfg.onThemeChange = (resolved: ResolvedTheme): void =>\n        this.ngZone.run(() => this.themeChange.emit(resolved));\n    }\n\n    // Transforms run synchronously inside core's paste pipeline and must return a\n    // value — never wrap them in ngZone.run.\n    const beforePaste = this.onBeforePaste;\n\n    if (beforePaste !== undefined) {\n      cfg.onBeforePaste = (html: string): string | null => beforePaste(html);\n    }\n\n    const onError = this.onError;\n\n    if (onError !== undefined) {\n      cfg.onError = onError;\n    }\n\n    return cfg;\n  }\n\n  ngAfterViewInit(): void {\n    this.content.set(this.contentQuery ?? null);\n  }\n\n  /**\n   * Reactive callback presence.\n   *\n   * Callback wiring was decided once, at construction, and in core the presence\n   * of a handler IS the semantics: an `onSubmit` makes Enter serialize-and-submit\n   * instead of splitting the block, an `onSave` arms the whole change-observation\n   * pipeline. A `[config]` swap, an `*ngIf`-gated `(save)` output or a\n   * `registerOnChange` from Angular forms arriving after mount therefore needed a\n   * `recreateKey` bump — destroying the editor and losing caret and undo history.\n   *\n   * Diff the wired handlers against what is installed and push genuine flips\n   * through the runtime `handlers.set` API, writing `undefined` for a handler\n   * that lost its consumer so the change stays reversible. `ngDoCheck` (not an\n   * `effect`) because `EventEmitter.observed` and the plain `@Input` transforms\n   * are not signals; the comparison is six identity checks against stable\n   * wrappers, so an unchanged cycle pushes nothing.\n   */\n  ngDoCheck(): void {\n    const editor = this.instance();\n\n    if (editor === null) {\n      return;\n    }\n\n    const desired = this.liveHandlers();\n    const applied = this.appliedHandlers;\n    const diff: LiveHandlers = {};\n    const changed: { value: boolean } = { value: false };\n\n    const sync = <K extends keyof LiveHandlers>(key: K, write: (value: LiveHandlers[K]) => void): void => {\n      if (desired[key] === applied[key]) {\n        return;\n      }\n\n      applied[key] = desired[key];\n      changed.value = true;\n      write(desired[key]);\n    };\n\n    sync('onChange', (value) => {\n      diff.onChange = value;\n    });\n    sync('onSave', (value) => {\n      diff.onSave = value;\n    });\n    sync('onEnter', (value) => {\n      diff.onEnter = value;\n    });\n    sync('onSubmit', (value) => {\n      diff.onSubmit = value;\n    });\n    sync('onBeforeRender', (value) => {\n      diff.onBeforeRender = value;\n    });\n    sync('onAfterRender', (value) => {\n      diff.onAfterRender = value;\n    });\n\n    if (changed.value) {\n      editor.handlers.set(diff);\n    }\n  }\n\n  // ---- Curated imperative facade (delegates to the live instance; no-ops until ready) ----\n\n  /** Serialize the current content. Resolves undefined until the editor is ready. */\n  save$(): Promise<OutputData> | undefined {\n    return this.instance()?.save();\n  }\n\n  /** Move the caret into the editor. */\n  focus(atEnd?: boolean): void {\n    this.instance()?.focus(atEnd);\n  }\n\n  /**\n   * Replace the editor content. Resolves undefined until the editor is ready.\n   *\n   * Safe to mix with a controlled `[data]` input: the rendered document becomes\n   * the content baseline once the call lands, so a later `[data]` change back to\n   * the previous document still re-renders instead of being deduped against a\n   * baseline the editor no longer reflects. Recorded only on the resolved path —\n   * a failed render leaves the editor on its previous content.\n   * @param data - the document to render\n   */\n  render(data: OutputData | LooseOutputData): Promise<void> | undefined {\n    const editor = this.instance();\n\n    if (editor === null) {\n      return undefined;\n    }\n\n    return editor.render(data).then(() => {\n      this.lastRenderedData = data;\n    });\n  }\n\n  constructor() {\n    // Each effect reads `instance()` so it re-applies once the editor appears\n    // (the Angular analog of React's `editor` effect-dependency).\n    effect(() => {\n      const editor = this.instance();\n      const readOnly = this.readOnly$() ?? this.config?.readOnly;\n\n      if (editor) {\n        const { enabled, hideControls } = normalizeReadOnlyConfig(readOnly);\n\n        // Only the object form carries options; the boolean form keeps the\n        // one-argument call so it never clobbers a config-seeded hideControls.\n        if (typeof readOnly === 'object' && readOnly !== null) {\n          void editor.readOnly.set(enabled, { hideControls });\n        } else {\n          void editor.readOnly.set(enabled);\n        }\n      }\n    });\n\n    effect(() => {\n      const editor = this.instance();\n      const hideToolbar = this.hideToolbar$();\n\n      if (editor && hideToolbar !== undefined) {\n        editor.toolbar.setHidden(hideToolbar);\n      }\n    });\n\n    effect(() => {\n      const editor = this.instance();\n      const toolbarPosition = this.toolbarPosition$();\n\n      if (editor && toolbarPosition !== undefined) {\n        editor.toolbar.setPosition(toolbarPosition);\n      }\n    });\n\n    // Content-compared (not identity): a new array with the same tool names is\n    // a no-op, so template-inline array literals don't thrash the assignment.\n    effect(() => {\n      const editor = this.instance();\n      const inlineToolbar = this.inlineToolbar$();\n\n      if (\n        !editor ||\n        inlineToolbar === undefined ||\n        deepEqual(inlineToolbar, this.appliedInlineToolbar)\n      ) {\n        return;\n      }\n\n      this.appliedInlineToolbar = Array.isArray(inlineToolbar) ? [...inlineToolbar] : inlineToolbar;\n      editor.tools.setInlineToolbar(inlineToolbar);\n    });\n\n    effect(() => {\n      const editor = this.instance();\n      const theme = this.theme$();\n\n      if (editor && theme !== undefined) {\n        editor.theme.set(theme);\n      }\n    });\n\n    effect(() => {\n      const editor = this.instance();\n      const width = this.width$();\n\n      if (editor && width !== undefined) {\n        editor.width.set(width);\n      }\n    });\n\n    effect(() => {\n      const editor = this.instance();\n      const placeholder = this.placeholder$();\n\n      if (editor && placeholder !== undefined) {\n        editor.placeholder.set(placeholder);\n      }\n    });\n\n    effect(() => {\n      const editor = this.instance();\n      const tokens = this.styleTokens$() ?? this.config?.style?.tokens;\n\n      if (!editor || tokens === undefined || deepEqual(tokens, this.appliedTokens)) {\n        return;\n      }\n\n      this.appliedTokens = { ...tokens };\n      editor.tokens.set(tokens);\n    });\n\n    effect(() => {\n      const editor = this.instance();\n      const i18n = this.i18n$() ?? this.config?.i18n;\n\n      if (!editor) {\n        return;\n      }\n\n      /*\n       * A freshly constructed editor already resolved this config during its\n       * own boot (buildConfig seeds it), so record the baseline and push\n       * nothing — re-applying it here would reload the locale after mount and\n       * flash the default language.\n       */\n      if (this.i18nAppliedFor !== editor) {\n        this.i18nAppliedFor = editor;\n        this.appliedI18n = i18n === undefined ? undefined : { ...i18n };\n\n        return;\n      }\n\n      if (i18n === undefined || deepEqual(i18n, this.appliedI18n)) {\n        return;\n      }\n\n      this.appliedI18n = { ...i18n };\n\n      const { locale, messages, direction } = i18n;\n\n      void editor.i18n.update({\n        ...(locale === undefined ? {} : { locale }),\n        ...(messages === undefined ? {} : { messages }),\n        ...(direction === undefined ? {} : { direction }),\n      });\n    });\n\n    effect(() => {\n      const editor = this.instance();\n\n      if (editor && this.autofocus$()) {\n        editor.focus();\n      }\n    });\n\n    // Reactive content. `data` seeds the editor at construction; afterwards a new\n    // *content* value re-renders via the public render() API (deep-equal-deduped\n    // and serialized, so an unchanged reference — including the editor's own\n    // echoed output — is a no-op and never clobbers the caret).\n    effect(() => {\n      const editor = this.instance();\n      const data = this.data$();\n\n      if (!editor || data === undefined) {\n        return;\n      }\n\n      // A freshly created editor was already seeded with `data` at construction;\n      // record it without re-rendering.\n      if (this.seededEditor !== editor) {\n        this.seededEditor = editor;\n        this.lastRenderedData = data;\n\n        return;\n      }\n\n      // Structural comparison (`equalsOutputData`, not a raw deep-equal): a host\n      // that persists the editor's own document and hands back a stripped copy —\n      // fresh `time`, dropped ids, no `lastEditedAt` stamp — is still echoing\n      // content the editor already shows, and re-rendering it would reset the\n      // caret for zero visual change. `undefined` means \"nothing recorded yet\",\n      // which is NOT an empty document, so it must never match.\n      const baseline = this.lastRenderedData;\n\n      if (baseline !== undefined && equalsOutputData(data, baseline)) {\n        return;\n      }\n\n      this.lastRenderedData = data;\n      // `data` may be null (a controlled \"clear to empty\"); render() throws on\n      // null, so normalize null → { blocks: [] } at the boundary.\n      this.renderChain = this.renderChain.catch(() => undefined).then(() => editor.render(toRenderableData(data)));\n    });\n\n    // Emit `ready` once per editor, after `instance()` is populated so a consumer\n    // reading the component/ref instance inside the handler sees it.\n    effect(() => {\n      const editor = this.instance();\n\n      if (editor && editor !== this.lastReadyInstance) {\n        this.lastReadyInstance = editor;\n        this.ready.emit(editor);\n      }\n    });\n\n    // Subscribe to the editor's rendered-lifecycle events once it exists (gated on\n    // the outputs being observed). `onCleanup` unsubscribes when the instance is\n    // replaced or the component is destroyed.\n    effect((onCleanup) => {\n      const editor = this.instance();\n\n      if (!editor) {\n        return;\n      }\n\n      const handlers: Array<[string, (payload?: unknown) => void]> = [];\n\n      if (this.blocksRendered.observed) {\n        const handler = (payload?: unknown): void =>\n          this.ngZone.run(() => this.blocksRendered.emit(payload as BlocksRenderedPayload));\n\n        editor.on('blocks:rendered', handler);\n        handlers.push(['blocks:rendered', handler]);\n      }\n\n      if (this.blockRendered.observed) {\n        const handler = (payload?: unknown): void =>\n          this.ngZone.run(() => this.blockRendered.emit(payload as BlockRenderedPayload));\n\n        editor.on('block:rendered', handler);\n        handlers.push(['block:rendered', handler]);\n      }\n\n      onCleanup(() => {\n        for (const [name, handler] of handlers) {\n          editor.off(name, handler);\n        }\n      });\n    });\n  }\n\n  // ---- ControlValueAccessor (optional forms integration) ----\n\n  /** Seeds/renders an externally-set form value through the same dedup machinery. */\n  writeValue(value: OutputData | LooseOutputData | null): void {\n    this.data$.set(value ?? undefined);\n  }\n\n  registerOnChange(fn: (data: OutputData) => void): void {\n    this.cvaOnChange = fn;\n  }\n\n  registerOnTouched(fn: () => void): void {\n    this.cvaOnTouched = fn;\n  }\n\n  /** Form disabled state maps to the editor's read-only mode (via the readOnly effect). */\n  setDisabledState(isDisabled: boolean): void {\n    this.readOnly$.set(isDisabled);\n  }\n}\n","import type { API, BlockAPI, BlockOrigin, BlockToolConstructable, BlockToolConstructorOptions, BlockToolData, ToolboxConfig } from '@bloklabs/core';\n// packages/angular/src/createAngularBlock.ts\nimport { signal, type Type, type WritableSignal } from '@angular/core';\n\nimport {\n  applyChildDecoration,\n  BlockChildrenMounted,\n  createChildDecorationLedger,\n  DATA_ATTR,\n} from '../adapters-contract';\nimport { deepEqual } from '../adapters-contract';\nimport { fillDefaults, type PropSchema } from '../adapters-contract';\nimport { mountChildBlocks } from '../adapters-contract';\n\nimport type { AngularBlockRenderContext, ChildAttributesFn } from './block-context';\nimport { BLOK_PORTAL_REGISTRY_CONFIG_KEY, type BlockPortalRegistry } from './block-portal-registry';\n\n/**\n * Every STATIC member of core's block-tool contract an Angular block may declare\n * for itself — `ownsChildren`, `keepsChildrenOnEnter`, `conversionConfig`,\n * `pasteConfig`, `sanitize`, `shortcut`, `upgradeData`, and whatever core adds\n * next. Derived from\n * `BlockToolConstructable` rather than enumerated, so a new core static needs no\n * adapter change to become reachable.\n *\n * `toolbox` and `isReadOnlySupported` are excluded because the factory owns\n * them: `toolbox` is authored as {@link CreateAngularBlockSpec.toolbox}, and\n * in-place read-only support is unconditional.\n */\nexport type BlockToolStatics = Omit<BlockToolConstructable, 'toolbox' | 'isReadOnlySupported'>;\n\n/** Statics the generated class owns; an authored `statics` bag can never take them over. */\nconst RESERVED_STATICS: readonly string[] = ['toolbox', 'isReadOnlySupported', '__isBlokAngularBlock'];\n\n/**\n * Origins that mean \"the author just made this block\" — the only ones that fire\n * {@link CreateAngularBlockSpec.onCreated}. Written as an allow-list so a future\n * core origin fails CLOSED (no creation signal) instead of silently opting in.\n *\n * `undefined` is included because core always supplies an origin: an absent one\n * means a host hand-built the constructor options, which is an explicit\n * creation — the same reading core's own container tools apply.\n *\n * Note what is NOT the axis here: `origin === 'user'`. A container gated on that\n * alone would refuse to seed for `api.blocks.insert('steps')` and for a\n * turn-into, leaving an empty, unusable container.\n */\nconst CREATION_ORIGINS: ReadonlySet<BlockOrigin | undefined> = new Set<BlockOrigin | undefined>([\n  undefined,\n  'user',\n  'api',\n  'convert',\n]);\n\n/**\n * Announce that a container's child holders have settled in its slot — the\n * signal a host waits on before putting the caret into a freshly inserted\n * child.\n *\n * Optional-chained: the editor always supplies `events`, but a host unit test\n * may hand a block a partial `api`, and an observability signal must never be\n * able to break a render.\n * @param api - the editor-level API\n * @param blockId - the container block's id\n * @param children - the container's model children, in model order\n */\nconst emitChildrenMounted = (api: API, blockId: string, children: BlockAPI[]): void => {\n  api?.events?.emit(BlockChildrenMounted, {\n    blockId,\n    childIds: children.map(child => child.id),\n  });\n};\n\n/**\n * Second argument of {@link CreateAngularBlockSpec.onMounted} and\n * {@link CreateAngularBlockSpec.onCreated} — everything the block cannot read\n * off its own `BlockAPI`.\n */\nexport interface AngularBlockMountedContext {\n  /**\n   * Why this block instance was constructed: a CREATION origin (`user`, `api`,\n   * `convert`) means the author just made it, so seeding default children is\n   * correct; a RESTORE origin (`load`, `replay`, `paste`) means the document\n   * already says what the children are. `probe` is an off-tree instance built\n   * only to read a tool's default data — it must not touch the block tree at\n   * all. Defaults to `'api'` when the constructor was handed no origin.\n   */\n  origin: BlockOrigin;\n  /** The editor-level API (`api.blocks`, `api.caret`, `api.events`…). */\n  api: API;\n}\n\n/** Spec for {@link createAngularBlock}. Authored as a standalone component. */\nexport interface CreateAngularBlockSpec<Data = BlockToolData> {\n  /** Tool type name (registered key). */\n  type: string;\n  /** Optional toolbox entry. */\n  toolbox?: ToolboxConfig;\n  /** Declarative defaults that also define the exact `save()` key set. */\n  propSchema: PropSchema;\n  /**\n   * The standalone Angular component to render for each block. It injects the\n   * per-block context via `inject(BLOK_BLOCK_CONTEXT)`.\n   */\n  component: Type<unknown>;\n  /**\n   * Static members of core's tool contract, forwarded verbatim onto the\n   * generated tool class — the single channel for everything core reads off the\n   * CLASS rather than the instance (`ownsChildren`, `keepsChildrenOnEnter`,\n   * `conversionConfig`, `pasteConfig`, `sanitize`, `shortcut`, `upgradeData`…).\n   * Without it the only way to declare one was to subclass the generated class.\n   *\n   * `keepsChildrenOnEnter` is the per-tool Enter POLICY: declare it and Enter on\n   * this container's empty LAST child creates the new line INSIDE the container\n   * instead of escaping to the container's parent (Blok's default, which is\n   * Notion's callout behaviour). Core cannot read that off the DOM — a callout\n   * renders the same `data-blok-nested-blocks` slot as a column yet wants the\n   * escape — so before it existed a layout container (a card, a `steps` block)\n   * had to hijack the editor-global `config.onEnter` and re-derive containment.\n   *\n   * `toolbox` and `isReadOnlySupported` are owned by the factory and cannot be\n   * overridden here (see {@link BlockToolStatics}).\n   */\n  statics?: BlockToolStatics;\n  /**\n   * The element the +/drag toolbar should vertically center on — core's\n   * `getToolbarAnchorElement` hook, resolved against this block's host element\n   * on every call (never cached, so it tracks re-renders).\n   *\n   * A container block whose own chrome is not editable needs it: with no anchor,\n   * core centers the toolbar on the first `[contenteditable]` under the host,\n   * which for a container is its FIRST CHILD BLOCK. Return `null`/`undefined`\n   * (or omit the field) to keep core's default.\n   * @param host - this block's mutation-free host element\n   * @param block - this block's per-block API\n   */\n  getToolbarAnchorElement?: (host: HTMLElement, block: BlockAPI) => HTMLElement | null | undefined;\n  /** Optional lifecycle callbacks mapped from Blok's block hooks. */\n  onRendered?: (block: BlockAPI) => void;\n  /**\n   * Fired ONCE per block instance, once the component's DOM (and, for a\n   * container, the child holders its `ctx.mountChildren` adopted) exists.\n   * Angular mounts the block synchronously while core is still inside\n   * `render()`, so this lands with `rendered()` — the first hook at which the\n   * host is also in the document. The React and Vue adapters spell the same\n   * contract; there it is genuinely LATER than `onRendered`, because their\n   * portals commit a frame after core returns.\n   *\n   * It is also the create-vs-restore signal: `context.origin` says whether the\n   * author just made this block (`user`/`api`/`convert`) or the document is\n   * being re-materialised (`load`/`replay`/`paste`) — so a container can seed\n   * its default children here exactly once, without the \"children are\n   * transiently empty during a replay\" trap.\n   * @example\n   * ```ts\n   * onMounted: (block, { origin, api }) => {\n   *   if (origin === 'user' && block.getChildren().length === 0) {\n   *     api.blocks.insertInsideParent(block.id);\n   *   }\n   * }\n   * ```\n   */\n  onMounted?: (block: BlockAPI, context: AngularBlockMountedContext) => void;\n  /**\n   * The SEEDING hook: `onMounted`, narrowed to a genuine creation. Fired ONCE\n   * per block instance, once the component's DOM exists, and only when this\n   * instance is the author making a new block (`origin` of `user`, `api` or\n   * `convert`) — never for a `load`/`replay`/`paste` restore, and never for the\n   * off-tree `probe` instance core builds to read a tool's default data.\n   *\n   * That predicate is why the hook exists rather than leaving every block to\n   * read `context.origin` in `onMounted`: the intuitive `origin === 'user'` test\n   * is wrong. It drops `api.blocks.insert('steps')` and turn-into, so a\n   * container seeded that way comes up empty for every path except a keystroke.\n   * Core refused to ship that axis into its own `column`/`column_list`; this\n   * encodes the correct one once, here.\n   *\n   * The `context` is the same object {@link CreateAngularBlockSpec.onMounted}\n   * receives, so a block that only seeds can read `origin` for finer decisions.\n   * @example\n   * ```ts\n   * onCreated: (block, { api }) => {\n   *   if (block.getChildren().length === 0) {\n   *     api.blocks.insertInsideParent(block.id);\n   *   }\n   * }\n   * ```\n   */\n  onCreated?: (block: BlockAPI, context: AngularBlockMountedContext) => void;\n  onMoved?: (block: BlockAPI) => void;\n  onRemoved?: (block: BlockAPI) => void;\n}\n\n/**\n * Author a first-party Angular block. Returns a `BlockToolConstructable`\n * registered exactly like a vanilla tool (`tools: { type: { class:\n * createAngularBlock(...) } }`).\n *\n * The factory owns the host element (`data-blok-mutation-free`), a frozen\n * defaults-filled data mirror, and signals the component reads. It mounts the\n * component into the host via the editor's shared portal registry (the analog of\n * Vue's Teleport registry), bridging Blok's block lifecycle to Angular:\n * - `render()` creates the host and registers the portal entry (mounted sync).\n * - `setData()` dedups, swaps the reactive snapshot, flushes CD, resolves true.\n * - `save()` returns the complete frozen mirror (never the DOM, never partial).\n * - `commit()` merges a patch and fires `dispatchChange` exactly once.\n * - `setReadOnly()` flips a reactive flag and flushes CD (in-place, no remount).\n * - `removed()`/`destroy()` unregister the portal (deterministic unmount).\n */\nexport function createAngularBlock<Data = BlockToolData>(\n  spec: CreateAngularBlockSpec<Data>\n): (new (options: BlockToolConstructorOptions) => {\n  render(): HTMLElement;\n  save(): BlockToolData;\n  setData(newData: BlockToolData): Promise<boolean>;\n  setReadOnly(state: boolean): void;\n  getToolbarAnchorElement(): HTMLElement | undefined;\n  rendered(): void;\n  moved(): void;\n  removed(): void;\n  destroy(): void;\n}) & BlockToolStatics & {\n  readonly __isBlokAngularBlock: true;\n  readonly toolbox: ToolboxConfig | undefined;\n  readonly isReadOnlySupported: boolean;\n} {\n  const AngularBlockTool = class AngularBlockTool {\n    /** Marker so the directive can detect Angular-block tools and inject the registry. */\n    public static readonly __isBlokAngularBlock = true as const;\n\n    public static get toolbox(): ToolboxConfig | undefined {\n      return spec.toolbox;\n    }\n\n    /**\n     * Angular blocks support read-only mode: `setReadOnly` flips a reactive flag\n     * the component reads, so the block re-renders read-only IN PLACE. Without\n     * this static, core's ReadOnly module throws when read-only is enabled and an\n     * Angular block is present.\n     */\n    public static get isReadOnlySupported(): boolean {\n      return true;\n    }\n\n    private readonly blockApi: BlockAPI;\n    /** The editor-level API, handed to the component as `ctx.api`. */\n    private readonly api: API;\n    private readonly registry: BlockPortalRegistry | undefined;\n    private readonly pointerDrag: () => boolean;\n    private readonly dataSig: WritableSignal<Readonly<Data>>;\n    private readonly readOnlySig: WritableSignal<boolean>;\n    private readonly ctx: AngularBlockRenderContext<Data>;\n    private mirror: Readonly<Data>;\n    /** Dedup baseline: skip a redundant flush of identical data. */\n    private lastRendered: Readonly<Data>;\n    private hostEl: HTMLElement | null = null;\n    /** Last host passed to ctx.mountChildren, re-mounted on each data change. */\n    private childHost: HTMLElement | null = null;\n    /** Element the component handed to ctx.setToolbarAnchor, if any. */\n    private anchorEl: HTMLElement | null = null;\n    /**\n     * Last per-child decorators passed to ctx.mountChildren; BOTH re-applied on\n     * every remount (the author calls mountChildren once, the factory re-runs the\n     * mount on each data change).\n     */\n    private childAttributes: ChildAttributesFn | undefined;\n    private childContentAttributes: ChildAttributesFn | undefined;\n    /** What the last decoration pass wrote, so a dropped key is cleaned up. */\n    private readonly childLedger = createChildDecorationLedger();\n    /** Why core built this instance — gates `onCreated`, handed to `onMounted`. */\n    private readonly origin: BlockOrigin;\n    /** True once the post-mount hooks fired; a repeated rendered() must not re-fire them. */\n    private mountSignalled = false;\n    /** True while a pointer drag suppresses dispatchChange. */\n    private pendingDispatch = false;\n\n    public constructor(options: BlockToolConstructorOptions) {\n      this.blockApi = options.block;\n\n      const config = (options.config ?? {}) as Record<string, unknown>;\n\n      this.registry = config[BLOK_PORTAL_REGISTRY_CONFIG_KEY] as BlockPortalRegistry | undefined;\n\n      this.api = options.api;\n\n      // Read the LIVE pointer-drag flag so a mid-drag commit can be deferred\n      // (core silently drops a dispatchChange while a drag is active).\n      const drag = options.api as unknown as { blocks?: { isPointerDragActive?: boolean } } | undefined;\n\n      this.pointerDrag = (): boolean => drag?.blocks?.isPointerDragActive === true;\n\n      this.mirror = fillDefaults<Data>(spec.propSchema, (options.data ?? {}) as Record<string, unknown>);\n      this.lastRendered = this.mirror;\n      this.dataSig = signal(this.mirror);\n      this.readOnlySig = signal(options.readOnly);\n      // Absent origin means a caller that predates the signal; 'api' is core's\n      // own default, so it is never mistaken for a user gesture.\n      this.origin = options.origin ?? 'api';\n\n      this.ctx = {\n        data: this.dataSig.asReadonly(),\n        commit: this.commit,\n        block: this.blockApi,\n        api: this.api,\n        readOnly: this.readOnlySig.asReadonly(),\n        mountChildren: this.mountChildren,\n        setToolbarAnchor: this.setToolbarAnchor,\n      };\n    }\n\n    public render(): HTMLElement {\n      const host = document.createElement('div');\n\n      // Core's MutationObserver ignores this subtree, so Angular's DOM writes\n      // never register as a user edit.\n      host.setAttribute('data-blok-mutation-free', 'true');\n      this.hostEl = host;\n\n      this.registry?.register(this.blockApi.id, {\n        hostEl: host,\n        component: spec.component,\n        context: this.ctx as AngularBlockRenderContext<unknown>,\n      });\n\n      return host;\n    }\n\n    public rendered(): void {\n      spec.onRendered?.(this.blockApi);\n\n      // register() mounted the component and ran its first change detection\n      // synchronously inside render(), and core has now put the host in the\n      // document — so this is the settled moment. Once per instance: core\n      // re-runs rendered() for a re-materialised block, and a repeated creation\n      // signal would seed a container's default children twice. With no\n      // registry (vanilla core, no directive) nothing was ever mounted, so\n      // there is no settle to report — matching React/Vue, where the signal\n      // originates in the component itself.\n      if (this.registry === undefined || this.mountSignalled) {\n        return;\n      }\n\n      this.mountSignalled = true;\n\n      const context = { origin: this.origin, api: this.api };\n\n      spec.onMounted?.(this.blockApi, context);\n\n      // Creation-only, and after onMounted: a seeding hook must see whatever\n      // the mount hook already put in place.\n      if (CREATION_ORIGINS.has(this.origin)) {\n        spec.onCreated?.(this.blockApi, context);\n      }\n    }\n\n    public save(): BlockToolData {\n      return this.mirror as BlockToolData;\n    }\n\n    public async setData(newData: BlockToolData): Promise<boolean> {\n      const next = fillDefaults<Data>(spec.propSchema, (newData ?? {}) as Record<string, unknown>);\n\n      // Dedup: identical data → skip the flush, but still return true so core\n      // keeps the block in place (no remount).\n      if (deepEqual(next, this.lastRendered)) {\n        return true;\n      }\n\n      this.mirror = next;\n      this.lastRendered = next;\n      this.dataSig.set(next);\n      // Synchronous CD: core drives setData outside NgZone, so nothing else\n      // schedules a render. Never throw (a throw would make core remount).\n      this.registry?.flush(this.blockApi.id);\n      this.remountChildren();\n\n      // Resolve after a microtask for interface symmetry with the async core\n      // setData contract; CD has already flushed synchronously above.\n      await Promise.resolve();\n\n      return true;\n    }\n\n    /**\n     * In-place read-only toggle. Flips the reactive flag the component reads via\n     * `ctx.readOnly`, then flushes CD so the block re-renders read-only WITHOUT a\n     * remount (ephemeral state survives). A prototype method (not an arrow field)\n     * so core's `supportsInPlaceReadOnly` — which probes the PROTOTYPE — selects\n     * the in-place path.\n     */\n    public setReadOnly(state: boolean): void {\n      this.readOnlySig.set(state);\n      this.registry?.flush(this.blockApi.id);\n    }\n\n    /**\n     * Core's toolbar-anchor hook. Always defined so the delegation is one\n     * `typeof … === 'function'` probe away, and always resolved fresh against\n     * the LIVE host — the anchor element is Angular-rendered, so it does not\n     * exist yet when the tool is constructed and may be replaced on any change\n     * detection pass. A spec without a resolver returns undefined, which is\n     * exactly what core's default positioning already assumes.\n     */\n    public getToolbarAnchorElement(): HTMLElement | undefined {\n      /**\n       * An element the component handed over wins — it is the exact node, chosen\n       * from inside the template. `isConnected` is the guard that matters: a\n       * component that re-renders its anchor can leave a detached node here, and\n       * positioning the toolbar against one silently parks it at 0,0.\n       */\n      const declared = this.anchorEl;\n\n      if (declared !== null && declared.isConnected) {\n        return declared;\n      }\n\n      const host = this.hostEl;\n\n      if (host === null || spec.getToolbarAnchorElement === undefined) {\n        return undefined;\n      }\n\n      return spec.getToolbarAnchorElement(host, this.blockApi) ?? undefined;\n    }\n\n    /**\n     * `ctx.setToolbarAnchor`. A bound field so the context object handed through\n     * DI keeps a stable identity.\n     * @param element - the anchor element, or null to fall back to the spec hook\n     */\n    private readonly setToolbarAnchor = (element: HTMLElement | null): void => {\n      this.anchorEl = element;\n    };\n\n    public moved(): void {\n      // No remount: core relocates the host element; the mounted view rides along\n      // as its DOM children.\n      spec.onMoved?.(this.blockApi);\n    }\n\n    public removed(): void {\n      // Ownership-scoped: core composes a REPLACEMENT block (which mounts under\n      // the SAME id) before it tears this one down, so an unqualified unregister\n      // here would destroy the live componentRef and blank the block.\n      this.registry?.unregister(this.blockApi.id, this.hostEl ?? undefined);\n      spec.onRemoved?.(this.blockApi);\n    }\n\n    public destroy(): void {\n      // Idempotent with removed(); unregister is safe when already absent.\n      this.registry?.unregister(this.blockApi.id, this.hostEl ?? undefined);\n    }\n\n    /**\n     * Container blocks: remember the host (and any per-child decorator) and\n     * (re)mount the real child holders.\n     */\n    private readonly mountChildren = (\n      host: HTMLElement,\n      childAttributes?: ChildAttributesFn,\n      childContentAttributes?: ChildAttributesFn\n    ): void => {\n      this.childHost = host;\n      this.childAttributes = childAttributes;\n      this.childContentAttributes = childContentAttributes;\n      host.setAttribute(DATA_ATTR.nestedBlocks, '');\n      this.remountChildren();\n    };\n\n    private remountChildren(): void {\n      if (this.childHost === null) {\n        return;\n      }\n\n      const children = this.blockApi.getChildren();\n\n      mountChildBlocks(this.childHost, children);\n      applyChildDecoration(this.childLedger, children, {\n        childAttributes: this.childAttributes,\n        childContentAttributes: this.childContentAttributes,\n      });\n      emitChildrenMounted(this.api, this.blockApi.id, children);\n    }\n\n    /**\n     * The only data write path. Merges the patch into the frozen mirror, swaps\n     * the reactive snapshot, flushes CD, and fires dispatchChange EXACTLY once —\n     * deferring it while a pointer drag is active (core would otherwise silently\n     * drop it).\n     */\n    private readonly commit = (patch: Partial<Data>): void => {\n      const next = fillDefaults<Data>(spec.propSchema, {\n        ...(this.mirror as Record<string, unknown>),\n        ...(patch as Record<string, unknown>),\n      });\n\n      // Idempotent: a patch that changes nothing is a full no-op — no signal\n      // swap, no CD flush, no dispatchChange — so an effect echoing the current\n      // value back through commit can never loop.\n      if (deepEqual(next, this.mirror)) {\n        return;\n      }\n\n      this.mirror = next;\n      this.lastRendered = next;\n      this.dataSig.set(next);\n      this.registry?.flush(this.blockApi.id);\n      this.remountChildren();\n      this.flushDispatch();\n    };\n\n    /** Dispatch the change, or retry on the next frame if a drag is in progress. */\n    private flushDispatch(): void {\n      if (!this.pointerDrag()) {\n        this.pendingDispatch = false;\n        this.blockApi.dispatchChange();\n\n        return;\n      }\n\n      if (this.pendingDispatch) {\n        return;\n      }\n\n      this.pendingDispatch = true;\n\n      const retry = (): void => {\n        if (this.pointerDrag()) {\n          requestAnimationFrame(retry);\n\n          return;\n        }\n\n        this.pendingDispatch = false;\n        this.blockApi.dispatchChange();\n      };\n\n      requestAnimationFrame(retry);\n    }\n  };\n\n  // Forward the authored statics onto the generated class. `defineProperty`\n  // (not assignment) because `toolbox`/`isReadOnlySupported` are accessors and a\n  // plain write would throw in strict mode; the reserved list keeps a stray bag\n  // from taking those — or the adapter's own marker — over.\n  for (const [key, value] of Object.entries(spec.statics ?? {})) {\n    if (RESERVED_STATICS.includes(key)) {\n      continue;\n    }\n\n    Object.defineProperty(AngularBlockTool, key, {\n      value,\n      writable: true,\n      enumerable: true,\n      configurable: true,\n    });\n  }\n\n  return AngularBlockTool;\n}\n","import type { Blok } from '@bloklabs/core';\n// packages/angular/src/useBlocks.ts\nimport { DestroyRef, effect, inject, signal, type Signal } from '@angular/core';\n\nimport { changeTouchesSubtree, createBlocksApiForEditor, EMPTY_API } from '../adapters-contract';\n\nimport type { UseBlocksApi } from './blocks-snapshot';\n\nconst BLOCK_CHANGED_EVENT = 'block changed';\n\n/** Options for {@link injectBlocks}. */\nexport interface InjectBlocksOptions {\n  /**\n   * Invalidate reads only for changes inside the subtree rooted at this block id\n   * (the block itself or any descendant). Omit — or pass `null` — for the\n   * document-wide default.\n   *\n   * This bounds REACTIVITY, not reads: the returned API still sees the whole\n   * tree, so a scoped consumer can still `getById` anything. Reach for it in a\n   * container block that renders only its own children — unscoped, such a block\n   * invalidates on every keystroke anywhere in the document, and a page of N\n   * containers turns one keystroke into N re-renders.\n   *\n   * Accepted as a plain value or a signal (like `editor`) and read at EMIT time,\n   * so changing it takes effect immediately with no re-subscription.\n   *\n   * A change whose block cannot be placed in the tree (a removal that emits\n   * after the block is gone) counts as in-scope: skipping it would leave a\n   * container rendering a child that no longer exists.\n   */\n  within?: Signal<string | null> | string | null;\n}\n\n/**\n * Angular factory exposing an id/parentId-relative, reactive view of the block\n * tree. Reads refresh whenever the editor emits `block changed`; mutators route\n * through the editor-level `blocks` API (core's chokepoints), so undo/redo and\n * Yjs sync are inherited rather than re-implemented.\n *\n * The block-tree logic is framework-agnostic and lives in the shared\n * {@link createBlocksApiForEditor} core — the SAME implementation behind React's\n * and Vue's `useBlocks`, so all three adapters expose the identical 28-method\n * surface and cannot drift. This wrapper supplies only Angular's reactivity:\n *\n * - A private `version` signal is bumped on every `block changed`. The shared API\n *   is built with an `onRead` seam (`() => { version() }`) that every read method\n *   calls, so reading inside a `computed`/template tracks `version` and re-runs on\n *   each structural mutation.\n * - The bound API is rebuilt (via `bindToEditor`, called eagerly on first call and\n *   then tracked by an `effect` for subsequent identity changes) when the editor\n *   IDENTITY changes; the returned facade is stable across that swap.\n *\n * Call it in an injection context (component constructor / field initializer),\n * passing the editor signal (e.g. `BlokEditorComponent.instance` /\n * `BlokContentDirective.instance`). Pre-ready (editor null) the bound API is the\n * shared {@link EMPTY_API}: every mutator a no-op, reads empty/null — except\n * `transact`/`transactWithoutCapture`, which still run their callback.\n *\n * Note: Angular 20's `effect()` is scheduled (not eager) — it does not fire\n * synchronously on first call. The initial binding therefore runs synchronously\n * in the `injectBlocks` body itself (mirroring Vue's `{ immediate: true }` watch),\n * and the effect re-binds only on subsequent editor identity changes. When the\n * effect fires for the first time with the same editor already bound, the guard\n * `ed === sub.editor` makes it a no-op, so no double-subscription occurs.\n *\n * @param editor - a signal of the Blok instance, or null pre-ready\n * @param options - reactivity options; see {@link InjectBlocksOptions.within} to\n *   scope invalidation to one block's subtree\n */\nexport function injectBlocks(\n  editor: Signal<Blok | null>,\n  options: InjectBlocksOptions = {}\n): UseBlocksApi {\n  /**\n   * The scope, resolved per emission so a signal `within` takes effect with no\n   * re-subscription. A signal is a zero-arg function, which is how it is told\n   * apart from a plain id.\n   */\n  const resolveWithin = (): string | null =>\n    (typeof options.within === 'function' ? options.within() : options.within) ?? null;\n\n  // Bumped on every `block changed`; the shared API's read methods touch it (via\n  // the onRead seam) so template/computed reads stay reactive.\n  const version = signal(0);\n  const touch = (): void => {\n    version();\n  };\n\n  // The API bound to the CURRENT editor; EMPTY_API while null. A signal so the\n  // facade's reads track the editor-identity swap.\n  const bound = signal<UseBlocksApi>(EMPTY_API);\n\n  // One subscription record (no `let` reassignment), re-bound on editor change.\n  const sub: { editor: Blok | null; handler: ((payload?: unknown) => void) | null } = { editor: null, handler: null };\n\n  const unsubscribe = (): void => {\n    if (sub.editor !== null && sub.handler !== null) {\n      sub.editor.off(BLOCK_CHANGED_EVENT, sub.handler);\n    }\n    sub.editor = null;\n    sub.handler = null;\n  };\n\n  /**\n   * Bind to `ed` if the identity has changed. Guards `ed === sub.editor` so a\n   * deferred first effect-run with the same editor already bound is a no-op\n   * (no double-subscription). Called synchronously on first call (immediate\n   * binding) and then re-tracked by the effect below (future identity changes).\n   */\n  const bindToEditor = (ed: Blok | null): void => {\n    if (ed === sub.editor) {\n      return; // Same editor already bound; nothing to do.\n    }\n\n    unsubscribe();\n    // A changed editor identity is itself a reason to re-read.\n    version.update((v) => v + 1);\n\n    if (ed === null) {\n      bound.set(EMPTY_API);\n\n      return;\n    }\n\n    const handler = (payload?: unknown): void => {\n      const within = resolveWithin();\n\n      if (within !== null && !changeTouchesSubtree(ed, payload, within)) {\n        return;\n      }\n\n      version.update((v) => v + 1);\n    };\n\n    ed.on(BLOCK_CHANGED_EVENT, handler);\n    sub.editor = ed;\n    sub.handler = handler;\n    bound.set(createBlocksApiForEditor(ed, touch));\n  };\n\n  // Run the initial binding SYNCHRONOUSLY so the returned facade is immediately\n  // usable (Angular's effect() is deferred — it does not fire on the same tick).\n  // This mirrors Vue's `watch(..., { immediate: true })`.\n  bindToEditor(editor());\n\n  // Re-bind when the editor identity changes. Angular 20 permits signal writes\n  // inside effect() by default (allowSignalWrites option was removed in v20).\n  effect(() => {\n    bindToEditor(editor());\n  });\n\n  inject(DestroyRef).onDestroy(unsubscribe);\n\n  // A stable facade whose methods delegate to the currently-bound API. Reading\n  // `bound()` tracks the editor swap; shared reads track `version` via onRead.\n  // Every key listed EXPLICITLY (no spread) so a forgotten delegation is a\n  // COMPILE error against UseBlocksApi rather than a silently-missing method.\n  return {\n    getById: (id) => bound().getById(id),\n    getChildren: (parentId) => bound().getChildren(parentId),\n    insert: (spec) => bound().insert(spec),\n    insertMany: (specs) => bound().insertMany(specs),\n    insertTree: (spec) => bound().insertTree(spec),\n    insertMarkdown: (markdown, options) => bound().insertMarkdown(markdown, options),\n    exportMarkdown: () => bound().exportMarkdown(),\n    move: (id, target) => bound().move(id, target),\n    nest: (id, parentId) => bound().nest(id, parentId),\n    unnest: (id) => bound().unnest(id),\n    remove: (id) => bound().remove(id),\n    update: (id, data, tunes) => bound().update(id, data, tunes),\n    convert: (id, newType, dataOverrides, options) => bound().convert(id, newType, dataOverrides, options),\n    transact: (fn) => bound().transact(fn),\n    transactWithoutCapture: (fn) => bound().transactWithoutCapture(fn),\n    getBlocksCount: () => bound().getBlocksCount(),\n    getCurrentBlockIndex: () => bound().getCurrentBlockIndex(),\n    getBlockByIndex: (index) => bound().getBlockByIndex(index),\n    getBlockByElement: (element) => bound().getBlockByElement(element),\n    getBlockData: (id) => bound().getBlockData(id),\n    getBlockIndex: (id) => bound().getBlockIndex(id),\n    composeBlockData: (toolName) => bound().composeBlockData(toolName),\n    renderFromHTML: (html) => bound().renderFromHTML(html),\n    insertOutputData: (blocks, options) => bound().insertOutputData(blocks, options),\n    splitBlock: (currentBlockId, currentBlockData, newBlockType, newBlockData, insertIndex) =>\n      bound().splitBlock(currentBlockId, currentBlockData, newBlockType, newBlockData, insertIndex),\n    insertInsideParent: (parentId, insertIndex, childData) =>\n      bound().insertInsideParent(parentId, insertIndex, childData),\n    render: (data) => bound().render(data),\n    clear: () => bound().clear(),\n    isSyncingFromYjs: () => bound().isSyncingFromYjs(),\n  };\n}\n","// packages/angular/src/useBlokReady.ts\nimport { DestroyRef, ElementRef, afterNextRender, inject, signal, type Signal } from '@angular/core';\n\nimport { Blok as BlokRuntime } from '@bloklabs/core';\n\n/** How the caller names the DOM scope to observe. */\nexport type BlokReadyScope =\n  | (() => Element | ElementRef<Element> | null | undefined)\n  | ElementRef<Element>\n  | Element\n  | null;\n\n/** Options accepted by {@link injectBlokReady}. */\nexport interface InjectBlokReadyOptions {\n  /**\n   * Restrict the wait to editors mounted inside this element. Accepts an\n   * element, an `ElementRef`, or a getter/signal returning either — the getter\n   * form lets you pass `() => this.scopeRef?.nativeElement` from a field\n   * initializer, before the view exists. It is re-read on every readiness\n   * change.\n   *\n   * Omit it to observe every editor on the page. Passing it while it still\n   * resolves to null reports NOT ready — an unresolved scope must never fall\n   * back to the page-global one.\n   */\n  within?: BlokReadyScope;\n  /**\n   * `'ready'` (default) settles when each editor has finished booting.\n   * `'rendered'` also waits for its content to be in the DOM and re-arms on\n   * every post-boot re-render.\n   */\n  settleOn?: 'ready' | 'rendered';\n}\n\n/**\n * Resolves the caller's scope description to an element, or null when it is\n * not available yet.\n * @param within - the scope description passed in options\n */\nfunction resolveScope(within: BlokReadyScope): Element | null {\n  const value = typeof within === 'function' ? within() : within;\n\n  if (value === null || value === undefined) {\n    return null;\n  }\n\n  return value instanceof ElementRef ? value.nativeElement : value;\n}\n\n/**\n * Angular factory exposing the live readiness of the Blok editors in a DOM\n * scope as a boolean signal.\n *\n * The readiness logic itself is framework-agnostic and lives in core\n * (`Blok.readyState` / `Blok.subscribeReady`) — the SAME implementation behind\n * React's and Vue's `useBlokReady`, so the three adapters cannot drift. This\n * wrapper supplies only Angular's reactivity: a signal re-read on every\n * registry change, unsubscribed through the injector's `DestroyRef`.\n *\n * Call it in an injection context (component constructor / field initializer).\n * The signal starts `false` and takes its first real reading in\n * `afterNextRender` — browser-only by contract, and late enough for a\n * `@ViewChild` scope to exist. Over-waiting is safe; under-waiting is a bug.\n * @param options - scope and readiness depth\n */\nexport function injectBlokReady(options: InjectBlokReadyOptions = {}): Signal<boolean> {\n  const { within, settleOn } = options;\n  const ready = signal(false);\n\n  const read = (): void => {\n    const scope = within === undefined ? null : resolveScope(within);\n\n    // A scope that was asked for but has not resolved yet is NOT the global\n    // scope — reporting ready here would gate on the wrong set of editors.\n    ready.set(within !== undefined && scope === null\n      ? false\n      : BlokRuntime.readyState({\n        within: scope,\n        settleOn,\n      }).ready);\n  };\n\n  inject(DestroyRef).onDestroy(BlokRuntime.subscribeReady(read));\n  afterNextRender(read);\n\n  return ready.asReadonly();\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["BlokRuntime"],"mappings":"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"}