{"version":3,"file":"index.cjs","sources":["../src/shared/are-maps-equal.ts","../src/shared/async-registry.ts","../src/shared/camel-case.ts","../src/shared/debounce.ts","../src/shared/is-plain-object.ts","../src/shared/deep-camel-case-keys.ts","../src/shared/get-csrf-token.ts","../src/shared/hook.ts","../src/shared/is-empty-object.ts","../src/shared/is-nil.ts","../src/shared/map-object-values.ts","../src/shared/parse-int-if-not-null.ts","../src/shared/parse-json-if-present.ts","../src/shared/shallow-equal.ts","../src/shared/uid.ts","../src/shared/wait-for.ts","../src/hooks/editor/utils/assign-editor-roots-to-config.ts","../src/hooks/editor/utils/cleanup-orphan-editor-elements.ts","../src/hooks/editor/utils/create-editor-in-context.ts","../src/hooks/editor/utils/is-multiroot-editor-instance.ts","../src/hooks/editor/utils/is-single-root-editor.ts","../src/hooks/editor/utils/load-editor-constructor.ts","../src/hooks/editor/custom-editor-plugins.ts","../src/hooks/editor/utils/load-editor-plugins.ts","../src/hooks/editor/utils/load-editor-translations.ts","../src/hooks/editor/utils/normalize-custom-translations.ts","../src/hooks/editor/utils/query-all-editor-editables.ts","../src/hooks/editor/typings.ts","../src/hooks/editor/utils/read-preset-or-throw.ts","../src/hooks/editor/utils/resolve-editor-config-elements-references.ts","../src/hooks/editor/utils/resolve-editor-config-translations.ts","../src/hooks/editor/utils/set-editor-editable-height.ts","../src/hooks/editor/utils/wrap-with-watchdog.ts","../src/hooks/context/contexts-registry.ts","../src/hooks/context/utils/read-context-config-or-throw.ts","../src/hooks/context/context.ts","../src/hooks/root-value-sentinel/root-attributes-updater.ts","../src/hooks/editor/plugins/phoenix-upload-adapter.ts","../src/hooks/editor/plugins/sync-editor-with-input.ts","../src/hooks/editor/plugins/sync-editor-with-phoenix.ts","../src/hooks/root-value-sentinel/root-value-sentinel.ts","../src/hooks/editor/editors-registry.ts","../src/hooks/editor/editor.ts","../src/hooks/editable.ts","../src/hooks/ui-part.ts","../src/hooks/index.ts"],"sourcesContent":["/**\n * Compares two Map structures for equality based on their contents.\n * The function checks if the maps have the same size, contain the exact same keys,\n * and have strictly equal values (using shallow comparison).\n *\n * @param map1 - The first map to compare (can be null).\n * @param map2 - The second map to compare.\n * @returns Returns `true` if the maps are identical in terms of keys and values, otherwise `false`.\n */\nexport function areMapsEqual(map1: Map<any, any> | null, map2: Map<any, any>): boolean {\n  if (!map1 || map1.size !== map2.size) {\n    return false;\n  }\n\n  for (const [key, value] of map1) {\n    if (!map2.has(key) || map2.get(key) !== value) {\n      return false;\n    }\n  }\n\n  return true;\n}\n","import { areMapsEqual } from './are-maps-equal';\n\n/**\n * Generic async registry for objects with an async destroy method.\n * Provides a way to register, unregister, and execute callbacks on objects by ID.\n */\nexport class AsyncRegistry<T extends Destructible> {\n  /**\n   * Map of registered items.\n   */\n  private readonly items = new Map<RegistryId | null, T>();\n\n  /**\n   * Map of initialization errors for items that failed to register.\n   */\n  private readonly initializationErrors = new Map<RegistryId | null, any>();\n\n  /**\n   * Map of pending callbacks waiting for items to be registered or fail.\n   */\n  private readonly pendingCallbacks = new Map<RegistryId | null, PendingCallbacks<T>>();\n\n  /**\n   * Set of watchers that observe changes to the registry.\n   */\n  private readonly watchers = new Set<RegistryWatcher<T>>();\n\n  /**\n   * Batch nesting depth. When > 0, watcher notifications are deferred.\n   */\n  private batchDepth = 0;\n\n  /**\n   * Snapshot of the last state dispatched to watchers, used for change detection.\n   */\n  private lastNotifiedItems: Map<any, any> | null = null;\n\n  private lastNotifiedErrors: Map<any, any> | null = null;\n\n  /**\n   * Executes a function on an item.\n   * If the item is not yet registered, it will wait for it to be registered.\n   *\n   * @param id The ID of the item.\n   * @param onSuccess The function to execute.\n   * @param onError Optional error callback.\n   * @returns A promise that resolves with the result of the function.\n   */\n  execute<R, E extends T = T>(\n    id: RegistryId | null,\n    onSuccess: (item: E) => R,\n    onError?: (error: any) => void,\n  ): Promise<Awaited<R>> {\n    const item = this.items.get(id);\n    const error = this.initializationErrors.get(id);\n\n    // If error exists and callback provided, invoke it immediately.\n    if (error) {\n      onError?.(error);\n      return Promise.reject(error);\n    }\n\n    // If item exists, invoke callback immediately (synchronously via Promise.resolve).\n    if (item) {\n      return Promise.resolve(onSuccess(item as E));\n    }\n\n    // Item not ready yet - queue the callbacks.\n    return new Promise((resolve, reject) => {\n      const pending = this.getPendingCallbacks(id);\n\n      pending.success.push(async (item: T) => {\n        resolve(await onSuccess(item as E));\n      });\n\n      if (onError) {\n        pending.error.push(onError);\n      }\n      else {\n        pending.error.push(reject);\n      }\n    });\n  }\n\n  /**\n   * Reactively binds a mount/unmount lifecycle to a single registry item.\n   *\n   * @param id The ID of the item to observe.\n   * @param onMount Function executed when the item mounts.\n   * @returns A function that stops observing and immediately runs any pending cleanup.\n   */\n  mountEffect<E extends T = T>(\n    id: RegistryId | null,\n    onMount: (item: E) => (() => void) | void,\n  ): () => void {\n    let cleanup: VoidFunction | void;\n    let mountedItem: T | undefined;\n    let unmounted = false;\n\n    const unwatch = this.watch((items) => {\n      const item = items.get(id);\n\n      if (item === mountedItem) {\n        return;\n      }\n\n      cleanup?.();\n      cleanup = undefined;\n      mountedItem = item;\n\n      if (!item) {\n        return;\n      }\n\n      try {\n        const newCleanup = onMount(item as E);\n\n        if (unmounted) {\n          newCleanup?.();\n          unwatch();\n        }\n        else {\n          cleanup = newCleanup;\n        }\n      /* v8 ignore next 5 */\n      }\n      catch (err) {\n        console.error(err);\n        throw err;\n      }\n    });\n\n    return () => {\n      unmounted = true;\n\n      if (mountedItem) {\n        unwatch();\n        cleanup?.();\n        cleanup = undefined;\n      }\n    };\n  }\n\n  /**\n   * Registers an item.\n   *\n   * @param id The ID of the item.\n   * @param item The item instance.\n   */\n  register(id: RegistryId | null, item: T): void {\n    this.batch(() => {\n      if (this.items.has(id)) {\n        throw new Error(`Item with ID \"${id}\" is already registered.`);\n      }\n\n      this.resetErrors(id);\n      this.items.set(id, item);\n\n      // Execute all pending callbacks for this item (synchronously).\n      const pending = this.pendingCallbacks.get(id);\n\n      if (pending) {\n        pending.success.forEach(callback => callback(item));\n        this.pendingCallbacks.delete(id);\n      }\n\n      // Register the first item as the default item (null ID).\n      if (this.items.size === 1 && id !== null) {\n        this.register(null, item);\n      }\n    });\n  }\n\n  /**\n   * Registers an error for an item.\n   *\n   * @param id The ID of the item.\n   * @param error The error to register.\n   */\n  error(id: RegistryId | null, error: any): void {\n    this.batch(() => {\n      this.items.delete(id);\n      this.initializationErrors.set(id, error);\n\n      // Execute all pending error callbacks for this item.\n      const pending = this.pendingCallbacks.get(id);\n\n      if (pending) {\n        pending.error.forEach(callback => callback(error));\n        this.pendingCallbacks.delete(id);\n      }\n\n      // Set as default error if this is the first error and no items exist.\n      if (this.initializationErrors.size === 1 && !this.items.size) {\n        this.error(null, error);\n      }\n    });\n  }\n\n  /**\n   * Resets errors for an item.\n   *\n   * @param id The ID of the item.\n   */\n  resetErrors(id: RegistryId | null): void {\n    const { initializationErrors } = this;\n\n    // Clear default error if it's the same as the specific error.\n    if (initializationErrors.has(null) && initializationErrors.get(null) === initializationErrors.get(id)) {\n      initializationErrors.delete(null);\n    }\n\n    initializationErrors.delete(id);\n  }\n\n  /**\n   * Un-registers an item.\n   *\n   * @param id The ID of the item.\n   * @param resetPendingCallbacks If true resets pending callbacks.\n   */\n  unregister(id: RegistryId | null, resetPendingCallbacks: boolean = true): void {\n    this.batch(() => {\n      // If unregistering the default item, clear it.\n      if (id && this.items.get(null) === this.items.get(id)) {\n        this.unregister(null, false);\n      }\n\n      this.items.delete(id);\n\n      if (resetPendingCallbacks) {\n        this.pendingCallbacks.delete(id);\n      }\n\n      this.resetErrors(id);\n    });\n  }\n\n  /**\n   * Gets all registered items.\n   *\n   * @returns An array of all registered items.\n   */\n  getItems(): T[] {\n    return Array.from(this.items.values());\n  }\n\n  /**\n   * Returns single registered item.\n   *\n   * @returns Registered item.\n   */\n  getItem(id: RegistryId | null): T | undefined {\n    return this.items.get(id);\n  }\n\n  /**\n   * Checks if an item with the given ID is registered.\n   *\n   * @param id The ID of the item.\n   * @returns `true` if the item is registered, `false` otherwise.\n   */\n  hasItem(id: RegistryId | null): boolean {\n    return this.items.has(id);\n  }\n\n  /**\n   * Gets a promise that resolves with the item instance for the given ID.\n   * If the item is not registered yet, it will wait for it to be registered.\n   *\n   * @param id The ID of the item.\n   * @returns A promise that resolves with the item instance.\n   */\n  waitFor<E extends T = T>(id: RegistryId | null): Promise<E> {\n    return new Promise<E>((resolve, reject) => {\n      void this.execute(id, resolve as (value: E) => void, reject);\n    });\n  }\n\n  /**\n   * Destroys all registered items and clears the registry.\n   * This will call the `destroy` method on each item.\n   */\n  async destroyAll() {\n    const promises = (\n      Array\n        .from(new Set(this.items.values()))\n        .map(item => item.destroy())\n    );\n\n    this.items.clear();\n    this.pendingCallbacks.clear();\n\n    await Promise.all(promises);\n\n    this.flushWatchers();\n  }\n\n  /**\n   * Destroys all registered editors and removes all watchers.\n   */\n  async reset() {\n    await this.destroyAll();\n    this.watchers.clear();\n  }\n\n  /**\n   * Executes a callback while deferring all watcher notifications.\n   * A single notification is fired synchronously after the callback returns,\n   * but only if the registry actually changed.\n   *\n   * Batches can be nested — watchers are notified only when the outermost\n   * batch completes.\n   *\n   * @param fn The callback to execute.\n   * @returns The return value of the callback.\n   */\n  batch<R>(fn: () => R): R {\n    this.batchDepth++;\n\n    try {\n      return fn();\n    }\n    finally {\n      this.batchDepth--;\n\n      if (this.batchDepth === 0) {\n        this.flushWatchers();\n      }\n    }\n  }\n\n  /**\n   * Registers a watcher that will be called whenever the registry changes.\n   *\n   * @param watcher The watcher function to register.\n   * @returns A function to unregister the watcher.\n   */\n  watch(watcher: RegistryWatcher<T>): () => void {\n    this.watchers.add(watcher);\n\n    // Call the watcher immediately with the current state.\n    watcher(\n      new Map(this.items),\n      new Map(this.initializationErrors),\n    );\n\n    return this.unwatch.bind(this, watcher);\n  }\n\n  /**\n   * Un-registers a watcher.\n   *\n   * @param watcher The watcher function to unregister.\n   */\n  unwatch(watcher: RegistryWatcher<T>): void {\n    this.watchers.delete(watcher);\n  }\n\n  /**\n   * Immediately dispatches the current state to all watchers if it changed.\n   */\n  private flushWatchers(): void {\n    if (\n      areMapsEqual(this.lastNotifiedItems, this.items)\n      && areMapsEqual(this.lastNotifiedErrors, this.initializationErrors)\n    ) {\n      return;\n    }\n\n    this.lastNotifiedItems = new Map(this.items);\n    this.lastNotifiedErrors = new Map(this.initializationErrors);\n\n    this.watchers.forEach(watcher => watcher(\n      new Map(this.items),\n      new Map(this.initializationErrors),\n    ));\n  }\n\n  /**\n   * Gets or creates pending callbacks for a specific ID.\n   *\n   * @param id The ID of the item.\n   * @returns The pending callbacks structure.\n   */\n  private getPendingCallbacks(id: RegistryId | null): PendingCallbacks<T> {\n    let pending = this.pendingCallbacks.get(id);\n\n    if (!pending) {\n      pending = { success: [], error: [] };\n      this.pendingCallbacks.set(id, pending);\n    }\n\n    return pending;\n  }\n}\n\n/**\n * Interface for objects that can be destroyed.\n */\nexport type Destructible = {\n  destroy: () => Promise<any>;\n};\n\n/**\n * Identifier of the registry item.\n */\ntype RegistryId = string;\n\n/**\n * Structure holding pending success and error callbacks for an item.\n */\ntype PendingCallbacks<T> = {\n  success: Array<(item: T) => void>;\n  error: Array<(error: Error) => void>;\n};\n\n/**\n * Callback type for watching registry changes.\n */\ntype RegistryWatcher<T> = (\n  items: Map<RegistryId | null, T>,\n  errors: Map<RegistryId | null, Error>,\n) => void;\n","/**\n * Converts a string to camelCase.\n *\n * @param str The string to convert\n * @returns The camelCased string\n */\nexport function camelCase(str: string): string {\n  return str\n    .replace(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n    .replace(/^./, m => m.toLowerCase());\n}\n","export function debounce<T extends (...args: any[]) => any>(\n  delay: number,\n  callback: T,\n): (...args: Parameters<T>) => void {\n  let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n  return (...args: Parameters<T>): void => {\n    if (timeoutId) {\n      clearTimeout(timeoutId);\n    }\n\n    timeoutId = setTimeout(() => {\n      callback(...args);\n    }, delay);\n  };\n}\n","/**\n * Utility to check if a value is a plain object (not an array, not null, not a class instance).\n *\n * @param value The value to check.\n * @returns True if the value is a plain object, false otherwise.\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n  if (Object.prototype.toString.call(value) !== '[object Object]') {\n    return false;\n  }\n\n  const proto = Object.getPrototypeOf(value);\n\n  return proto === Object.prototype || proto === null;\n}\n","import { camelCase } from './camel-case';\nimport { isPlainObject } from './is-plain-object';\n\n/**\n * Recursively converts all keys of a plain object or array to camelCase.\n * Skips class instances and leaves them untouched.\n *\n * @param input The object or array to process\n */\nexport function deepCamelCaseKeys<T>(input: T): T {\n  if (Array.isArray(input)) {\n    return input.map(deepCamelCaseKeys) as unknown as T;\n  }\n\n  if (isPlainObject(input)) {\n    const result: Record<string, unknown> = Object.create(null);\n\n    for (const [key, value] of Object.entries(input)) {\n      result[camelCase(key)] = deepCamelCaseKeys(value);\n    }\n\n    return result as T;\n  }\n\n  return input;\n}\n","/**\n * Retrieves the CSRF token from the meta tag or cookie.\n *\n * @returns The CSRF token or null if not found.\n */\nexport function getCsrfToken(): string | null {\n  // Try to get from meta tag (Phoenix default).\n  const metaTag = document.querySelector('meta[name=\"csrf-token\"]');\n\n  if (metaTag) {\n    return metaTag.getAttribute('content');\n  }\n\n  // Try to get from cookie.\n  const match = document.cookie.match(/(?:^|; )_csrf_token=([^;]*)/);\n\n  return match ? decodeURIComponent(match[1]!) : null;\n}\n","import type { Hook } from 'phoenix_live_view';\n\nimport type { RequiredBy } from '../types';\n\n/**\n * An abstract class that provides a class-based API for creating Phoenix LiveView hooks.\n *\n * This class defines the structure and lifecycle methods of a hook, which can be extended\n * to implement custom client-side behavior that integrates with LiveView.\n */\nexport abstract class ClassHook {\n  /**\n   * The current state of the hook.\n   */\n  state: ClassHookState = 'mounting';\n\n  /**\n   * The DOM element the hook is attached to.\n   * It includes an `instance` property to hold the hook instance.\n   */\n  el: HTMLElement & { instance: Hook; };\n\n  /**\n   * Callbacks to run before the hook is destroyed.\n   */\n  private _beforeDestroyCallbacks: Array<() => void> = [];\n\n  /**\n   * Registers a callback to be called before the hook is destroyed.\n   * Callbacks are called in LIFO order (last registered, first called).\n   */\n  onBeforeDestroy(callback: () => void): void {\n    this._beforeDestroyCallbacks.push(callback);\n  }\n\n  /**\n   * Pushes an event from the client to the LiveView server process.\n   * @param _event The name of the event.\n   * @param _payload The data to send with the event.\n   * @param _callback An optional function to be called with the server's reply.\n   */\n  pushEvent!: (\n    _event: string,\n    _payload: any,\n    _callback?: (reply: any, ref: number) => void,\n  ) => void;\n\n  /**\n   * Pushes an event to another hook on the page.\n   * @param _selector The CSS selector of the target element with the hook.\n   * @param _event The name of the event.\n   * @param _payload The data to send with the event.\n   * @param _callback An optional function to be called with the reply.\n   */\n  pushEventTo!: (\n    _selector: string,\n    _event: string,\n    _payload: any,\n    _callback?: (reply: any, ref: number) => void,\n  ) => void;\n\n  /**\n   * Registers a handler for an event pushed from the server.\n   * @param _event The name of the event to handle.\n   * @param _callback The function to execute when the event is received.\n   */\n  handleEvent!: (\n    _event: string,\n    _callback: (payload: any) => void,\n  ) => void;\n\n  /**\n   * Called when the hook has been mounted to the DOM.\n   * This is the ideal place for initialization code.\n   */\n  mounted(): any {}\n\n  /**\n   * Called when the element has been removed from the DOM.\n   * Perfect for cleanup tasks.\n   */\n  destroyed(): any {}\n\n  /**\n   * Called when the element has been updated by a LiveView patch.\n   */\n  updated(): any {}\n\n  /**\n   * Called before the element is updated by a LiveView patch.\n   */\n  beforeUpdate?(): void;\n\n  /**\n   * Called when the client has disconnected from the server.\n   */\n  disconnected?(): void;\n\n  /**\n   * Called when the client has reconnected to the server.\n   */\n  reconnected?(): void;\n\n  /**\n   * Checks if the hook is in the process of being destroyed.\n   */\n  isBeingDestroyed(): boolean {\n    return this.state === 'destroyed' || this.state === 'destroying';\n  }\n\n  /**\n   * Runs all registered before-destroy callbacks and clears the list.\n   * Called internally by makeHook before destroyed().\n   */\n  _runBeforeDestroyCallbacks(): void {\n    for (const cb of this._beforeDestroyCallbacks.reverse()) {\n      cb();\n    }\n\n    this._beforeDestroyCallbacks = [];\n  }\n}\n\n/**\n * A type that represents the state of a class-based hook.\n */\nexport type ClassHookState = 'mounting' | 'mounted' | 'destroying' | 'destroyed';\n\n/**\n * A factory function that adapts a class-based hook to the object-based API expected by Phoenix LiveView.\n *\n * @param constructor The constructor of the class that extends the `Hook` abstract class.\n */\nexport function makeHook(constructor: new () => ClassHook): RequiredBy<Hook<any>, 'mounted' | 'destroyed'> {\n  return {\n    /**\n     * The mounted lifecycle callback for the LiveView hook object.\n     * It creates an instance of the user-defined hook class and sets up the necessary properties and methods.\n     */\n    async mounted(this: any) {\n      const instance = new constructor();\n\n      this.el.instance = instance;\n\n      instance.el = this.el;\n\n      instance.pushEvent = (event, payload, callback) => this.pushEvent?.(event, payload, callback);\n      instance.pushEventTo = (selector, event, payload, callback) => this.pushEventTo?.(selector, event, payload, callback);\n      instance.handleEvent = (event, callback) => this.handleEvent?.(event, callback);\n\n      instance.state = 'mounting';\n      const result = await instance.mounted?.();\n      instance.state = 'mounted';\n\n      return result;\n    },\n\n    /**\n     * The beforeUpdate lifecycle callback that delegates to the hook instance.\n     */\n    beforeUpdate(this: any) {\n      this.el.instance.beforeUpdate?.();\n    },\n\n    /**\n     * The destroyed lifecycle callback that delegates to the hook instance.\n     */\n    async destroyed(this: any) {\n      const { instance } = this.el;\n\n      instance.state = 'destroying';\n      instance._runBeforeDestroyCallbacks();\n      await instance.destroyed?.();\n      instance.state = 'destroyed';\n    },\n\n    /**\n     * The disconnected lifecycle callback that delegates to the hook instance.\n     */\n    disconnected(this: any) {\n      this.el.instance.disconnected?.();\n    },\n\n    /**\n     * The reconnected lifecycle callback that delegates to the hook instance.\n     */\n    reconnected(this: any) {\n      this.el.instance.reconnected?.();\n    },\n\n    /**\n     * The updated lifecycle callback that delegates to the hook instance.\n     */\n    updated(this: any) {\n      return this.el.instance.updated?.();\n    },\n  };\n}\n","export function isEmptyObject(obj: Record<string, unknown>): boolean {\n  return Object.keys(obj).length === 0 && obj.constructor === Object;\n}\n","export function isNil(value: any): value is null | undefined {\n  return value === null || value === undefined;\n}\n","/**\n * Maps the values of an object using a provided mapper function.\n *\n * @param obj The object whose values will be mapped.\n * @param mapper A function that takes a value and its key, and returns a new value.\n * @template T The type of the original values in the object.\n * @template U The type of the new values in the object.\n * @returns A new object with the same keys as the original, but with values transformed by\n */\nexport function mapObjectValues<T, U>(\n  obj: Record<string, T>,\n  mapper: (value: T, key: string) => U,\n): Record<string, U> {\n  const mappedEntries = Object\n    .entries(obj)\n    .map(([key, value]) => [key, mapper(value, key)] as const);\n\n  return Object.fromEntries(mappedEntries);\n}\n","export function parseIntIfNotNull(value: string | null): number | null {\n  if (value === null) {\n    return null;\n  }\n\n  const parsed = Number.parseInt(value, 10);\n\n  return Number.isNaN(parsed) ? null : parsed;\n}\n","/**\n * Parses a JSON string if it is provided.\n *\n * Returns `null` when the input is `null`, `undefined` or an empty string.\n * Otherwise it parses the string using `JSON.parse` and returns the parsed value.\n *\n * @throws SyntaxError when the input is not valid JSON.\n */\nexport function parseJsonIfPresent<T = unknown>(json: string | null | undefined): T | null {\n  if (json == null || json.trim() === '') {\n    return null;\n  }\n\n  return JSON.parse(json) as T;\n}\n","/**\n * Performs a shallow comparison of two objects.\n *\n * @param objA - The first object to compare.\n * @param objB - The second object to compare.\n * @returns True if the objects are shallowly equal, false otherwise.\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n  objA: T,\n  objB: T,\n): boolean {\n  if (objA === objB) {\n    return true;\n  }\n\n  const keysA = Object.keys(objA);\n  const keysB = Object.keys(objB);\n\n  if (keysA.length !== keysB.length) {\n    return false;\n  }\n\n  for (const key of keysA) {\n    if (objA[key] !== objB[key] || !Object.prototype.hasOwnProperty.call(objB, key)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n","/**\n * Generates a unique identifier string\n *\n * @returns Random string that can be used as unique identifier\n */\nexport function uid() {\n  return Math.random().toString(36).substring(2);\n}\n","import type { CanBePromise } from '../types';\n\n/**\n * Waits for the provided callback to succeed. The callback is executed multiple times until it succeeds or the timeout is reached.\n * It's executed immediately and then with a delay defined by the `retry` option.\n *\n * @param callback The callback to execute.\n * @param config Configuration for the function.\n * @param config.timeOutAfter The maximum time to wait for the callback to succeed, in milliseconds. Default is 500ms.\n * @param config.retryAfter The time to wait between retries, in milliseconds. Default is 100ms.\n * @returns A promise that resolves when the callback succeeds.\n */\nexport function waitFor<R>(\n  callback: () => CanBePromise<R>,\n  {\n    timeOutAfter = 500,\n    retryAfter = 100,\n  }: WaitForConfig = {},\n): Promise<R> {\n  return new Promise<R>((resolve, reject) => {\n    const startTime = Date.now();\n    let lastError: Error | null = null;\n\n    const timeoutTimerId = setTimeout(() => {\n      reject(lastError ?? new Error('Timeout'));\n    }, timeOutAfter);\n\n    const tick = async () => {\n      try {\n        const result = await callback();\n        clearTimeout(timeoutTimerId);\n        resolve(result);\n      }\n      catch (err: any) {\n        lastError = err;\n\n        if (Date.now() - startTime > timeOutAfter) {\n          reject(err);\n        }\n        else {\n          setTimeout(tick, retryAfter);\n        }\n      }\n    };\n\n    void tick();\n  });\n}\n\n/**\n * Configuration for the `waitFor` function.\n */\nexport type WaitForConfig = {\n  timeOutAfter?: number;\n  retryAfter?: number;\n};\n","import type { EditorConfig } from 'ckeditor5';\n\nimport type { EditorRelaxedConstructor } from '../types/editor-relaxed-constructor.type';\nimport type { EditableItem } from './query-all-editor-editables';\n\n/**\n * Assigns DOM elements and initial data to the editor configuration in a way that is compatible\n * with the specific editor type.\n *\n * @param Editor Constructor of the editor used to determine the location of element config entry.\n * @param editables Map of editable items (element + initial value) keyed by root name.\n * @param config Config of the editor.\n * @returns The updated configuration object.\n */\nexport function assignEditorRootsToConfig<C extends EditorConfig>(\n  Editor: EditorRelaxedConstructor,\n  editables: Record<string, EditableItem>,\n  config: C,\n): C {\n  const isClassicEditor = !Editor.editorName || Editor.editorName === 'ClassicEditor';\n  const allRootsKeys = new Set([\n    ...Object.keys(editables),\n    ...Object.keys(config.roots ?? {}),\n  ]);\n\n  const rootsConfig = Array.from(allRootsKeys).reduce((acc, rootKey) => ({\n    ...acc,\n    [rootKey]: {\n      /* v8 ignore next 1 */\n      ...config.roots?.[rootKey],\n      ...rootKey === 'main' ? config.root : {},\n\n      /* v8 ignore next 6 */\n      ...rootKey in editables\n        ? {\n            initialData: editables[rootKey]!.initialValue,\n            ...!isClassicEditor && { element: editables[rootKey]!.content },\n          }\n        : {},\n    },\n  }), Object.create(config.roots || {}));\n\n  const mappedConfig: C = {\n    ...config,\n    roots: rootsConfig,\n    ...isClassicEditor && {\n      attachTo: editables['main']?.content,\n    },\n  };\n\n  delete mappedConfig.root;\n\n  return mappedConfig;\n}\n","import type { Editor } from 'ckeditor5';\n\n/**\n * Removes all DOM elements injected by a specific CKEditor instance.\n * Call this before assigning a new instance (e.g. in the 'restart' watchdog handler),\n * because the watchdog does not clean up the previous editor's DOM on its own.\n */\nexport function cleanupOrphanEditorElements(editor: Editor): void {\n  const uiElements = [\n    editor.ui?.element,\n    editor.ui?.view?.toolbar?.element,\n    editor.ui?.view?.menuBarView?.element,\n  ].filter(Boolean) as HTMLElement[];\n\n  for (const uiElement of uiElements) {\n    removeOrReset(uiElement);\n  }\n\n  const bodyCollectionContainer = (editor.ui as any)?.view?.body?._bodyCollectionContainer;\n\n  if (bodyCollectionContainer?.isConnected) {\n    removeOrReset(bodyCollectionContainer);\n  }\n\n  const editingView = editor.editing?.view;\n\n  if (editingView) {\n    for (const domRoot of editingView.domRoots.values()) {\n      if (!(domRoot instanceof HTMLElement)) {\n        continue;\n      }\n\n      domRoot.removeAttribute('contenteditable');\n      domRoot.removeAttribute('role');\n      domRoot.removeAttribute('aria-label');\n      domRoot.removeAttribute('aria-multiline');\n      domRoot.removeAttribute('spellcheck');\n      domRoot.classList.remove(\n        'ck',\n        'ck-content',\n        'ck-editor__editable',\n        'ck-rounded-corners',\n        'ck-editor__editable_inline',\n        'ck-blurred',\n        'ck-focused',\n      );\n\n      removeOrReset(domRoot);\n    }\n  }\n\n  function removeOrReset(element: HTMLElement) {\n    if (element.hasAttribute('data-cke-controlled')) {\n      element.innerHTML = '';\n    }\n    else {\n      element.remove();\n    }\n  }\n}\n","import type { Context, ContextWatchdog, Editor, EditorConfig } from 'ckeditor5';\n\nimport { uid } from '../../../shared';\n\n/**\n * Symbol used to store the context watchdog on the editor instance.\n * Internal use only.\n */\nconst CONTEXT_EDITOR_WATCHDOG_SYMBOL = Symbol.for('context-editor-watchdog');\n\n/**\n * Creates a CKEditor 5 editor instance within a given context watchdog.\n *\n * @param params Parameters for editor creation.\n * @param params.context The context watchdog instance.\n * @param params.creator The editor creator utility.\n * @param params.config The editor configuration object.\n * @returns The created editor instance.\n */\nexport async function createEditorInContext({ context, creator, config }: Attrs) {\n  const editorContextId = uid();\n\n  await context.add({\n    creator: creator.create.bind(creator),\n    id: editorContextId,\n    type: 'editor',\n    config,\n  });\n\n  const editor = context.getItem(editorContextId) as Editor;\n  const contextDescriptor: EditorContextDescriptor = {\n    state: 'available',\n    editorContextId,\n    context,\n  };\n\n  (editor as any)[CONTEXT_EDITOR_WATCHDOG_SYMBOL] = contextDescriptor;\n\n  // Destroying of context is async. There can be situation when the destroy of the context\n  // and the destroy of the editor is called in parallel. It often happens during unmounting of\n  // phoenix hooks. Let's make sure that descriptor informs other components, that context is being\n  // destroyed.\n  const originalDestroy = context.destroy.bind(context);\n  context.destroy = async () => {\n    contextDescriptor.state = 'unavailable';\n    return originalDestroy();\n  };\n\n  return {\n    ...contextDescriptor,\n    editor,\n  };\n}\n\n/**\n * Retrieves the context watchdog from an editor instance, if available.\n *\n * @param editor The editor instance.\n * @returns The context watchdog or null if not found.\n */\nexport function unwrapEditorContext(editor: Editor): EditorContextDescriptor | null {\n  if (CONTEXT_EDITOR_WATCHDOG_SYMBOL in editor) {\n    return (editor as any)[CONTEXT_EDITOR_WATCHDOG_SYMBOL];\n  }\n\n  return null;\n}\n\n/**\n * Parameters for creating an editor in a context.\n */\ntype Attrs = {\n  context: ContextWatchdog<Context>;\n  creator: EditorCreator;\n  config: EditorConfig;\n};\n\n/**\n * Descriptor for an editor context.\n */\ntype EditorContextDescriptor = {\n  state: 'available' | 'unavailable';\n  editorContextId: string;\n  context: ContextWatchdog<Context>;\n};\n\n/**\n * Type representing an Editor creator with a create method.\n */\ntype EditorCreator = {\n  create: (...args: any) => Promise<Editor>;\n};\n","import type { Editor, MultiRootEditor } from 'ckeditor5';\n\n/**\n * Check if passed editor is multiroot editor.\n */\nexport function isMultirootEditorInstance(editor: Editor): editor is MultiRootEditor {\n  return 'addEditable' in editor.ui;\n}\n","import type { EditorType } from '../typings';\n\n/**\n * Checks if the given editor type is one of the single editing-like editors.\n *\n * @param editorType - The type of the editor to check.\n * @returns `true` if the editor type is 'inline', 'classic', or 'balloon', otherwise `false`.\n */\nexport function isSingleRootEditor(editorType: EditorType): boolean {\n  return ['inline', 'classic', 'balloon', 'decoupled'].includes(editorType);\n}\n","import type { EditorType } from '../typings';\n\n/**\n * Returns the constructor for the specified CKEditor5 editor type.\n *\n * @param type - The type of the editor to load.\n * @returns A promise that resolves to the editor constructor.\n */\nexport async function loadEditorConstructor(type: EditorType) {\n  const PKG = await import('ckeditor5');\n\n  const editorMap = {\n    inline: PKG.InlineEditor,\n    balloon: PKG.BalloonEditor,\n    classic: PKG.ClassicEditor,\n    decoupled: PKG.DecoupledEditor,\n    multiroot: PKG.MultiRootEditor,\n  } as const;\n\n  const EditorConstructor = editorMap[type];\n\n  if (!EditorConstructor) {\n    throw new Error(`Unsupported editor type: ${type}`);\n  }\n\n  return EditorConstructor;\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport type { CanBePromise } from '../../types';\n\ntype PluginReader = () => CanBePromise<PluginConstructor>;\n\n/**\n * Registry for custom CKEditor plugins.\n * Allows registration and retrieval of custom plugins that can be used alongside built-in plugins.\n */\nexport class CustomEditorPluginsRegistry {\n  static readonly the = new CustomEditorPluginsRegistry();\n\n  /**\n   * Map of registered custom plugins.\n   */\n  private readonly plugins = new Map<string, PluginReader>();\n\n  /**\n   * Private constructor to enforce singleton pattern.\n   */\n  private constructor() {}\n\n  /**\n   * Registers a custom plugin for the CKEditor.\n   *\n   * @param name The name of the plugin.\n   * @param reader The plugin reader function that returns the plugin constructor.\n   * @returns A function to unregister the plugin.\n   */\n  register(name: string, reader: PluginReader): () => void {\n    if (this.plugins.has(name)) {\n      throw new Error(`Plugin with name \"${name}\" is already registered.`);\n    }\n\n    this.plugins.set(name, reader);\n\n    return this.unregister.bind(this, name);\n  }\n\n  /**\n   * Removes a custom plugin by its name.\n   *\n   * @param name The name of the plugin to unregister.\n   * @throws Will throw an error if the plugin is not registered.\n   */\n  unregister(name: string): void {\n    if (!this.plugins.has(name)) {\n      throw new Error(`Plugin with name \"${name}\" is not registered.`);\n    }\n\n    this.plugins.delete(name);\n  }\n\n  /**\n   * Removes all custom editor plugins.\n   * This is useful for cleanup in tests or when reloading plugins.\n   */\n  unregisterAll(): void {\n    this.plugins.clear();\n  }\n\n  /**\n   * Retrieves a custom plugin by its name.\n   *\n   * @param name The name of the plugin.\n   * @returns The plugin constructor or undefined if not found.\n   */\n  async get(name: string): Promise<PluginConstructor | undefined> {\n    const reader = this.plugins.get(name);\n\n    return reader?.();\n  }\n\n  /**\n   * Checks if a plugin with the given name is registered.\n   *\n   * @param name The name of the plugin.\n   * @returns `true` if the plugin is registered, `false` otherwise.\n   */\n  has(name: string): boolean {\n    return this.plugins.has(name);\n  }\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport type { EditorPlugin } from '../typings';\n\nimport { CustomEditorPluginsRegistry } from '../custom-editor-plugins';\n\n/**\n * Loads CKEditor plugins from base and premium packages.\n * First tries to load from the base 'ckeditor5' package, then falls back to 'ckeditor5-premium-features'.\n *\n * @param plugins - Array of plugin names to load\n * @returns Promise that resolves to an array of loaded Plugin instances\n * @throws Error if a plugin is not found in either package\n */\nexport async function loadEditorPlugins(plugins: EditorPlugin[]): Promise<LoadedPlugins> {\n  const basePackage = await import('ckeditor5');\n  let premiumPackage: Record<string, any> | null = null;\n\n  const loaders = plugins.map(async (plugin) => {\n    // Let's first try to load the plugin from the base package.\n    // Coverage is disabled due to Vitest issues with mocking dynamic imports.\n\n    // Try custom plugins before checking packages.\n    const customPlugin = await CustomEditorPluginsRegistry.the.get(plugin);\n\n    if (customPlugin) {\n      return customPlugin;\n    }\n\n    // If not found, try to load from the base package.\n    const { [plugin]: basePkgImport } = basePackage as Record<string, unknown>;\n\n    if (basePkgImport) {\n      return basePkgImport as PluginConstructor;\n    }\n\n    // Plugin not found in base package, try premium package.\n    if (!premiumPackage) {\n      try {\n        premiumPackage = await import('ckeditor5-premium-features');\n        /* v8 ignore next 6 */\n      }\n      catch (error) {\n        console.error(`Failed to load premium package: ${error}`);\n      }\n    }\n\n    /* v8 ignore next */\n    const { [plugin]: premiumPkgImport } = premiumPackage || {};\n\n    if (premiumPkgImport) {\n      return premiumPkgImport as PluginConstructor;\n    }\n\n    // Plugin not found in either package, throw an error.\n    throw new Error(`Plugin \"${plugin}\" not found in base or premium packages.`);\n  });\n\n  return {\n    loadedPlugins: await Promise.all(loaders),\n    hasPremium: !!premiumPackage,\n  };\n}\n\n/**\n * Type representing the loaded plugins and whether premium features are available.\n */\ntype LoadedPlugins = {\n  loadedPlugins: PluginConstructor<any>[];\n  hasPremium: boolean;\n};\n","/**\n * Loads all required translations for the editor based on the language configuration.\n *\n * @param language - The language configuration object containing UI and content language codes.\n * @param language.ui - The UI language code.\n * @param language.content - The content language code.\n * @param hasPremium - Whether premium features are enabled and premium translations should be loaded.\n * @returns A promise that resolves to an array of loaded translation objects.\n */\nexport async function loadAllEditorTranslations(\n  language: { ui: string; content: string; },\n  hasPremium: boolean,\n) {\n  const translations = [language.ui, language.content];\n  const loadedTranslations = await Promise.all(\n    [\n      loadEditorPkgTranslations('ckeditor5', translations),\n      /* v8 ignore next */\n      hasPremium && loadEditorPkgTranslations('ckeditor5-premium-features', translations),\n    ].filter(pkg => !!pkg),\n  )\n    .then(translations => translations.flat());\n\n  return loadedTranslations;\n}\n\n/**\n * Loads the editor translations for the given languages.\n *\n * Make sure this function is properly compiled and bundled in self hosted environments!\n *\n * @param pkg - The package to load translations from ('ckeditor5' or 'ckeditor5-premium-features').\n * @param translations - The list of language codes to load translations for.\n * @returns A promise that resolves to an array of loaded translation packs.\n */\nasync function loadEditorPkgTranslations(\n  pkg: EditorPkgName,\n  translations: string[],\n) {\n  /* v8 ignore next */\n  return await Promise.all(\n    translations\n      .filter(lang => lang !== 'en') // 'en' is the default language, no need to load it.\n      .map(async (lang) => {\n        const pack = await loadEditorTranslation(pkg, lang);\n\n        /* v8 ignore next */\n        return pack?.default ?? pack;\n      })\n      .filter(Boolean),\n  );\n}\n\n/**\n * Type representing the package name for CKEditor 5.\n */\ntype EditorPkgName = 'ckeditor5' | 'ckeditor5-premium-features';\n\n/**\n * Load translation for CKEditor 5\n * @param pkg - Package type: 'ckeditor5' or 'premium'\n * @param lang - Language code (e.g., 'pl', 'en', 'de')\n * @returns Translation object or null if failed\n */\nasync function loadEditorTranslation(pkg: EditorPkgName, lang: string): Promise<any> {\n  try {\n    /* v8 ignore next 2 */\n    if (pkg === 'ckeditor5') {\n      /* v8 ignore next 79 */\n      switch (lang) {\n        case 'af': return await import('ckeditor5/translations/af.js');\n        case 'ar': return await import('ckeditor5/translations/ar.js');\n        case 'ast': return await import('ckeditor5/translations/ast.js');\n        case 'az': return await import('ckeditor5/translations/az.js');\n        case 'bg': return await import('ckeditor5/translations/bg.js');\n        case 'bn': return await import('ckeditor5/translations/bn.js');\n        case 'bs': return await import('ckeditor5/translations/bs.js');\n        case 'ca': return await import('ckeditor5/translations/ca.js');\n        case 'cs': return await import('ckeditor5/translations/cs.js');\n        case 'da': return await import('ckeditor5/translations/da.js');\n        case 'de': return await import('ckeditor5/translations/de.js');\n        case 'de-ch': return await import('ckeditor5/translations/de-ch.js');\n        case 'el': return await import('ckeditor5/translations/el.js');\n        case 'en': return await import('ckeditor5/translations/en.js');\n        case 'en-au': return await import('ckeditor5/translations/en-au.js');\n        case 'en-gb': return await import('ckeditor5/translations/en-gb.js');\n        case 'eo': return await import('ckeditor5/translations/eo.js');\n        case 'es': return await import('ckeditor5/translations/es.js');\n        case 'es-co': return await import('ckeditor5/translations/es-co.js');\n        case 'et': return await import('ckeditor5/translations/et.js');\n        case 'eu': return await import('ckeditor5/translations/eu.js');\n        case 'fa': return await import('ckeditor5/translations/fa.js');\n        case 'fi': return await import('ckeditor5/translations/fi.js');\n        case 'fr': return await import('ckeditor5/translations/fr.js');\n        case 'gl': return await import('ckeditor5/translations/gl.js');\n        case 'gu': return await import('ckeditor5/translations/gu.js');\n        case 'he': return await import('ckeditor5/translations/he.js');\n        case 'hi': return await import('ckeditor5/translations/hi.js');\n        case 'hr': return await import('ckeditor5/translations/hr.js');\n        case 'hu': return await import('ckeditor5/translations/hu.js');\n        case 'hy': return await import('ckeditor5/translations/hy.js');\n        case 'id': return await import('ckeditor5/translations/id.js');\n        case 'it': return await import('ckeditor5/translations/it.js');\n        case 'ja': return await import('ckeditor5/translations/ja.js');\n        case 'jv': return await import('ckeditor5/translations/jv.js');\n        case 'kk': return await import('ckeditor5/translations/kk.js');\n        case 'km': return await import('ckeditor5/translations/km.js');\n        case 'kn': return await import('ckeditor5/translations/kn.js');\n        case 'ko': return await import('ckeditor5/translations/ko.js');\n        case 'ku': return await import('ckeditor5/translations/ku.js');\n        case 'lt': return await import('ckeditor5/translations/lt.js');\n        case 'lv': return await import('ckeditor5/translations/lv.js');\n        case 'ms': return await import('ckeditor5/translations/ms.js');\n        case 'nb': return await import('ckeditor5/translations/nb.js');\n        case 'ne': return await import('ckeditor5/translations/ne.js');\n        case 'nl': return await import('ckeditor5/translations/nl.js');\n        case 'no': return await import('ckeditor5/translations/no.js');\n        case 'oc': return await import('ckeditor5/translations/oc.js');\n        case 'pl': return await import('ckeditor5/translations/pl.js');\n        case 'pt': return await import('ckeditor5/translations/pt.js');\n        case 'pt-br': return await import('ckeditor5/translations/pt-br.js');\n        case 'ro': return await import('ckeditor5/translations/ro.js');\n        case 'ru': return await import('ckeditor5/translations/ru.js');\n        case 'si': return await import('ckeditor5/translations/si.js');\n        case 'sk': return await import('ckeditor5/translations/sk.js');\n        case 'sl': return await import('ckeditor5/translations/sl.js');\n        case 'sq': return await import('ckeditor5/translations/sq.js');\n        case 'sr': return await import('ckeditor5/translations/sr.js');\n        case 'sr-latn': return await import('ckeditor5/translations/sr-latn.js');\n        case 'sv': return await import('ckeditor5/translations/sv.js');\n        case 'th': return await import('ckeditor5/translations/th.js');\n        case 'tk': return await import('ckeditor5/translations/tk.js');\n        case 'tr': return await import('ckeditor5/translations/tr.js');\n        case 'tt': return await import('ckeditor5/translations/tt.js');\n        case 'ug': return await import('ckeditor5/translations/ug.js');\n        case 'uk': return await import('ckeditor5/translations/uk.js');\n        case 'ur': return await import('ckeditor5/translations/ur.js');\n        case 'uz': return await import('ckeditor5/translations/uz.js');\n        case 'vi': return await import('ckeditor5/translations/vi.js');\n        case 'zh': return await import('ckeditor5/translations/zh.js');\n        case 'zh-cn': return await import('ckeditor5/translations/zh-cn.js');\n        default:\n          console.warn(`Language ${lang} not found in ckeditor5 translations`);\n          return null;\n      }\n    }\n    /* v8 ignore next 79 */\n    else {\n      // Premium features translations\n      switch (lang) {\n        case 'af': return await import('ckeditor5-premium-features/translations/af.js');\n        case 'ar': return await import('ckeditor5-premium-features/translations/ar.js');\n        case 'ast': return await import('ckeditor5-premium-features/translations/ast.js');\n        case 'az': return await import('ckeditor5-premium-features/translations/az.js');\n        case 'bg': return await import('ckeditor5-premium-features/translations/bg.js');\n        case 'bn': return await import('ckeditor5-premium-features/translations/bn.js');\n        case 'bs': return await import('ckeditor5-premium-features/translations/bs.js');\n        case 'ca': return await import('ckeditor5-premium-features/translations/ca.js');\n        case 'cs': return await import('ckeditor5-premium-features/translations/cs.js');\n        case 'da': return await import('ckeditor5-premium-features/translations/da.js');\n        case 'de': return await import('ckeditor5-premium-features/translations/de.js');\n        case 'de-ch': return await import('ckeditor5-premium-features/translations/de-ch.js');\n        case 'el': return await import('ckeditor5-premium-features/translations/el.js');\n        case 'en': return await import('ckeditor5-premium-features/translations/en.js');\n        case 'en-au': return await import('ckeditor5-premium-features/translations/en-au.js');\n        case 'en-gb': return await import('ckeditor5-premium-features/translations/en-gb.js');\n        case 'eo': return await import('ckeditor5-premium-features/translations/eo.js');\n        case 'es': return await import('ckeditor5-premium-features/translations/es.js');\n        case 'es-co': return await import('ckeditor5-premium-features/translations/es-co.js');\n        case 'et': return await import('ckeditor5-premium-features/translations/et.js');\n        case 'eu': return await import('ckeditor5-premium-features/translations/eu.js');\n        case 'fa': return await import('ckeditor5-premium-features/translations/fa.js');\n        case 'fi': return await import('ckeditor5-premium-features/translations/fi.js');\n        case 'fr': return await import('ckeditor5-premium-features/translations/fr.js');\n        case 'gl': return await import('ckeditor5-premium-features/translations/gl.js');\n        case 'gu': return await import('ckeditor5-premium-features/translations/gu.js');\n        case 'he': return await import('ckeditor5-premium-features/translations/he.js');\n        case 'hi': return await import('ckeditor5-premium-features/translations/hi.js');\n        case 'hr': return await import('ckeditor5-premium-features/translations/hr.js');\n        case 'hu': return await import('ckeditor5-premium-features/translations/hu.js');\n        case 'hy': return await import('ckeditor5-premium-features/translations/hy.js');\n        case 'id': return await import('ckeditor5-premium-features/translations/id.js');\n        case 'it': return await import('ckeditor5-premium-features/translations/it.js');\n        case 'ja': return await import('ckeditor5-premium-features/translations/ja.js');\n        case 'jv': return await import('ckeditor5-premium-features/translations/jv.js');\n        case 'kk': return await import('ckeditor5-premium-features/translations/kk.js');\n        case 'km': return await import('ckeditor5-premium-features/translations/km.js');\n        case 'kn': return await import('ckeditor5-premium-features/translations/kn.js');\n        case 'ko': return await import('ckeditor5-premium-features/translations/ko.js');\n        case 'ku': return await import('ckeditor5-premium-features/translations/ku.js');\n        case 'lt': return await import('ckeditor5-premium-features/translations/lt.js');\n        case 'lv': return await import('ckeditor5-premium-features/translations/lv.js');\n        case 'ms': return await import('ckeditor5-premium-features/translations/ms.js');\n        case 'nb': return await import('ckeditor5-premium-features/translations/nb.js');\n        case 'ne': return await import('ckeditor5-premium-features/translations/ne.js');\n        case 'nl': return await import('ckeditor5-premium-features/translations/nl.js');\n        case 'no': return await import('ckeditor5-premium-features/translations/no.js');\n        case 'oc': return await import('ckeditor5-premium-features/translations/oc.js');\n        case 'pl': return await import('ckeditor5-premium-features/translations/pl.js');\n        case 'pt': return await import('ckeditor5-premium-features/translations/pt.js');\n        case 'pt-br': return await import('ckeditor5-premium-features/translations/pt-br.js');\n        case 'ro': return await import('ckeditor5-premium-features/translations/ro.js');\n        case 'ru': return await import('ckeditor5-premium-features/translations/ru.js');\n        case 'si': return await import('ckeditor5-premium-features/translations/si.js');\n        case 'sk': return await import('ckeditor5-premium-features/translations/sk.js');\n        case 'sl': return await import('ckeditor5-premium-features/translations/sl.js');\n        case 'sq': return await import('ckeditor5-premium-features/translations/sq.js');\n        case 'sr': return await import('ckeditor5-premium-features/translations/sr.js');\n        case 'sr-latn': return await import('ckeditor5-premium-features/translations/sr-latn.js');\n        case 'sv': return await import('ckeditor5-premium-features/translations/sv.js');\n        case 'th': return await import('ckeditor5-premium-features/translations/th.js');\n        case 'tk': return await import('ckeditor5-premium-features/translations/tk.js');\n        case 'tr': return await import('ckeditor5-premium-features/translations/tr.js');\n        case 'tt': return await import('ckeditor5-premium-features/translations/tt.js');\n        case 'ug': return await import('ckeditor5-premium-features/translations/ug.js');\n        case 'uk': return await import('ckeditor5-premium-features/translations/uk.js');\n        case 'ur': return await import('ckeditor5-premium-features/translations/ur.js');\n        case 'uz': return await import('ckeditor5-premium-features/translations/uz.js');\n        case 'vi': return await import('ckeditor5-premium-features/translations/vi.js');\n        case 'zh': return await import('ckeditor5-premium-features/translations/zh.js');\n        case 'zh-cn': return await import('ckeditor5-premium-features/translations/zh-cn.js');\n        default:\n          console.warn(`Language ${lang} not found in premium translations`);\n          return await import('ckeditor5-premium-features/translations/en.js'); // fallback to English\n      }\n    }\n    /* v8 ignore next 7 */\n  }\n  catch (error) {\n    console.error(`Failed to load translation for ${pkg}/${lang}:`, error);\n    return null;\n  }\n}\n","import type { Translations } from 'ckeditor5';\n\nimport type { EditorCustomTranslationsDictionary } from '../typings';\n\nimport { mapObjectValues } from '../../../shared';\n\n/**\n * This function takes a custom translations object and maps it to the format expected by CKEditor5.\n * Each translation dictionary is wrapped in an object with a `dictionary` key.\n *\n * @param translations - The custom translations to normalize.\n * @returns A normalized translations object suitable for CKEditor5.\n */\nexport function normalizeCustomTranslations(translations: EditorCustomTranslationsDictionary): Translations {\n  return mapObjectValues(translations, dictionary => ({\n    dictionary,\n  }));\n}\n","import type { EditorId } from '../typings';\n\n/**\n * Queries all editable elements within a specific editor instance.\n *\n * @param editorId The ID of the editor to query.\n * @returns An object mapping editable names to their corresponding elements and initial values.\n */\nexport function queryAllEditorEditables(editorId: EditorId): Record<string, EditableItem> {\n  const iterator = document.querySelectorAll<HTMLElement>(\n    [\n      `[data-cke-editor-id=\"${editorId}\"][data-cke-editable-root-name]`,\n      '[data-cke-editable-root-name]:not([data-cke-editor-id])',\n    ]\n      .join(', '),\n  );\n\n  const acc = (\n    Array\n      .from(iterator)\n      .reduce<Record<string, EditableItem>>((acc, element) => {\n        const name = element.getAttribute('data-cke-editable-root-name');\n        const initialValue = element.getAttribute('data-cke-editable-initial-value') || '';\n        const content = element.querySelector('[data-cke-editable-content]') as HTMLElement;\n\n        if (!name || !content) {\n          return acc;\n        }\n\n        return {\n          ...acc,\n          [name]: {\n            content,\n            initialValue,\n          },\n        };\n      }, Object.create({}))\n  );\n\n  const rootEditorElement = document.querySelector<HTMLElement>(`[phx-hook=\"CKEditor5\"][id=\"${editorId}\"]`);\n\n  if (!rootEditorElement) {\n    return acc;\n  }\n\n  const initialRootEditableValue = rootEditorElement.getAttribute('data-cke-initial-value') || '';\n  const contentElement = rootEditorElement.querySelector<HTMLElement>(`#${editorId}_editor `);\n  const currentMain = acc['main'];\n\n  if (currentMain) {\n    return {\n      ...acc,\n      main: {\n        ...currentMain,\n        initialValue: currentMain.initialValue || initialRootEditableValue,\n      },\n    };\n  }\n\n  if (contentElement) {\n    return {\n      ...acc,\n      main: {\n        content: contentElement,\n        initialValue: initialRootEditableValue,\n      },\n    };\n  }\n\n  return acc;\n}\n\n/**\n * Type representing an editable item within an editor.\n */\nexport type EditableItem = {\n  content: HTMLElement;\n  initialValue: string;\n};\n","import type { WatchdogConfig } from 'ckeditor5';\n\n/**\n * List of supported CKEditor5 editor types.\n */\nexport const EDITOR_TYPES = ['inline', 'classic', 'balloon', 'decoupled', 'multiroot'] as const;\n\n/**\n * Represents a unique identifier for a CKEditor5 editor instance.\n * This is typically the ID of the HTML element that the editor is attached to.\n */\nexport type EditorId = string;\n\n/**\n * Defines editor type supported by CKEditor5. It must match list of available\n * editor types specified in `preset/parser.ex` file.\n */\nexport type EditorType = (typeof EDITOR_TYPES)[number];\n\n/**\n * Represents a CKEditor5 plugin as a string identifier.\n */\nexport type EditorPlugin = string;\n\n/**\n * Configuration object for CKEditor5 editor instance.\n */\nexport type EditorConfig = {\n  /**\n   * Array of plugin identifiers to be loaded by the editor.\n   */\n  plugins: EditorPlugin[];\n\n  /**\n   * Other configuration options are flexible and can be any key-value pairs.\n   */\n  [key: string]: any;\n};\n\n/**\n * Represents a license key for CKEditor5.\n */\nexport type EditorLicense = {\n  key: string;\n};\n\n/**\n * Configuration object for the CKEditor5 hook.\n */\nexport type EditorPreset = {\n  /**\n   * The type of CKEditor5 editor to use.\n   * Must be one of the predefined types: 'inline', 'classic', 'balloon', 'decoupled', or 'multiroot'.\n   */\n  type: EditorType;\n\n  /**\n   * The configuration object for the CKEditor5 editor.\n   * This should match the configuration expected by CKEditor5.\n   */\n  config: EditorConfig;\n\n  /**\n   * Editor watchdog configuration.\n   */\n  watchdog: WatchdogConfig | null;\n\n  /**\n   * The license key for CKEditor5.\n   * This is required for using CKEditor5 with a valid license.\n   */\n  license: EditorLicense;\n\n  /**\n   * Optional custom translations for the editor.\n   * This allows for localization of the editor interface.\n   */\n  customTranslations?: {\n    dictionary: EditorCustomTranslationsDictionary;\n  };\n};\n\n/**\n * Represents custom translations for the editor.\n */\nexport type EditorCustomTranslationsDictionary = {\n  [language: string]: {\n    [key: string]: string | ReadonlyArray<string>;\n  };\n};\n","import type { EditorPreset } from '../typings';\n\nimport { deepCamelCaseKeys } from '../../../shared/deep-camel-case-keys';\nimport { EDITOR_TYPES } from '../typings';\n\n/**\n * Reads the hook configuration from the element's attribute and parses it as JSON.\n *\n * @param element - The HTML element that contains the hook configuration.\n * @returns The parsed hook configuration.\n */\nexport function readPresetOrThrow(element: HTMLElement): EditorPreset {\n  const attributeValue = element.getAttribute('data-cke-preset');\n\n  if (!attributeValue) {\n    throw new Error('CKEditor5 hook requires a \"cke-preset\" attribute on the element.');\n  }\n\n  const { type, config, license, watchdog, ...rest } = JSON.parse(attributeValue);\n\n  if (!type || !config || !license) {\n    throw new Error('CKEditor5 hook configuration must include \"editor\", \"config\", and \"license\" properties.');\n  }\n\n  if (!EDITOR_TYPES.includes(type)) {\n    throw new Error(`Invalid editor type: ${type}. Must be one of: ${EDITOR_TYPES.join(', ')}.`);\n  }\n\n  return {\n    type,\n    license,\n    watchdog,\n    config: deepCamelCaseKeys(config),\n    customTranslations: rest.customTranslations || rest.custom_translations,\n  };\n}\n","/**\n * Resolves element references in configuration object.\n * Looks for objects with { $element: \"selector\" } format and replaces them with actual DOM elements.\n *\n * @param obj - Configuration object to process\n * @returns Processed configuration object with resolved element references\n */\nexport function resolveEditorConfigElementReferences<T>(obj: T): T {\n  if (!obj || typeof obj !== 'object') {\n    return obj;\n  }\n\n  if (Array.isArray(obj)) {\n    return obj.map(item => resolveEditorConfigElementReferences(item)) as T;\n  }\n\n  const anyObj = obj as any;\n\n  if (anyObj.$element && typeof anyObj.$element === 'string') {\n    const element = document.querySelector(anyObj.$element);\n\n    if (!element) {\n      console.warn(`Element not found for selector: ${anyObj.$element}`);\n    }\n\n    return (element || null) as T;\n  }\n\n  const result = Object.create(null);\n\n  for (const [key, value] of Object.entries(obj)) {\n    result[key] = resolveEditorConfigElementReferences(value);\n  }\n\n  return result as T;\n}\n","import type { Translations } from 'ckeditor5';\n\n/**\n * Resolves translation references in a configuration object.\n *\n * The configuration may contain objects with the form `{ $translation: \"some.key\" }`.\n * These are replaced with the actual string from the provided translations map.\n *\n * The function will walk the provided object recursively, handling arrays and\n * nested objects. Primitive values are returned as-is. If a translation key is\n * not present in the map, a warning is logged and `null` is returned for that\n * value.\n *\n * @param translations - An array of CKEditor `Translations` objects. Each translation\n *                       pack will be searched in order for the requested key, and the\n *                       first matching value will be returned. This mirrors the format\n *                       returned by `loadAllEditorTranslations` and simplifies the\n *                       caller's API.\n * @param language - Language identifier to look up in the packs. Only this locale\n *                   will be consulted, ensuring that keys from other languages are\n *                   ignored even if they appear earlier in the array.\n * @param obj - Configuration object to process\n * @returns Processed configuration object with resolved translations.\n */\nexport function resolveEditorConfigTranslations<T>(\n  translations: Translations[],\n  language: string,\n  obj: T,\n): T {\n  if (!obj || typeof obj !== 'object') {\n    return obj;\n  }\n\n  if (Array.isArray(obj)) {\n    return obj.map(item => resolveEditorConfigTranslations(translations, language, item)) as T;\n  }\n\n  const anyObj = obj as any;\n\n  if (anyObj.$translation && typeof anyObj.$translation === 'string') {\n    const key: string = anyObj.$translation;\n    const value = getTranslationValue(translations, key, language);\n\n    if (value === undefined) {\n      console.warn(`Translation not found for key: ${key}`);\n    }\n\n    return (value !== undefined ? value : null) as T;\n  }\n\n  const result = Object.create(null);\n\n  for (const [key, value] of Object.entries(obj)) {\n    result[key] = resolveEditorConfigTranslations(translations, language, value);\n  }\n\n  return result as T;\n}\n\n/**\n * Look up a translation value inside the provided map or array of CKEditor packs.\n */\nfunction getTranslationValue(\n  translations: Translations[],\n  key: string,\n  language: string,\n): string | ReadonlyArray<string> | undefined {\n  for (const pack of translations) {\n    const langData = pack[language];\n\n    if (langData?.dictionary && key in langData.dictionary) {\n      return langData.dictionary[key] as string | ReadonlyArray<string>;\n    }\n  }\n\n  return undefined;\n}\n","import type { Editor } from 'ckeditor5';\n\n/**\n * Sets the height of the editable area in the CKEditor instance.\n *\n * @param instance - The CKEditor instance to modify.\n * @param height - The height in pixels to set for the editable area.\n */\nexport function setEditorEditableHeight(instance: Editor, height: number): void {\n  const { editing } = instance;\n\n  editing.view.change((writer) => {\n    writer.setStyle('height', `${height}px`, editing.view.document.getRoot()!);\n  });\n}\n","import type { Editor, EditorWatchdog, WatchdogConfig } from 'ckeditor5';\n\nconst EDITOR_WATCHDOG_SYMBOL = Symbol.for('elixir-editor-watchdog');\n\n/**\n * Wraps an editor factory with a watchdog for automatic recovery.\n * The factory is invoked on each (re)start, so configuration is rebuilt every time.\n *\n * @param factory Async function that creates and returns an Editor instance.\n * @param watchdogConfig Configuration of the watchdog.\n * @returns The watchdog instance.\n */\nexport async function wrapWithWatchdog(factory: () => Promise<Editor>, watchdogConfig: WatchdogConfig | null) {\n  const { EditorWatchdog } = await import('ckeditor5');\n\n  const watchdog = new EditorWatchdog(null, watchdogConfig ?? {\n    crashNumberLimit: 10,\n    minimumNonErrorTimePeriod: 5000,\n  });\n\n  watchdog.setCreator(async () => {\n    const editor = await factory();\n\n    (editor as any)[EDITOR_WATCHDOG_SYMBOL] = watchdog;\n\n    return editor;\n  });\n\n  return watchdog;\n}\n\n/**\n * Unwraps the EditorWatchdog from the editor instance.\n */\nexport function unwrapEditorWatchdog(editor: Editor): EditorWatchdog | null {\n  if (EDITOR_WATCHDOG_SYMBOL in editor) {\n    return (editor as any)[EDITOR_WATCHDOG_SYMBOL] as EditorWatchdog;\n  }\n\n  return null;\n}\n","import type { Context, ContextWatchdog } from 'ckeditor5';\n\nimport { AsyncRegistry } from '../../shared';\n\n/**\n * It provides a way to register contexts and execute callbacks on them when they are available.\n */\nexport class ContextsRegistry extends AsyncRegistry<ContextWatchdog<Context>> {\n  static readonly the = new ContextsRegistry();\n}\n","import type { ContextConfig } from '../typings';\n\nimport { deepCamelCaseKeys } from '../../../shared/deep-camel-case-keys';\n\n/**\n * Reads the hook configuration from the element's attribute and parses it as JSON.\n *\n * @param element - The HTML element that contains the hook configuration.\n * @returns The parsed hook configuration.\n */\nexport function readContextConfigOrThrow(element: HTMLElement): ContextConfig {\n  const attributeValue = element.getAttribute('data-cke-context');\n\n  if (!attributeValue) {\n    throw new Error('CKEditor5 hook requires a \"data-cke-context\" attribute on the element.');\n  }\n\n  const { config, ...rest } = JSON.parse(attributeValue);\n\n  return {\n    config: deepCamelCaseKeys(config),\n    customTranslations: rest.customTranslations || rest.custom_translations,\n    watchdogConfig: rest.watchdogConfig || rest.watchdog_config,\n  };\n}\n","import type { Context, ContextWatchdog } from 'ckeditor5';\n\nimport { ClassHook, isEmptyObject, makeHook } from '../../shared';\nimport {\n  loadAllEditorTranslations,\n  loadEditorPlugins,\n  normalizeCustomTranslations,\n  resolveEditorConfigElementReferences,\n  resolveEditorConfigTranslations,\n} from '../editor/utils';\nimport { ContextsRegistry } from './contexts-registry';\nimport { readContextConfigOrThrow } from './utils';\n\n/**\n * Context hook for Phoenix LiveView. It allows you to create contexts for collaboration editors.\n */\nclass ContextHookImpl extends ClassHook {\n  /**\n   * The promise that resolves to the context instance.\n   */\n  private contextPromise: Promise<ContextWatchdog<Context>> | null = null;\n\n  /**\n   * Attributes for the context instance.\n   */\n  private get attrs() {\n    const get = (attr: string) => this.el.getAttribute(attr) || null;\n    const value = {\n      id: this.el.id,\n      config: readContextConfigOrThrow(this.el),\n      language: {\n        ui: get('data-cke-language') || 'en',\n        content: get('data-cke-content-language') || 'en',\n      },\n    };\n\n    Object.defineProperty(this, 'attrs', {\n      value,\n      writable: false,\n      configurable: false,\n      enumerable: true,\n    });\n\n    return value;\n  }\n\n  /**\n   * Mounts the context component.\n   */\n  override async mounted() {\n    const { id, language } = this.attrs;\n    const { customTranslations, watchdogConfig, config: { plugins, ...config } } = this.attrs.config;\n    const { loadedPlugins, hasPremium } = await loadEditorPlugins(plugins ?? []);\n\n    // Mix custom translations with loaded translations.\n    const loadedTranslations = await loadAllEditorTranslations(language, hasPremium);\n    const mixedTranslations = [\n      ...loadedTranslations,\n      normalizeCustomTranslations(customTranslations?.dictionary || {}),\n    ]\n      .filter(translations => !isEmptyObject(translations));\n\n    // Construct parsed config. First resolve DOM element references in the provided configuration.\n    let resolvedConfig = resolveEditorConfigElementReferences(config);\n\n    // Then resolve translation references in the provided configuration, using the mixed translations.\n    resolvedConfig = resolveEditorConfigTranslations([...mixedTranslations].reverse(), language.ui, resolvedConfig);\n\n    // Initialize context.\n    this.contextPromise = (async () => {\n      const { ContextWatchdog, Context } = await import('ckeditor5');\n      const instance = new ContextWatchdog(Context, {\n        crashNumberLimit: 10,\n        ...watchdogConfig,\n      });\n\n      await instance.create({\n        ...resolvedConfig,\n        language,\n        plugins: loadedPlugins,\n        ...mixedTranslations.length && {\n          translations: mixedTranslations,\n        },\n      });\n\n      instance.on('itemError', (...args) => {\n        console.error('Context item error:', ...args);\n      });\n\n      return instance;\n    })();\n\n    const context = await this.contextPromise;\n\n    if (!this.isBeingDestroyed()) {\n      ContextsRegistry.the.register(id, context);\n    }\n  }\n\n  /**\n   * Destroys the context component. Unmounts root from the editor.\n   */\n  override async destroyed() {\n    const { id } = this.attrs;\n\n    // Let's hide the element during destruction to prevent flickering.\n    this.el.style.display = 'none';\n\n    // Let's wait for the mounted promise to resolve before proceeding with destruction.\n    try {\n      const context = await this.contextPromise;\n\n      await context?.destroy();\n    }\n    finally {\n      this.contextPromise = null;\n\n      if (ContextsRegistry.the.hasItem(id)) {\n        ContextsRegistry.the.unregister(id);\n      }\n    }\n  }\n}\n\n/**\n * Type guard to check if an element is a context hook HTMLElement.\n */\nfunction isContextHookHTMLElement(el: HTMLElement): el is HTMLElement & { instance: ContextHookImpl; } {\n  return el.hasAttribute('data-cke-context');\n}\n\n/**\n * Gets the nearest context hook parent element.\n */\nfunction getNearestContextParent(el: HTMLElement) {\n  let parent: HTMLElement | null = el;\n\n  while (parent) {\n    if (isContextHookHTMLElement(parent)) {\n      return parent;\n    }\n\n    parent = parent.parentElement;\n  }\n\n  return null;\n}\n\n/**\n * Gets the nearest context parent element as a promise.\n */\nexport async function getNearestContextParentPromise(el: HTMLElement): Promise<ContextWatchdog<Context> | null> {\n  const parent = getNearestContextParent(el);\n\n  if (!parent) {\n    return null;\n  }\n\n  return ContextsRegistry.the.waitFor(parent.id);\n}\n\n/**\n * Phoenix LiveView hook for CKEditor 5 context elements.\n */\nexport const ContextHook = makeHook(ContextHookImpl);\n","import type { Editor } from 'ckeditor5';\n\n/**\n * Creates a function that synchronizes root attributes on the given editor root.\n *\n * The returned function tracks which attributes were set by itself and will only\n * remove attributes it previously managed. This avoids interfering with other\n * consumers that may also change attributes on the same root.\n *\n * @param editor The editor instance containing the root to manage.\n * @param rootName The name of the root to manage attributes on.\n * @returns A function that can be called with the desired set of attributes to apply them to the root.\n *          Calling the function with `null` or an empty object will clear all attributes previously set by it.\n */\nexport function createRootAttributesUpdater(editor: Editor, rootName: string): RootAttributesUpdater {\n  const managedAttrs = new Set<string>();\n\n  return (rootAttributes?: Record<string, unknown> | null): boolean => {\n    let updated = false;\n\n    editor.model.enqueueChange({ isUndoable: false }, (writer) => {\n      const root = editor.model.document.getRoot(rootName);\n\n      /* v8 ignore next if -- @preserve */\n      if (!root) {\n        return;\n      }\n\n      // Remove previously managed attributes that are no longer requested.\n      for (const key of managedAttrs) {\n        if (rootAttributes && key in rootAttributes) {\n          continue;\n        }\n\n        writer.removeAttribute(key, root);\n        managedAttrs.delete(key);\n        updated = true;\n      }\n\n      // Apply or overwrite requested attributes.\n      for (const [key, value] of Object.entries(rootAttributes ?? {})) {\n        writer.setAttribute(key, value, root);\n        managedAttrs.add(key);\n        updated = true;\n      }\n    });\n\n    return updated;\n  };\n}\n\nexport type RootAttributesUpdater = (rootAttributes?: Record<string, unknown> | null) => boolean;\n","import type { FileLoader, PluginConstructor, UploadAdapter } from 'ckeditor5';\n\nimport { getCsrfToken } from '../../../shared';\n\n/**\n * Creates a PhoenixUploadAdapter plugin class for CKEditor 5.\n * This adapter handles image uploads to a Phoenix backend endpoint.\n */\nexport async function createPhoenixUploadAdapterPlugin(): Promise<PluginConstructor> {\n  const { Plugin, FileRepository } = await import('ckeditor5');\n\n  return class PhoenixUploadAdapter extends Plugin {\n    /**\n     * The name of the plugin.\n     */\n    static get pluginName() {\n      return 'PhoenixUploadAdapter' as const;\n    }\n\n    static get requires() {\n      return [FileRepository];\n    }\n\n    /**\n     * Initializes the plugin.\n     */\n    public init(): void {\n      const { editor } = this;\n      const { plugins, config } = editor;\n      const uploadUrl = config.get('phoenixUpload.url');\n\n      if (!uploadUrl) {\n        return;\n      }\n\n      // Check if we should enable this adapter\n      if (\n        plugins.has('SimpleUploadAdapter')\n        || plugins.has('Base64UploadAdapter')\n        || plugins.has('CKFinderUploadAdapter')\n      ) {\n        return;\n      }\n\n      // Register the upload adapter\n      const fileRepository = plugins.get(FileRepository);\n\n      fileRepository.createUploadAdapter = (loader: FileLoader) => new Adapter(loader, uploadUrl);\n    }\n  };\n}\n\ndeclare module 'ckeditor5' {\n  // eslint-disable-next-line ts/consistent-type-definitions\n  interface EditorConfig {\n    /**\n     * Configuration for Phoenix upload adapter.\n     */\n    phoenixUpload?: {\n      /**\n       * The URL to which files will be uploaded.\n       */\n      url: string;\n    };\n  }\n}\n\n/**\n * Upload adapter that handles communication with Phoenix backend.\n */\nclass Adapter implements UploadAdapter {\n  private readonly loader: FileLoader;\n\n  private readonly uploadUrl: string;\n\n  private abortController: AbortController | null = null;\n\n  constructor(loader: FileLoader, uploadUrl: string) {\n    this.loader = loader;\n    this.uploadUrl = uploadUrl;\n  }\n\n  /**\n   * Starts the upload process.\n   */\n  public async upload(): Promise<{ default: string; }> {\n    const file = (await this.loader.file)!;\n\n    this.abortController = new AbortController();\n\n    const data = new FormData();\n\n    data.append('file', file);\n\n    // Attempt to track progress if the file size is known, though fetch doesn't support\n    // upload progress events natively.\n    if (file.size) {\n      this.loader.uploadTotal = file.size;\n      this.loader.uploaded = 0;\n    }\n\n    const headers: HeadersInit = {};\n    const csrfToken = getCsrfToken();\n\n    if (csrfToken) {\n      headers['X-CSRF-Token'] = csrfToken;\n    }\n\n    try {\n      const response = await fetch(this.uploadUrl, {\n        method: 'POST',\n        headers,\n        body: data,\n        signal: this.abortController.signal,\n      });\n\n      if (!response.ok) {\n        let errorMessage = 'Couldn\\'t upload file!';\n\n        try {\n          const errorData = await response.json();\n          if (errorData?.error?.message) {\n            errorMessage = errorData.error.message;\n          }\n        }\n        catch { /* ignore */ }\n\n        throw new Error(errorMessage);\n      }\n\n      this.loader.uploaded = this.loader.uploadTotal!;\n\n      const result = await response.json();\n\n      return {\n        default: result.url,\n      };\n    }\n    /* v8 ignore next 7 */\n    catch (error: any) {\n      if (error.name === 'AbortError') {\n        throw error;\n      }\n\n      throw error.message || 'Couldn\\'t upload file!';\n    }\n  }\n\n  /**\n   * Aborts the upload process.\n   */\n  /* v8 ignore next 4 */\n  public abort(): void {\n    this.abortController?.abort();\n    this.abortController = null;\n  }\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport { debounce } from '../../../shared';\n\n/**\n * Creates a SyncEditorWithInput plugin class.\n */\nexport async function createSyncEditorWithInputPlugin(\n  {\n    editorId,\n    saveDebounceMs,\n  }: Attrs,\n): Promise<PluginConstructor> {\n  const { Plugin } = await import('ckeditor5');\n\n  return class SyncEditorWithInput extends Plugin {\n    /**\n     * The input element to synchronize with.\n     */\n    private input: HTMLInputElement | null = null;\n\n    /**\n     * The form element reference for cleanup.\n     */\n    private form: HTMLFormElement | null = null;\n\n    /**\n     * The name of the plugin.\n     */\n    static get pluginName() {\n      return 'SyncEditorWithInput' as const;\n    }\n\n    /**\n     * Initializes the plugin.\n     */\n    public afterInit(): void {\n      const { editor } = this;\n\n      this.input = document.getElementById(`${editorId}_input`) as HTMLInputElement | null;\n\n      if (!this.input) {\n        return;\n      }\n\n      // Setup handlers.\n      editor.model.document.on('change:data', debounce(saveDebounceMs, () => this.sync()));\n      editor.once('ready', this.sync);\n\n      // Setup form integration.\n      this.form = this.input.closest('form');\n      this.form?.addEventListener('submit', this.sync);\n    }\n\n    /**\n     * Synchronizes the editor's content with the input field.\n     */\n    private sync = (): void => {\n      const newValue = this.editor.getData();\n\n      this.input!.value = newValue;\n      this.input!.dispatchEvent(new Event('input', { bubbles: true }));\n    };\n\n    /**\n     * Destroys the plugin.\n     */\n    public override destroy(): void {\n      if (this.form) {\n        this.form.removeEventListener('submit', this.sync);\n      }\n\n      this.input = null;\n      this.form = null;\n    }\n  };\n}\n\ntype Attrs = {\n  editorId: string;\n  saveDebounceMs: number;\n};\n","import type { Editor, PluginConstructor } from 'ckeditor5';\n\nimport type { EditorId } from '../typings';\n\nimport { debounce, isNil, shallowEqual } from '../../../shared';\n\nconst SUPPRESS_PHOENIX_SYNC_KEY = Symbol('suppress-phoenix-sync');\n\n/**\n * Creates a SyncEditorWithPhoenix plugin class. It's not two way binding, but\n * it allows you to push editor data to Phoenix on change, focus and blur events, and\n * also to set editor data from Phoenix.\n *\n * In order to debug two-way binding, check `EditorRootValueSentinel` component, which is used\n * to assign the value to the editor based on modification of the Elixir component's assigns.\n *\n * @param options The options for the plugin, including editorId, debounce time, events to listen to, and pushEvent/handleEvent functions.\n * @returns A Promise that resolves to the SyncEditorWithPhoenix plugin constructor.\n */\nexport async function createSyncEditorWithPhoenixPlugin(options: Attrs): Promise<PluginConstructor> {\n  const { Plugin } = await import('ckeditor5');\n  const { editorId, saveDebounceMs, events, pushEvent, handleEvent } = options;\n\n  return class SyncEditorWithPhoenix extends Plugin {\n    /**\n     * The name of the plugin.\n     */\n    static get pluginName() {\n      return 'SyncEditorWithPhoenix' as const;\n    }\n\n    /**\n     * Initializes the plugin.\n     */\n    public init(): void {\n      const { editor } = this;\n\n      if (events.change) {\n        this.setupTypingContentPush();\n      }\n\n      if (events.blur) {\n        this.setupEventPush('blur');\n      }\n\n      if (events.focus) {\n        this.setupEventPush('focus');\n      }\n\n      if (events.ready) {\n        this.editor.once('ready', () => {\n          pushEvent('ckeditor5:ready', {\n            editorId,\n            data: getEditorRootsValues(editor),\n          });\n        });\n      }\n\n      handleEvent('ckeditor5:set-data', ({ editorId: targetId, data }) => {\n        if (isNil(targetId) || targetId === editorId) {\n          editor.setData(data);\n        }\n      });\n    }\n\n    /**\n     * Setups the content push event for the editor.\n     */\n    private setupTypingContentPush() {\n      const { editor } = this;\n\n      let lastValue: Record<string, string> | null = null;\n      let isDestroyed = false;\n\n      const pushContentChange = () => {\n        if (isDestroyed) {\n          return;\n        }\n\n        const newValue = getEditorRootsValues(editor);\n\n        if (!lastValue || !shallowEqual(lastValue, newValue)) {\n          pushEvent(\n            'ckeditor5:change',\n            {\n              editorId,\n              data: newValue,\n            },\n          );\n\n          lastValue = newValue;\n        }\n      };\n\n      const debouncedPushContentChange = debounce(saveDebounceMs, pushContentChange);\n\n      editor.model.document.on('change:data', debounce(10, (evt) => {\n        /* v8 ignore next 4 */\n        if (releasePhoenixSyncSuppressLock(evt)) {\n          lastValue = null;\n          return;\n        }\n\n        if (editor.ui.focusTracker.isFocused) {\n          debouncedPushContentChange();\n        }\n        else {\n          pushContentChange();\n        }\n      }));\n\n      editor.once('ready', pushContentChange);\n      editor.once('destroy', () => {\n        isDestroyed = true;\n      });\n    }\n\n    /**\n     * Setups the event push for the editor.\n     */\n    private setupEventPush(eventType: 'focus' | 'blur') {\n      const { editor } = this;\n\n      const pushEventCallback = () => {\n        const { isFocused } = editor.ui.focusTracker;\n        const currentType = isFocused ? 'focus' : 'blur';\n\n        if (currentType !== eventType) {\n          return;\n        }\n\n        pushEvent(\n          `ckeditor5:${eventType}`,\n          {\n            editorId,\n            data: getEditorRootsValues(editor),\n          },\n        );\n      };\n\n      editor.ui.focusTracker.on('change:isFocused', pushEventCallback);\n    }\n  };\n}\n\ntype Attrs = {\n  editorId: EditorId;\n  saveDebounceMs: number;\n  events: {\n    change: boolean;\n    focus: boolean;\n    blur: boolean;\n    ready: boolean;\n  };\n  pushEvent: (event: string, payload: any) => void;\n  handleEvent: (event: string, callback: (payload: any) => void) => void;\n};\n\n/**\n * Gets the values of the editor's roots.\n *\n * @param editor The CKEditor instance.\n * @returns An object mapping root names to their content.\n */\nfunction getEditorRootsValues(editor: Editor) {\n  const roots = editor.model.document.getRootNames();\n\n  return roots.reduce<Record<string, string>>((acc, rootName) => {\n    acc[rootName] = editor.getData({ rootName });\n    return acc;\n  }, Object.create({}));\n}\n\n/**\n * Drops lock that informs plugin that data should not be synced with Phoenix.\n *\n * @param evt Event instance.\n * @returns `true` if event suppressed phoenix lock.\n */\nfunction releasePhoenixSyncSuppressLock(evt: any) {\n  const lock = evt[SUPPRESS_PHOENIX_SYNC_KEY];\n\n  delete evt[SUPPRESS_PHOENIX_SYNC_KEY];\n\n  return !!lock;\n}\n\n/**\n * Marks pending `change:data` as non-syncable with Phoenix.\n *\n * @param editor Editor instance.\n */\nexport function skipPendingPhoenixDataChangeSync(editor: Editor) {\n  let ignore = false;\n\n  const callback = (evt: any) => {\n    if (!ignore) {\n      evt[SUPPRESS_PHOENIX_SYNC_KEY] = true;\n    }\n  };\n\n  editor.model.document.once('change:data', callback, { priority: 'highest' });\n\n  return () => {\n    ignore = true;\n    editor.model.document.off('change:data', callback);\n  };\n}\n","import type { Editor } from 'ckeditor5';\n\nimport type { RootAttributesUpdater } from './root-attributes-updater';\n\nimport { parseJsonIfPresent } from '../../shared';\nimport { skipPendingPhoenixDataChangeSync } from '../editor/plugins';\nimport { createRootAttributesUpdater } from './root-attributes-updater';\n\nexport class RootValueSentinel {\n  /**\n   * The DOM element being observed for attribute changes.\n   */\n  private el: HTMLElement;\n\n  /**\n   * The name of the specific root in a multi-root editor setup.\n   */\n  private readonly rootName: string;\n\n  /**\n   * The name of the HTML attribute storing the value.\n   */\n  private readonly valueAttrName: string;\n\n  /**\n   * The name of the HTML attribute storing the root attributes.\n   */\n  private readonly rootAttrsAttrName: string;\n\n  /**\n   * A flag indicating whether the sentinel has been destroyed, used to prevent operations after cleanup.\n   */\n  private isDestroyed: boolean = false;\n\n  /**\n   * Cleanup callbacks to be executed when the sentinel is destroyed.\n   */\n  private cleanupCallbacks: Array<() => void> = [];\n\n  /**\n   * The editor instance.\n   */\n  private editor: Editor;\n\n  /**\n   * When the editor is focused and the value attribute changes, we want to wait until it blurs to\n   * avoid disrupting the user while typing. This variable holds the pending value that should be applied\n   * once the editor blurs. It is set to null when there is no pending value or when the user makes changes in the editor,\n   * indicating that the pending value should be discarded.\n   */\n  private pendingValue: string | null = null;\n\n  /**\n   * Cache the previous value to avoid reacting to attribute changes that don't actually change the value.\n   * This can happen when the parent LiveView re-renders and sets the same value again, which would otherwise cause an\n   * unnecessary update in the editor.\n   */\n  private previousValue: string | null = null;\n\n  /**\n   * Updater created once the editor is ready. Tracks which root attributes\n   * were applied by this sentinel so it can clean them up independently of\n   * other consumers.\n   */\n  private attrsUpdater: RootAttributesUpdater | null = null;\n\n  /**\n   * When the hook is mounted, we will wait for the editor to be registered and then set the initial value of the root.\n   * Accepts an options object to configure element, identifiers, and custom attribute names.\n   */\n  constructor(\n    {\n      el,\n      editor,\n      rootName,\n      valueAttrName = 'data-cke-value',\n      rootAttrsAttrName = 'data-cke-root-attrs',\n    }: RootValueSentinelOptions,\n  ) {\n    this.el = el;\n    this.editor = editor;\n    this.rootName = rootName;\n    this.valueAttrName = valueAttrName;\n    this.rootAttrsAttrName = rootAttrsAttrName;\n\n    const { value } = this.attrs;\n\n    this.previousValue = value;\n    this.setupSyncHandlers(editor, this.rootName);\n  }\n\n  /**\n   * Helper to read and parse attributes from the element.\n   * It uses dynamically provided attribute names.\n   */\n  private get attrs() {\n    return {\n      rootAttributes: parseJsonIfPresent<Record<string, unknown>>(this.el.getAttribute(this.rootAttrsAttrName)),\n      value: this.el.getAttribute(this.valueAttrName)!,\n    };\n  }\n\n  /**\n   * When the value attribute changes, we want to update the editor root value.\n   * However, if the editor is focused, we want to wait until it blurs to avoid disrupting the user while typing.\n   */\n  async updated() {\n    const { editor } = this;\n    const { value, rootAttributes } = this.attrs;\n\n    if (!editor || editor.state === 'destroyed' || this.isDestroyed) {\n      return;\n    }\n\n    // Synchronize root attributes on every update, regardless of value changes.\n    let unmountLock: VoidFunction = () => {};\n\n    editor.model.enqueueChange({ isUndoable: false }, () => {\n      let updated = this.attrsUpdater?.(rootAttributes);\n\n      // React only if the value attribute actually changed.\n      if (value !== this.previousValue) {\n        this.previousValue = value;\n\n        if (editor.ui.focusTracker.isFocused) {\n          this.pendingValue = value;\n        }\n        else {\n          this.setRootValue(editor, this.rootName, value);\n          updated = true;\n        }\n      }\n\n      if (updated) {\n        unmountLock = skipPendingPhoenixDataChangeSync(editor);\n      }\n    });\n\n    unmountLock();\n  }\n\n  /**\n   * Sets up focus-aware sync handlers on the editor.\n   * Registers cleanup via onBeforeDestroy.\n   */\n  private setupSyncHandlers(editor: Editor, rootName: string) {\n    this.attrsUpdater = createRootAttributesUpdater(editor, rootName);\n    this.attrsUpdater(this.attrs.rootAttributes);\n\n    const onDataChange = () => {\n      this.pendingValue = null;\n    };\n\n    const onFocusChange = () => {\n      if (!editor.ui.focusTracker.isFocused && this.pendingValue !== null) {\n        this.setRootValue(editor, rootName, this.pendingValue);\n        this.pendingValue = null;\n      }\n    };\n\n    editor.model.document.on('change:data', onDataChange);\n    editor.ui.focusTracker.on('change:isFocused', onFocusChange);\n\n    this.cleanupCallbacks.push(() => {\n      editor.model.document.off('change:data', onDataChange);\n      editor.ui.focusTracker.off('change:isFocused', onFocusChange);\n    });\n  }\n\n  /**\n   * Sets the value of a specific root in the editor.\n   */\n  private setRootValue(editor: Editor, rootName: string, value: string) {\n    const current = editor.getData({ rootName });\n\n    if (current !== value) {\n      editor.setData({ [rootName]: value });\n    }\n  }\n\n  /**\n   * Disconnects the observer and cleans up editor event listeners.\n   * This should be called manually when the element is removed from the DOM.\n   */\n  public destroy() {\n    this.isDestroyed = true;\n\n    this.cleanupCallbacks.forEach(cleanup => cleanup());\n    this.cleanupCallbacks = [];\n  }\n}\n\nexport type RootValueSentinelOptions = {\n  /**\n   * The DOM element being observed for attribute changes.\n   */\n  el: HTMLElement;\n\n  /**\n   * Editor instance.\n   */\n  editor: Editor;\n\n  /**\n   * The name of the specific root in a multi-root editor setup.\n   */\n  rootName: string;\n\n  /**\n   * The name of the HTML attribute storing the value. Defaults to 'data-cke-value'.\n   */\n  valueAttrName?: string;\n\n  /**\n   * The name of the HTML attribute storing the root attributes. Defaults to 'data-cke-root-attrs'.\n   */\n  rootAttrsAttrName?: string;\n};\n","import type { Editor } from 'ckeditor5';\n\nimport { AsyncRegistry } from '../../shared/async-registry';\n\n/**\n * It provides a way to register editors and execute callbacks on them when they are available.\n */\nexport class EditorsRegistry extends AsyncRegistry<Editor> {\n  static readonly the = new EditorsRegistry();\n}\n","import type { EditorId } from './typings';\nimport type { EditableItem } from './utils';\n\nimport { isEmptyObject, parseIntIfNotNull, waitFor } from '../../shared';\nimport { ClassHook, makeHook } from '../../shared/hook';\nimport { ContextsRegistry, getNearestContextParentPromise } from '../context';\nimport { RootValueSentinel } from '../root-value-sentinel';\nimport { EditorsRegistry } from './editors-registry';\nimport {\n  createPhoenixUploadAdapterPlugin,\n  createSyncEditorWithInputPlugin,\n  createSyncEditorWithPhoenixPlugin,\n} from './plugins';\nimport {\n  assignEditorRootsToConfig,\n  cleanupOrphanEditorElements,\n  createEditorInContext,\n  isSingleRootEditor,\n  loadAllEditorTranslations,\n  loadEditorConstructor,\n  loadEditorPlugins,\n  normalizeCustomTranslations,\n  queryAllEditorEditables,\n  readPresetOrThrow,\n  resolveEditorConfigElementReferences,\n  resolveEditorConfigTranslations,\n  setEditorEditableHeight,\n  unwrapEditorContext,\n  unwrapEditorWatchdog,\n  wrapWithWatchdog,\n} from './utils';\n\n/**\n * Editor hook for Phoenix LiveView.\n *\n * This class is a hook that can be used with Phoenix LiveView to integrate\n * the CKEditor 5 WYSIWYG editor.\n */\nclass EditorHookImpl extends ClassHook {\n  /**\n   * The sentinel instance responsible for tracking and updating root values and attributes\n   * for single-root editors.\n   */\n  private sentinel: RootValueSentinel | null = null;\n\n  /**\n   * Attributes for the editor instance.\n   */\n  private get attrs() {\n    const { el } = this;\n    const get = el.getAttribute.bind(el);\n    const has = el.hasAttribute.bind(el);\n\n    const value = {\n      editorId: get('id')!,\n      contextId: get('data-cke-context-id'),\n      preset: readPresetOrThrow(el),\n      editableHeight: parseIntIfNotNull(get('data-cke-editable-height')),\n      watchdog: has('data-cke-watchdog'),\n      events: {\n        change: has('data-cke-change-event'),\n        blur: has('data-cke-blur-event'),\n        focus: has('data-cke-focus-event'),\n        ready: has('data-cke-ready-event'),\n      },\n      saveDebounceMs: parseIntIfNotNull(get('data-cke-save-debounce-ms')) ?? 400,\n      language: {\n        ui: get('data-cke-language') || 'en',\n        content: get('data-cke-content-language') || 'en',\n      },\n    };\n\n    Object.defineProperty(this, 'attrs', {\n      value,\n      writable: false,\n      configurable: false,\n      enumerable: true,\n    });\n\n    return value;\n  }\n\n  /**\n   * Mounts the editor component.\n   */\n  override async mounted() {\n    const { editorId } = this.attrs;\n\n    EditorsRegistry.the.resetErrors(editorId);\n\n    try {\n      // Run stuff that have to be initialized once, even if editor might restart.\n      const editor = await this.createEditor();\n\n      // Do not even try to broadcast about the registration of the editor if hook was immediately destroyed.\n      /* v8 ignore next 3 */\n      if (this.isBeingDestroyed()) {\n        return;\n      }\n\n      // Run some stuff that have to be reinitialized every-time editor is being restarted.\n      const unmountEffect = EditorsRegistry.the.mountEffect(editorId, (editor) => {\n        // Enforce deregistration of the editor when it's being destroyed by watchdog.\n        editor.once('destroy', () => {\n          // Let's handle case when watchdog (or context watchdog) destroyed editor \"externally\"\n          // user might also manually kill the editor using `.destroy()` method.\n          // Keep pending callbacks though. Someone might register new callbacks just before calling `.destroy()`.\n          EditorsRegistry.the.unregister(editorId, false);\n        }, { priority: 'highest' });\n\n        this.sentinel = new RootValueSentinel({\n          editor,\n          el: this.el,\n          rootName: 'main',\n          valueAttrName: 'data-cke-initial-value',\n          rootAttrsAttrName: 'data-cke-root-attrs',\n        });\n\n        return () => {\n          this.sentinel?.destroy();\n          this.sentinel = null;\n        };\n      });\n\n      this.onBeforeDestroy(async () => {\n        // If for some reason editor not fired `destroy`, enforce deregistration.\n        EditorsRegistry.the.unregister(editorId);\n        unmountEffect();\n\n        const editorContext = unwrapEditorContext(editor);\n        const watchdog = unwrapEditorWatchdog(editor);\n\n        if (editorContext) {\n          // If context is present, make sure it's not in unmounting phase, as it'll kill the editors.\n          // If it's being destroyed, don't do anything, as the context will take care of it.\n          if (editorContext.state !== 'unavailable') {\n            await editorContext.context.remove(editorContext.editorContextId);\n          }\n        }\n        else if (watchdog) {\n          await watchdog.destroy();\n        }\n        else {\n          await editor.destroy();\n        }\n      });\n\n      EditorsRegistry.the.register(editorId, editor);\n    }\n    catch (error: any) {\n      console.error(error);\n      EditorsRegistry.the.error(editorId, error);\n    }\n\n    return this;\n  }\n\n  /**\n   * Watch attributes changes and sync value if something changed.\n   */\n  override async updated() {\n    this.sentinel?.updated();\n  }\n\n  /**\n   * Destroys editor component.\n   */\n  override async destroyed() {\n    this.el.style.display = 'none';\n  }\n\n  /**\n   * Creates the CKEditor instance.\n   */\n  private async createEditor() {\n    const {\n      preset,\n      editorId,\n      contextId,\n      editableHeight,\n      events,\n      saveDebounceMs,\n      language,\n      watchdog: useWatchdog,\n    } = this.attrs;\n\n    const { customTranslations, type, license, config: { plugins, ...config } } = preset;\n\n    const Constructor = await loadEditorConstructor(type);\n    const context = await (\n      contextId\n        ? ContextsRegistry.the.waitFor(contextId)\n        : getNearestContextParentPromise(this.el)\n    );\n\n    /**\n     * Builds the full editor configuration and creates the editor instance.\n     */\n    const buildAndCreateEditor = async () => {\n      const { loadedPlugins, hasPremium } = await loadEditorPlugins(plugins);\n\n      // Sync `main` root (usually in single root editors) with hidden input.\n      if (isSingleRootEditor(type)) {\n        loadedPlugins.push(\n          await createSyncEditorWithInputPlugin({\n            editorId,\n            saveDebounceMs,\n          }),\n        );\n      }\n\n      // Add phoenix integration plugins.\n      loadedPlugins.push(\n        ...await Promise.all([\n          createSyncEditorWithPhoenixPlugin(\n            {\n              editorId,\n              saveDebounceMs,\n              events,\n              pushEvent: this.pushEvent.bind(this),\n              handleEvent: this.handleEvent.bind(this),\n            },\n          ),\n          createPhoenixUploadAdapterPlugin(),\n        ]),\n      );\n\n      // Mix custom translations with loaded translations.\n      const loadedTranslations = await loadAllEditorTranslations(language, hasPremium);\n      const mixedTranslations = [\n        ...loadedTranslations,\n        normalizeCustomTranslations(customTranslations?.dictionary || {}),\n      ]\n        .filter(translations => !isEmptyObject(translations));\n\n      // Query all editable elements along with their initial values in one pass.\n      let editables = queryAllEditorEditables(editorId);\n      const requiredRoots = Object.keys(editables);\n\n      if (isSingleRootEditor(type)) {\n        requiredRoots.push('main');\n      }\n\n      if (!checkIfAllRootsArePresent(editables, requiredRoots)) {\n        editables = await waitForAllRootsToBePresent(editorId, requiredRoots);\n      }\n\n      // Do some postprocessing on received configuration.\n      let resolvedConfig = {\n        ...config,\n        licenseKey: license.key,\n        plugins: loadedPlugins,\n        language,\n        ...mixedTranslations.length && {\n          translations: mixedTranslations,\n        },\n      };\n\n      resolvedConfig = resolveEditorConfigElementReferences(resolvedConfig);\n      resolvedConfig = resolveEditorConfigTranslations([...mixedTranslations].reverse(), language.ui, resolvedConfig);\n      resolvedConfig = assignEditorRootsToConfig(Constructor, editables, resolvedConfig);\n\n      const editor = await (async () => {\n        if (!context) {\n          return Constructor.create(resolvedConfig);\n        }\n\n        const result = await createEditorInContext({\n          context,\n          creator: Constructor,\n          config: resolvedConfig,\n        });\n\n        return result.editor;\n      })();\n\n      if (isSingleRootEditor(type) && editableHeight) {\n        setEditorEditableHeight(editor, editableHeight);\n      }\n\n      return editor;\n    };\n\n    // Do not use editor specific watchdog if context is attached, as the context is by default protected.\n    if (useWatchdog && !context) {\n      const watchdog = await wrapWithWatchdog(buildAndCreateEditor, preset.watchdog);\n\n      // Cleanup editor registry before restart of the editor (restart might fail too).\n      watchdog.on('error', (_, { causesRestart }) => {\n        if (causesRestart) {\n          const prevEditor = EditorsRegistry.the.getItem(editorId);\n\n          /* v8 ignore next 3 */\n          if (prevEditor) {\n            cleanupOrphanEditorElements(prevEditor);\n\n            EditorsRegistry.the.unregister(editorId);\n          }\n        }\n      });\n\n      // Register new instance after editor restarted.\n      watchdog.on('restart', () => {\n        const newInstance = watchdog.editor!;\n\n        EditorsRegistry.the.register(editorId, newInstance);\n      });\n\n      // Start the watchdog — internally calls buildAndCreateEditor via setCreator.\n      await watchdog.create({});\n\n      return watchdog.editor!;\n    }\n\n    return buildAndCreateEditor();\n  }\n}\n\n/**\n * Checks if all required root elements are present in the editables map.\n *\n * @param editables The editables map keyed by root name.\n * @param requiredRoots The list of required root names.\n * @returns True if all required roots are present, false otherwise.\n */\nfunction checkIfAllRootsArePresent(editables: Record<string, EditableItem>, requiredRoots: string[]): boolean {\n  return requiredRoots.every(rootId => editables[rootId]);\n}\n\n/**\n * Waits for all required root elements to be present in the DOM.\n *\n * @param editorId The editor's ID.\n * @param requiredRoots The list of required root names.\n * @returns A promise that resolves to the map of editable items.\n */\nasync function waitForAllRootsToBePresent(\n  editorId: EditorId,\n  requiredRoots: string[],\n): Promise<Record<string, EditableItem>> {\n  return waitFor(\n    () => {\n      const editables = queryAllEditorEditables(editorId);\n\n      if (!checkIfAllRootsArePresent(editables, requiredRoots)) {\n        throw new Error(\n          'It looks like not all required root elements are present yet.\\n'\n          + '* If you want to wait for them, ensure they are registered before editor initialization.\\n'\n          + '* If you want lazy initialize roots, consider removing root values from the `initialData` config '\n          + 'and assign initial data in editable components.\\n'\n          + `Missing roots: ${requiredRoots.filter(rootId => !editables[rootId]).join(', ')}.`,\n        );\n      }\n\n      return editables;\n    },\n    { timeOutAfter: 2000, retryAfter: 100 },\n  );\n}\n\n/**\n * Phoenix LiveView hook for CKEditor 5.\n */\nexport const EditorHook = makeHook(EditorHookImpl);\n","import type { DecoupledEditor, MultiRootEditor } from 'ckeditor5';\n\nimport { ClassHook, debounce, makeHook } from '../shared';\nimport { isMultirootEditorInstance } from './editor';\nimport { EditorsRegistry } from './editor/editors-registry';\nimport { RootValueSentinel } from './root-value-sentinel';\n\n/**\n * Editable hook for Phoenix LiveView. It allows you to create editables for multi-root editors.\n */\nclass EditableHookImpl extends ClassHook {\n  /**\n   * The sentinel instance responsible for tracking and updating root values and attributes.\n   */\n  private sentinel: RootValueSentinel | null = null;\n\n  /**\n   * Attributes for the editable instance.\n   */\n  private get attrs() {\n    const value = {\n      editableId: this.el.getAttribute('id')!,\n      editorId: this.el.getAttribute('data-cke-editor-id') || null,\n      rootName: this.el.getAttribute('data-cke-editable-root-name')!,\n      initialValue: this.el.getAttribute('data-cke-editable-initial-value') || '',\n    };\n\n    Object.defineProperty(this, 'attrs', {\n      value,\n      writable: false,\n      configurable: false,\n      enumerable: true,\n    });\n\n    return value;\n  }\n\n  /**\n   * Mounts the editable component.\n   */\n  override mounted() {\n    const { editableId, editorId, rootName, initialValue } = this.attrs;\n\n    const unmountEffect = EditorsRegistry.the.mountEffect(editorId, (editor: MultiRootEditor | DecoupledEditor) => {\n      const contentElement = this.el.querySelector('[data-cke-editable-content]') as HTMLElement;\n\n      /* v8 ignore next 3 */\n      if (this.isBeingDestroyed()) {\n        return;\n      }\n\n      const input = this.el.querySelector<HTMLInputElement>(`#${editableId}_input`);\n\n      if (isMultirootEditorInstance(editor) && !editor.model.document.getRoot(rootName)) {\n        const { ui, editing } = editor;\n\n        editor.addRoot(rootName, {\n          isUndoable: false,\n          initialData: initialValue,\n        });\n\n        const editable = ui.view.createEditable(rootName, contentElement);\n\n        ui.addEditable(editable);\n        editing.view.forceRender();\n      }\n\n      this.sentinel = new RootValueSentinel({\n        el: this.el,\n        editor,\n        rootName,\n        valueAttrName: 'data-cke-editable-initial-value',\n        rootAttrsAttrName: 'data-cke-editable-root-attrs',\n      });\n\n      const unsyncInput = input ? syncEditorRootToInput(input, editor, rootName) : null;\n\n      return () => {\n        unsyncInput?.();\n\n        this.sentinel?.destroy();\n        this.sentinel = null;\n\n        if (editor.state !== 'destroyed') {\n          const root = editor.model.document.getRoot(rootName);\n\n          if (root && isMultirootEditorInstance(editor)) {\n            if (editor.ui.view.editables[rootName]) {\n              editor.detachEditable(root);\n            }\n\n            if (root.isAttached()) {\n              editor.detachRoot(rootName, false);\n            }\n          }\n        }\n      };\n    });\n\n    // Let's hide the element during destruction to prevent flickering.\n    this.onBeforeDestroy(() => {\n      this.el.style.display = 'none';\n      unmountEffect();\n    });\n  }\n\n  /**\n   * Watch attributes changes and sync value if something changed.\n   */\n  override async updated() {\n    this.sentinel?.updated();\n  }\n}\n\n/**\n * Phoenix LiveView hook for CKEditor 5 editable elements.\n */\nexport const EditableHook = makeHook(EditableHookImpl);\n\n/**\n * Synchronizes the editor's root data to the corresponding input element.\n * This is used to keep the input value in sync with the editor's content.\n *\n * @param input - The input element to synchronize with the editor.\n * @param editor - The CKEditor instance.\n * @param rootName - The name of the root to synchronize.\n */\nfunction syncEditorRootToInput(\n  input: HTMLInputElement,\n  editor: MultiRootEditor | DecoupledEditor,\n  rootName: string,\n) {\n  const sync = () => {\n    input.value = editor.getData({ rootName });\n  };\n\n  const debouncedSync = debounce(200, sync);\n\n  editor.model.document.on('change:data', debouncedSync);\n  sync();\n\n  return () => {\n    editor.model.document.off('change:data', debouncedSync);\n  };\n}\n","import { ClassHook, makeHook } from '../shared';\nimport { EditorsRegistry } from './editor/editors-registry';\n\n/**\n * UI Part hook for Phoenix LiveView. It allows you to create UI parts for multi-root editors.\n */\nclass UIPartHookImpl extends ClassHook {\n  /**\n   * Attributes for the editable instance.\n   */\n  private get attrs() {\n    const value = {\n      editorId: this.el.getAttribute('data-cke-editor-id') || null,\n      name: this.el.getAttribute('data-cke-ui-part-name')!,\n    };\n\n    Object.defineProperty(this, 'attrs', {\n      value,\n      writable: false,\n      configurable: false,\n      enumerable: true,\n    });\n\n    return value;\n  }\n\n  /**\n   * Mounts the UI part component.\n   */\n  override mounted() {\n    const { editorId, name } = this.attrs;\n\n    const unmountEffect = EditorsRegistry.the.mountEffect(editorId, (editor) => {\n      /* v8 ignore next 3 */\n      if (this.isBeingDestroyed()) {\n        return;\n      }\n\n      const { ui } = editor;\n\n      const uiViewName = mapUIPartView(name);\n      const uiPart = (ui.view as any)[uiViewName!];\n\n      if (!uiPart) {\n        console.error(`Unknown UI part name: \"${name}\". Supported names are \"toolbar\" and \"menubar\".`);\n        return;\n      }\n\n      this.el.appendChild(uiPart.element);\n\n      return () => {\n        this.el.innerHTML = '';\n      };\n    });\n\n    // Let's hide the element during destruction to prevent flickering.\n    this.onBeforeDestroy(() => {\n      this.el.style.display = 'none';\n      unmountEffect();\n    });\n  }\n}\n\n/**\n * Maps the UI part name to the corresponding view in the editor.\n */\nfunction mapUIPartView(name: string): string | null {\n  switch (name) {\n    case 'toolbar':\n      return 'toolbar';\n\n    case 'menubar':\n      return 'menuBarView';\n\n    default:\n      return null;\n  }\n}\n\n/**\n * Phoenix LiveView hook for CKEditor 5 UI parts.\n */\nexport const UIPartHook = makeHook(UIPartHookImpl);\n","import { ContextHook } from './context';\nimport { EditableHook } from './editable';\nimport { EditorHook } from './editor';\nimport { UIPartHook } from './ui-part';\n\nexport const Hooks = {\n  CKEditor5: EditorHook,\n  CKEditable: EditableHook,\n  CKUIPart: UIPartHook,\n  CKContext: ContextHook,\n};\n"],"names":["areMapsEqual","map1","map2","key","value","AsyncRegistry","id","onSuccess","onError","item","error","resolve","reject","pending","onMount","cleanup","mountedItem","unmounted","unwatch","items","newCleanup","err","callback","initializationErrors","resetPendingCallbacks","promises","fn","watcher","camelCase","str","_","c","m","debounce","delay","timeoutId","args","isPlainObject","proto","deepCamelCaseKeys","input","result","getCsrfToken","metaTag","match","ClassHook","cb","makeHook","constructor","instance","event","payload","selector","isEmptyObject","obj","isNil","mapObjectValues","mapper","mappedEntries","parseIntIfNotNull","parsed","parseJsonIfPresent","json","shallowEqual","objA","objB","keysA","keysB","uid","waitFor","timeOutAfter","retryAfter","startTime","lastError","timeoutTimerId","tick","assignEditorRootsToConfig","Editor","editables","config","isClassicEditor","allRootsKeys","rootsConfig","acc","rootKey","mappedConfig","cleanupOrphanEditorElements","editor","uiElements","uiElement","removeOrReset","bodyCollectionContainer","editingView","domRoot","element","CONTEXT_EDITOR_WATCHDOG_SYMBOL","createEditorInContext","context","creator","editorContextId","contextDescriptor","originalDestroy","unwrapEditorContext","isMultirootEditorInstance","isSingleRootEditor","editorType","loadEditorConstructor","type","PKG","EditorConstructor","CustomEditorPluginsRegistry","name","reader","loadEditorPlugins","plugins","basePackage","premiumPackage","loaders","plugin","customPlugin","basePkgImport","premiumPkgImport","loadAllEditorTranslations","language","hasPremium","translations","loadEditorPkgTranslations","pkg","lang","pack","loadEditorTranslation","normalizeCustomTranslations","dictionary","queryAllEditorEditables","editorId","iterator","initialValue","content","rootEditorElement","initialRootEditableValue","contentElement","currentMain","EDITOR_TYPES","readPresetOrThrow","attributeValue","license","watchdog","rest","resolveEditorConfigElementReferences","anyObj","resolveEditorConfigTranslations","getTranslationValue","langData","setEditorEditableHeight","height","editing","writer","EDITOR_WATCHDOG_SYMBOL","wrapWithWatchdog","factory","watchdogConfig","EditorWatchdog","unwrapEditorWatchdog","ContextsRegistry","readContextConfigOrThrow","ContextHookImpl","get","attr","customTranslations","loadedPlugins","mixedTranslations","resolvedConfig","ContextWatchdog","Context","isContextHookHTMLElement","el","getNearestContextParent","parent","getNearestContextParentPromise","ContextHook","createRootAttributesUpdater","rootName","managedAttrs","rootAttributes","updated","root","createPhoenixUploadAdapterPlugin","Plugin","FileRepository","uploadUrl","fileRepository","loader","Adapter","file","data","headers","csrfToken","response","errorMessage","errorData","createSyncEditorWithInputPlugin","saveDebounceMs","newValue","SUPPRESS_PHOENIX_SYNC_KEY","createSyncEditorWithPhoenixPlugin","options","events","pushEvent","handleEvent","getEditorRootsValues","targetId","lastValue","isDestroyed","pushContentChange","debouncedPushContentChange","evt","releasePhoenixSyncSuppressLock","eventType","pushEventCallback","isFocused","lock","skipPendingPhoenixDataChangeSync","ignore","RootValueSentinel","valueAttrName","rootAttrsAttrName","unmountLock","onDataChange","onFocusChange","EditorsRegistry","EditorHookImpl","has","unmountEffect","editorContext","preset","contextId","editableHeight","useWatchdog","Constructor","buildAndCreateEditor","requiredRoots","checkIfAllRootsArePresent","waitForAllRootsToBePresent","causesRestart","prevEditor","newInstance","rootId","EditorHook","EditableHookImpl","editableId","ui","editable","unsyncInput","syncEditorRootToInput","EditableHook","sync","debouncedSync","UIPartHookImpl","uiViewName","mapUIPartView","uiPart","UIPartHook","Hooks"],"mappings":"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AAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,QAAS,OAAO,KAAM,QAAO,iCAAiC,EACnE,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,QAAS,OAAO,KAAM,QAAO,iCAAiC,EACnE,IAAK,QAAS,OAAO,KAAM,QAAO,iCAAiC,EACnE,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,QAAS,OAAO,KAAM,QAAO,iCAAiC,EACnE,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BAA8B,EAC7D,IAAK,KAAM,OAAO,KAAM,QAAO,8BA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"}