ckeditor5-symfony 1.9.0 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/elements/editor/editor.d.ts.map +1 -1
  2. package/dist/elements/editor/utils/assign-editor-roots-to-config.d.ts +17 -0
  3. package/dist/elements/editor/utils/assign-editor-roots-to-config.d.ts.map +1 -0
  4. package/dist/elements/editor/utils/index.d.ts +2 -3
  5. package/dist/elements/editor/utils/index.d.ts.map +1 -1
  6. package/dist/elements/editor/utils/query-all-editor-editables.d.ts +23 -0
  7. package/dist/elements/editor/utils/query-all-editor-editables.d.ts.map +1 -0
  8. package/dist/index.cjs +2 -2
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.mjs +250 -299
  11. package/dist/index.mjs.map +1 -1
  12. package/package.json +1 -1
  13. package/src/elements/editor/editor.ts +44 -65
  14. package/src/elements/editor/utils/assign-editor-roots-to-config.ts +60 -0
  15. package/src/elements/editor/utils/index.ts +2 -3
  16. package/src/elements/editor/utils/query-all-editor-editables.ts +74 -0
  17. package/dist/elements/editor/utils/assign-initial-data-to-editor-config.d.ts +0 -10
  18. package/dist/elements/editor/utils/assign-initial-data-to-editor-config.d.ts.map +0 -1
  19. package/dist/elements/editor/utils/assign-source-elements-to-editor-config.d.ts +0 -12
  20. package/dist/elements/editor/utils/assign-source-elements-to-editor-config.d.ts.map +0 -1
  21. package/dist/elements/editor/utils/query-editor-editables.d.ts +0 -25
  22. package/dist/elements/editor/utils/query-editor-editables.d.ts.map +0 -1
  23. package/src/elements/editor/utils/assign-initial-data-to-editor-config.ts +0 -47
  24. package/src/elements/editor/utils/assign-source-elements-to-editor-config.ts +0 -60
  25. package/src/elements/editor/utils/query-editor-editables.ts +0 -101
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/shared/are-maps-equal.ts","../src/shared/async-registry.ts","../src/shared/debounce.ts","../src/shared/filter-object-values.ts","../src/shared/is-empty-object.ts","../src/shared/map-object-values.ts","../src/shared/uid.ts","../src/shared/wait-for.ts","../src/shared/wait-for-dom-ready.ts","../src/elements/editor/utils/assign-initial-data-to-editor-config.ts","../src/elements/editor/utils/assign-source-elements-to-editor-config.ts","../src/elements/editor/utils/create-editor-in-context.ts","../src/elements/editor/utils/get-editor-roots-values.ts","../src/elements/editor/utils/is-multiroot-editor-instance.ts","../src/elements/editor/utils/is-single-root-editor.ts","../src/ckeditor5-symfony-error.ts","../src/elements/editor/utils/load-editor-constructor.ts","../src/elements/editor/custom-editor-plugins.ts","../src/elements/editor/utils/load-editor-plugins.ts","../src/elements/editor/utils/load-editor-translations.ts","../src/elements/editor/utils/normalize-custom-translations.ts","../src/elements/editor/utils/query-all-editor-ids.ts","../src/elements/editor/utils/query-editor-editables.ts","../src/elements/editor/utils/resolve-editor-config-elements-references.ts","../src/elements/editor/utils/resolve-editor-config-translations.ts","../src/elements/editor/utils/set-editor-editable-height.ts","../src/elements/editor/utils/wrap-with-watchdog.ts","../src/elements/context/contexts-registry.ts","../src/elements/context/context.ts","../src/elements/editor/editors-registry.ts","../src/elements/editable.ts","../src/elements/editor/plugins/dispatch-editor-roots-change-event.ts","../src/elements/editor/plugins/sync-editor-with-input.ts","../src/elements/editor/editor.ts","../src/elements/ui-part.ts","../src/elements/register-custom-elements.ts","../src/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 start -- @preserve */\n }\n catch (err) {\n console.error(err);\n throw err;\n /* v8 ignore end */\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","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 * Filters the values of an object based on a provided filter function.\n *\n * @param obj The object to filter.\n * @param filter The filter function that determines whether a value should be included.\n * @returns A new object containing only the key-value pairs that passed the filter.\n */\nexport function filterObjectValues<T>(\n obj: Record<string, T>,\n filter: (value: T, key: string) => boolean,\n): Record<string, T> {\n const filteredEntries = Object\n .entries(obj)\n .filter(([key, value]) => filter(value, key));\n\n return Object.fromEntries(filteredEntries);\n}\n","export function isEmptyObject(obj: Record<string, unknown>): boolean {\n return Object.keys(obj).length === 0 && obj.constructor === Object;\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","/**\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","/**\n * Returns a promise that resolves when the DOM is fully loaded and ready.\n */\nexport function waitForDOMReady(): Promise<void> {\n return new Promise((resolve) => {\n switch (document.readyState) {\n case 'loading':\n document.addEventListener('DOMContentLoaded', () => resolve(), { once: true });\n break;\n\n case 'interactive':\n case 'complete':\n setTimeout(resolve, 0);\n break;\n\n default:\n console.warn('Unexpected document.readyState:', document.readyState);\n setTimeout(resolve, 0);\n }\n });\n}\n","import type { EditorConfig } from 'ckeditor5';\n\n/**\n * Assigns initial data to specified editor config.\n *\n * @param dataOrMap Initial data to be assigned to config.\n * @param config Config of the editor.\n * @returns The updated configuration object.\n */\nexport function assignInitialDataToEditorConfig<C extends EditorConfig>(\n dataOrMap: string | Record<string, string>,\n config: C,\n): C {\n const dataMap = toDataMap(dataOrMap);\n const allRootsKeys = new Set([\n ...Object.keys(dataMap),\n ...Object.keys(config.roots ?? {}),\n ]);\n\n const rootsConfig = Array.from(allRootsKeys).reduce((acc, rootKey) => ({\n ...acc,\n [rootKey]: {\n ...config.roots?.[rootKey],\n ...rootKey === 'main' ? config.root : {},\n\n /* v8 ignore next 5 */\n ...rootKey in dataMap\n ? {\n initialData: dataMap[rootKey],\n }\n : {},\n },\n }), Object.create(config.roots || {}));\n\n const mappedConfig: C = {\n ...config,\n roots: rootsConfig,\n };\n\n delete mappedConfig.root;\n\n return mappedConfig;\n}\n\nfunction toDataMap(element: string | Record<string, string>): Record<string, string> {\n return typeof element === 'string' ? { main: element } : { ...element };\n}\n","import type { EditorConfig } from 'ckeditor5';\n\nimport type { EditorRelaxedConstructor } from '../types/editor-relaxed-constructor.type';\n\n/**\n * Assigns a DOM element to the editor configuration in a way that is compatible with the specific editor type.\n *\n * @param Editor Constructor of the editor used to determine the location of element config entry.\n * @param elementOrMap Element to be assigned to config.\n * @param config Config of the editor.\n * @returns The updated configuration object.\n */\nexport function assignSourceElementsToEditorConfig<C extends EditorConfig>(\n Editor: EditorRelaxedConstructor,\n elementOrMap: HTMLElement | Record<string, HTMLElement>,\n config: C,\n): C {\n const elementsMap = toElementsMap(elementOrMap);\n\n if (!Editor.editorName || Editor.editorName === 'ClassicEditor') {\n return {\n ...config,\n attachTo: elementsMap['main'],\n };\n }\n\n const allRootsKeys = new Set([\n ...Object.keys(elementsMap),\n ...Object.keys(config.roots ?? {}),\n ]);\n\n const rootsConfig = Array.from(allRootsKeys).reduce((acc, rootKey) => ({\n ...acc,\n [rootKey]: {\n /* v8 ignore next */\n ...config.roots?.[rootKey],\n ...rootKey === 'main' ? config.root : {},\n\n /* v8 ignore next 5 */\n ...rootKey in elementsMap\n ? {\n element: elementsMap[rootKey],\n }\n : {},\n },\n }), Object.create(config.roots || {}));\n\n const mappedConfig: C = {\n ...config,\n roots: rootsConfig,\n };\n\n delete mappedConfig.root;\n\n return mappedConfig;\n}\n\nfunction toElementsMap(element: HTMLElement | Record<string, HTMLElement>): Record<string, HTMLElement> {\n return element instanceof HTMLElement ? { main: element } : { ...element };\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 } from 'ckeditor5';\n\n/**\n * Gets values of all editor roots.\n *\n * @param editor The editor instance.\n * @returns A record where keys are root names and values are root HTML strings.\n */\nexport function getEditorRootsValues(editor: Editor): Record<string, string> {\n return Array\n .from(editor.model.document.getRoots())\n .reduce<Record<string, string>>((acc, root) => {\n if (root.rootName === '$graveyard') {\n return acc;\n }\n\n acc[root.rootName] = editor.getData({ rootName: root.rootName });\n\n return acc;\n }, Object.create({}));\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","/**\n * Custom error class for CKEditor5 Symfony-related errors.\n */\nexport class CKEditor5SymfonyError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CKEditor5SymfonyError';\n }\n}\n","import type { EditorType } from '../typings';\n\nimport { CKEditor5SymfonyError } from '../../../ckeditor5-symfony-error';\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 CKEditor5SymfonyError(`Unsupported editor type: ${type}`);\n }\n\n return EditorConstructor;\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport type { CanBePromise } from '../../types';\n\nimport { CKEditor5SymfonyError } from '../../ckeditor5-symfony-error';\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 CKEditor5SymfonyError(`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 CKEditor5SymfonyError(`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 { CKEditor5SymfonyError } from '../../../ckeditor5-symfony-error';\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 // If the plugin is not found in the base package, try custom plugins.\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 throw new CKEditor5SymfonyError(`Plugin \"${plugin}\" not found in base package and failed to load premium package.`);\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 CKEditor5SymfonyError(`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","import type { Translations } from 'ckeditor5';\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): Promise<Translations[]> {\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","/**\n * Queries all CKEditor 5 editor IDs present in the document.\n */\nexport function queryAllEditorIds(): string[] {\n return Array\n .from(document.querySelectorAll<HTMLElement>('cke5-editor'))\n .map(element => element.getAttribute('data-cke-editor-id'))\n .filter((id): id is string => id !== null);\n}\n","import type { EditorId } from '../typings';\n\nimport { filterObjectValues, mapObjectValues } from '../../../shared';\n\n/**\n * Gets the initial root elements for the editor based on its type.\n *\n * @param editorId The editor's ID.\n * @returns The root element(s) for the editor.\n */\nexport function queryEditablesElements(editorId: EditorId) {\n const editables = queryAllEditorEditables(editorId);\n\n return mapObjectValues(editables, ({ element }) => element);\n}\n\n/**\n * Gets the initial data for the roots of the editor. If the editor is a single editing-like editor,\n * it retrieves the initial value from the element's attribute. Otherwise, it returns an object mapping\n * editable names to their initial values.\n *\n * @param editorId The editor's ID.\n * @returns The initial values for the editor's roots.\n */\nexport function queryEditablesSnapshotContent(editorId: EditorId) {\n const editables = queryAllEditorEditables(editorId);\n const values = mapObjectValues(editables, ({ content }) => content);\n\n return filterObjectValues(values, value => typeof value === 'string') as Record<string, string>;\n}\n\n/**\n * Queries all editable elements within a specific editor instance. It picks\n * initial values from actually rendered elements or from the editor container's.\n *\n * It may differ from the `initialData` used during editor creation, as it might\n * not set all roots or set different values.\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 */\nfunction queryAllEditorEditables(editorId: EditorId) {\n const acc = (\n Array\n .from(document.querySelectorAll<HTMLElement>(`cke5-editable[data-cke-editor-id=\"${editorId}\"]`))\n .reduce<Record<string, EditableItem>>((acc, element) => {\n const rootName = element.getAttribute('data-cke-root-name')!;\n const content = element.getAttribute('data-cke-content');\n\n acc[rootName] = {\n element: element.querySelector<HTMLElement>('[data-cke-editable-content]')!,\n content,\n };\n\n return acc;\n }, Object.create({}))\n );\n\n const editor = document.querySelector<HTMLElement>(`cke5-editor[data-cke-editor-id=\"${editorId}\"]`);\n\n /* v8 ignore next 3 */\n if (!editor) {\n return acc;\n }\n\n const currentMain = acc['main'];\n const initialRootEditableValue = JSON.parse(editor.getAttribute('data-cke-content')!);\n const contentElement = document.querySelector<HTMLElement>(`#${editorId}_editor `);\n\n // If found `main` editable, but it has no content, try to fill it from the editor container.\n if (currentMain && initialRootEditableValue?.['main']) {\n return {\n ...acc,\n main: {\n ...currentMain,\n content: currentMain.content || initialRootEditableValue['main'],\n },\n };\n }\n\n // If no `main` editable found, try to create it from the editor container.\n if (contentElement) {\n return {\n ...acc,\n main: {\n element: contentElement,\n content: initialRootEditableValue?.['main'] || null,\n },\n };\n }\n\n return acc;\n}\n\n/**\n * Type representing an editable item within an editor.\n */\nexport type EditableItem = {\n element: HTMLElement;\n content: string | null;\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('symfony-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 { Context, ContextWatchdog } from 'ckeditor5';\n\nimport type { EditorLanguage } from '../editor';\nimport type { ContextConfig } from './typings';\n\nimport { isEmptyObject, waitForDOMReady } from '../../shared';\nimport {\n loadAllEditorTranslations,\n loadEditorPlugins,\n normalizeCustomTranslations,\n resolveEditorConfigElementReferences,\n resolveEditorConfigTranslations,\n} from '../editor/utils';\nimport { ContextsRegistry } from './contexts-registry';\n\n/**\n * The Symfony hook that mounts CKEditor context instances.\n */\nexport class ContextComponentElement extends HTMLElement {\n /**\n * The promise that resolves to the context instance.\n */\n private contextPromise: Promise<ContextWatchdog<Context>> | null = null;\n\n /**\n * Mounts the context component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n const contextId = this.getAttribute('data-cke-context-id')!;\n const language = JSON.parse(this.getAttribute('data-cke-language')!) as EditorLanguage;\n const contextConfig = JSON.parse(this.getAttribute('data-cke-context')!) as ContextConfig;\n\n const { customTranslations, watchdogConfig, config: { plugins, ...config } } = contextConfig;\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 || {}),\n ]\n .filter(translations => !isEmptyObject(translations));\n\n // Initialize context with watchdog.\n this.contextPromise = (async () => {\n const { ContextWatchdog, Context } = await import('ckeditor5');\n\n const instance = new ContextWatchdog(Context, {\n crashNumberLimit: 10,\n ...watchdogConfig,\n });\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(\n [...mixedTranslations].reverse(),\n language.ui,\n resolvedConfig,\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.isConnected) {\n ContextsRegistry.the.register(contextId, context);\n }\n }\n\n /**\n * Destroys the context component. Unmounts root from the editor.\n */\n async disconnectedCallback() {\n const contextId = this.getAttribute('data-cke-context-id');\n\n // Let's hide the element during destruction to prevent flickering.\n this.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 (contextId && ContextsRegistry.the.hasItem(contextId)) {\n ContextsRegistry.the.unregister(contextId);\n }\n }\n }\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 { DecoupledEditor, MultiRootEditor } from 'ckeditor5';\n\nimport { CKEditor5SymfonyError } from '../ckeditor5-symfony-error';\nimport { debounce, waitForDOMReady } from '../shared';\nimport { EditorsRegistry } from './editor/editors-registry';\nimport { isMultirootEditorInstance, queryAllEditorIds } from './editor/utils';\n\n/**\n * Editable hook for Symfony. It allows you to create editables for multi-root editors.\n */\nexport class EditableComponentElement extends HTMLElement {\n /**\n * Stops observing the editor registry and immediately runs any pending cleanup.\n */\n private unmountEffect: VoidFunction | null = null;\n\n /**\n * Mounts the editable component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n if (!this.hasAttribute('data-cke-editor-id')) {\n this.setAttribute('data-cke-editor-id', queryAllEditorIds()[0]!);\n }\n\n const editorId = this.getAttribute('data-cke-editor-id');\n const rootName = this.getAttribute('data-cke-root-name');\n const content = this.getAttribute('data-cke-content');\n const saveDebounceMs = Number.parseInt(this.getAttribute('data-cke-save-debounce-ms')!, 10);\n\n /* v8 ignore next 3 */\n if (!editorId || !rootName) {\n throw new CKEditor5SymfonyError('Editor ID or Root Name is missing.');\n }\n\n // If the editor is not registered yet, we will wait for it to be registered.\n this.style.display = 'block';\n\n this.unmountEffect = EditorsRegistry.the.mountEffect(editorId, (editor: DecoupledEditor | MultiRootEditor) => {\n if (!this.isConnected) {\n return;\n }\n\n const input = this.querySelector('input') as HTMLInputElement | null;\n\n if (editor.model.document.getRoot(rootName)) {\n // If the newly added root already exists, but the newly added editable has content,\n // we need to update the root data with the editable content.\n if (content !== null) {\n const data = editor.getData({ rootName });\n\n if (data && data !== content) {\n editor.setData({\n [rootName]: content,\n });\n }\n }\n\n return;\n }\n\n if (isMultirootEditorInstance(editor)) {\n const { ui, editing } = editor;\n\n editor.addRoot(rootName, {\n isUndoable: false,\n ...content !== null && {\n initialData: content,\n },\n });\n\n const contentElement = this.querySelector('[data-cke-editable-content]') as HTMLElement | null;\n const editable = ui.view.createEditable(rootName, contentElement!);\n\n ui.addEditable(editable);\n editing.view.forceRender();\n }\n\n // Sync data with socket and input element.\n const sync = () => {\n const html = editor.getData({ rootName });\n\n if (input) {\n input.value = html;\n input.dispatchEvent(new Event('input'));\n }\n\n this.dispatchEvent(new CustomEvent('change', { detail: { value: html } }));\n };\n\n const debouncedSync = debounce(saveDebounceMs, 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 if (editor.state !== 'destroyed' && rootName) {\n const root = editor.model.document.getRoot(rootName);\n\n if (root && isMultirootEditorInstance(editor)) {\n // Detaching editables seem to be buggy when something removed DOM element of the editable (e.g. Blazor re-render) before\n // the editable is unmounted. To prevent errors in such cases, we will try to detach the editable if it exists, but ignore errors.\n try {\n if (editor.ui.view.editables[rootName]) {\n editor.detachEditable(root);\n }\n /* v8 ignore start -- @preserve */\n }\n catch (err) {\n // Ignore errors when detaching editable.\n console.error('Unable unmount editable from root:', err);\n }\n /* v8 ignore end */\n\n if (root.isAttached()) {\n editor.detachRoot(rootName, false);\n }\n }\n }\n };\n });\n }\n\n /**\n * Destroys the editable component. Unmounts root from the editor.\n */\n disconnectedCallback() {\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Stop observing the registry and run cleanup immediately.\n this.unmountEffect?.();\n this.unmountEffect = null;\n }\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport { debounce } from '../../../shared';\nimport { getEditorRootsValues } from '../utils';\n\n/**\n * Creates a DispatchEditorRootsChangeEvent plugin class.\n */\nexport async function createDispatchEditorRootsChangeEventPlugin(\n {\n saveDebounceMs,\n editorId,\n targetElement,\n }: CreateDispatchEditorRootsChangeEventPluginParams,\n): Promise<PluginConstructor> {\n const { Plugin } = await import('ckeditor5');\n\n return class DispatchEditorRootsChangeEvent extends Plugin {\n /**\n * The name of the plugin.\n */\n static get pluginName() {\n return 'DispatchEditorRootsChangeEvent' as const;\n }\n\n /**\n * Initializes the plugin.\n */\n public afterInit(): void {\n const sync = debounce(saveDebounceMs, this.dispatch);\n\n this.editor.model.document.on('change:data', sync);\n this.editor.once('ready', this.dispatch);\n }\n\n /**\n * Dispatches a custom event with all roots data.\n */\n private dispatch = (): void => {\n targetElement.dispatchEvent(\n new CustomEvent('ckeditor5:change:data', {\n detail: {\n editorId,\n editor: this.editor,\n roots: getEditorRootsValues(this.editor),\n },\n bubbles: true,\n }),\n );\n };\n };\n}\n\ntype CreateDispatchEditorRootsChangeEventPluginParams = {\n saveDebounceMs: number;\n editorId: string;\n targetElement: HTMLElement;\n};\n","import type { ClassicEditor, PluginConstructor } from 'ckeditor5';\n\nimport { debounce } from '../../../shared';\n\n/**\n * Creates a SyncEditorWithInput plugin class.\n */\nexport async function createSyncEditorWithInputPlugin(saveDebounceMs: number): 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 const editorElement = (editor as ClassicEditor).sourceElement as HTMLElement;\n\n // Try to find the associated input field.\n const editorId = editorElement.id.replace(/_editor$/, '');\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 if (this.input) {\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 /**\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","import type { Editor } from 'ckeditor5';\n\nimport type { EditorId, EditorLanguage, EditorPreset } from './typings';\n\nimport { isEmptyObject, waitFor, waitForDOMReady } from '../../shared';\nimport { ContextsRegistry } from '../context';\nimport { EditorsRegistry } from './editors-registry';\nimport {\n createDispatchEditorRootsChangeEventPlugin,\n createSyncEditorWithInputPlugin,\n} from './plugins';\nimport {\n assignInitialDataToEditorConfig,\n assignSourceElementsToEditorConfig,\n createEditorInContext,\n isSingleRootEditor,\n loadAllEditorTranslations,\n loadEditorConstructor,\n loadEditorPlugins,\n normalizeCustomTranslations,\n queryEditablesElements,\n queryEditablesSnapshotContent,\n resolveEditorConfigElementReferences,\n resolveEditorConfigTranslations,\n setEditorEditableHeight,\n unwrapEditorContext,\n unwrapEditorWatchdog,\n wrapWithWatchdog,\n} from './utils';\n\n/**\n * The Symfony hook that manages the lifecycle of CKEditor5 instances.\n */\nexport class EditorComponentElement extends HTMLElement {\n /**\n * Stops observing the editor registry and immediately runs any pending cleanup.\n */\n private unmountEffect: VoidFunction | null = null;\n\n /**\n * Mounts the editor component.\n */\n async connectedCallback(): Promise<void> {\n await waitForDOMReady();\n await this.initializeEditor();\n }\n\n /**\n * Initializes the editor instance.\n */\n private async initializeEditor(): Promise<void> {\n const editorId = this.getAttribute('data-cke-editor-id')!;\n\n EditorsRegistry.the.resetErrors(editorId);\n\n try {\n this.style.display = 'block';\n\n const editor = await this.createEditor();\n const editorContext = unwrapEditorContext(editor);\n const watchdog = unwrapEditorWatchdog(editor);\n\n // Do not even try to broadcast about the registration of the editor\n // if hook was immediately destroyed.\n if (this.isConnected) {\n // Run some stuff that have to be reinitialized every-time editor is being restarted.\n const unmountDestroyWatchers = 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 destroyed editor \"externally\" or user manually\n // called `.destroy()`. Keep pending callbacks though.\n EditorsRegistry.the.unregister(editorId, false);\n }, { priority: 'highest' });\n });\n\n this.unmountEffect = async () => {\n // If for some reason editor not fired `destroy`, enforce deregistration.\n EditorsRegistry.the.unregister(editorId);\n unmountDestroyWatchers();\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 /* v8 ignore next 7 */\n }\n catch (error: any) {\n console.error(`Error initializing CKEditor5 instance with ID \"${editorId}\":`, error);\n this.unmountEffect = null;\n EditorsRegistry.the.error(editorId, error);\n }\n }\n\n /**\n * Destroys the editor instance when the component is destroyed.\n * This is important to prevent memory leaks and ensure that the editor is properly cleaned up.\n */\n disconnectedCallback() {\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Stop observing the registry and run cleanup immediately.\n this.unmountEffect?.();\n this.unmountEffect = null;\n }\n\n /**\n * Creates the CKEditor instance.\n */\n private async createEditor(): Promise<Editor> {\n const editorId = this.getAttribute('data-cke-editor-id')!;\n const preset = JSON.parse(this.getAttribute('data-cke-preset')!) as EditorPreset;\n const contextId = this.getAttribute('data-cke-context-id');\n const editableHeight = this.getAttribute('data-cke-editable-height') ? Number.parseInt(this.getAttribute('data-cke-editable-height')!, 10) : null;\n const saveDebounceMs = Number.parseInt(this.getAttribute('data-cke-save-debounce-ms')!, 10);\n const language = JSON.parse(this.getAttribute('data-cke-language')!) as EditorLanguage;\n const useWatchdog = this.hasAttribute('data-cke-watchdog');\n const content = JSON.parse(this.getAttribute('data-cke-content')!) as Record<string, string>;\n\n const {\n customTranslations,\n editorType,\n licenseKey,\n config: { plugins, ...config },\n } = preset;\n\n const Constructor = await loadEditorConstructor(editorType);\n const context = await (\n contextId\n ? ContextsRegistry.the.waitFor(contextId)\n : null\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 loadedPlugins.push(\n await createDispatchEditorRootsChangeEventPlugin({\n saveDebounceMs,\n editorId,\n targetElement: this,\n }),\n );\n\n if (isSingleRootEditor(editorType)) {\n loadedPlugins.push(\n await createSyncEditorWithInputPlugin(saveDebounceMs),\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 || {}),\n ]\n .filter(translations => !isEmptyObject(translations));\n\n // Let's query all elements, and create basic configuration.\n let initialData: string | Record<string, string> = {\n ...content,\n ...queryEditablesSnapshotContent(editorId),\n };\n\n if (isSingleRootEditor(editorType)) {\n initialData = initialData['main'] || '';\n }\n\n // Depending of the editor type, and parent lookup for nearest context or initialize it without it.\n const editor = await (async () => {\n let sourceElements: HTMLElement | Record<string, HTMLElement> = queryEditablesElements(editorId);\n\n // Handle special case when user specified `initialData` of several root elements, but editable components\n // are not yet present in the DOM. In other words - editor is initialized before attaching root elements.\n if (!sourceElements['main']) {\n const requiredRoots = (\n isSingleRootEditor(editorType)\n ? ['main']\n : Object.keys(initialData as Record<string, string>)\n );\n\n if (!checkIfAllRootsArePresent(sourceElements, requiredRoots)) {\n sourceElements = await waitForAllRootsToBePresent(editorId, requiredRoots);\n initialData = {\n ...content,\n ...queryEditablesSnapshotContent(editorId),\n };\n }\n }\n\n // If single root editor, unwrap the element from the object.\n if (isSingleRootEditor(editorType) && 'main' in sourceElements) {\n sourceElements = sourceElements['main'];\n }\n\n let resolvedConfig = {\n ...config,\n licenseKey,\n plugins: loadedPlugins,\n language,\n ...mixedTranslations.length && {\n translations: mixedTranslations,\n },\n };\n\n // Do some postprocessing on received configuration.\n resolvedConfig = resolveEditorConfigElementReferences(resolvedConfig);\n resolvedConfig = resolveEditorConfigTranslations([...mixedTranslations].reverse(), language.ui, resolvedConfig);\n resolvedConfig = assignSourceElementsToEditorConfig(Constructor, sourceElements, resolvedConfig);\n resolvedConfig = assignInitialDataToEditorConfig(initialData, resolvedConfig);\n\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(editorType) && 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 watchdogInstance = await wrapWithWatchdog(buildAndCreateEditor);\n\n watchdogInstance.on('restart', () => {\n const newInstance = watchdogInstance.editor!;\n\n EditorsRegistry.the.register(editorId, newInstance);\n });\n\n await watchdogInstance.create({});\n\n return watchdogInstance.editor!;\n }\n\n return buildAndCreateEditor();\n }\n}\n\n/**\n * Checks if all required root elements are present in the elements object.\n *\n * @param elements The elements object mapping root IDs to HTMLElements.\n * @param requiredRoots The list of required root IDs.\n * @returns True if all required roots are present, false otherwise.\n */\nfunction checkIfAllRootsArePresent(elements: Record<string, HTMLElement>, requiredRoots: string[]): boolean {\n return requiredRoots.every(rootId => elements[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 IDs.\n * @returns A promise that resolves to the record of root elements.\n */\nasync function waitForAllRootsToBePresent(\n editorId: EditorId,\n requiredRoots: string[],\n): Promise<Record<string, HTMLElement>> {\n return waitFor(\n () => {\n const elements = queryEditablesElements(editorId) as unknown as Record<string, HTMLElement>;\n\n if (!checkIfAllRootsArePresent(elements, 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 => !elements[rootId]).join(', ')}.`,\n );\n }\n\n return elements;\n },\n { timeOutAfter: 2000, retryAfter: 100 },\n );\n}\n","import { CKEditor5SymfonyError } from '../ckeditor5-symfony-error';\nimport { waitForDOMReady } from '../shared';\nimport { EditorsRegistry } from './editor/editors-registry';\nimport { queryAllEditorIds } from './editor/utils';\n\n/**\n * UI Part hook for Symfony. It allows you to create UI parts for multi-root editors.\n */\nexport class UIPartComponentElement extends HTMLElement {\n /**\n * Stops observing the editor registry and immediately runs any pending cleanup.\n */\n private unmountEffect: VoidFunction | null = null;\n\n /**\n * Mounts the UI part component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n const editorId = this.getAttribute('data-cke-editor-id') || queryAllEditorIds()[0]!;\n const name = this.getAttribute('data-cke-name');\n\n /* v8 ignore next 3 */\n if (!editorId || !name) {\n return;\n }\n\n // If the editor is not registered yet, we will wait for it to be registered.\n this.style.display = 'block';\n\n this.unmountEffect = EditorsRegistry.the.mountEffect(editorId, (editor) => {\n if (!this.isConnected) {\n return;\n }\n\n const { ui } = editor;\n\n const uiViewName = mapUIPartView(name);\n const uiPart = (ui.view as any)[uiViewName!];\n\n /* v8 ignore next 3 */\n if (!uiPart) {\n throw new CKEditor5SymfonyError(`Unknown UI part name: \"${name}\". Supported names are \"toolbar\" and \"menubar\".`);\n }\n\n this.appendChild(uiPart.element);\n\n return () => {\n this.innerHTML = '';\n };\n });\n }\n\n /**\n * Destroys the UI part component. Unmounts UI parts from the editor.\n */\n disconnectedCallback() {\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Stop observing the registry and run cleanup immediately.\n this.unmountEffect?.();\n this.unmountEffect = null;\n }\n}\n\n/**\n * Maps the UI part name to the corresponding view in the editor.\n *\n * @param name The name of the UI part.\n * @returns The name of the 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 /* v8 ignore next 3 */\n default:\n return null;\n }\n}\n","import { ContextComponentElement } from './context';\nimport { EditableComponentElement } from './editable';\nimport { EditorComponentElement } from './editor';\nimport { UIPartComponentElement } from './ui-part';\n\nconst CUSTOM_ELEMENTS = {\n 'cke5-editor': EditorComponentElement,\n 'cke5-context': ContextComponentElement,\n 'cke5-ui-part': UIPartComponentElement,\n 'cke5-editable': EditableComponentElement,\n};\n\n/**\n * Registers all available Symfony component hooks.\n */\nexport function registerCustomElements() {\n for (const [name, CustomElement] of Object.entries(CUSTOM_ELEMENTS)) {\n if (window.customElements.get(name)) {\n continue;\n }\n\n window.customElements.define(name, CustomElement);\n }\n}\n","import { registerCustomElements } from './elements';\n\nexport { CKEditor5SymfonyError } from './ckeditor5-symfony-error';\nexport { ContextsRegistry } from './elements/context/contexts-registry';\nexport { EditableComponentElement } from './elements/editable';\nexport { EditorComponentElement } from './elements/editor';\nexport { CustomEditorPluginsRegistry } from './elements/editor/custom-editor-plugins';\nexport { EditorsRegistry } from './elements/editor/editors-registry';\nexport { UIPartComponentElement } from './elements/ui-part';\n\nregisterCustomElements();\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","debounce","delay","timeoutId","args","filterObjectValues","obj","filter","filteredEntries","isEmptyObject","mapObjectValues","mapper","mappedEntries","uid","waitFor","timeOutAfter","retryAfter","startTime","lastError","timeoutTimerId","tick","result","waitForDOMReady","assignInitialDataToEditorConfig","dataOrMap","config","dataMap","toDataMap","allRootsKeys","rootsConfig","acc","rootKey","mappedConfig","element","assignSourceElementsToEditorConfig","Editor","elementOrMap","elementsMap","toElementsMap","CONTEXT_EDITOR_WATCHDOG_SYMBOL","createEditorInContext","context","creator","editorContextId","editor","contextDescriptor","originalDestroy","unwrapEditorContext","getEditorRootsValues","root","isMultirootEditorInstance","isSingleRootEditor","editorType","CKEditor5SymfonyError","message","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","queryAllEditorIds","queryEditablesElements","editorId","editables","queryAllEditorEditables","queryEditablesSnapshotContent","values","content","rootName","currentMain","initialRootEditableValue","contentElement","resolveEditorConfigElementReferences","anyObj","resolveEditorConfigTranslations","getTranslationValue","langData","setEditorEditableHeight","instance","height","editing","writer","EDITOR_WATCHDOG_SYMBOL","wrapWithWatchdog","factory","watchdogConfig","EditorWatchdog","watchdog","unwrapEditorWatchdog","ContextsRegistry","ContextComponentElement","contextId","contextConfig","customTranslations","loadedPlugins","mixedTranslations","ContextWatchdog","Context","resolvedConfig","EditorsRegistry","EditableComponentElement","saveDebounceMs","input","data","ui","editable","sync","html","debouncedSync","createDispatchEditorRootsChangeEventPlugin","targetElement","Plugin","createSyncEditorWithInputPlugin","newValue","EditorComponentElement","editorContext","unmountDestroyWatchers","preset","editableHeight","useWatchdog","licenseKey","Constructor","buildAndCreateEditor","initialData","sourceElements","requiredRoots","checkIfAllRootsArePresent","waitForAllRootsToBePresent","watchdogInstance","newInstance","elements","rootId","UIPartComponentElement","uiViewName","mapUIPartView","uiPart","CUSTOM_ELEMENTS","registerCustomElements","CustomElement"],"mappings":"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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,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,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,UAAW,OAAO,KAAM,QAAO,mCAAmC,EACvE,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,QAAS,OAAO,KAAM,QAAO,iCAAiC,EACnE,QACE,eAAQ,KAAK,YAAYA,CAAI,sCAAsC,EAC5D,IAAA,KAMX,QAAQA,EAAA,CACN,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,MAAO,OAAO,KAAM,QAAO,gDAAgD,EAChF,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,QAAS,OAAO,KAAM,QAAO,kDAAkD,EACpF,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,QAAS,OAAO,KAAM,QAAO,kDAAkD,EACpF,IAAK,QAAS,OAAO,KAAM,QAAO,kDAAkD,EACpF,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,QAAS,OAAO,KAAM,QAAO,kDAAkD,EACpF,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,I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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/shared/are-maps-equal.ts","../src/shared/async-registry.ts","../src/shared/debounce.ts","../src/shared/is-empty-object.ts","../src/shared/map-object-values.ts","../src/shared/uid.ts","../src/shared/wait-for.ts","../src/shared/wait-for-dom-ready.ts","../src/elements/editor/utils/assign-editor-roots-to-config.ts","../src/elements/editor/utils/create-editor-in-context.ts","../src/elements/editor/utils/get-editor-roots-values.ts","../src/elements/editor/utils/is-multiroot-editor-instance.ts","../src/elements/editor/utils/is-single-root-editor.ts","../src/ckeditor5-symfony-error.ts","../src/elements/editor/utils/load-editor-constructor.ts","../src/elements/editor/custom-editor-plugins.ts","../src/elements/editor/utils/load-editor-plugins.ts","../src/elements/editor/utils/load-editor-translations.ts","../src/elements/editor/utils/normalize-custom-translations.ts","../src/elements/editor/utils/query-all-editor-editables.ts","../src/elements/editor/utils/query-all-editor-ids.ts","../src/elements/editor/utils/resolve-editor-config-elements-references.ts","../src/elements/editor/utils/resolve-editor-config-translations.ts","../src/elements/editor/utils/set-editor-editable-height.ts","../src/elements/editor/utils/wrap-with-watchdog.ts","../src/elements/context/contexts-registry.ts","../src/elements/context/context.ts","../src/elements/editor/editors-registry.ts","../src/elements/editable.ts","../src/elements/editor/plugins/dispatch-editor-roots-change-event.ts","../src/elements/editor/plugins/sync-editor-with-input.ts","../src/elements/editor/editor.ts","../src/elements/ui-part.ts","../src/elements/register-custom-elements.ts","../src/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 start -- @preserve */\n }\n catch (err) {\n console.error(err);\n throw err;\n /* v8 ignore end */\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","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","export function isEmptyObject(obj: Record<string, unknown>): boolean {\n return Object.keys(obj).length === 0 && obj.constructor === Object;\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","/**\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","/**\n * Returns a promise that resolves when the DOM is fully loaded and ready.\n */\nexport function waitForDOMReady(): Promise<void> {\n return new Promise((resolve) => {\n switch (document.readyState) {\n case 'loading':\n document.addEventListener('DOMContentLoaded', () => resolve(), { once: true });\n break;\n\n case 'interactive':\n case 'complete':\n setTimeout(resolve, 0);\n break;\n\n default:\n console.warn('Unexpected document.readyState:', document.readyState);\n setTimeout(resolve, 0);\n }\n });\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 * Roots with `element: null` (pending roots not yet in the DOM) contribute only `initialData`\n * and are skipped for element assignment.\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 + content) 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 /* v8 ignore start -- @preserve */\n const rootsConfig = Array.from(allRootsKeys).reduce((acc, rootKey) => ({\n ...acc,\n [rootKey]: {\n ...config.roots?.[rootKey],\n ...rootKey === 'main' ? config.root : {},\n ...rootKey in editables\n ? {\n ...editables[rootKey]!.content !== null && {\n initialData: editables[rootKey]!.content,\n },\n ...!isClassicEditor && editables[rootKey]!.element !== null && {\n element: editables[rootKey]!.element,\n },\n }\n : {},\n },\n }), Object.create(config.roots || {}));\n /* v8 ignore stop */\n\n const mappedConfig: C = {\n ...config,\n roots: rootsConfig,\n ...isClassicEditor && editables['main']?.element && {\n attachTo: editables['main'].element,\n },\n };\n\n delete mappedConfig.root;\n\n return mappedConfig;\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 } from 'ckeditor5';\n\n/**\n * Gets values of all editor roots.\n *\n * @param editor The editor instance.\n * @returns A record where keys are root names and values are root HTML strings.\n */\nexport function getEditorRootsValues(editor: Editor): Record<string, string> {\n return Array\n .from(editor.model.document.getRoots())\n .reduce<Record<string, string>>((acc, root) => {\n if (root.rootName === '$graveyard') {\n return acc;\n }\n\n acc[root.rootName] = editor.getData({ rootName: root.rootName });\n\n return acc;\n }, Object.create({}));\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","/**\n * Custom error class for CKEditor5 Symfony-related errors.\n */\nexport class CKEditor5SymfonyError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CKEditor5SymfonyError';\n }\n}\n","import type { EditorType } from '../typings';\n\nimport { CKEditor5SymfonyError } from '../../../ckeditor5-symfony-error';\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 CKEditor5SymfonyError(`Unsupported editor type: ${type}`);\n }\n\n return EditorConstructor;\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport type { CanBePromise } from '../../types';\n\nimport { CKEditor5SymfonyError } from '../../ckeditor5-symfony-error';\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 CKEditor5SymfonyError(`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 CKEditor5SymfonyError(`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 { CKEditor5SymfonyError } from '../../../ckeditor5-symfony-error';\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 // If the plugin is not found in the base package, try custom plugins.\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 throw new CKEditor5SymfonyError(`Plugin \"${plugin}\" not found in base package and failed to load premium package.`);\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 CKEditor5SymfonyError(`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","import type { Translations } from 'ckeditor5';\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): Promise<Translations[]> {\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. It picks\n * initial values from actually rendered elements or from the editor container's\n * `data-cke-content` attribute, whichever is available.\n *\n * Roots present in the editor container's content but without a matching\n * `cke5-editable` element yet are included with `element: null` — these are\n * \"pending\" roots that haven't been attached to the DOM yet.\n *\n * @param editorId The ID of the editor to query.\n * @returns An object mapping root names to their corresponding elements and content.\n */\nexport function queryAllEditorEditables(editorId: EditorId): Record<string, EditableItem> {\n const acc = Array\n .from(document.querySelectorAll<HTMLElement>(`cke5-editable[data-cke-editor-id=\"${editorId}\"]`))\n .reduce<Record<string, EditableItem>>((acc, element) => {\n const rootName = element.getAttribute('data-cke-root-name')!;\n\n acc[rootName] = {\n element: element.querySelector<HTMLElement>('[data-cke-editable-content]'),\n content: element.getAttribute('data-cke-content'),\n };\n\n return acc;\n }, Object.create({}));\n\n const rootEditorElement = document.querySelector<HTMLElement>(`cke5-editor[data-cke-editor-id=\"${editorId}\"]`);\n\n /* v8 ignore next 3 -- @preserve */\n if (!rootEditorElement) {\n return acc;\n }\n\n /* v8 ignore next 1 -- @preserve */\n const editorContent: Record<string, string> = JSON.parse(rootEditorElement.getAttribute('data-cke-content')!) ?? {};\n const classicMainElement = document.querySelector<HTMLElement>(`#${editorId}_editor`);\n\n if (classicMainElement && !acc['main']) {\n acc['main'] = {\n element: classicMainElement,\n content: editorContent['main'] || '',\n };\n }\n\n for (const [rootName, rootContent] of Object.entries(editorContent)) {\n if (acc[rootName]) {\n // Editable element is already present — fill content from editor level if the editable didn't provide its own.\n acc[rootName] = {\n ...acc[rootName],\n content: acc[rootName].content ?? rootContent,\n };\n }\n else {\n // Root has server-provided content but its editable element hasn't been attached to the DOM yet.\n acc[rootName] = {\n element: null,\n content: rootContent,\n };\n }\n }\n\n return acc;\n}\n\n/**\n * Type representing an editable item within an editor.\n * `element` is null when the root's DOM element hasn't appeared yet (pending root).\n */\nexport type EditableItem = {\n element: HTMLElement | null;\n content: string | null;\n};\n","/**\n * Queries all CKEditor 5 editor IDs present in the document.\n */\nexport function queryAllEditorIds(): string[] {\n return Array\n .from(document.querySelectorAll<HTMLElement>('cke5-editor'))\n .map(element => element.getAttribute('data-cke-editor-id'))\n .filter((id): id is string => id !== null);\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('symfony-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 { Context, ContextWatchdog } from 'ckeditor5';\n\nimport type { EditorLanguage } from '../editor';\nimport type { ContextConfig } from './typings';\n\nimport { isEmptyObject, waitForDOMReady } from '../../shared';\nimport {\n loadAllEditorTranslations,\n loadEditorPlugins,\n normalizeCustomTranslations,\n resolveEditorConfigElementReferences,\n resolveEditorConfigTranslations,\n} from '../editor/utils';\nimport { ContextsRegistry } from './contexts-registry';\n\n/**\n * The Symfony hook that mounts CKEditor context instances.\n */\nexport class ContextComponentElement extends HTMLElement {\n /**\n * The promise that resolves to the context instance.\n */\n private contextPromise: Promise<ContextWatchdog<Context>> | null = null;\n\n /**\n * Mounts the context component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n const contextId = this.getAttribute('data-cke-context-id')!;\n const language = JSON.parse(this.getAttribute('data-cke-language')!) as EditorLanguage;\n const contextConfig = JSON.parse(this.getAttribute('data-cke-context')!) as ContextConfig;\n\n const { customTranslations, watchdogConfig, config: { plugins, ...config } } = contextConfig;\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 || {}),\n ]\n .filter(translations => !isEmptyObject(translations));\n\n // Initialize context with watchdog.\n this.contextPromise = (async () => {\n const { ContextWatchdog, Context } = await import('ckeditor5');\n\n const instance = new ContextWatchdog(Context, {\n crashNumberLimit: 10,\n ...watchdogConfig,\n });\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(\n [...mixedTranslations].reverse(),\n language.ui,\n resolvedConfig,\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.isConnected) {\n ContextsRegistry.the.register(contextId, context);\n }\n }\n\n /**\n * Destroys the context component. Unmounts root from the editor.\n */\n async disconnectedCallback() {\n const contextId = this.getAttribute('data-cke-context-id');\n\n // Let's hide the element during destruction to prevent flickering.\n this.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 (contextId && ContextsRegistry.the.hasItem(contextId)) {\n ContextsRegistry.the.unregister(contextId);\n }\n }\n }\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 { DecoupledEditor, MultiRootEditor } from 'ckeditor5';\n\nimport { CKEditor5SymfonyError } from '../ckeditor5-symfony-error';\nimport { debounce, waitForDOMReady } from '../shared';\nimport { EditorsRegistry } from './editor/editors-registry';\nimport { isMultirootEditorInstance, queryAllEditorIds } from './editor/utils';\n\n/**\n * Editable hook for Symfony. It allows you to create editables for multi-root editors.\n */\nexport class EditableComponentElement extends HTMLElement {\n /**\n * Stops observing the editor registry and immediately runs any pending cleanup.\n */\n private unmountEffect: VoidFunction | null = null;\n\n /**\n * Mounts the editable component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n if (!this.hasAttribute('data-cke-editor-id')) {\n this.setAttribute('data-cke-editor-id', queryAllEditorIds()[0]!);\n }\n\n const editorId = this.getAttribute('data-cke-editor-id');\n const rootName = this.getAttribute('data-cke-root-name');\n const content = this.getAttribute('data-cke-content');\n const saveDebounceMs = Number.parseInt(this.getAttribute('data-cke-save-debounce-ms')!, 10);\n\n /* v8 ignore next 3 */\n if (!editorId || !rootName) {\n throw new CKEditor5SymfonyError('Editor ID or Root Name is missing.');\n }\n\n // If the editor is not registered yet, we will wait for it to be registered.\n this.style.display = 'block';\n\n this.unmountEffect = EditorsRegistry.the.mountEffect(editorId, (editor: DecoupledEditor | MultiRootEditor) => {\n if (!this.isConnected) {\n return;\n }\n\n const input = this.querySelector('input') as HTMLInputElement | null;\n\n if (editor.model.document.getRoot(rootName)) {\n // If the newly added root already exists, but the newly added editable has content,\n // we need to update the root data with the editable content.\n if (content !== null) {\n const data = editor.getData({ rootName });\n\n if (data && data !== content) {\n editor.setData({\n [rootName]: content,\n });\n }\n }\n\n return;\n }\n\n if (isMultirootEditorInstance(editor)) {\n const { ui, editing } = editor;\n\n editor.addRoot(rootName, {\n isUndoable: false,\n ...content !== null && {\n initialData: content,\n },\n });\n\n const contentElement = this.querySelector('[data-cke-editable-content]') as HTMLElement | null;\n const editable = ui.view.createEditable(rootName, contentElement!);\n\n ui.addEditable(editable);\n editing.view.forceRender();\n }\n\n // Sync data with socket and input element.\n const sync = () => {\n const html = editor.getData({ rootName });\n\n if (input) {\n input.value = html;\n input.dispatchEvent(new Event('input'));\n }\n\n this.dispatchEvent(new CustomEvent('change', { detail: { value: html } }));\n };\n\n const debouncedSync = debounce(saveDebounceMs, 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 if (editor.state !== 'destroyed' && rootName) {\n const root = editor.model.document.getRoot(rootName);\n\n if (root && isMultirootEditorInstance(editor)) {\n // Detaching editables seem to be buggy when something removed DOM element of the editable (e.g. Blazor re-render) before\n // the editable is unmounted. To prevent errors in such cases, we will try to detach the editable if it exists, but ignore errors.\n try {\n if (editor.ui.view.editables[rootName]) {\n editor.detachEditable(root);\n }\n /* v8 ignore start -- @preserve */\n }\n catch (err) {\n // Ignore errors when detaching editable.\n console.error('Unable unmount editable from root:', err);\n }\n /* v8 ignore end */\n\n if (root.isAttached()) {\n editor.detachRoot(rootName, false);\n }\n }\n }\n };\n });\n }\n\n /**\n * Destroys the editable component. Unmounts root from the editor.\n */\n disconnectedCallback() {\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Stop observing the registry and run cleanup immediately.\n this.unmountEffect?.();\n this.unmountEffect = null;\n }\n}\n","import type { PluginConstructor } from 'ckeditor5';\n\nimport { debounce } from '../../../shared';\nimport { getEditorRootsValues } from '../utils';\n\n/**\n * Creates a DispatchEditorRootsChangeEvent plugin class.\n */\nexport async function createDispatchEditorRootsChangeEventPlugin(\n {\n saveDebounceMs,\n editorId,\n targetElement,\n }: CreateDispatchEditorRootsChangeEventPluginParams,\n): Promise<PluginConstructor> {\n const { Plugin } = await import('ckeditor5');\n\n return class DispatchEditorRootsChangeEvent extends Plugin {\n /**\n * The name of the plugin.\n */\n static get pluginName() {\n return 'DispatchEditorRootsChangeEvent' as const;\n }\n\n /**\n * Initializes the plugin.\n */\n public afterInit(): void {\n const sync = debounce(saveDebounceMs, this.dispatch);\n\n this.editor.model.document.on('change:data', sync);\n this.editor.once('ready', this.dispatch);\n }\n\n /**\n * Dispatches a custom event with all roots data.\n */\n private dispatch = (): void => {\n targetElement.dispatchEvent(\n new CustomEvent('ckeditor5:change:data', {\n detail: {\n editorId,\n editor: this.editor,\n roots: getEditorRootsValues(this.editor),\n },\n bubbles: true,\n }),\n );\n };\n };\n}\n\ntype CreateDispatchEditorRootsChangeEventPluginParams = {\n saveDebounceMs: number;\n editorId: string;\n targetElement: HTMLElement;\n};\n","import type { ClassicEditor, PluginConstructor } from 'ckeditor5';\n\nimport { debounce } from '../../../shared';\n\n/**\n * Creates a SyncEditorWithInput plugin class.\n */\nexport async function createSyncEditorWithInputPlugin(saveDebounceMs: number): 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 const editorElement = (editor as ClassicEditor).sourceElement as HTMLElement;\n\n // Try to find the associated input field.\n const editorId = editorElement.id.replace(/_editor$/, '');\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 if (this.input) {\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 /**\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","import type { Editor } from 'ckeditor5';\n\nimport type { EditorId, EditorLanguage, EditorPreset } from './typings';\nimport type {\n EditableItem,\n} from './utils';\n\nimport { isEmptyObject, waitFor, waitForDOMReady } from '../../shared';\nimport { ContextsRegistry } from '../context';\nimport { EditorsRegistry } from './editors-registry';\nimport {\n createDispatchEditorRootsChangeEventPlugin,\n createSyncEditorWithInputPlugin,\n} from './plugins';\nimport {\n assignEditorRootsToConfig,\n createEditorInContext,\n isSingleRootEditor,\n loadAllEditorTranslations,\n loadEditorConstructor,\n loadEditorPlugins,\n normalizeCustomTranslations,\n queryAllEditorEditables,\n resolveEditorConfigElementReferences,\n resolveEditorConfigTranslations,\n setEditorEditableHeight,\n unwrapEditorContext,\n unwrapEditorWatchdog,\n wrapWithWatchdog,\n} from './utils';\n\n/**\n * The Symfony hook that manages the lifecycle of CKEditor5 instances.\n */\nexport class EditorComponentElement extends HTMLElement {\n /**\n * Stops observing the editor registry and immediately runs any pending cleanup.\n */\n private unmountEffect: VoidFunction | null = null;\n\n /**\n * Mounts the editor component.\n */\n async connectedCallback(): Promise<void> {\n await waitForDOMReady();\n await this.initializeEditor();\n }\n\n /**\n * Initializes the editor instance.\n */\n private async initializeEditor(): Promise<void> {\n const editorId = this.getAttribute('data-cke-editor-id')!;\n\n EditorsRegistry.the.resetErrors(editorId);\n\n try {\n this.style.display = 'block';\n\n const editor = await this.createEditor();\n const editorContext = unwrapEditorContext(editor);\n const watchdog = unwrapEditorWatchdog(editor);\n\n // Do not even try to broadcast about the registration of the editor\n // if hook was immediately destroyed.\n if (this.isConnected) {\n // Run some stuff that have to be reinitialized every-time editor is being restarted.\n const unmountDestroyWatchers = 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 destroyed editor \"externally\" or user manually\n // called `.destroy()`. Keep pending callbacks though.\n EditorsRegistry.the.unregister(editorId, false);\n }, { priority: 'highest' });\n });\n\n this.unmountEffect = async () => {\n // If for some reason editor not fired `destroy`, enforce deregistration.\n EditorsRegistry.the.unregister(editorId);\n unmountDestroyWatchers();\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 /* v8 ignore next 7 */\n }\n catch (error: any) {\n console.error(`Error initializing CKEditor5 instance with ID \"${editorId}\":`, error);\n this.unmountEffect = null;\n EditorsRegistry.the.error(editorId, error);\n }\n }\n\n /**\n * Destroys the editor instance when the component is destroyed.\n * This is important to prevent memory leaks and ensure that the editor is properly cleaned up.\n */\n disconnectedCallback() {\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Stop observing the registry and run cleanup immediately.\n this.unmountEffect?.();\n this.unmountEffect = null;\n }\n\n /**\n * Creates the CKEditor instance.\n */\n private async createEditor(): Promise<Editor> {\n const editorId = this.getAttribute('data-cke-editor-id')!;\n const preset = JSON.parse(this.getAttribute('data-cke-preset')!) as EditorPreset;\n const contextId = this.getAttribute('data-cke-context-id');\n const editableHeight = this.getAttribute('data-cke-editable-height') ? Number.parseInt(this.getAttribute('data-cke-editable-height')!, 10) : null;\n const saveDebounceMs = Number.parseInt(this.getAttribute('data-cke-save-debounce-ms')!, 10);\n const language = JSON.parse(this.getAttribute('data-cke-language')!) as EditorLanguage;\n const useWatchdog = this.hasAttribute('data-cke-watchdog');\n\n const {\n customTranslations,\n editorType,\n licenseKey,\n watchdogConfig,\n config: { plugins, ...config },\n } = preset;\n\n const Constructor = await loadEditorConstructor(editorType);\n const context = await (\n contextId\n ? ContextsRegistry.the.waitFor(contextId)\n : null\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 loadedPlugins.push(\n await createDispatchEditorRootsChangeEventPlugin({\n saveDebounceMs,\n editorId,\n targetElement: this,\n }),\n );\n\n if (isSingleRootEditor(editorType)) {\n loadedPlugins.push(\n await createSyncEditorWithInputPlugin(saveDebounceMs),\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 || {}),\n ]\n .filter(translations => !isEmptyObject(translations));\n\n // Query all editable elements along with their content in one pass.\n // Roots present in the editor container's data-cke-content but not yet in the DOM\n // are included with element: null so we know which roots to wait for.\n let editables = queryAllEditorEditables(editorId);\n const requiredRoots = Object.keys(editables);\n\n if (isSingleRootEditor(editorType)) {\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,\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 // Depending of the editor type, and parent lookup for nearest context or initialize it without it.\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(editorType) && 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 watchdogInstance = await wrapWithWatchdog(buildAndCreateEditor, watchdogConfig);\n\n watchdogInstance.on('restart', () => {\n const newInstance = watchdogInstance.editor!;\n\n EditorsRegistry.the.register(editorId, newInstance);\n });\n\n await watchdogInstance.create({});\n\n return watchdogInstance.editor!;\n }\n\n return buildAndCreateEditor();\n }\n}\n\n/**\n * Checks if all required root elements are present (i.e. have a non-null element) 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 have a DOM element attached, false otherwise.\n */\nfunction checkIfAllRootsArePresent(editables: Record<string, EditableItem>, requiredRoots: string[]): boolean {\n return requiredRoots.every(rootId => editables[rootId]?.element);\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 updated editables map once all elements are attached.\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]?.element).join(', ')}.`,\n );\n }\n\n return editables;\n },\n { timeOutAfter: 2000, retryAfter: 100 },\n );\n}\n","import { CKEditor5SymfonyError } from '../ckeditor5-symfony-error';\nimport { waitForDOMReady } from '../shared';\nimport { EditorsRegistry } from './editor/editors-registry';\nimport { queryAllEditorIds } from './editor/utils';\n\n/**\n * UI Part hook for Symfony. It allows you to create UI parts for multi-root editors.\n */\nexport class UIPartComponentElement extends HTMLElement {\n /**\n * Stops observing the editor registry and immediately runs any pending cleanup.\n */\n private unmountEffect: VoidFunction | null = null;\n\n /**\n * Mounts the UI part component.\n */\n async connectedCallback() {\n await waitForDOMReady();\n\n const editorId = this.getAttribute('data-cke-editor-id') || queryAllEditorIds()[0]!;\n const name = this.getAttribute('data-cke-name');\n\n /* v8 ignore next 3 */\n if (!editorId || !name) {\n return;\n }\n\n // If the editor is not registered yet, we will wait for it to be registered.\n this.style.display = 'block';\n\n this.unmountEffect = EditorsRegistry.the.mountEffect(editorId, (editor) => {\n if (!this.isConnected) {\n return;\n }\n\n const { ui } = editor;\n\n const uiViewName = mapUIPartView(name);\n const uiPart = (ui.view as any)[uiViewName!];\n\n /* v8 ignore next 3 */\n if (!uiPart) {\n throw new CKEditor5SymfonyError(`Unknown UI part name: \"${name}\". Supported names are \"toolbar\" and \"menubar\".`);\n }\n\n this.appendChild(uiPart.element);\n\n return () => {\n this.innerHTML = '';\n };\n });\n }\n\n /**\n * Destroys the UI part component. Unmounts UI parts from the editor.\n */\n disconnectedCallback() {\n // Let's hide the element during destruction to prevent flickering.\n this.style.display = 'none';\n\n // Stop observing the registry and run cleanup immediately.\n this.unmountEffect?.();\n this.unmountEffect = null;\n }\n}\n\n/**\n * Maps the UI part name to the corresponding view in the editor.\n *\n * @param name The name of the UI part.\n * @returns The name of the 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 /* v8 ignore next 3 */\n default:\n return null;\n }\n}\n","import { ContextComponentElement } from './context';\nimport { EditableComponentElement } from './editable';\nimport { EditorComponentElement } from './editor';\nimport { UIPartComponentElement } from './ui-part';\n\nconst CUSTOM_ELEMENTS = {\n 'cke5-editor': EditorComponentElement,\n 'cke5-context': ContextComponentElement,\n 'cke5-ui-part': UIPartComponentElement,\n 'cke5-editable': EditableComponentElement,\n};\n\n/**\n * Registers all available Symfony component hooks.\n */\nexport function registerCustomElements() {\n for (const [name, CustomElement] of Object.entries(CUSTOM_ELEMENTS)) {\n if (window.customElements.get(name)) {\n continue;\n }\n\n window.customElements.define(name, CustomElement);\n }\n}\n","import { registerCustomElements } from './elements';\n\nexport { CKEditor5SymfonyError } from './ckeditor5-symfony-error';\nexport { ContextsRegistry } from './elements/context/contexts-registry';\nexport { EditableComponentElement } from './elements/editable';\nexport { EditorComponentElement } from './elements/editor';\nexport { CustomEditorPluginsRegistry } from './elements/editor/custom-editor-plugins';\nexport { EditorsRegistry } from './elements/editor/editors-registry';\nexport { UIPartComponentElement } from './elements/ui-part';\n\nregisterCustomElements();\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","debounce","delay","timeoutId","args","isEmptyObject","obj","mapObjectValues","mapper","mappedEntries","uid","waitFor","timeOutAfter","retryAfter","startTime","lastError","timeoutTimerId","tick","result","waitForDOMReady","assignEditorRootsToConfig","Editor","editables","config","isClassicEditor","allRootsKeys","rootsConfig","acc","rootKey","mappedConfig","CONTEXT_EDITOR_WATCHDOG_SYMBOL","createEditorInContext","context","creator","editorContextId","editor","contextDescriptor","originalDestroy","unwrapEditorContext","getEditorRootsValues","root","isMultirootEditorInstance","isSingleRootEditor","editorType","CKEditor5SymfonyError","message","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","element","rootName","rootEditorElement","editorContent","classicMainElement","rootContent","queryAllEditorIds","resolveEditorConfigElementReferences","anyObj","resolveEditorConfigTranslations","getTranslationValue","langData","setEditorEditableHeight","instance","height","editing","writer","EDITOR_WATCHDOG_SYMBOL","wrapWithWatchdog","factory","watchdogConfig","EditorWatchdog","watchdog","unwrapEditorWatchdog","ContextsRegistry","ContextComponentElement","contextId","contextConfig","customTranslations","loadedPlugins","mixedTranslations","ContextWatchdog","Context","resolvedConfig","EditorsRegistry","EditableComponentElement","content","saveDebounceMs","input","data","ui","contentElement","editable","sync","html","debouncedSync","createDispatchEditorRootsChangeEventPlugin","targetElement","Plugin","createSyncEditorWithInputPlugin","newValue","EditorComponentElement","editorContext","unmountDestroyWatchers","preset","editableHeight","useWatchdog","licenseKey","Constructor","buildAndCreateEditor","requiredRoots","checkIfAllRootsArePresent","waitForAllRootsToBePresent","watchdogInstance","newInstance","rootId","UIPartComponentElement","uiViewName","mapUIPartView","uiPart","CUSTOM_ELEMENTS","registerCustomElements","CustomElement"],"mappings":"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AM,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,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,8BAA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M,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,QAAS,OAAO,KAAM,QAAO,kDAAkD,EACpF,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+C,EAC9E,IAAK,KAAM,OAAO,KAAM,QAAO,+CAA+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"}